void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { return; } // Cleave Timer if (m_uiCleaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) { m_uiCleaveTimer = 7000; } } else { m_uiCleaveTimer -= uiDiff; } // Blast Wave if (m_uiBlastWaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BLAST_WAVE) == CAST_OK) { m_uiBlastWaveTimer = urand(8000, 16000); } } else { m_uiBlastWaveTimer -= uiDiff; } // Mortal Strike Timer if (m_uiMortalStrikeTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MORTAL_STRIKE) == CAST_OK) { m_uiMortalStrikeTimer = urand(25000, 35000); } } else { m_uiMortalStrikeTimer -= uiDiff; } if (m_uiKnockAwayTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_KNOCK_AWAY); // Drop 50% aggro - TODO should be scriptedEffect? if (m_creature->GetThreatManager().getThreat(m_creature->getVictim())) { m_creature->GetThreatManager().modifyThreatPercent(m_creature->getVictim(), -50); } m_uiKnockAwayTimer = urand(15000, 30000); } else { m_uiKnockAwayTimer -= uiDiff; } DoMeleeAttackIfReady(); if (EnterEvadeIfOutOfCombatArea(uiDiff)) { DoScriptText(SAY_LEASH, m_creature); } }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (EnterEvadeIfOutOfCombatArea(uiDiff)) return; if (m_bBlink) { DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_EXPLOSION : SPELL_ARCANE_EXPLOSION_H); DoCastSpellIfCan(m_creature, SPELL_ARCANE_BUBBLE, CAST_TRIGGERED); DoResetThreat(); m_bBlink = false; } if (m_uiArcaneVolleyTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_VOLLEY : SPELL_ARCANE_VOLLEY_H) == CAST_OK) m_uiArcaneVolleyTimer = urand(8000, 12000); } else m_uiArcaneVolleyTimer -= uiDiff; if (m_uiSheepTimer < uiDiff) { // second top aggro target in normal, random target in heroic if (Unit* pTarget = m_bIsRegularMode ? m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1) : m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_POLYMORPH : SPELL_POLYMORPH_H); m_uiSheepTimer = urand(15000, 17500); } else m_uiSheepTimer -= uiDiff; if (!m_bManaShield && m_creature->GetHealthPercent() < 15.0f) { if (DoCastSpellIfCan(m_creature, SPELL_MANA_SHIELD) == CAST_OK) m_bManaShield = true; } if (!m_bIsRegularMode) { if (m_uiSlowTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SLOW_H) == CAST_OK) m_uiSlowTimer = urand(15000, 24000); } else m_uiSlowTimer -= uiDiff; } if (m_creature->GetHealthPercent() < m_fHealthCheck) { if (DoCastSpellIfCan(m_creature, SPELL_BLINK, CAST_INTERRUPT_PREVIOUS) == CAST_OK) { m_bBlink = true; DoScriptText(EMOTE_ARCANE_EXP, m_creature); // There is no relationship between the health percentages switch (m_uiBlinkPhase) { case 0: m_fHealthCheck = 50.0f; break; case 1: m_fHealthCheck = 25.0f; break; case 2: m_fHealthCheck = 0.0f; break; } ++m_uiBlinkPhase; } } if (!m_bBlink) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (Phase == 1 && HealthBelowPct(20)) { Phase = 2; DoScriptText(SAY_PHASE_2, me); } if (HealthBelowPct(2)) { me->SummonGameObject(GAMEOBJECT_GIVE_OF_THE_OBSERVER, 1634.258667f, -295.101166f, 417.321381f, 0, 0, 0, 0, 0, 0); // All of them. or random? DoScriptText(SAY_DEATH_1, me); DoScriptText(SAY_DEATH_2, me); DoScriptText(SAY_DEATH_3, me); DoScriptText(SAY_DEATH_4, me); DoScriptText(SAY_DEATH_5, me); me->DisappearAndDie(); if (instance) instance->SetData(BOSS_ALGALON, DONE); return; } if (Phase == 1) { if (!Summon) { if (uiPhase_timer <= diff) { switch (uiStep) { case 1: DoScriptText(SAY_SUMMON_1, me); JumpToNextStep(3000); break; case 2: DoScriptText(SAY_SUMMON_2, me); JumpToNextStep(3000); break; case 3: DoScriptText(SAY_SUMMON_3, me); JumpToNextStep(3000); break; case 4: DoScriptText(SAY_ENGADED_FOR_FIRTS_TIME, me); JumpToNextStep(3000); break; case 5: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_AGGRESSIVE); Summon = true; break; } } else uiPhase_timer -= diff; return; } if (QuantumStrike_Timer <= diff) { DoCast(me->getVictim(), RAID_MODE(SPELL_QUANTUM_STRIKE, H_SPELL_QUANTUM_STRIKE), true); QuantumStrike_Timer = urand(4000, 14000); } else QuantumStrike_Timer -= diff; if (BigBang_Timer <= diff) { DoScriptText(RAND(SAY_BIG_BANG_1, SAY_BIG_BANG_2), me); DoCast(me->getVictim(), RAID_MODE(SPELL_BIG_BANG, H_SPELL_BIG_BANG), true); BigBang_Timer = 90000; } else BigBang_Timer -= diff; if (Ascend_Timer <= diff) { DoCast(me->getVictim(), SPELL_ASCEND, true); Ascend_Timer = 480000; } else Ascend_Timer -= diff; if (PhasePunch_Timer <= diff) { DoCast(me->getVictim(), SPELL_PHASE_PUNCH, true); PhasePunch_Timer = 8000; } else PhasePunch_Timer -= diff; if (CosmicSmash_Timer <= diff) { DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), RAID_MODE(SPELL_COSMIC_SMASH, H_SPELL_COSMIC_SMASH), true); CosmicSmash_Timer = urand(30000, 60000); } else CosmicSmash_Timer -= diff; if (Berserk_Timer <= diff) { DoScriptText(SAY_BERSERK, me); DoCast(me->getVictim(), SPELL_BERSERK, true); Berserk_Timer = 360000; } else Berserk_Timer -= diff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); } if (Phase == 2) { if (Enrage) { if (Ascend_Timer <= diff) { DoCast(me, SPELL_ASCEND); DoScriptText(SAY_BERSERK, me); Ascend_Timer = urand(360000, 365000); Enrage = false; } else Ascend_Timer -= diff; } } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (events.ExecuteEvent()) { case EVENT_SPELL_BERSERK: Talk(SAY_ENRAGE); me->CastSpell(me, SPELL_BERSERK, true); break; case EVENT_SPELL_BLOOD_BOIL: me->CastCustomSpell(SPELL_BLOODBOIL, SPELLVALUE_MAX_TARGETS, 5, me, false); events.ScheduleEvent(EVENT_SPELL_BLOOD_BOIL, 10000); break; case EVENT_SPELL_BEWILDERING_STRIKE: me->CastSpell(me->GetVictim(), SPELL_BEWILDERING_STRIKE, false); events.ScheduleEvent(EVENT_SPELL_BEWILDERING_STRIKE, 30000, GROUP_DELAY); break; case EVENT_SPELL_FEL_ACID_BREATH: me->CastSpell(me->GetVictim(), me->HasAura(SPELL_FEL_RAGE_SELF) ? SPELL_FEL_ACID_BREATH2 : SPELL_FEL_ACID_BREATH1, false); events.ScheduleEvent(EVENT_SPELL_FEL_ACID_BREATH, 30000); break; case EVENT_SPELL_EJECT: me->CastSpell(me->GetVictim(), me->HasAura(SPELL_FEL_RAGE_SELF) ? SPELL_EJECT2 : SPELL_EJECT1, false); events.ScheduleEvent(EVENT_SPELL_EJECT, 20000); break; case EVENT_SPELL_ARCING_SMASH: me->CastSpell(me->GetVictim(), me->HasAura(SPELL_FEL_RAGE_SELF) ? SPELL_ARCING_SMASH2 : SPELL_ARCING_SMASH1, false); events.ScheduleEvent(EVENT_SPELL_ARCING_SMASH, 15000); break; case EVENT_SPELL_FEL_GEYSER: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 40.0f, true)) { me->RemoveAurasByType(SPELL_AURA_MOD_TAUNT); me->CastSpell(me, SPELL_FEL_RAGE_SELF, true); me->CastSpell(target, SPELL_FEL_RAGE_TARGET, true); me->CastSpell(target, SPELL_FEL_RAGE_2, true); me->CastSpell(target, SPELL_FEL_RAGE_3, true); me->CastSpell(target, SPELL_FEL_RAGE_SIZE, true); target->CastSpell(me, SPELL_TAUNT_GURTOGG, true); me->CastSpell(target, SPELL_FEL_GEYSER_SUMMON, true); me->CastSpell(me, SPELL_FEL_GEYSER_STUN, true); me->CastSpell(me, SPELL_INSIGNIFICANCE, true); events.ScheduleEvent(EVENT_SPELL_CHARGE, 2000); events.DelayEvents(30000, GROUP_DELAY); } events.ScheduleEvent(EVENT_SPELL_FEL_GEYSER, 90000); break; case EVENT_SPELL_CHARGE: me->CastSpell(me->GetVictim(), SPELL_CHARGE, true); break; } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Check if out of range if (EnterEvadeIfOutOfCombatArea(uiDiff)) { DoScriptText(SAY_EVADE, m_creature); return; } if (m_uiAssassinsTimer) { if (m_uiAssassinsTimer <= uiDiff) { SpawnAssassin(); m_uiAssassinsTimer = 0; } else m_uiAssassinsTimer -= uiDiff; } if (m_bInBlade) { if (m_uiWaitTimer) { if (m_uiWaitTimer <= uiDiff) { if (m_uiTargetNum == 0) { // stop bladedance m_bInBlade = false; m_creature->SetSpeedRate(MOVE_RUN, 2.0f); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiWaitTimer = 0; if (!m_bIsRegularMode) m_uiChargeTimer = 5000; } else { // move in bladedance float x, y, randx, randy; randx = (rand()%40); randy = (rand()%40); x = 210+ randx ; y = -60- randy ; m_creature->GetMotionMaster()->MovePoint(1, x, y, m_creature->GetPositionZ()); m_uiWaitTimer = 0; } } else m_uiWaitTimer -= uiDiff; } } else // !m_bInBlade { if (m_uiBladeDanceTimer < uiDiff) { m_uiTargetNum = TARGET_NUM; m_uiWaitTimer = 1; m_bInBlade = true; m_uiBladeDanceTimer = 30000; m_creature->SetSpeedRate(MOVE_RUN, 4.0f); return; } else m_uiBladeDanceTimer -= uiDiff; if (m_uiChargeTimer) { if (m_uiChargeTimer <= uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, SPELL_CHARGE_H); m_uiChargeTimer = 0; } else m_uiChargeTimer -= uiDiff; } if (m_uiSummonAssistantTimer < uiDiff) { for (uint32 i = 0; i < m_uiSummoned; ++i) { switch (urand(0, 2)) { case 0: m_creature->SummonCreature(NPC_HEARTHEN_GUARD, AddsEntrance[0], AddsEntrance[1], AddsEntrance[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); break; case 1: m_creature->SummonCreature(NPC_SHARPSHOOTER_GUARD, AddsEntrance[0], AddsEntrance[1], AddsEntrance[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); break; case 2: m_creature->SummonCreature(NPC_REAVER_GUARD, AddsEntrance[0], AddsEntrance[1], AddsEntrance[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); break; } } if (!urand(0, 4)) ++m_uiSummoned; m_uiSummonAssistantTimer = urand(25000, 35000); } else m_uiSummonAssistantTimer -= uiDiff; DoMeleeAttackIfReady(); } }
void UpdateAI(const uint32 uiDiff) override { // Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // spell will target dragons, if they are still alive at 35% if (!m_bIsBerserk && m_creature->GetHealthPercent() < 35.0f) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { DoScriptText(SAY_SARTHARION_BERSERK, m_creature); m_bIsBerserk = true; } } // soft enrage if (!m_bIsSoftEnraged && m_creature->GetHealthPercent() <= 10.0f) { // TODO m_bIsSoftEnraged = true; } // hard enrage if (!m_bIsHardEnraged) { if (m_uiEnrageTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_PYROBUFFET, CAST_TRIGGERED) == CAST_OK) m_bIsHardEnraged = true; } else m_uiEnrageTimer -= uiDiff; } // flame tsunami if (m_uiFlameTsunamiTimer < uiDiff) { SendFlameTsunami(); m_uiFlameTsunamiTimer = 30000; } else m_uiFlameTsunamiTimer -= uiDiff; // flame breath if (m_uiFlameBreathTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H) == CAST_OK) { DoScriptText(SAY_SARTHARION_BREATH, m_creature); m_uiFlameBreathTimer = urand(25000, 35000); } } else m_uiFlameBreathTimer -= uiDiff; // Tail Sweep if (m_uiTailSweepTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H) == CAST_OK) m_uiTailSweepTimer = urand(15000, 20000); } else m_uiTailSweepTimer -= uiDiff; // Cleave if (m_uiCleaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) m_uiCleaveTimer = urand(7000, 10000); } else m_uiCleaveTimer -= uiDiff; // Lavas Strike if (m_uiLavaStrikeTimer < uiDiff) { if (m_pInstance) { if (Creature* pCyclone = m_creature->GetMap()->GetCreature(m_pInstance->SelectRandomFireCycloneGuid())) pCyclone->CastSpell(pCyclone, SPELL_CYCLONE_AURA_STRIKE, true); switch (urand(0, 5)) { case 0: DoScriptText(SAY_SARTHARION_SPECIAL_1, m_creature); break; case 1: DoScriptText(SAY_SARTHARION_SPECIAL_2, m_creature); break; case 2: DoScriptText(SAY_SARTHARION_SPECIAL_3, m_creature); break; case 3: DoScriptText(SAY_SARTHARION_SPECIAL_4, m_creature); break; } } m_uiLavaStrikeTimer = 30000; } else m_uiLavaStrikeTimer -= uiDiff; // call tenebron if (!m_bHasCalledTenebron) { if (m_uiTenebronTimer < uiDiff) { CallDragon(NPC_TENEBRON); m_bHasCalledTenebron = true; } else m_uiTenebronTimer -= uiDiff; } // call shadron if (!m_bHasCalledShadron) { if (m_uiShadronTimer < uiDiff) { CallDragon(NPC_SHADRON); m_bHasCalledShadron = true; } else m_uiShadronTimer -= uiDiff; } // call vesperon if (!m_bHasCalledVesperon) { if (m_uiVesperonTimer < uiDiff) { CallDragon(NPC_VESPERON); m_bHasCalledVesperon = true; } else m_uiVesperonTimer -= uiDiff; } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(uiDiff); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Pounding if (m_uiPoundingTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_POUNDING) == CAST_OK) { DoScriptText(urand(0, 1) ? SAY_POUNDING1 : SAY_POUNDING2, m_creature); m_uiPoundingTimer = 14000; } } else m_uiPoundingTimer -= uiDiff; // Arcane Orb if (m_uiArcaneOrbTimer < uiDiff) { // Search only for players which are not within 18 yards of the boss std::vector<Unit*> suitableTargets; ThreatList const& threatList = m_creature->getThreatManager().getThreatList(); ThreatList::const_iterator itr = threatList.begin(); for (itr; itr != threatList.end(); ++itr) { if (Unit* pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid())) { if (pTarget->GetTypeId() == TYPEID_PLAYER && !pTarget->IsWithinDist(m_creature, 18.0f)) suitableTargets.push_back(pTarget); } } if (suitableTargets.empty()) m_uiArcaneOrbTimer = 3000; else { Unit* pTarget = suitableTargets[urand(0, suitableTargets.size() - 1)]; if (pTarget) m_creature->SummonCreature(NPC_ARCANE_ORB_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 0); m_uiArcaneOrbTimer = 3000; } } else m_uiArcaneOrbTimer -= uiDiff; // Single Target knock back, reduces aggro if (m_uiKnockAwayTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_KNOCK_AWAY) == CAST_OK) m_uiKnockAwayTimer = 30000; } else m_uiKnockAwayTimer -= uiDiff; // Berserk if (m_uiBerserkTimer) { if (m_uiBerserkTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) m_uiBerserkTimer = 0; } else m_uiBerserkTimer -= uiDiff; } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(uiDiff); }
void UpdateAI(const uint32 uiDiff) { if (m_bFrozen && !m_bExploded) { if (m_uiThawTimer <= uiDiff) // remove all slows and reset counters { RemoveAuras(); ResetBool(0); ResetBool(1); } else m_uiThawTimer -= uiDiff; } if(m_bExploded) { if (m_uiSetInvisTimer <= uiDiff) { SetVisible(0); m_creature->SetObjectScale(0.1f); m_creature->UpdateModelData(); } else m_uiSetInvisTimer -= uiDiff; if (m_uiSetVisibleTimer <= uiDiff) { SetVisible(1); // set scale 0.4f scale is the smallest m_creature->SetObjectScale(m_creature->GetHealthPercent() * 0.0084 + 0.358); // set Viscidus' size depending on the blobs that are alive 1/ too small? m_creature->UpdateModelData(); m_creature->RemoveAllAuras(AuraRemoveMode::AURA_REMOVE_BY_DEFAULT); if(!m_creature->HasAura(SPELL_MEMBRANE_VISCIDUS)) m_creature->CastSpell(m_creature, SPELL_MEMBRANE_VISCIDUS, true); // reapply dmg reduction } else m_uiSetVisibleTimer -= uiDiff; if (!m_bSummoned) { if (m_uiGlobSpawnTimer <= uiDiff) { SpawnGlobs(); m_bSummoned = true; } else m_uiGlobSpawnTimer -= uiDiff; } } if (m_bCanDoDamage) { if (m_uiPoisonBoltCastTimer) { if (m_uiPoisonBoltCastTimer > uiDiff) { m_uiPoisonBoltCastTimer -= uiDiff; Unit* pTarget = m_creature->GetMap()->GetUnit(m_PoisonTargetGuid); if (m_uiPoisonBoltCastTimer < 500 && pTarget) { m_creature->SetTargetGuid(pTarget->GetObjectGuid()); m_creature->SetFacingToObject(pTarget); return; } } else { if (m_creature->SelectHostileTarget() && m_creature->getVictim()) m_creature->SetTargetGuid(m_creature->getVictim()->GetObjectGuid()); m_uiPoisonBoltCastTimer = 0; return; } } //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiPoisonShockTimer <= uiDiff) { m_creature->CastSpell(m_creature, SPELL_POISON_SHOCK, false); m_uiPoisonShockTimer = 10000; } else m_uiPoisonShockTimer -= uiDiff; if (m_uiPoisonVolleyTimer <= uiDiff) { m_creature->CastSpell(m_creature, SPELL_POISONBOLT_VOLLEY, false); m_uiPoisonVolleyTimer = 10000; } else m_uiPoisonVolleyTimer -= uiDiff; if (m_uiToxicCloudTimer <= uiDiff) // redo this, should probably not cast a spell, just visually cast it. Missing that the boss should turn towards the victim during cast. { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { m_creature->CastSpell(pTarget, SPELL_POISON_BOLT, true); m_PoisonTargetGuid = pTarget->GetObjectGuid(); m_uiPoisonBoltCastTimer = 2800; } m_uiToxicCloudTimer = urand(30000,40000); return; } else m_uiToxicCloudTimer -= uiDiff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(uiDiff); } }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Berserk if (m_uiBerserkTimer) { if (m_uiBerserkTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { DoScriptText(SAY_BERSERK, m_creature); m_uiBerserkTimer = 0; } } else m_uiBerserkTimer -= uiDiff; } switch(m_uiPhase) { case SINDRAGOSA_PHASE_THREE: // TODO:Ice Tombs // no break case SINDRAGOSA_PHASE_GROUND: { // Phase 1 only if (m_uiPhase == SINDRAGOSA_PHASE_GROUND) { // Health Check if (m_creature->GetHealthPercent() <= 30.0f) { if (DoCastSpellIfCan(m_creature, SPELL_MYSTIC_BUFFET) == CAST_OK) { m_uiPhase = SINDRAGOSA_PHASE_THREE; DoScriptText(SAY_PHASE_3, m_creature); } } // Phase 2 (air) if (m_uiPhaseTimer <= uiDiff) { m_uiPhaseTimer = 35000; DoScriptText(SAY_TAKEOFF, m_creature); SetCombatMovement(false); m_creature->GetMotionMaster()->MovePoint(SINDRAGOSA_POINT_GROUND_CENTER, SindragosaPosition[0][0], SindragosaPosition[0][1], SindragosaPosition[0][2], false); } else m_uiPhaseTimer -= uiDiff; } // Cleave if (m_uiCleaveTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) m_uiCleaveTimer = urand(5000, 15000); } else m_uiCleaveTimer -= uiDiff; // Tail Smash if (m_uiTailSmashTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TAIL_SMASH) == CAST_OK) m_uiTailSmashTimer = urand(10000, 20000); } else m_uiTailSmashTimer -= uiDiff; // Frost Breath if (m_uiFrostBreathTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FROST_BREATH) == CAST_OK) m_uiFrostBreathTimer = urand(15000, 20000); } else m_uiFrostBreathTimer -= uiDiff; // Unchained Magic if (m_uiUnchainedMagicTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_UNCHAINED_MAGIC) == CAST_OK) { m_uiUnchainedMagicTimer = urand(40000, 60000); DoScriptText(SAY_UNCHAINED_MAGIC, m_creature); } } else m_uiUnchainedMagicTimer -= uiDiff; // Icy Grip and Blistering Cold if (m_uiIcyGripTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_ICY_GRIP) == CAST_OK) { m_uiIcyGripTimer = 70000; DoScriptText(SAY_BLISTERING_COLD, m_creature); } } else m_uiIcyGripTimer -= uiDiff; DoMeleeAttackIfReady(); break; } case SINDRAGOSA_PHASE_FLYING_TO_GROUND: case SINDRAGOSA_PHASE_FLYING_TO_AIR: break; case SINDRAGOSA_PHASE_AIR: { // Phase One (ground) if (m_uiPhaseTimer <= uiDiff) { m_uiPhase = SINDRAGOSA_PHASE_FLYING_TO_GROUND; m_uiPhaseTimer = 42000; m_creature->GetMotionMaster()->MovePoint(SINDRAGOSA_POINT_AIR_CENTER, SindragosaPosition[1][0], SindragosaPosition[1][1], SindragosaPosition[1][2], false); } else m_uiPhaseTimer -= uiDiff; break; } } // evade on top of the stairs EnterEvadeIfOutOfCombatArea(uiDiff); }
void UpdateAI(const uint32 uiDiff) { // respawntime is calculated duration of GO_sapphirons birth special animation // if sapphiron assemble is in progres TYPE_SAPPHIRON = SPECIAL if (m_pInstance && m_pInstance->GetData(TYPE_SAPPHIRON) == SPECIAL && m_creature->GetVisibility() == VISIBILITY_OFF) { GameObject* pSapphironBirth = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_SAPPHIRON_BIRTH)); if (pSapphironBirth && pSapphironBirth->GetRespawnTime() == 0) { pSapphironBirth->SetRespawnTime(604800); pSapphironBirth->Delete(); } if (m_uiRespawnTime < uiDiff) { m_creature->RemoveFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)); m_creature->SetVisibility(VISIBILITY_ON); } else m_uiRespawnTime -= uiDiff; } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_bHundredClub) { if (m_uiHundredClubCheckTimer <= uiDiff) { m_bHundredClub = DoHundredClubCheck(); m_uiHundredClubCheckTimer = 5000; }else m_uiHundredClubCheckTimer -= uiDiff; } if (m_uiBeserkTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_BESERK); m_uiBeserkTimer = 300000; DoScriptText(EMOTE_ENRAGE, m_creature); } else m_uiBeserkTimer -= uiDiff; switch(m_uiPhase) { case PHASE_FIGHT_ON_GROUND: if (m_creature->GetHealthPercent() > 10.0f) { if (m_uiFlyTimer < uiDiff) { m_creature->InterruptNonMeleeSpells(false); SetCombatMovement(false); m_creature->GetMotionMaster()->MovePoint(POINT_HOME, fHomeX, fHomeY, fHomeZ); m_uiPhase = PHASE_RETURN_TO_THE_CENTER; return; } else m_uiFlyTimer -= uiDiff; } if (m_uiLifeDrainTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_LIFE_DRAIN : H_SPELL_LIFE_DRAIN); m_uiLifeDrainTimer = 24000; } else m_uiLifeDrainTimer -= uiDiff; if (m_uiBlizzardTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_ACTIVATE_BLIZZARD); m_uiBlizzardTimer = 20000; } else m_uiBlizzardTimer -= uiDiff; if (m_uiCleaveTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE); m_uiCleaveTimer = urand(7000, 10000); } else m_uiCleaveTimer -= uiDiff; if (m_uiTailSweepTimer < uiDiff) { DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_TAIL_SWEEP : H_SPELL_TAIL_SWEEP); m_uiTailSweepTimer = urand(10000, 15000); } else m_uiTailSweepTimer -= uiDiff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(uiDiff); break; // walking back to the center, he is supposed to do nothing at this time case PHASE_RETURN_TO_THE_CENTER: return; // casting ice bolts (2:3 n/h) than visual effect (ball) of Frost Breath and waiting untill ball reach ground case PHASE_ICEBOLTS: if (m_uiIceboltTimer < uiDiff) { if (Unit* pTarget = SelectTargetForIcebolt()) DoCastSpellIfCan(pTarget, SPELL_ICEBOLT); ++m_iIceboltCount; if (m_iIceboltCount >= (m_bIsRegularMode ? 2 : 3)) { DoScriptText(EMOTE_BREATH, m_creature); Creature* pWingBuffet = m_creature->GetMap()->GetCreature(m_uiWingBuffetGuid); if (pWingBuffet && pWingBuffet->isAlive()) DoCastSpellIfCan(pWingBuffet, SPELL_FROSTBREATH_VISUAL, CAST_TRIGGERED); m_uiPhase = PHASE_LANDING; m_uiLandTimer = 7000; } m_uiIceboltTimer = 4000; } else m_uiIceboltTimer -= uiDiff; break; // when ball of Frostbreath reaches ground dmg and visual effect of AoE Frostbreath is triggered // Sapphiron descends to the ground to rejoin melee fight case PHASE_LANDING: if (m_uiLandTimer < uiDiff) { m_uiPhase = PHASE_FIGHT_ON_GROUND; // !!HACK!! bool variable needed to determine when DealDmg should be = 0. // dunno how to check which dmg was done by which spell to disable only // dmg form FrostBreath :/ m_bCastingFrostBreath = true; DoCastSpellIfCan(m_creature, SPELL_FROSTBREATH, CAST_TRIGGERED); Creature* pWingBuffet = m_creature->GetMap()->GetCreature(m_uiWingBuffetGuid); if (pWingBuffet && pWingBuffet->isAlive()) pWingBuffet->ForcedDespawn(); m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); m_creature->RemoveAurasDueToSpell(SPELL_HOVER); m_uiBlizzardTimer = 5000; m_uiFlyTimer = 45000; DoScriptText(EMOTE_GROUND, m_creature); SetCombatMovement(true); m_creature->GetMotionMaster()->MovementExpired(true); if (m_creature->getVictim()) m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_bCastingFrostBreath = false; } else m_uiLandTimer -= uiDiff; break; } }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiPhase == PHASE_GROUND) { if (m_uiLeechingSwarmTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_LEECHING_SWARM : SPELL_LEECHING_SWARM_H) == CAST_OK) { switch (urand(0, 2)) { case 0: DoScriptText(SAY_LOCUST_1, m_creature); break; case 1: DoScriptText(SAY_LOCUST_2, m_creature); break; case 2: DoScriptText(SAY_LOCUST_3, m_creature); break; } m_uiLeechingSwarmTimer = 19000; } } else m_uiLeechingSwarmTimer -= uiDiff; if (m_uiCarrionBeetlesTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_CARRION_BEETLES) == CAST_OK) m_uiCarrionBeetlesTimer = 25000; } else m_uiCarrionBeetlesTimer -= uiDiff; if (m_uiPoundTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_POUND : SPELL_POUND_H) == CAST_OK) m_uiPoundTimer = 16000; } else m_uiPoundTimer -= uiDiff; if (m_creature->GetHealthPercent() < 100 - 25*m_uiSubmergePhase) { DoCastSpellIfCan(m_creature, SPELL_IMPALE_AURA, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_SUBMERGE, CAST_TRIGGERED); DoScriptText(urand(0, 1) ? SAY_SUBMERGE_1 : SAY_SUBMERGE_2, m_creature); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); m_uiPhase = PHASE_SUBMERGED; m_bIsFirstWave = true; m_uiSummonTimer = 5000; // Emerge timers aren't the same. They depend on the submerge phase switch (m_uiSubmergePhase) { case 1: m_uiEmergeTimer = 20000; break; case 2: m_uiEmergeTimer = 45000; break; case 3: m_uiEmergeTimer = 50000; break; } ++m_uiSubmergePhase; } DoMeleeAttackIfReady(); } else if (m_uiPhase == PHASE_SUBMERGED) { if (m_uiSummonTimer < uiDiff) { if (!m_pInstance) return; // Summon 2 Assassins for (uint8 i = 0; i < 2; ++i) { if (Creature* pTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetRandomAssassinTrigger())) pTrigger->CastSpell(pTrigger, SPELL_SUMMON_ASSASSIN, true, NULL, NULL, m_creature->GetObjectGuid()); } // on the first wave summon a guardian; on the second wave summon a venonmancer if (Creature* pTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetGuardianTrigger())) { pTrigger->CastSpell(pTrigger, m_bIsFirstWave ? SPELL_SUMMON_GUARDIAN : SPELL_SUMMON_VENOMANCER, true, NULL, NULL, m_creature->GetObjectGuid()); m_bIsFirstWave = false; } m_uiSummonTimer = 26000; } else m_uiSummonTimer -= uiDiff; // only on the last submerge phase if (m_uiSubmergePhase == 4) { if (m_uiDarterTimer < uiDiff) { if (!m_pInstance) return; if (Creature* pTrigger = m_creature->GetMap()->GetCreature(m_pInstance->GetDarterTrigger())) { pTrigger->CastSpell(pTrigger, SPELL_SUMMON_DARTER, true, NULL, NULL, m_creature->GetObjectGuid()); m_uiDarterTimer = urand(10000, 15000); } } else m_uiDarterTimer -= uiDiff; } if (m_uiEmergeTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_EMERGE, CAST_INTERRUPT_PREVIOUS); m_creature->RemoveAurasDueToSpell(SPELL_SUBMERGE); m_creature->RemoveAurasDueToSpell(SPELL_IMPALE_AURA); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); m_uiPhase = PHASE_GROUND; } else m_uiEmergeTimer -= uiDiff; } EnterEvadeIfOutOfCombatArea(uiDiff); }
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return; // Pounding if (Pounding_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_POUNDING); switch(rand()%2) { case 0: DoScriptText(SAY_POUNDING1, m_creature); break; case 1: DoScriptText(SAY_POUNDING2, m_creature); break; } Pounding_Timer = 15000; //cast time(3000) + cooldown time(12000) }else Pounding_Timer -= diff; // Arcane Orb if (ArcaneOrb_Timer < diff) { Unit *target = NULL; std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList(); std::vector<Unit *> target_list; for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); // exclude pets & totems if (target->GetTypeId() != TYPEID_PLAYER) continue; //18 yard radius minimum if (target && !target->IsWithinDist(m_creature, 18.0f, false)) target_list.push_back(target); target = NULL; } if (target_list.size()) target = *(target_list.begin()+rand()%target_list.size()); else target = m_creature->getVictim(); if (target) DoCast(target, SPELL_ARCANE_ORB_MISSILE); ArcaneOrb_Timer = 3000; }else ArcaneOrb_Timer -= diff; // Single Target knock back, reduces aggro if (KnockAway_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_KNOCK_AWAY); //Drop 25% aggro if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-25); KnockAway_Timer = 30000; }else KnockAway_Timer -= diff; //Berserk if (Berserk_Timer < diff) { if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); DoCast(m_creature,SPELL_BERSERK); Berserk_Timer = 600000; }else Berserk_Timer -= diff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(uint32 const diff) { events.Update(diff); if (!UpdateVictim()) { if (events.ExecuteEvent() == EVENT_DRAIN_SPIRIT_ESSENCE_COSMETIC_INTRO) { me->CastSpell(me, SPELL_DRAIN_SPIRIT_ESSENCE, false); events.ScheduleEvent(EVENT_DRAIN_SPIRIT_ESSENCE_COSMETIC_INTRO, urand(10000, 20000)); } return; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; if (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_DEADZONE: me->CastSpell(me, SPELL_DEADZONE, false); events.ScheduleEvent(EVENT_DEADZONE, 21000); events.ScheduleEvent(EVENT_SHADOWS_OF_HAKKAR, urand(5000, 10000)); break; case EVENT_SHADOWS_OF_HAKKAR: Talk(JINDO_EMOTE_SHADOWS_OF_HAKKAR); me->CastSpell(me, SPELL_SHADOWS_OF_HAKKAR, false); break; case EVENT_SET_FACING: me->SetFacingTo(1.570796f); events.ScheduleEvent(EVENT_SPIRIT_WORLD, 500); break; case EVENT_SPIRIT_WORLD: me->CastSpell(me, SPELL_ADD_PLAYERS_THREAD, false); me->CastSpell(me, SPELL_SPIRIT_WORLD, false); me->CastSpell(me, SPELL_VANISH, false); events.ScheduleEvent(EVENT_SPIRIT_WORLD_SUMMON, 3000); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); break; case EVENT_SPIRIT_WORLD_SUMMON: { me->SummonCreature(52150, JindoSpiritSP); uint8 id = urand(0, 1); for (int i = 0; i < 3; ++i) me->SummonCreature(52430, HakkarChainSP[id][i]); for (int i = 0; i < 15; ++i) me->SummonCreature(52532, SpiritPortalSP[i]); for (int i = 0; i < 4; ++i) me->SummonCreature(SpiritTrollSpawMask & 1 << i ? 52730 : 52732, SpiritWarriorSP[i]); if (Creature* hakkar = me->SummonCreature(52222, HakkarSP)) hakkar->AI()->Talk(HAKKAR_YELL_SPIT); } break; case EVENT_HAKKAR_SET_FACING: { if (Creature* hakkar = ObjectAccessor::GetCreature(*me, HakkarGUID)) hakkar->SetFacingTo(4.712389f); events.ScheduleEvent(EVENT_HAKKAR_KILL_JINDO, 17000); } break; case EVENT_HAKKAR_KILL_JINDO: { if (Creature* hakkar = ObjectAccessor::GetCreature(*me, HakkarGUID)) hakkar->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H); me->RemoveAura(SPELL_SPIRIT_WORLD); events.ScheduleEvent(EVENT_HAKKAR_YELL_BYE, 2500); } break; case EVENT_HAKKAR_YELL_BYE: { if (Creature* hakkar = ObjectAccessor::GetCreature(*me, HakkarSpiritGUID)) { hakkar->AI()->Talk(HAKKAR_SPIRIT_YELL_INSECTS); hakkar->DespawnOrUnsummon(5000); } events.ScheduleEvent(EVENT_JINDO_KILL_SELF, 5000); } break; case EVENT_JINDO_KILL_SELF: { me->RemoveAllAuras(); me->CastSpell(me, SPELL_TRANSFORM, false); if (!me->getThreatManager().getThreatList().empty()) if (Unit* killer = ObjectAccessor::GetUnit(*me, (*me->getThreatManager().getThreatList().begin())->getUnitGuid())) killer->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } break; } } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); switch (events.ExecuteEvent()) { case EVENT_SUMMON_FETID_TROLL: if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET)) trigger->CastSpell(trigger, SPELL_SUMMON_FETID_TROLL_CORPSE, true, NULL, NULL, me->GetGUID()); events.ScheduleEvent(EVENT_SUMMON_FETID_TROLL, 3000); break; case EVENT_SUMMON_HULKING_CORPSE: if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET)) trigger->CastSpell(trigger, SPELL_SUMMON_HULKING_CORPSE, true, NULL, NULL, me->GetGUID()); events.ScheduleEvent(EVENT_SUMMON_HULKING_CORPSE, 30000); break; case EVENT_SUMMON_SHADOWCASTER: if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET)) trigger->CastSpell(trigger, SPELL_SUMMON_RISEN_SHADOWCASTER, true, NULL, NULL, me->GetGUID()); events.ScheduleEvent(EVENT_SUMMON_SHADOWCASTER, 10000); break; case EVENT_SUMMON_CRYSTAL_HANDLER: if (_crystalCounter++ < 4) { Talk(SAY_SUMMONING_ADDS); Talk(EMOTE_SUMMONING_ADDS); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f)) target->CastSpell(target, SPELL_SUMMON_CRYSTAL_HANDLER, true, NULL, NULL, me->GetGUID()); events.ScheduleEvent(EVENT_SUMMON_CRYSTAL_HANDLER, 20000); } break; case EVENT_CHECK_PHASE: if (me->HasAura(SPELL_BEAM_CHANNEL)) { events.ScheduleEvent(EVENT_CHECK_PHASE, 2000); break; } events.Reset(); events.ScheduleEvent(EVENT_CAST_OFFENSIVE_SPELL, 3000); events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 10000); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->InterruptNonMeleeSpells(false); break; case EVENT_CAST_OFFENSIVE_SPELL: if (!me->HasUnitState(UNIT_STATE_CASTING)) if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) me->CastSpell(target, RAND(SPELL_BLIZZARD,SPELL_FROSTBOLT,SPELL_TOUCH_OF_MISERY), false); events.ScheduleEvent(EVENT_CAST_OFFENSIVE_SPELL, 500); break; case EVENT_SPELL_SUMMON_MINIONS: if (me->HasUnitState(UNIT_STATE_CASTING)) { me->CastSpell(me, SPELL_SUMMON_MINIONS, false); events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 15000); break; } events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 500); break; } EnterEvadeIfOutOfCombatArea(); }
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) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; //spell will target dragons, if they are still alive at 35% if (!m_bIsBerserk && m_creature->GetHealthPercent() < 35.0f) { DoScriptText(SAY_SARTHARION_BERSERK, m_creature); DoCastSpellIfCan(m_creature, SPELL_BERSERK); m_bIsBerserk = true; } //soft enrage if (!m_bIsSoftEnraged && m_creature->GetHealthPercent() <= 10.0f) { // TODO m_bIsSoftEnraged = true; } // hard enrage if (!m_bIsHardEnraged) { if (m_uiEnrageTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_PYROBUFFET, CAST_TRIGGERED); m_bIsHardEnraged = true; } else m_uiEnrageTimer -= uiDiff; } // flame tsunami if (m_uiFlameTsunamiTimer < uiDiff) { SendFlameTsunami(); m_uiFlameTsunamiTimer = 30000; } else m_uiFlameTsunamiTimer -= uiDiff; // flame breath if (m_uiFlameBreathTimer < uiDiff) { DoScriptText(SAY_SARTHARION_BREATH, m_creature); DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FLAME_BREATH : SPELL_FLAME_BREATH_H); m_uiFlameBreathTimer = urand(25000, 35000); } else m_uiFlameBreathTimer -= uiDiff; // Tail Sweep if (m_uiTailSweepTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_TAIL_LASH : SPELL_TAIL_LASH_H); m_uiTailSweepTimer = urand(15000, 20000); } else m_uiTailSweepTimer -= uiDiff; // Cleave if (m_uiCleaveTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE); m_uiCleaveTimer = urand(7000, 10000); } else m_uiCleaveTimer -= uiDiff; // Lavas Strike if (m_uiLavaStrikeTimer < uiDiff) { if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) { DoCastSpellIfCan(pTarget, SPELL_LAVA_STRIKE); switch(urand(0, 15)) { case 0: DoScriptText(SAY_SARTHARION_SPECIAL_1, m_creature); break; case 1: DoScriptText(SAY_SARTHARION_SPECIAL_2, m_creature); break; case 2: DoScriptText(SAY_SARTHARION_SPECIAL_3, m_creature); break; } } m_uiLavaStrikeTimer = urand(5000, 20000); } else m_uiLavaStrikeTimer -= uiDiff; // call tenebron if (!m_bHasCalledTenebron && m_uiTenebronTimer < uiDiff) { CallDragon(DATA_TENEBRON); m_bHasCalledTenebron = true; } else m_uiTenebronTimer -= uiDiff; // call shadron if (!m_bHasCalledShadron && m_uiShadronTimer < uiDiff) { CallDragon(DATA_SHADRON); m_bHasCalledShadron = true; } else m_uiShadronTimer -= uiDiff; // call vesperon if (!m_bHasCalledVesperon && m_uiVesperonTimer < uiDiff) { CallDragon(DATA_VESPERON); m_bHasCalledVesperon = true; } else m_uiVesperonTimer -= uiDiff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(uiDiff); }
void UpdateAI(uint32 diff) { EnterEvadeIfOutOfCombatArea(); if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (events.ExecuteEvent()) { case EVENT_SPELL_SHOCK_BLAST: me->CastSpell(me->GetVictim(), SPELL_SHOCK_BLAST, false); events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, urand(10000, 20000)); break; case EVENT_SPELL_STATIC_CHARGE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f)) me->CastSpell(target, SPELL_STATIC_CHARGE, false); events.ScheduleEvent(EVENT_SPELL_STATIC_CHARGE, 20000); break; case EVENT_SPELL_ENTANGLE: me->CastSpell(me, SPELL_ENTANGLE, false); events.ScheduleEvent(EVENT_SPELL_ENTANGLE, 30000); break; case EVENT_CHECK_HEALTH: if (me->HealthBelowPct(71)) { Talk(SAY_PHASE2); me->SetReactState(REACT_PASSIVE); me->GetMotionMaster()->MovePoint(POINT_HOME, me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY(), me->GetHomePosition().GetPositionZ(), true, true); break; } events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); break; case EVENT_SPELL_FORKED_LIGHTNING: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f)) me->CastSpell(target, SPELL_FORKED_LIGHTNING, false); events.ScheduleEvent(EVENT_SPELL_FORKED_LIGHTNING, urand(2500, 5000)); break; case EVENT_SUMMON_A: me->CastSpell(me, SPELL_SUMMON_ENCHANTED_ELEMENTAL, true); events.ScheduleEvent(EVENT_SUMMON_A, 2500); break; case EVENT_SUMMON_B: me->CastSpell(me, SPELL_SUMMON_COILFANG_ELITE, true); events.ScheduleEvent(EVENT_SUMMON_B, 45000); break; case EVENT_SUMMON_C: me->CastSpell(me, SPELL_SUMMON_COILFANG_STRIDER, true); events.ScheduleEvent(EVENT_SUMMON_C, 60000); break; case EVENT_SUMMON_D: me->CastSpell(me, SPELL_SUMMON_TAINTED_ELEMENTAL, true); events.ScheduleEvent(EVENT_SUMMON_D, 50000); break; case EVENT_CHECK_HEALTH2: if (!me->HasAura(SPELL_MAGIC_BARRIER)) { Talk(SAY_PHASE3); me->SetReactState(REACT_AGGRESSIVE); me->GetMotionMaster()->MoveChase(me->GetVictim()); events.Reset(); events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 10000); events.ScheduleEvent(EVENT_SPELL_STATIC_CHARGE, 15000); events.ScheduleEvent(EVENT_SPELL_ENTANGLE, 20000); events.ScheduleEvent(EVENT_SUMMON_SPOREBAT, 5000); break; } events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); break; case EVENT_SUMMON_SPOREBAT: me->CastSpell(me, SPELL_SUMMON_TOXIC_SPOREBAT, true); events.ScheduleEvent(EVENT_SUMMON_SPOREBAT, 20000 - 1000*std::min(count++, 16)); break; } if (me->GetReactState() != REACT_AGGRESSIVE || !me->isAttackReady()) return; if (!me->IsWithinMeleeRange(me->GetVictim())) { me->resetAttackTimer(); me->SetSheath(SHEATH_STATE_RANGED); me->CastSpell(me->GetVictim(), roll_chance_i(33) ? SPELL_MULTI_SHOT : SPELL_SHOOT, false); if (roll_chance_i(15)) Talk(SAY_BOWSHOT); } else { me->SetSheath(SHEATH_STATE_MELEE); DoMeleeAttackIfReady(); } }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiDanceTimer < uiDiff) { for (uint8 i = TOP_MOST; i < TOTAL_AREAS; ++i) { if (i == CurrentSafeArea) continue; m_pInstance->ActivateAreaFissures(ChamberArea(i)); } if (CurrentSafeArea == BOTTOM_LOWEST) Direction = -1; else if (CurrentSafeArea == TOP_MOST) Direction = 1; CurrentSafeArea = CurrentSafeArea + Direction; m_uiDanceTimer = m_uiPhase == PHASE_GROUND ? 10000 : 3000; }else m_uiDanceTimer -= uiDiff; if (m_uiPhase == PHASE_GROUND) { // Teleport to platform if (m_uiPhaseTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT) == CAST_OK) { DoScriptText(EMOTE_TELEPORT, m_creature); m_creature->GetMotionMaster()->MoveIdle(); m_uiPhase = PHASE_PLATFORM; ResetPhase(); return; } } else m_uiPhaseTimer -= uiDiff; // Fever if (m_uiFeverTimer < uiDiff) { DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_DECREPIT_FEVER_N : SPELL_DECREPIT_FEVER_H); m_uiFeverTimer = 21000; } else m_uiFeverTimer -= uiDiff; // Disruption if (m_uiDisruptionTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_DISRUPTION); m_uiDisruptionTimer = 10000; } else m_uiDisruptionTimer -= uiDiff; } else //Platform Phase { if (m_uiPhaseTimer <= uiDiff) // return to fight { m_creature->InterruptNonMeleeSpells(true); DoScriptText(EMOTE_RETURN, m_creature); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiPhase = PHASE_GROUND; ResetPhase(); return; } else m_uiPhaseTimer -= uiDiff; if (m_uiStartChannelingTimer) { if (m_uiStartChannelingTimer <=uiDiff) { DoScriptText(SAY_CHANNELING, m_creature); DoCastSpellIfCan(m_creature, SPELL_PLAGUE_CLOUD); m_uiStartChannelingTimer = 0; // no more } else m_uiStartChannelingTimer -= uiDiff; } } // Taunt if (m_uiTauntTimer < uiDiff) { switch(urand(0, 3)) { case 0: DoScriptText(SAY_TAUNT1, m_creature); break; case 1: DoScriptText(SAY_TAUNT2, m_creature); break; case 2: DoScriptText(SAY_TAUNT3, m_creature); break; case 3: DoScriptText(SAY_TAUNT4, m_creature); break; } m_uiTauntTimer = urand(20000, 70000); } else m_uiTauntTimer -= uiDiff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(uiDiff); }
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Pounding if (Pounding_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_POUNDING); DoScriptText(urand(0, 1) ? SAY_POUNDING1 : SAY_POUNDING2, m_creature); Pounding_Timer = 15000; //cast time(3000) + cooldown time(12000) }else Pounding_Timer -= diff; // Arcane Orb if (ArcaneOrb_Timer < diff) { Unit *target = NULL; std::vector<Unit *> target_list; ThreatList const& tList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) { target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); // exclude pets & totems if (!target || target->GetTypeId() != TYPEID_PLAYER) continue; //18 yard radius minimum if (target->IsWithinDist(m_creature, 18.0f, false)) continue; target_list.push_back(target); } if (target_list.size()) target = *(target_list.begin()+rand()%target_list.size()); else target = m_creature->getVictim(); if (target) DoCastSpellIfCan(target, SPELL_ARCANE_ORB_MISSILE); ArcaneOrb_Timer = 3000; }else ArcaneOrb_Timer -= diff; // Single Target knock back, reduces aggro if (KnockAway_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_KNOCK_AWAY); KnockAway_Timer = 30000; }else KnockAway_Timer -= diff; //Berserk if (Berserk_Timer < diff) { if (m_creature->IsNonMeleeSpellCasted(false)) m_creature->InterruptNonMeleeSpells(false); DoCastSpellIfCan(m_creature,SPELL_BERSERK); Berserk_Timer = 600000; }else Berserk_Timer -= diff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Start bombing if (m_uiBombTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FIRE_BOMB_CHANNEL) == CAST_OK) { DoCastSpellIfCan(m_creature, SPELL_TELEPORT_TO_CENTER, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_SUMMON_ALL_PLAYERS, CAST_TRIGGERED); DoScriptText(SAY_FIRE_BOMBS, m_creature); DoCreateFireWall(); m_uiBombAuraTimer = 5000; m_uiBombTimer = urand(20000, 40000); } } else m_uiBombTimer -= uiDiff; if (m_uiFireBreathTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_FLAME_BREATH) == CAST_OK) m_uiFireBreathTimer = 8000; } } else m_uiFireBreathTimer -= uiDiff; // Remove bomb aura after five seconds if (m_uiBombAuraTimer) { if (m_uiBombAuraTimer <= uiDiff) { m_creature->RemoveAurasDueToSpell(SPELL_FIRE_BOMB_CHANNEL); m_uiBombAuraTimer = 0; m_uiExplodeTimer = 5000; } else m_uiBombAuraTimer -= uiDiff; } // Explode the summoned bombs on timer if (m_uiExplodeTimer) { if (m_uiExplodeTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FIRE_BOMB_EXPLODE) == CAST_OK) m_uiExplodeTimer = 0; } else m_uiExplodeTimer -= uiDiff; } // Hatch all eggs at 35% health if (!m_bHasHatchedEggs && m_creature->GetHealthPercent() < 35.0f) { if (DoCastSpellIfCan(m_creature, SPELL_HATCH_ALL_EGGS) == CAST_OK) { DoScriptText(SAY_ALL_EGGS, m_creature); m_bHasHatchedEggs = true; } } // Soft Enrage - after 5 min, or at 20% health if (!m_bIsEnraged) { if (m_uiEnrageTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) m_bIsEnraged = true; } else m_uiEnrageTimer -= uiDiff; if (m_creature->GetHealthPercent() < 20.0f) { if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK) m_bIsEnraged = true; } } // Spawn Hatchers - if necessary if (!m_bHasHatchedEggs) { if (m_uiHatcherTimer < uiDiff) { DoScriptText(SAY_SUMMON_HATCHER, m_creature); Creature* pHatcer1 = m_creature->GetMap()->GetCreature(m_hatcherOneGuid); Creature* pHatcer2 = m_creature->GetMap()->GetCreature(m_hatcherTwoGuid); if (!pHatcer1 || !pHatcer1->isAlive()) DoCastSpellIfCan(m_creature, SPELL_SUMMON_HATCHER_1, CAST_TRIGGERED); if (!pHatcer2 || !pHatcer2->isAlive()) DoCastSpellIfCan(m_creature, SPELL_SUMMON_HATCHER_2, CAST_TRIGGERED); m_uiHatcherTimer = 90000; } else m_uiHatcherTimer -= uiDiff; } // Hard enrage if (m_uiBerserkTimer) { if (m_uiBerserkTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { DoScriptText(SAY_BERSERK, m_creature); m_uiBerserkTimer = 0; } } else m_uiBerserkTimer -= uiDiff; } DoMeleeAttackIfReady(); // check for reset ... exploit preventing ... pulled from his podest EnterEvadeIfOutOfCombatArea(uiDiff); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; shatteredHelper.Update(diff); events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_JET: Talk(EMOTE_JETS); DoCast(me, SPELL_FLAME_JETS); events.DelayEvents(5*IN_MILLISECONDS); // Cast time events.ScheduleEvent(EVENT_JET, urand(35*IN_MILLISECONDS, 40*IN_MILLISECONDS)); return; case EVENT_SLAG_POT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) { Talk(SAY_SLAG_POT); slagPotGUID = target->GetGUID(); DoCast(target, SPELL_GRAB); events.DelayEvents(3*IN_MILLISECONDS); events.ScheduleEvent(EVENT_GRAB_POT, 0.5*IN_MILLISECONDS); } events.ScheduleEvent(EVENT_SLAG_POT, RAID_MODE(30*IN_MILLISECONDS, 15*IN_MILLISECONDS)); return; case EVENT_GRAB_POT: if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, slagPotGUID)) { slagPotTarget->EnterVehicle(me, 1); events.ScheduleEvent(EVENT_CHANGE_POT, 1*IN_MILLISECONDS); } return; case EVENT_CHANGE_POT: if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, slagPotGUID)) { slagPotTarget->EnterVehicle(me, 1); slagPotTarget->ClearUnitState(UNIT_STATE_ONVEHICLE); DoCast(slagPotTarget, SPELL_SLAG_POT); events.ScheduleEvent(EVENT_END_POT, 10*IN_MILLISECONDS); } return; case EVENT_END_POT: if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, slagPotGUID)) { slagPotTarget->ExitVehicle(); slagPotGUID = 0; } return; case EVENT_SCORCH: Talk(SAY_SCORCH); if (Unit* target = me->getVictim()) me->SummonCreature(NPC_GROUND_SCORCH, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 45*IN_MILLISECONDS); DoCast(SPELL_SCORCH); events.ScheduleEvent(EVENT_SCORCH, 25*IN_MILLISECONDS); return; case EVENT_CONSTRUCT: if (!summons.empty()) { Talk(SAY_SUMMON); DoCast(me, SPELL_ACTIVATE_CONSTRUCT); events.ScheduleEvent(EVENT_CONSTRUCT, RAID_MODE(40*IN_MILLISECONDS, 30*IN_MILLISECONDS)); } return; case EVENT_BERSERK: DoCast(me, SPELL_BERSERK, true); Talk(SAY_BERSERK); return; default: return; } } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; EnterEvadeIfOutOfCombatArea(diff); if (me->HealthBelowPct(35) && !bEnraged) { bEnraged = true; Talk(SAY_35); DoCast(me, SPELL_FRENZY, true); events.CancelEvent(EVENT_SUMMON_HATCHERS); DoCast(me, SPELL_HATCH_ALL); return; } events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FLAME_BREATH: me->SetReactState(REACT_PASSIVE); me->AttackStop(); if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) DoCast(pTarget, SPELL_FLAME_BREATH); events.ScheduleEvent(EVENT_CONTINUE, 3000); events.ScheduleEvent(EVENT_FLAME_BREATH, 9000); break; case EVENT_CONTINUE: me->SetReactState(REACT_AGGRESSIVE); AttackStart(me->getVictim()); break; case EVENT_SUMMON_HATCHERS: Talk(SAY_HATCHER); if (!summons.HasEntry(NPC_AMANISHI_HATCHER1)) me->SummonCreature(NPC_AMANISHI_HATCHER1, posHatchersWay[0][0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); if (!summons.HasEntry(NPC_AMANISHI_HATCHER2)) me->SummonCreature(NPC_AMANISHI_HATCHER2, posHatchersWay[1][0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); events.ScheduleEvent(EVENT_SUMMON_HATCHERS, 90000); break; case EVENT_SPAWN_BOMBS: me->SetReactState(REACT_PASSIVE); me->AttackStop(); bombsCount = 0; Talk(SAY_FIRE_BOMB); SpawnBombs(); events.ScheduleEvent(EVENT_SUMMON_BOMBS, 1000); break; case EVENT_SUMMON_BOMBS: if (bombsCount < 40) { if (Creature* pBomb = Creature::GetCreature(*me, FireBombsGUID[bombsCount])) DoCast(pBomb, SPELL_FIRE_BOMB_THROW, true); bombsCount++; events.ScheduleEvent(EVENT_SUMMON_BOMBS, 100); } else events.ScheduleEvent(EVENT_DETONATE_BOMBS, 2000); break; case EVENT_DETONATE_BOMBS: for (uint8 i = 0; i < 40; ++i) if (Creature* pBomb = Creature::GetCreature(*me, FireBombsGUID[i])) { pBomb->RemoveAllAuras(); pBomb->CastSpell(pBomb, SPELL_FIRE_BOMB_DAMAGE, true); } events.ScheduleEvent(EVENT_CONTINUE, 1000); break; case EVENT_TELEPORT: me->SetReactState(REACT_PASSIVE); me->AttackStop(); events.RescheduleEvent(EVENT_SUMMON_HATCHERS, events.GetNextEventTime(EVENT_SUMMON_HATCHERS) + 7000); events.RescheduleEvent(EVENT_FLAME_BREATH, events.GetNextEventTime(EVENT_FLAME_BREATH) + 7000); Firewall(); DoCast(me, SPELL_TELE_TO_CENTER, true); events.ScheduleEvent(EVENT_SPAWN_BOMBS, 2000); break; } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_JET: me->MonsterTextEmote(EMOTE_JETS, 0, true); DoCast(me, SPELL_FLAME_JETS); events.ScheduleEvent(EVENT_JET, urand(35000, 40000)); break; case EVENT_SLAG_POT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { DoScriptText(SAY_SLAG_POT, me); _slagPotGUID = target->GetGUID(); DoCast(target, SPELL_GRAB); events.DelayEvents(3000); events.ScheduleEvent(EVENT_GRAB_POT, 500); } events.ScheduleEvent(EVENT_SLAG_POT, RAID_MODE(30000, 15000)); break; case EVENT_GRAB_POT: if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, _slagPotGUID)) { slagPotTarget->EnterVehicle(me, 0); events.CancelEvent(EVENT_GRAB_POT); events.ScheduleEvent(EVENT_CHANGE_POT, 1000); } break; case EVENT_CHANGE_POT: if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, _slagPotGUID)) { slagPotTarget->AddAura(SPELL_SLAG_POT, slagPotTarget); slagPotTarget->EnterVehicle(me, 1); events.CancelEvent(EVENT_CHANGE_POT); events.ScheduleEvent(EVENT_END_POT, 10000); } break; case EVENT_END_POT: if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, _slagPotGUID)) { slagPotTarget->ExitVehicle(); slagPotTarget = NULL; _slagPotGUID = 0; events.CancelEvent(EVENT_END_POT); } break; case EVENT_SCORCH: DoScriptText(RAND(SAY_SCORCH_1, SAY_SCORCH_2), me); if (Unit* target = me->getVictim()) me->SummonCreature(NPC_GROUND_SCORCH, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 45000); DoCast(SPELL_SCORCH); events.ScheduleEvent(EVENT_SCORCH, 25000); break; case EVENT_CONSTRUCT: DoScriptText(SAY_SUMMON, me); DoSummon(NPC_IRON_CONSTRUCT, ConstructSpawnPosition[urand(0, CONSTRUCT_SPAWN_POINTS - 1)], 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT); DoCast(SPELL_STRENGHT); DoCast(me, SPELL_ACTIVATE_CONSTRUCT); events.ScheduleEvent(EVENT_CONSTRUCT, RAID_MODE(40000, 30000)); break; case EVENT_BERSERK: DoCast(me, SPELL_BERSERK, true); DoScriptText(SAY_BERSERK, me); break; } } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_POUNDING: DoCastVictim(SPELL_POUNDING); Talk(SAY_POUNDING); events.ScheduleEvent(EVENT_POUNDING, 15000); break; case EVENT_ARCANE_ORB: { 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 = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()); if (!target) continue; // exclude pets & totems, 18 yard radius minimum if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive() && !target->IsWithinDist(me, 18, false)) target_list.push_back(target); target = NULL; } if (!target_list.empty()) target = *(target_list.begin() + rand32() % target_list.size()); else target = me->GetVictim(); if (target) me->CastSpell(target, SPELL_ARCANE_ORB, false, NULL, NULL); events.ScheduleEvent(EVENT_ARCANE_ORB, 3000); break; } case EVENT_KNOCK_AWAY: DoCastVictim(SPELL_KNOCK_AWAY); // Drop 25% aggro if (DoGetThreat(me->GetVictim())) DoModifyThreatPercent(me->GetVictim(), -25); events.ScheduleEvent(EVENT_KNOCK_AWAY, 30000); break; case EVENT_BERSERK: if (!Enraged) { DoCast(me, SPELL_BERSERK); Enraged = true; } break; default: break; } } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(uint32 const diff) { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; if (uint32 eventId = events.ExecuteEvent()) { switch(eventId) { case EVENT_CRYSTAL_BARRAGE: DoCast(SELECT_TARGET_RANDOM, SPELL_CRYSTAL_BARRAGE); events.ScheduleEvent(EVENT_CRYSTAL_BARRAGE, urand(10000, 12000), 0, PHASE_NORMAL); break; case EVENT_DAMPENING_WAVE: DoCast(me, SPELL_DAMPENING_WAVE); events.ScheduleEvent(EVENT_DAMPENING_WAVE, urand(10000, 12000), 0, PHASE_NORMAL); break; case EVENT_SUBMERGE: thrashingCharges = 0; me->SetCombatReach(3.0f); events.SetPhase(PHASE_SUBMERGED); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_PASSIVE); me->SetTarget(0); me->RemoveAllAuras(); me->StopMoving(); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); DoCast(me, SPELL_SUBMERGE); events.RescheduleEvent(EVENT_THRASHING_CHARGE, 4000, 0, PHASE_SUBMERGED); break; case EVENT_EMERGE: ported = false; events.SetPhase(PHASE_NORMAL); events.RescheduleEvent(EVENT_DAMPENING_WAVE, 3000, 0, PHASE_NORMAL); events.RescheduleEvent(EVENT_CRYSTAL_BARRAGE, 4500, 0, PHASE_NORMAL); events.ScheduleEvent(EVENT_EMERGE_END, 2500, 0, PHASE_NORMAL); DoCast(me, SPELL_EMERGE_CORBORUS); break; case EVENT_EMERGE_END: me->RemoveAllAuras(); me->SetReactState(REACT_AGGRESSIVE); me->SetCombatReach(12.0f); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); if (Unit * victim = me->GetVictim()) DoStartMovement(victim); events.ScheduleEvent(EVENT_SUBMERGE, 60000, 0, PHASE_NORMAL); break; case EVENT_THRASHING_CHARGE: ported = true; if (Unit * target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { me->GetMotionMaster()->Clear(); me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 2.0f, 0.0f); } events.ScheduleEvent(EVENT_THRASHING_CHARGE_CAST, 500, 0, PHASE_SUBMERGED); break; case EVENT_THRASHING_CHARGE_CAST: DoCast(me, SPELL_THRASHING_CHARGE, false); me->ClearUnitState(UNIT_STATE_CASTING); if (thrashingCharges >= 3) events.ScheduleEvent(EVENT_EMERGE, 3000, 0, PHASE_SUBMERGED); else { ++thrashingCharges; events.ScheduleEvent(EVENT_THRASHING_CHARGE, urand(6000, 8000), 0, PHASE_SUBMERGED); } events.ScheduleEvent(EVENT_THRASHING_CHARGE_DMG, 3500, 0, PHASE_SUBMERGED); break; case EVENT_THRASHING_CHARGE_DMG: DoCast(me, SPELL_THRASHING_CHARGE_SUMMON, true); break; default: break; } } if (events.IsInPhase(PHASE_NORMAL)) DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_HARD_ENRAGE: if (!_isHardEnraged) { DoCast(me, SPELL_PYROBUFFET, true); _isHardEnraged = true; } break; case EVENT_FLAME_TSUNAMI: Talk(WHISPER_LAVA_CHURN); switch (urand(0, 1)) { case 0: { if (Creature* right1 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight1Spawn, TEMPSUMMON_TIMED_DESPAWN, 12000)) right1->GetMotionMaster()->MovePoint(0, FlameRight1Direction); if (Creature* right2 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight2Spawn, TEMPSUMMON_TIMED_DESPAWN, 12000)) right2->GetMotionMaster()->MovePoint(0, FlameRight2Direction); if (Creature* right3 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight3Spawn, TEMPSUMMON_TIMED_DESPAWN, 12000)) right3->GetMotionMaster()->MovePoint(0, FlameRight3Direction); break; } case 1: { if (Creature* left1 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameLeft1Spawn, TEMPSUMMON_TIMED_DESPAWN, 12000)) left1->GetMotionMaster()->MovePoint(0, FlameLeft1Direction); if (Creature* left2 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameLeft2Spawn, TEMPSUMMON_TIMED_DESPAWN, 12000)) left2->GetMotionMaster()->MovePoint(0, FlameLeft2Direction); break; } } events.ScheduleEvent(EVENT_FLAME_TSUNAMI, 30000); break; case EVENT_FLAME_BREATH: Talk(SAY_SARTHARION_BREATH); DoCastVictim(SPELL_FLAME_BREATH); events.ScheduleEvent(EVENT_FLAME_BREATH, urand(25000, 35000)); break; case EVENT_TAIL_SWEEP: DoCastVictim(SPELL_TAIL_LASH); events.ScheduleEvent(EVENT_TAIL_SWEEP, urand(15000, 20000)); break; case EVENT_CLEAVE_ATTACK: DoCastVictim(SPELL_CLEAVE); events.ScheduleEvent(EVENT_CLEAVE_ATTACK, urand(7000, 10000)); break; case EVENT_LAVA_STRIKE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { CastLavaStrikeOnTarget(target); if (urand(0, 5) == 0) Talk(SAY_SARTHARION_SPECIAL); } events.ScheduleEvent(EVENT_LAVA_STRIKE, (_isSoftEnraged ? urand(1400, 2000) : urand(5000, 20000))); break; case EVENT_CALL_TENEBRON: CallDragon(DATA_TENEBRON); break; case EVENT_CALL_SHADRON: CallDragon(DATA_SHADRON); break; case EVENT_CALL_VESPERON: CallDragon(DATA_VESPERON); break; default: break; } } // At 35% spell will target dragons, if they are still alive. if (!_isBerserk && !HealthAbovePct(35)) { if (instance->GetBossState(DATA_TENEBRON) != DONE || instance->GetBossState(DATA_SHADRON) != DONE || instance->GetBossState(DATA_VESPERON) != DONE) { Talk(SAY_SARTHARION_BERSERK); DoCast(me, SPELL_BERSERK); _isBerserk = true; } } // Soft Enrage used while determining Lava Strike cooldown. if (!_isSoftEnraged && HealthBelowPct(10)) { _isSoftEnraged = true; } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; // Pounding if (Pounding_Timer <= diff) { DoCast(me->getVictim(), SPELL_POUNDING); DoScriptText(RAND(SAY_POUNDING1, SAY_POUNDING2), me); Pounding_Timer = 15000; //cast time(3000) + cooldown time(12000) } else Pounding_Timer -= diff; // Arcane Orb if (ArcaneOrb_Timer <= 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) continue; // exclude pets & totems, 18 yard radius minimum if (target->GetTypeId() == TYPEID_PLAYER && target->isAlive() && !target->IsWithinDist(me, 18, false)) target_list.push_back(target); target = NULL; } if (!target_list.empty()) target = *(target_list.begin()+rand()%target_list.size()); else target = me->getVictim(); if (target) me->CastSpell(target, SPELL_ARCANE_ORB, false, NULL, NULL, 0); ArcaneOrb_Timer = 3000; } else ArcaneOrb_Timer -= diff; // Single Target knock back, reduces aggro if (KnockAway_Timer <= diff) { DoCast(me->getVictim(), SPELL_KNOCK_AWAY); //Drop 25% aggro if (DoGetThreat(me->getVictim())) DoModifyThreatPercent(me->getVictim(), -25); KnockAway_Timer = 30000; } else KnockAway_Timer -= diff; //Berserk if (Berserk_Timer < diff && !Enraged) { DoCast(me, SPELL_BERSERK); Enraged = true; } else Berserk_Timer -= diff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(uint32 const diff) { if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BERSERK: DoScriptText(EMOTE_GENERIC_BERSERK_RAID, me); Talk(SAY_BERSERK); DoCast(me, SPELL_BERSERK); break; case EVENT_VAMPIRIC_BITE: { std::list<Player*> targets; SelectRandomTarget(false, &targets); if (!targets.empty()) { Unit* target = targets.front(); DoCast(target, SPELL_VAMPIRIC_BITE); if (IsHeroic()) me->AddAura(SPELL_PRESENCE_OF_THE_DARKFALLEN_TRIG, me); Talk(SAY_VAMPIRIC_BITE); _vampires.insert(target->GetGUID()); } break; } case EVENT_BLOOD_MIRROR: { // victim can be NULL when this is processed in the same update tick as EVENT_AIR_PHASE if (me->getVictim()) { Player* newOfftank = SelectRandomTarget(true); if (_offtank != newOfftank) { _offtank = newOfftank; if (_offtank) { // both spells have SPELL_ATTR5_SINGLE_TARGET_SPELL, no manual removal needed _offtank->CastSpell(me->getVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true); me->getVictim()->CastSpell(_offtank, SPELL_BLOOD_MIRROR_DUMMY, true); DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL); if (Item* shadowsEdge = _offtank->GetWeaponForAttack(BASE_ATTACK, true)) if (!_offtank->HasAura(SPELL_THIRST_QUENCHED) && shadowsEdge->GetEntry() == ITEM_SHADOW_S_EDGE && !_offtank->HasAura(SPELL_GUSHING_WOUND)) _offtank->CastSpell(_offtank, SPELL_GUSHING_WOUND, true); } } } events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500, EVENT_GROUP_CANCELLABLE); break; } case EVENT_DELIRIOUS_SLASH: if (_offtank && !me->HasByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03)) DoCast(_offtank, SPELL_DELIRIOUS_SLASH); events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, urand(20000, 24000), EVENT_GROUP_NORMAL); break; case EVENT_PACT_OF_THE_DARKFALLEN: { std::list<Player*> targets; SelectRandomTarget(false, &targets); uint32 targetCount = 2; // do not combine these checks! we want it incremented TWICE when both conditions are met if (IsHeroic()) ++targetCount; if (Is25ManRaid()) ++targetCount; TrinityCore::RandomResizeList<Player*>(targets, targetCount); if (targets.size() > 1) { Talk(SAY_PACT_OF_THE_DARKFALLEN); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_PACT_OF_THE_DARKFALLEN); } events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 30500, EVENT_GROUP_NORMAL); break; } case EVENT_SWARMING_SHADOWS: if (Player* target = SelectRandomTarget(false)) { Talk(EMOTE_SWARMING_SHADOWS, target->GetGUID()); Talk(SAY_SWARMING_SHADOWS); DoCast(target, SPELL_SWARMING_SHADOWS); } events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500, EVENT_GROUP_NORMAL); break; case EVENT_TWILIGHT_BLOODBOLT: { std::list<Player*> targets; SelectRandomTarget(false, &targets); TrinityCore::RandomResizeList<Player*>(targets, uint32(Is25ManRaid() ? 4 : 2)); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT); DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET); events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, urand(10000, 15000), EVENT_GROUP_NORMAL); break; } case EVENT_AIR_PHASE: DoStopAttack(); me->SetReactState(REACT_PASSIVE); events.DelayEvents(10000, EVENT_GROUP_NORMAL); events.CancelEventGroup(EVENT_GROUP_CANCELLABLE); me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos); break; case EVENT_AIR_START_FLYING: me->SetDisableGravity(true); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND); me->SetCanFly(true); me->GetMotionMaster()->MoveTakeoff(POINT_AIR, airPos); break; case EVENT_AIR_FLY_DOWN: me->GetMotionMaster()->MoveLand(POINT_GROUND, centerPos); break; default: break; } } DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(const uint32 diff) { if (isFlameBreathing) { if (!me->IsNonMeleeSpellCasted(false)) isFlameBreathing = false; else return; } if (isBombing) { if (BombSequenceTimer <= diff) HandleBombSequence(); else BombSequenceTimer -= diff; return; } if (!UpdateVictim()) return; //enrage if under 25% hp before 5 min. if (!enraged && HealthBelowPct(25)) EnrageTimer = 0; if (EnrageTimer <= diff) { if (!enraged) { DoCast(me, SPELL_ENRAGE, true); enraged = true; EnrageTimer = 300000; } else { DoScriptText(SAY_BERSERK, me); DoCast(me, SPELL_BERSERK, true); EnrageTimer = 300000; } } else EnrageTimer -= diff; if (BombTimer <= diff) { DoScriptText(SAY_FIRE_BOMBS, me); me->AttackStop(); me->GetMotionMaster()->Clear(); DoTeleportTo(JanalainPos[0][0],JanalainPos[0][1],JanalainPos[0][2]); me->StopMoving(); DoCast(me, SPELL_FIRE_BOMB_CHANNEL, false); //DoTeleportPlayer(me, JanalainPos[0][0], JanalainPos[0][1],JanalainPos[0][2], 0); //DoCast(me, SPELL_TELE_TO_CENTER, true); FireWall(); SpawnBombs(); isBombing = true; BombSequenceTimer = 100; //Teleport every Player into the middle Map* pMap = me->GetMap(); if (!pMap->IsDungeon()) return; Map::PlayerList const &PlayerList = pMap->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* i_pl = i->getSource()) if (i_pl->isAlive()) DoTeleportPlayer(i_pl, JanalainPos[0][0]-5+rand()%10, JanalainPos[0][1]-5+rand()%10, JanalainPos[0][2], 0); //DoCast(Temp, SPELL_SUMMON_PLAYERS, true) // core bug, spell does not work if too far return; } else BombTimer -= diff; if (!noeggs) { if (HealthBelowPct(35)) { DoScriptText(SAY_ALL_EGGS, me); me->AttackStop(); me->GetMotionMaster()->Clear(); DoTeleportTo(JanalainPos[0][0],JanalainPos[0][1],JanalainPos[0][2]); me->StopMoving(); DoCast(me, SPELL_HATCH_ALL, false); HatchAllEggs(2); noeggs = true; } else if (HatcherTimer <= diff) { if (HatchAllEggs(0)) { DoScriptText(SAY_SUMMON_HATCHER, me); me->SummonCreature(MOB_AMANI_HATCHER,hatcherway[0][0][0],hatcherway[0][0][1],hatcherway[0][0][2],0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000); me->SummonCreature(MOB_AMANI_HATCHER,hatcherway[1][0][0],hatcherway[1][0][1],hatcherway[1][0][2],0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000); HatcherTimer = 90000; } else noeggs = true; } else HatcherTimer -= diff; } EnterEvadeIfOutOfCombatArea(diff); DoMeleeAttackIfReady(); if (FireBreathTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,0)) { me->AttackStop(); me->GetMotionMaster()->Clear(); DoCast(pTarget, SPELL_FLAME_BREATH, false); me->StopMoving(); isFlameBreathing = true; } FireBreathTimer = 8000; } else FireBreathTimer -= diff; }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if ((me->GetHealth()*100 / me->GetMaxHealth()) < 20 && Phase == 1) { Phase = 2; DoScriptText(SAY_PHASE_2, me); } if ((me->GetHealth()*100 / me->GetMaxHealth()) < 2) { me->SummonGameObject(GAMEOBJECT_GIVE_OF_THE_OBSERVER, 1634.258667, -295.101166,417.321381,0,0,0,0,0,-10); DoScriptText(SAY_DEATH_1, me); DoScriptText(SAY_DEATH_2, me); DoScriptText(SAY_DEATH_3, me); DoScriptText(SAY_DEATH_4, me); me->DisappearAndDie(); _JustDied(); } if (Phase == 1) { if (!Summon) { if (uiPhase_timer <= diff) { switch(uiStep) { case 1: DoScriptText(SAY_SUMMON1, me); break; JumpToNextStep(3000); case 2: DoScriptText(SAY_SUMMON2, me); break; JumpToNextStep(3000); case 3: DoScriptText(SAY_SUMMON3, me); break; JumpToNextStep(3000); case 4: DoScriptText(SAY_ENGADED_FOR_FIRTS_TIME, me); break; JumpToNextStep(3000); case 5: DoScriptText(SAY_AGGRO, me); break; case 6: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); break; case 7: me->SetReactState(REACT_AGGRESSIVE); break; } }else uiPhase_timer -= diff; } if(QuantumStrike_Timer <= diff) { DoCast(me->getVictim(), m_bIsHeroicMode ? H_SPELL_QUANTUM_STRIKE : SPELL_QUANTUM_STRIKE, true); QuantumStrike_Timer = 4000 + rand()%10000; }else QuantumStrike_Timer -= diff; if(BigBang_Timer <= diff) { DoScriptText(RAND(SAY_BIG_BANG_1,SAY_BIG_BANG_2), me); DoCast(me->getVictim(), m_bIsHeroicMode ? H_SPELL_BIG_BANG : SPELL_BIG_BANG, true); BigBang_Timer = 90000; }else BigBang_Timer -= diff; if(Ascend_Timer <= diff) { DoCast(me->getVictim(),SPELL_ASCEND, true); Ascend_Timer = 480000; }else Ascend_Timer -= diff; if(PhasePunch_Timer <= diff) { DoCast(me->getVictim(),SPELL_PHASE_PUNCH, true); PhasePunch_Timer = 8000; }else PhasePunch_Timer -= diff; if(CosmicSmash_Timer <= diff) { DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), m_bIsHeroicMode ? H_SPELL_COSMIC_SMASH : SPELL_COSMIC_SMASH, true); CosmicSmash_Timer = urand(30000, 60000); }else CosmicSmash_Timer -= diff; if(Berserk_Timer <= diff) { DoScriptText(SAY_BERSERK, me); DoCast(me->getVictim(),SPELL_BERSERK, true); Berserk_Timer = 360000; }else Berserk_Timer -= diff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); } if (Phase == 2) { if (Enrage) { if (Ascend_Timer <= diff) { DoCast(me, SPELL_ASCEND); DoScriptText(SAY_BERSERK, me); Ascend_Timer = 360000 + rand()%5000; Enrage = false; } else Ascend_Timer -= diff; } } DoMeleeAttackIfReady(); }