void UpdateAI (const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; //MightyBlow_Timer if (MightyBlow_Timer <= diff) { DoCast(me->getVictim(), SPELL_MIGHTYBLOW); MightyBlow_Timer = 18000; } else MightyBlow_Timer -= diff; //HamString_Timer if (HamString_Timer <= diff) { DoCast(me->getVictim(), SPELL_HAMSTRING); HamString_Timer = 15000; } else HamString_Timer -= diff; //Cleave_Timer if (Cleave_Timer <= diff) { DoCast(me->getVictim(), SPELL_CLEAVE); Cleave_Timer = 9000; } else Cleave_Timer -= diff; //Adds_Timer if (HealthBelowPct(21)) { if (Adds_Timer <= diff) { // summon 3 Adds every 25s SummonAdds(me->getVictim()); SummonAdds(me->getVictim()); SummonAdds(me->getVictim()); Adds_Timer = 25000; } else Adds_Timer -= diff; } //Summon Medics if (!Medics && HealthBelowPct(21)) { SummonMedics(me->getVictim()); SummonMedics(me->getVictim()); Medics = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (Invisible && Invisible_Timer < diff) { //Become visible again m_creature->setFaction(14); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); //Noxxion model m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,11172); Invisible = false; //m_creature->m_canMove = true; } else if (Invisible) { Invisible_Timer -= diff; //Do nothing while invisible return; } //Return since we have no target if (!UpdateVictim() ) return; //ToxicVolley_Timer if (ToxicVolley_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_TOXICVOLLEY); ToxicVolley_Timer = 9000; }else ToxicVolley_Timer -= diff; //Uppercut_Timer if (Uppercut_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_UPPERCUT); Uppercut_Timer = 12000; }else Uppercut_Timer -= diff; //Adds_Timer if (!Invisible && Adds_Timer < diff) { //Inturrupt any spell casting //m_creature->m_canMove = true; m_creature->InterruptNonMeleeSpells(false); m_creature->setFaction(35); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Invisible Model m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,11686); SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); Invisible = true; Invisible_Timer = 15000; Adds_Timer = 40000; }else Adds_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return; //MightyBlow_Timer if (MightyBlow_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_MIGHTYBLOW); MightyBlow_Timer = 18000; }else MightyBlow_Timer -= diff; //HamString_Timer if (HamString_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_HAMSTRING); HamString_Timer = 15000; }else HamString_Timer -= diff; //Cleave_Timer if (Cleave_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_CLEAVE); Cleave_Timer = 9000; }else Cleave_Timer -= diff; //Adds_Timer if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 21) { if (Adds_Timer < diff) { // summon 3 Adds every 25s SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); Adds_Timer = 25000; } else Adds_Timer -= diff; } //Summon Medics if (!Medics && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 21) { SummonMedics(m_creature->getVictim()); SummonMedics(m_creature->getVictim()); Medics = true; } DoMeleeAttackIfReady(); }
void InitializeAI() override { if (!me->isDead()) { Reset(); SummonAdds(); } }
void SetData(uint32 uiData, uint32 uiValue) { if (uiData == 1) { uiBossRandom = uiValue; SummonAdds(); } }
void UpdateAI(const uint32 diff) { switch (phase) { case 0: // circle around the platform return; break; case 1: // go to the middle and begin the fight if (check <= diff) { if (!me->IsWithinDist3d(VazrudenMiddle[0], VazrudenMiddle[1], VazrudenMiddle[2], 5)) { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(0, VazrudenMiddle[0], VazrudenMiddle[1], VazrudenMiddle[2]); check = 1000; } else { SummonAdds(); phase = 2; return; } } else check -= diff; break; default: // adds do the job now if (check <= diff) { Creature* Nazan = Unit::GetCreature(*me, NazanGUID); Creature* Vazruden = Unit::GetCreature(*me, VazrudenGUID); if ((Nazan && Nazan->isAlive()) || (Vazruden && Vazruden->isAlive())) { if ((Nazan && Nazan->GetVictim()) || (Vazruden && Vazruden->GetVictim())) return; else { UnsummonAdds(); EnterEvadeMode(); return; } } else if (!lootSpawned) { me->SummonGameObject(DUNGEON_MODE(ENTRY_REINFORCED_FEL_IRON_CHEST, ENTRY_REINFORCED_FEL_IRON_CHEST_H), VazrudenMiddle[0], VazrudenMiddle[1], VazrudenMiddle[2], 0, 0, 0, 0, 0, 0); me->SetLootRecipient(NULL); // don't think this is necessary.. //me->Kill(me); lootSpawned = true; } check = 2000; } else check -= diff; break; } }
void UpdateAI(const uint32 diff) { switch (phase) { case 0: // circle around the platform return; break; case 1: // go to the middle and begin the fight if (check <= diff) { if (me->GetDistance(VazrudenMiddle[0], VazrudenMiddle[1], VazrudenMiddle[2]) > 5) { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(0, VazrudenMiddle[0], VazrudenMiddle[1], VazrudenMiddle[2]); check = 1000; } else { SummonAdds(); phase = 2; return; } } else check -= diff; break; default: // adds do the job now if (check <= diff) { Creature* Nazan = Unit::GetCreature(*me, NazanGUID); Creature* Vazruden = Unit::GetCreature(*me, VazrudenGUID); if ((Nazan && Nazan->IsAlive()) || (Vazruden && Vazruden->IsAlive())) { if ((Nazan && Nazan->getVictim()) || (Vazruden && Vazruden->getVictim())) return; else { Reset(); EnterEvadeMode(); return; } } else { me->SummonGameObject(ENTRY_REINFORCED_FEL_IRON_CHEST, VazrudenMiddle[0], VazrudenMiddle[1], VazrudenMiddle[2], 0, 0, 0, 0, 0, 0); me->SetLootRecipient(NULL); me->DealDamage(me, me->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); if (pInstance) pInstance->SetData(DATA_VAZRUDEN, DONE); } check = 2000; } else check -= diff; break; } }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiSummonTimer) { if (m_uiSummonTimer <= uiDiff) { SummonAdds(); m_uiSummonTimer = 0; } else m_uiSummonTimer -= uiDiff; } if (m_uiShadowboltTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_SHADOWBOLT : SPELL_SHADOWBOLT_H); m_uiShadowboltTimer = 3000; } else m_uiShadowboltTimer -= uiDiff; if (m_uiFrostTombTimer < uiDiff) { if (Unit* pTombTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) { //DoCastSpellIfCan(pTombTarget, SPELL_SUMMON_FROST_TOMB); float fPosX, fPosY, fPosZ; pTombTarget->GetPosition(fPosX, fPosY, fPosZ); if (Creature* pFrostTomb = m_creature->SummonCreature(NPC_FROST_TOMB, fPosX, fPosY, fPosZ, 0, TEMPSUMMON_TIMED_DESPAWN, 20000)) { pFrostTomb->AddThreat(pTombTarget); pFrostTomb->CastSpell(pTombTarget, SPELL_FROST_TOMB, false); } DoScriptText(SAY_FROSTTOMB, m_creature); DoScriptText(EMOTE_FROST_TOMB, m_creature, pTombTarget); } m_uiFrostTombTimer = 25000; } else m_uiFrostTombTimer -= uiDiff; DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { switch (phase) { case 0: // circle around the platform return; break; case 1: // go to the middle and begin the fight if (check <= diff) { if (!me->IsWithinDist3d(VazrudenMiddle[0], VazrudenMiddle[1], VazrudenMiddle[2], 5)) { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(0, VazrudenMiddle[0], VazrudenMiddle[1], VazrudenMiddle[2]); check = 1000; } else { SummonAdds(); phase = 2; return; } } else check -= diff; break; default: // adds do the job now if (check <= diff) { Creature* Nazan = ObjectAccessor::GetCreature(*me, NazanGUID); Creature* Vazruden = ObjectAccessor::GetCreature(*me, VazrudenGUID); if ((Nazan && Nazan->IsAlive()) || (Vazruden && Vazruden->IsAlive())) { if ((Nazan && Nazan->GetVictim()) || (Vazruden && Vazruden->GetVictim())) return; else { UnsummonAdds(); EnterEvadeMode(); return; } } check = 2000; } else check -= diff; break; } }
void InitializeAI() override { BossAI::InitializeAI(); SummonAdds(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostilTarget()) return; //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { //MightyBlow_Timer if (MightyBlow_Timer < diff) { //Cast DoCast(m_creature->getVictim(),SPELL_MIGHTYBLOW); //18 seconds MightyBlow_Timer = 18000; }else MightyBlow_Timer -= diff; //HamString_Timer if (HamString_Timer < diff) { //Cast DoCast(m_creature->getVictim(),SPELL_HAMSTRING); //15 seconds HamString_Timer = 15000; }else HamString_Timer -= diff; //Cleave_Timer if (Cleave_Timer < diff) { //Cast DoCast(m_creature->getVictim(),SPELL_CLEAVE); //45 seconds Cleave_Timer = 9000; }else Cleave_Timer -= diff; //Adds_Timer if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 21 ) { if (Adds_Timer < diff) { // summon 3 Adds every 25s SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); //25 seconds until we should cast this agian Adds_Timer = 25000; } else Adds_Timer -= diff; } //Summon Medics if ( !Medics && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 21 ) { //Cast SummonMedics(m_creature->getVictim()); SummonMedics(m_creature->getVictim()); Medics = true; } //If we are within range melee the target if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) { //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } } }
void UpdateAI(uint32 diff) override { if (Invisible && InvisibleTimer <= diff) { //Become visible again me->SetFaction(FACTION_MONSTER); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); //Noxxion model me->SetDisplayId(11172); Invisible = false; //me->m_canMove = true; } else if (Invisible) { InvisibleTimer -= diff; //Do nothing while invisible return; } //Return since we have no target if (!UpdateVictim()) return; //ToxicVolleyTimer if (ToxicVolleyTimer <= diff) { DoCastVictim(SPELL_TOXICVOLLEY); ToxicVolleyTimer = 9000; } else ToxicVolleyTimer -= diff; //UppercutTimer if (UppercutTimer <= diff) { DoCastVictim(SPELL_UPPERCUT); UppercutTimer = 12000; } else UppercutTimer -= diff; //AddsTimer if (!Invisible && AddsTimer <= diff) { //Interrupt any spell casting //me->m_canMove = true; me->InterruptNonMeleeSpells(false); me->SetFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Invisible Model me->SetDisplayId(11686); SummonAdds(me->GetVictim()); SummonAdds(me->GetVictim()); SummonAdds(me->GetVictim()); SummonAdds(me->GetVictim()); SummonAdds(me->GetVictim()); Invisible = true; InvisibleTimer = 15000; AddsTimer = 40000; } else AddsTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM,0); if (!pTarget) return; if(me->GetPositionY() > -60 || me->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles. { me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(false); me->GetMotionMaster()->MoveTargetedHome(); } if (me->getVictim() && !me->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()) me->Kill(me->getVictim()); if ((me->GetHealth()*100 / me->GetMaxHealth()) < 90 && Phase == 0) { Phase = 1; bFly = true; } if ((me->GetHealth()*100 / me->GetMaxHealth()) < 50 && Phase == 1) { me->RemoveAllAuras(); Phase = 2; InitialSpawn = false; if (IsFlying) { me->SetFlying(false); me->GetMotionMaster()->MoveTargetedHome(); IsFlying = false; me->SetReactState(REACT_AGGRESSIVE); me->SendMovementFlagUpdate(); } DoScriptText(SAY_PHASE_2_TRANS, me); } if ((me->GetHealth()*100 / me->GetMaxHealth()) < 33 && Phase == 2) { Phase = 3; DoScriptText(SAY_PHASE_3_TRANS, me); } if (Phase >= 2) { if (FuseArmorTimer <= diff) { DoCastVictim(SPELL_FUSEARMOR); FuseArmorTimer = 10000; } else FuseArmorTimer -= diff; if (WingBuffetTimer <= diff) { DoCast(SPELL_WINGBUFFET); WingBuffetTimer = urand(27000,34000); } else WingBuffetTimer -= diff; if (FireballTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) { me->SetInFront(pTarget); DoCast(pTarget, SPELL_FIREBALL); } FireballTimer = 18000; } else FireballTimer -= diff; if (Phase == 3) { if (FlameBuffetTimer <= diff) { DoScriptText(EMOTE_BREATH, me); std::list<Unit*> pTargets; SelectTargetList(pTargets, RAID_MODE(3,9), SELECT_TARGET_RANDOM, 100, true); uint8 i = 0; for (std::list<Unit*>::const_iterator itr = pTargets.begin(); itr != pTargets.end();) { if (me->HasInArc(M_PI, *itr)) { DoCast(*itr, SPELL_FLAMEBUFFET, true); ++i; } if (++itr == pTargets.end() || i == RAID_MODE(3,9)) { AttackStart(*--itr); break; } if (!i) return; } FlameBuffetTimer = 25000; } else FlameBuffetTimer -= diff; if (FlameBreathTimer <= diff) { DoScriptText(EMOTE_BREATH, me); DoCastVictim(SPELL_FLAMEBREATH); FlameBreathTimer = 15000; } else FlameBreathTimer -= diff; } DoMeleeAttackIfReady(); } else if (Phase == 1) { if (bFly) { FlyPhase(Phase, diff); SummonAddsTimer = 8000; bFly = false; } Creature* pSpellHitt; pSpellHitt = NULL; if (pSpellHitt = me->FindNearestCreature(NPC_VISUAL_HITT, 5.0f, true)) { me->GetMotionMaster()->MoveTargetedHome(); me->SetFlying(false); me->SendMovementFlagUpdate(); IsFlying = false; bFlyPhase1 = true; bFlyPhaseTimer = 35000; bFly = false; InitialSpawn = false; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); StunTimer = 2000; } if (!bFly && bFlyPhase1 && !IsFlying && StunTimer <= diff) { DoCast(me,SPELL_STUN); StunTimer = 2000; } else StunTimer -= diff; if (bFlyPhase1 && bFlyPhaseTimer <= diff) { me->RemoveAllAuras(); me->SetReactState(REACT_AGGRESSIVE); me->SendMovementFlagUpdate(); DoScriptText(EMOTE_BREATH, me); DoCastVictim(SPELL_FLAMEBREATH); DoCast(SPELL_WINGBUFFET); bFlyPhaseTimer = 40000; SpawnHarpoonTimer = 60000; bFly = true; bFlyPhase1 = false; } else bFlyPhaseTimer -= diff; if (FireballTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) { me->SetInFront(pTarget); DoCast(pTarget, SPELL_FIREBALL); } FireballTimer = 12000; } else FireballTimer -= diff; if (DevouringFlameTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) { me->SetInFront(pTarget); DoCast(pTarget, DEVOURING_FLAME_VISUAL); } DevouringFlameTimer = 6000; } else DevouringFlameTimer -= diff; if (InitialSpawn) { if (SummonAddsTimer <= diff) { SummonAdds(); InitialSpawn = true; } else SummonAddsTimer -= diff; } if (InitialSpawn && SpawnHarpoonTimer <= diff) { if (pInstance) pInstance->SetData(DATA_HARPOON, pInstance->GetData(DATA_HARPOON)+1); //if(!GetClosestGameObjectWithEntry(me, GO_BROKEN_HARPOON, 200.0f)) //if (GameObject* pGo = me->SummonGameObject(GO_BROKEN_HARPOON, 607.613, -134.207, 391.297, 4.10138, 0, 0, 0, 0,0)) SpawnHarpoonTimer = 60000; } else SpawnHarpoonTimer -= diff; //EnterEvadeIfOutOfCombatArea(diff); } }
void JustReachedHome() override { _JustReachedHome(); SummonAdds(); me->GetMotionMaster()->Initialize(); }
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_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 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_creature->GetMotionMaster()->Clear(); 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_uiPhase == PHASE_GROUND) { if (m_creature->GetHealthPercent() < 30.0f) { DoScriptText(EMOTE_GATE, m_creature); m_pInstance->SetData(TYPE_GOTHIK, SPECIAL); m_uiPhase = PHASE_END; m_uiShadowboltTimer = 2000; // all out of combat summons from Death Side storm the raid at once for (std::list<uint64>::iterator itr = m_pInstance->lGothikDeathAdds.begin(); itr != m_pInstance->lGothikDeathAdds.end(); itr++) if (Creature* pCreature = m_pInstance->instance->GetCreature(*itr) ) if (pCreature->isAlive() && !pCreature->getVictim() ) pCreature->AI()->AttackStart(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ); // all out of combat summons from Live Side storm the raid at once for (std::list<uint64>::iterator itr = m_pInstance->lGothikLiveAdds.begin(); itr != m_pInstance->lGothikLiveAdds.end(); itr++) if (Creature* pCreature = m_pInstance->instance->GetCreature(*itr) ) if (pCreature->isAlive() && !pCreature->getVictim() ) pCreature->AI()->AttackStart(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) ); 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; if (m_uiHarvestsoulTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_HARVESTSOUL); m_uiHarvestsoulTimer = 15000; } else m_uiHarvestsoulTimer -= uiDiff; DoMeleeAttackIfReady(); // possibly no melee at all break; } } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (me->getVictim() && !me->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()) me->Kill(me->getVictim()); events.Update(diff); if (HealthBelowPct(50) && !PermaGround) EnterPermaGround(); if (EnrageTimer <= diff && !Enraged) { DoCast(me, SPELL_BERSERK); Enraged = true; } else EnrageTimer -= diff; if (phase == PHASE_GROUND) { while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FLIGHT: phase = PHASE_FLIGHT; events.SetPhase(PHASE_FLIGHT); me->SetFlying(true); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_PASSIVE); me->AttackStop(); me->RemoveAllAuras(); me->GetMotionMaster()->MovePoint(0, RazorFlight); events.ScheduleEvent(EVENT_FIREBALL, 7000, 0, PHASE_FLIGHT); events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT); events.ScheduleEvent(EVENT_SUMMON, 5000, 0, PHASE_FLIGHT); events.ScheduleEvent(EVENT_GROUND, 75000, 0, PHASE_FLIGHT); ++FlyCount; return; case EVENT_LAND: me->SetFlying(false); me->NearTeleportTo(586.966f, -175.534f, 391.517f, 1.692f); DoCast(me, SPELL_STUN, true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (Creature *pCommander = me->GetCreature(*me, instance->GetData64(DATA_EXP_COMMANDER))) pCommander->AI()->DoAction(ACTION_GROUND_PHASE); events.ScheduleEvent(EVENT_HARPOON, 0, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_BREATH, 30000, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_BUFFET, 33000, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_FLIGHT, 35000, 0, PHASE_GROUND); return; case EVENT_HARPOON: for (uint8 n = 0; n < RAID_MODE(2, 4); ++n) if (Harpoon[n]) Harpoon[n]->CastSpell(me, SPELL_HARPOON, true); events.ScheduleEvent(EVENT_HARPOON, 1500, 0, PHASE_GROUND); return; case EVENT_BREATH: me->MonsterTextEmote(EMOTE_BREATH, 0, true); DoCastAOE(SPELL_FLAMEBREATH); events.CancelEvent(EVENT_HARPOON); events.CancelEvent(EVENT_BREATH); return; case EVENT_BUFFET: DoCastAOE(SPELL_WINGBUFFET); for (uint8 n = 0; n < RAID_MODE(2, 4); ++n) if (Harpoon[n]) Harpoon[n]->CastSpell(Harpoon[n], SPELL_FLAMED, true); events.CancelEvent(EVENT_BUFFET); return; } } } if (phase == PHASE_PERMAGROUND) { while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FLAME: DoCastAOE(SPELL_FLAMEBUFFET); events.ScheduleEvent(EVENT_FLAME, 10000, 0, PHASE_PERMAGROUND); return; case EVENT_BREATH: me->MonsterTextEmote(EMOTE_BREATH, 0, true); DoCastVictim(SPELL_FLAMEBREATH); events.ScheduleEvent(EVENT_BREATH, 20000, 0, PHASE_PERMAGROUND); return; case EVENT_FIREBALL: if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) DoCast(pTarget, SPELL_FIREBALL); events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_PERMAGROUND); return; case EVENT_DEVOURING: if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) DoCast(pTarget, SPELL_DEVOURING_FLAME); events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_PERMAGROUND); return; case EVENT_BUFFET: DoCastAOE(SPELL_WINGBUFFET); events.CancelEvent(EVENT_BUFFET); return; case EVENT_FUSE: DoCastVictim(SPELL_FUSEARMOR); events.ScheduleEvent(EVENT_FUSE, 10000, 0, PHASE_PERMAGROUND); return; } } DoMeleeAttackIfReady(); } else { if (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_GROUND: phase = PHASE_GROUND; events.SetPhase(PHASE_GROUND); if (Harpoon[0]) Harpoon[0]->MonsterTextEmote(EMOTE_HARPOON, 0, true); me->GetMotionMaster()->MovePoint(0, RazorGround); events.ScheduleEvent(EVENT_LAND, 5500, 0, PHASE_GROUND); return; case EVENT_FIREBALL: if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) DoCast(pTarget, SPELL_FIREBALL); events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_FLIGHT); return; case EVENT_DEVOURING: if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) DoCast(pTarget, SPELL_DEVOURING_FLAME); events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT); return; case EVENT_SUMMON: SummonAdds(); events.ScheduleEvent(EVENT_SUMMON, 45000, 0, PHASE_FLIGHT); return; } } } }
void JustReachedHome() override { _JustReachedHome(); SummonAdds(); }
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_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 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_uiPhase == PHASE_GROUND) { if (m_creature->GetHealthPercent() < 30.0f) { // reset speed of Deadside Adds upon opening combat gate for(std::set<uint64>::const_iterator itr = m_lDeadsideAdds.begin(); itr != m_lDeadsideAdds.end(); ++itr) { if (Creature* pDeadsideAdds = m_pInstance->instance->GetCreature(*itr)) { pDeadsideAdds->SetSpeedRate(MOVE_RUN, 1.14f); } } 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 UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostilTarget()) return; //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { //Wrath_Timer if (Wrath_Timer < diff) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,0); if (target)DoCast(target,SPELL_WRATH); //20 seconds Wrath_Timer = 20000; }else Wrath_Timer -= diff; //EntanglingRoots_Timer if (EntanglingRoots_Timer < diff) { //Cast DoCast(m_creature->getVictim(),SPELL_ENTANGLINGROOTS); //12 seconds until we should cast this agian EntanglingRoots_Timer = 12000; }else EntanglingRoots_Timer -= diff; //TwistedTranquility_Timer if (TwistedTranquility_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_TWISTEDTRANQUILITY); //30 seconds until we should cast this agian TwistedTranquility_Timer = 30000; }else TwistedTranquility_Timer -= diff; //Adds_Timer if (Adds_Timer < diff) { //Cast SummonAdds(m_creature->getVictim()); SummonAdds(m_creature->getVictim()); //28 seconds until we should cast this agian Adds_Timer = 28000; }else Adds_Timer -= diff; //If we are within range melee the target if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) { //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } } }
void JustRespawned() override { BossAI::JustRespawned(); SummonAdds(); }
void UpdateAI(const uint32 uiDiff) { 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(0, 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 = 2 * IN_MILLISECONDS; 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)) 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) { if (instance->GetData(DATA_STRANGE_POOL) != IN_PROGRESS) return; if (me->GetVisibility() == VISIBILITY_OFF) { me->SetVisibility(VISIBILITY_ON); me->RemoveAurasDueToSpell(SPELL_SUBMERGE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoZoneInCombat(); } if (!UpdateVictim()) return; DoSpecialThings(diff, DO_PULSE_COMBAT); Rotate(diff);//always check rotate things events.Update(diff); if(!m_submerged && RotType == NOROTATE)//is not spouting and not submerged { if(SpoutTimer < diff) { if(me->getVictim() && RotType == NOROTATE) StartRotate(me->getVictim());//start spout and random rotate SpoutTimer= 35000; return; } else SpoutTimer -= diff; } while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { /*case LURKER_EVENT_SPOUT_EMOTE: { me->MonsterTextEmote(EMOTE_SPOUT, 0, true); ForceSpellCast(me, SPELL_SPOUT_BREATH); events.ScheduleEvent(LURKER_EVENT_SPOUT, 3000); break; } case LURKER_EVENT_SPOUT: { me->SetReactState(REACT_PASSIVE); me->SetSelection(0); me->GetMotionMaster()->MoveRotate(20000, RAND(ROTATE_DIRECTION_LEFT, ROTATE_DIRECTION_RIGHT)); ForceSpellCast(me, SPELL_SPOUT_VISUAL, INTERRUPT_AND_CAST_INSTANTLY); m_rotating = true; events.DelayEvents(20000, 0); events.ScheduleEvent(LURKER_EVENT_SPOUT_EMOTE, 45000); events.RescheduleEvent(LURKER_EVENT_WHIRL, 21000); break; }*/ case LURKER_EVENT_WHIRL: { AddSpellToCast(me, SPELL_WHIRL); events.ScheduleEvent(LURKER_EVENT_WHIRL, 18000); break; } case LURKER_EVENT_GEYSER: { AddSpellToCast(SPELL_GEYSER, CAST_RANDOM); events.ScheduleEvent(LURKER_EVENT_GEYSER, urand(15000, 20000)); break; } case LURKER_EVENT_SUBMERGE: { ForceSpellCast(me, SPELL_SUBMERGE, INTERRUPT_AND_CAST_INSTANTLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); SummonAdds(); m_submerged = true; events.CancelEvent(LURKER_EVENT_SPOUT_EMOTE); SpoutTimer = 4000; // directly cast Spout after emerging! // events.CancelEvent(LURKER_EVENT_SPOUT); events.CancelEvent(LURKER_EVENT_WHIRL); events.CancelEvent(LURKER_EVENT_GEYSER); events.ScheduleEvent(LURKER_EVENT_REEMERGE, 60000); break; } case LURKER_EVENT_REEMERGE: { me->RemoveAurasDueToSpell(SPELL_SUBMERGE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_submerged = false; events.ScheduleEvent(LURKER_EVENT_SPOUT_EMOTE, 0); events.ScheduleEvent(LURKER_EVENT_WHIRL, 2000); events.ScheduleEvent(LURKER_EVENT_GEYSER, urand(5000, 15000)); events.ScheduleEvent(LURKER_EVENT_SUBMERGE, 90000); break; } } } CastNextSpellIfAnyAndReady(); DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (Invisible && Invisible_Timer < diff) { //Become visible again m_creature->setFaction(14); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); //Noxxion model m_creature->SetDisplayId(11172); Invisible = false; //m_creature->m_canMove = true; } else if (Invisible) { Invisible_Timer -= diff; //Do nothing while invisible return; } //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; //ToxicVolley_Timer if (ToxicVolley_Timer < diff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_TOXICVOLLEY) == CAST_OK) ToxicVolley_Timer = 9000; } else ToxicVolley_Timer -= diff; //Uppercut_Timer if (Uppercut_Timer < diff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_UPPERCUT) == CAST_OK) Uppercut_Timer = 12000; } else Uppercut_Timer -= diff; //Adds_Timer if (!Invisible && Adds_Timer < diff) { //Inturrupt any spell casting m_creature->InterruptNonMeleeSpells(false); m_creature->setFaction(35); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Invisible Model m_creature->SetDisplayId(11686); for (int i = 0; i < 5; ++i) SummonAdds(m_creature->getVictim()); Invisible = true; Invisible_Timer = 15000; Adds_Timer = 40000; } else Adds_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (m_creature->GetPositionY() > -60 || m_creature->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles. { m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(false); m_creature->GetMotionMaster()->MoveTargetedHome(); } // Victim is not controlled by a player (should never happen) if (m_creature->getVictim() && !m_creature->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()) m_creature->Kill(m_creature->getVictim()); if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 99 && Phase == 1) // TODO: Only land (exit Phase 1) if brought down with harpoon guns! This is important! { Phase = 2; DoScriptText(SAY_PHASE_2_TRANS, m_creature); // Audio: "Move quickly! She won't remain grounded for long!" } if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 33 && Phase == 2) // Health under 33%, Razorscale can't fly anymore. { Phase = 3; DoScriptText(SAY_PHASE_3_TRANS, m_creature); // "Razorscale lands permanently!" // TODO: Cast Devouring Flame on all harpoon guns simultaneously, briefly after Phase 3 starts (lasts until the harpoon guns are destroyed) } /* if (Phase == 2 && CastSpellsTimer > 0) // 5 seconds of spell casting, after stun breaks, during Phase 2 { if (CastSpellsTimer <= diff) // 5 seconds are up Phase = 1; // Return to phase 1 else CastSpellsTimer -= diff; }*/ FlyPhase(Phase, diff); if (Phase >= 2) // Ground Phase (Phase 3 = permanent ground phase) { if (FuseArmorTimer <= diff) { DoCastVictim(SPELL_FUSEARMOR); FuseArmorTimer = 10000; } else FuseArmorTimer -= diff; if (WingBuffetTimer <= diff) { DoCast(SPELL_WINGBUFFET); WingBuffetTimer = urand(7000,14000); } else WingBuffetTimer -= diff; if (FireballTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) { m_creature->SetInFront(pTarget); DoCast(pTarget, SPELL_FIREBALL); } FireballTimer = 18000; } else FireballTimer -= diff; if (FlameBreathTimer <= diff) { DoScriptText(EMOTE_BREATH, m_creature); // TODO: "Razorscale takes a deep breath..." DoCastVictim(SPELL_FLAMEBREATH); FlameBreathTimer = 15000; WingBuffetTimer = 0; } else FlameBreathTimer -= diff; if (Phase == 3) { if (FlameBuffetTimer <= diff) { DoScriptText(EMOTE_BREATH, m_creature); std::list<Unit*> pTargets; SelectTargetList(pTargets, RAID_MODE(3,9), SELECT_TARGET_RANDOM, 100, true); uint8 i = 0; for (std::list<Unit*>::iterator itr = pTargets.begin(); itr != pTargets.end();) { if (m_creature->HasInArc(M_PI, *itr)) { DoCast(*itr, SPELL_FLAMEBUFFET, true); ++i; } if (++itr == pTargets.end() || i == RAID_MODE(3,9)) { AttackStart(*--itr); // seems to attack targets randomly during perma-ground phase.. break; } } FlameBuffetTimer = 25000; } else FlameBuffetTimer -= diff; } DoMeleeAttackIfReady(); } else if (Phase == 1) //Flying Phase { if (InitialSpawn) SummonAdds(); InitialSpawn = false; if (FireballTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) { m_creature->SetInFront(pTarget); DoCast(pTarget, SPELL_FIREBALL); } FireballTimer = 18000; } else FireballTimer -= diff; if (DevouringFlameTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) { m_creature->SetInFront(pTarget); DoCast(pTarget, SPELL_DEVOURINGFLAME); } DevouringFlameTimer = 10000; } else DevouringFlameTimer -= diff; if (SummonAddsTimer <= diff) SummonAdds(); else SummonAddsTimer -= diff; } }
void UpdateAI(const uint32 diff) { if (instance->GetData(DATA_LURKER_FISHING_EVENT) != DONE) return; //boss is invisible, don't attack if (!CanStartEvent) { if (m_submerged) { m_submerged = false; WaitTimer2 = 500; } //wait 500ms before emerge anim if (!m_submerged && WaitTimer2 <= diff) { me->SetVisibility(VISIBILITY_ON); me->RemoveAllAuras(); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); DoCast(me, SPELL_EMERGE, false); WaitTimer2 = 60000;//never reached WaitTimer = 3000; } else WaitTimer2 -= diff; //wait 3secs for emerge anim, then attack if (WaitTimer <= diff) { //fresh fished from pool WaitTimer = 3000; CanStartEvent = true; me->RemoveAurasDueToSpell(SPELL_SUBMERGE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoZoneInCombat(); if (ConsecutiveSubmerge) { events.RescheduleEvent(LURKER_EVENT_WHIRL, 2000); events.RescheduleEvent(LURKER_EVENT_GEYSER, urand(5000, 15000)); events.RescheduleEvent(LURKER_EVENT_SUBMERGE, 90000); } } else WaitTimer -= diff; return; } if (!UpdateVictim()) return; DoSpecialThings(diff, DO_PULSE_COMBAT); Rotate(diff);//always check rotate things events.Update(diff); if(!m_submerged && RotType == NOROTATE)//is not spouting and not submerged { if(SpoutTimer < diff) { if(me->getVictim() && RotType == NOROTATE) StartRotate(me->getVictim());//start spout and random rotate SpoutTimer= 35000; return; } else SpoutTimer -= diff; } while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case LURKER_EVENT_WHIRL: { if (m_submerged == false) { AddSpellToCast(me, SPELL_WHIRL); } events.RescheduleEvent(LURKER_EVENT_WHIRL, 18000); break; } case LURKER_EVENT_GEYSER: { AddSpellToCast(SPELL_GEYSER, CAST_RANDOM); events.ScheduleEvent(LURKER_EVENT_GEYSER, urand(15000, 20000)); break; } case LURKER_EVENT_SUBMERGE: { ForceSpellCast(me, SPELL_SUBMERGE, INTERRUPT_AND_CAST_INSTANTLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); me->SetVisibility(VISIBILITY_OFF); SummonAdds(); m_submerged = true; // directly cast Spout after emerging! SpoutTimer = 4000; events.CancelEvent(LURKER_EVENT_WHIRL); events.CancelEvent(LURKER_EVENT_GEYSER); events.ScheduleEvent(LURKER_EVENT_REEMERGE, 60000); break; } case LURKER_EVENT_REEMERGE: { me->SetVisibility(VISIBILITY_OFF); DoStopAttack(); //Time values here is irrelevant, they just need to be set WaitTimer = 60000; WaitTimer2 = 60000; CanStartEvent = false; m_submerged = true; ConsecutiveSubmerge = true; break; } } } CastNextSpellIfAnyAndReady(); DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (uiCheckTimer <= diff) { if (CheckPlayersInDistance()) { if (!me->isInCombat()) { SummonAdds(); } } else if (me->isInCombat()) { Summons.DespawnAll(); EnterEvadeMode(); } uiCheckTimer = 2*IN_MILLISECONDS; } else uiCheckTimer -= diff; //Return since we have no target if (!UpdateVictim()) return; if (!bClosedDoor) { if (uiSummonTimer <= diff) { SummonAdds(); uiSummonTimer = 5*IN_MILLISECONDS; } else uiSummonTimer -= diff; if (uiDoorsTimer <= diff) { bClosedDoor = true; } else uiDoorsTimer -= diff; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; if (uiPierceTimer <= diff) { DoCast(me->getVictim(), SPELL_PIERCE_ARMOR); uiPierceTimer = 8*IN_MILLISECONDS; } else uiPierceTimer -= diff; if (uiAcidTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_ACID_CLOUD); uiAcidTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS); } else uiAcidTimer -= diff; if (uiLeechTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_LEECH_POISON); uiLeechTimer = urand(11*IN_MILLISECONDS, 14*IN_MILLISECONDS); } else uiLeechTimer -= diff; if (uiGrabTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) // Draws all players (and attacking Mobs) to itself. DoCast(target, SPELL_WEB_GRAB); uiGrabTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS); } else uiGrabTimer -= diff; DoMeleeAttackIfReady(); }