void UpdateAI(uint32 diff) override { events.Update(diff); // Speech if (!UpdateVictim()) { while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_SPEECH_1: Talk(SAY_LINE1); me->SetStandState(UNIT_STAND_STATE_STAND); me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); events.ScheduleEvent(EVENT_SPEECH_2, 12000); break; case EVENT_SPEECH_2: Talk(SAY_LINE2); me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); events.ScheduleEvent(EVENT_SPEECH_3, 12000); break; case EVENT_SPEECH_3: Talk(SAY_LINE3); me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); events.ScheduleEvent(EVENT_SPEECH_4, 16000); break; case EVENT_SPEECH_4: me->setFaction(103); if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) AttackStart(player); break; } } return; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_CLEAVE: events.ScheduleEvent(EVENT_CLEAVE, 15000); DoCastVictim(SPELL_CLEAVE); break; case EVENT_FLAMEBREATH: DoCastVictim(SPELL_FLAMEBREATH); events.ScheduleEvent(EVENT_FLAMEBREATH, urand(8000, 14000)); break; case EVENT_FIRENOVA: DoCastVictim(SPELL_FIRENOVA); events.ScheduleEvent(EVENT_FIRENOVA, 15000); break; case EVENT_TAILSWIPE: //Only cast if we are behind /*if (!me->HasInArc(M_PI, me->GetVictim())) { DoCast(me->GetVictim(), SPELL_TAILSWIPE); }*/ events.ScheduleEvent(EVENT_TAILSWIPE, 15000); break; case EVENT_BURNINGADRENALINE_CASTER: { Unit* target = NULL; uint8 i = 0; while (i < 3) // max 3 tries to get a random target with power_mana { ++i; target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); // not aggro leader if (target && target->getPowerType() == POWER_MANA) i = 3; } if (target) // cast on self (see below) target->CastSpell(target, SPELL_BURNINGADRENALINE, true); } events.ScheduleEvent(EVENT_BURNINGADRENALINE_CASTER, 15000); break; case EVENT_BURNINGADRENALINE_TANK: // have the victim cast the spell on himself otherwise the third effect aura will be applied to Vael instead of the player me->EnsureVictim()->CastSpell(me->GetVictim(), SPELL_BURNINGADRENALINE, true); events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45000); break; } } // Yell if hp lower than 15% if (HealthBelowPct(15) && !HasYelled) { Talk(SAY_HALFLIFE); HasYelled = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { // Always decrease our global cooldown first if (GlobalCooldown > diff) GlobalCooldown -= diff; else GlobalCooldown = 0; // Buff timer (only buff when we are alive and not in combat if (!me->isInCombat() && me->isAlive()) { if (BuffTimer <= diff) { // Find a spell that targets friendly and applies an aura (these are generally buffs) SpellInfo const* info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_AURA); if (info && !GlobalCooldown) { // Cast the buff spell DoCastSpell(me, info); // Set our global cooldown GlobalCooldown = GENERIC_CREATURE_COOLDOWN; // Set our timer to 10 minutes before rebuff BuffTimer = 600000; } // Try again in 30 seconds else BuffTimer = 30000; } else BuffTimer -= diff; } // Return since we have no target if (!UpdateVictim()) return; // If we are within range melee the target if (me->IsWithinMeleeRange(me->getVictim())) { // Make sure our attack is ready and we aren't currently casting if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false)) { bool Healing = false; SpellInfo const* info = NULL; // Select a healing spell if less than 30% hp if (HealthBelowPct(30)) info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING); // No healing spell available, select a hostile spell if (info) Healing = true; else info = SelectSpell(me->getVictim(), 0, 0, SELECT_TARGET_ANY_ENEMY, 0, 0, 0, 0, SELECT_EFFECT_DONTCARE); // 50% chance if elite or higher, 20% chance if not, to replace our white hit with a spell if (info && (rand() % (me->GetCreatureTemplate()->rank > 1 ? 2 : 5) == 0) && !GlobalCooldown) { // Cast the spell if (Healing)DoCastSpell(me, info); else DoCastSpell(me->getVictim(), info); // Set our global cooldown GlobalCooldown = GENERIC_CREATURE_COOLDOWN; } else me->AttackerStateUpdate(me->getVictim()); me->resetAttackTimer(); } } else { // Only run this code if we aren't already casting if (!me->IsNonMeleeSpellCasted(false)) { bool Healing = false; SpellInfo const* info = NULL; // Select a healing spell if less than 30% hp ONLY 33% of the time if (HealthBelowPct(30) && rand() % 3 == 0) info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING); // No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE) if (info) Healing = true; else info = SelectSpell(me->getVictim(), 0, 0, SELECT_TARGET_ANY_ENEMY, 0, 0, NOMINAL_MELEE_RANGE, 0, SELECT_EFFECT_DONTCARE); // Found a spell, check if we are not on a cooldown if (info && !GlobalCooldown) { // If we are currently moving stop us and set the movement generator if (!IsSelfRooted) IsSelfRooted = true; // Cast spell if (Healing) DoCastSpell(me, info); else DoCastSpell(me->getVictim(), info); // Set our global cooldown GlobalCooldown = GENERIC_CREATURE_COOLDOWN; } // If no spells available and we aren't moving run to target else if (IsSelfRooted) { // Cancel our current spell and then allow movement again me->InterruptNonMeleeSpells(false); IsSelfRooted = false; } } } }
void UpdateAI(const uint32 diff) { //Only if not incombat check if the event is started if (!me->isInCombat() && pInstance && pInstance->GetData(DATA_MAULGAREVENT)) { Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_MAULGAREVENT_TANK)); if (pTarget) { AttackStart(pTarget); GetCouncil(); } } //Return since we have no target if (!UpdateVictim()) return; //someone evaded! if (pInstance && !pInstance->GetData(DATA_MAULGAREVENT)) { EnterEvadeMode(); return; } //ArcingSmash_Timer if (ArcingSmash_Timer <= diff) { DoCast(me->getVictim(), SPELL_ARCING_SMASH); ArcingSmash_Timer = 10000; } else ArcingSmash_Timer -= diff; //Whirlwind_Timer if (Whirlwind_Timer <= diff) { DoCast(me->getVictim(), SPELL_WHIRLWIND); Whirlwind_Timer = 55000; } else Whirlwind_Timer -= diff; //MightyBlow_Timer if (MightyBlow_Timer <= diff) { DoCast(me->getVictim(), SPELL_MIGHTY_BLOW); MightyBlow_Timer = 30000+rand()%10000; } else MightyBlow_Timer -= diff; //Entering Phase 2 if (!Phase2 && HealthBelowPct(50)) { Phase2 = true; DoScriptText(SAY_ENRAGE, me); DoCast(me, SPELL_DUAL_WIELD, true); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); } if (Phase2) { //Charging_Timer if (Charging_Timer <= diff) { Unit *pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); if (pTarget) { AttackStart(pTarget); DoCast(pTarget, SPELL_BERSERKER_C); } Charging_Timer = 20000; } else Charging_Timer -= diff; //Intimidating Roar if (Roar_Timer <= diff) { DoCast(me, SPELL_ROAR); Roar_Timer = 40000+(rand()%10000); } else Roar_Timer -= diff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (HealthBelowPct(10) && !Enraged) { Enraged = true; DoCast(me, SPELL_ENRAGE, true); DoScriptText(SAY_ENRAGE, me); } //Randomly cast one beam. if (BeamTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target || !target->isAlive()) return; BeamTimer = 9000; switch (CurrentBeam) { case 0: DoCast(target, SPELL_BEAM_SINISTER); break; case 1: DoCast(target, SPELL_BEAM_VILE); break; case 2: DoCast(target, SPELL_BEAM_WICKED); break; case 3: DoCast(target, SPELL_BEAM_SINFUL); break; } ++BeamCount; uint32 Beam = CurrentBeam; if (BeamCount > 3) while (CurrentBeam == Beam) CurrentBeam = rand()%3; } else BeamTimer -= diff; // Random Prismatic Shield every 15 seconds. if (PrismaticShieldTimer <= diff) { uint32 random = rand()%6; if (PrismaticAuras[random]) DoCast(me, PrismaticAuras[random]); PrismaticShieldTimer = 15000; } else PrismaticShieldTimer -= diff; // Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other. if (FatalAttractionTimer <= diff) { ExplosionCount = 0; TeleportPlayers(); DoScriptText(RAND(SAY_SPELL2, SAY_SPELL3), me); FatalAttractionExplodeTimer = 2000; FatalAttractionTimer = urand(40, 71) * 1000; } else FatalAttractionTimer -= diff; if (FatalAttractionExplodeTimer <= diff) { // Just make them explode three times... they're supposed to keep exploding while they are in range, but it'll take too much code. I'll try to think of an efficient way for it later. if (ExplosionCount < 3) { for (uint8 i = 0; i < 3; ++i) { Unit* unit = NULL; if (TargetGUID[i]) { unit = Unit::GetUnit(*me, TargetGUID[i]); if (unit) unit->CastSpell(unit, SPELL_ATTRACTION, true); TargetGUID[i] = 0; } } ++ExplosionCount; FatalAttractionExplodeTimer = 1000; } else { FatalAttractionExplodeTimer = FatalAttractionTimer + 2000; ExplosionCount = 0; } } else FatalAttractionExplodeTimer -= diff; if (ShriekTimer <= diff) { DoCast(me->getVictim(), SPELL_SILENCING_SHRIEK); ShriekTimer = 25000+rand()%10 * 1000; } else ShriekTimer -= diff; if (SaberTimer <= diff) { DoCast(me->getVictim(), SPELL_SABER_LASH); SaberTimer = 25000+rand()%10 * 1000; } else SaberTimer -= diff; //Enrage if (!me->HasAura(SPELL_BERSERK)) { if (EnrageTimer <= diff) { DoCast(me, SPELL_BERSERK); DoScriptText(SAY_ENRAGE, me); } else EnrageTimer -= diff; } //Random taunts if (RandomYellTimer <= diff) { DoScriptText(RAND(SAY_TAUNT1, SAY_TAUNT2, SAY_TAUNT3), me); RandomYellTimer = urand(60, 151) * 1000; } else RandomYellTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!UpdateVictim()) return; //Common to PHASE_START && PHASE_END if (m_uiPhase == PHASE_START || m_uiPhase == PHASE_END) { //Specific to PHASE_START || PHASE_END if (m_uiPhase == PHASE_START) { if (HealthBelowPct(60)) { SetCombatMovement(false); m_uiPhase = PHASE_BREATH; me->GetMotionMaster()->MovePoint(10, Phase2Location); return; } } else { if (m_uiBellowingRoarTimer <= uiDiff) { DoCastVictim(SPELL_BELLOWING_ROAR); // Eruption GameObject* pFloor = NULL; Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15); Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, pFloor, check); me->VisitNearbyGridObject(30, searcher); if (m_pInstance && pFloor) m_pInstance->SetData64(DATA_FLOOR_ERUPTION_GUID, pFloor->GetGUID()); m_uiBellowingRoarTimer = 30000; } else m_uiBellowingRoarTimer -= uiDiff; } if (m_uiFlameBreathTimer <= uiDiff) { DoCastVictim(SPELL_FLAME_BREATH); m_uiFlameBreathTimer = urand(10000, 20000); } else m_uiFlameBreathTimer -= uiDiff; if (m_uiTailSweepTimer <= uiDiff) { DoCastAOE(SPELL_TAIL_SWEEP); m_uiTailSweepTimer = urand(15000, 20000); } else m_uiTailSweepTimer -= uiDiff; if (m_uiCleaveTimer <= uiDiff) { DoCastVictim(SPELL_CLEAVE); m_uiCleaveTimer = urand(2000, 5000); } else m_uiCleaveTimer -= uiDiff; if (m_uiWingBuffetTimer <= uiDiff) { DoCastVictim(SPELL_WING_BUFFET); m_uiWingBuffetTimer = urand(15000, 30000); } else m_uiWingBuffetTimer -= uiDiff; DoMeleeAttackIfReady(); } else { if (HealthBelowPct(40)) { m_uiPhase = PHASE_END; if (m_pInstance) m_pInstance->SetData(DATA_ONYXIA_PHASE, m_uiPhase); DoScriptText(SAY_PHASE_3_TRANS, me); SetCombatMovement(true); me->SetFlying(false); m_bIsMoving = false; me->GetMotionMaster()->MovePoint(9,me->GetHomePosition()); return; } if (m_uiDeepBreathTimer <= uiDiff) { if (!m_bIsMoving) { if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); DoScriptText(EMOTE_BREATH, me); DoCast(me, m_pPointData->uiSpellId); m_uiDeepBreathTimer = 70000; } } else m_uiDeepBreathTimer -= uiDiff; if (m_uiMovementTimer <= uiDiff) { if (!m_bIsMoving) { SetNextRandomPoint(); m_pPointData = GetMoveData(); if (!m_pPointData) return; me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); m_bIsMoving = true; m_uiMovementTimer = 25000; } } else m_uiMovementTimer -= uiDiff; if (m_uiFireballTimer <= uiDiff) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) { if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(pTarget, SPELL_FIREBALL); m_uiFireballTimer = 8000; } } else m_uiFireballTimer -= uiDiff; if (m_uiLairGuardTimer <= uiDiff) { me->SummonCreature(NPC_LAIRGUARD, aSpawnLocations[2].GetPositionX(), aSpawnLocations[2].GetPositionY(), aSpawnLocations[2].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); m_uiLairGuardTimer = 30000; } else m_uiLairGuardTimer -= uiDiff; if (m_uiWhelpTimer <= uiDiff) { me->SummonCreature(NPC_WHELP, aSpawnLocations[0].GetPositionX(), aSpawnLocations[0].GetPositionY(), aSpawnLocations[0].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); me->SummonCreature(NPC_WHELP, aSpawnLocations[1].GetPositionX(), aSpawnLocations[1].GetPositionY(), aSpawnLocations[1].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); if (m_uiSummonWhelpCount >= RAID_MODE(20,40)) { m_uiSummonWhelpCount = 0; m_uiWhelpTimer = 90000; } else m_uiWhelpTimer = 500; } else m_uiWhelpTimer -= uiDiff; } }
void UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; if(!bIsFrenzy && HealthBelowPct(25) && !bIsExploded) { DoScriptText(SAY_ENRAGE, me); DoCast(me, SPELL_FRENZY, true); bIsFrenzy = true; } if(!bIsFrenzy) { if(uiBubbleCheckerTimer <= diff) { if(!bIsExploded) { if(!me->HasAura(SPELL_PROTECTIVE_BUBBLE, 0)) { DoScriptText(SAY_SHATTER, me); DoCast(me, SPELL_WATER_BLAST); DoCast(me, SPELL_DRAINED); bIsExploded = true; me->AttackStop(); me->SetVisible(false); for(uint8 i = 0; i < 10; i++) { int tmp = urand(0, MAX_SPAWN_LOC-1); me->SummonCreature(NPC_ICHOR_GLOBULE, SpawnLoc[tmp], TEMPSUMMON_CORPSE_DESPAWN); } } } else { bool bIsWaterElementsAlive = false; if(!m_waterElements.empty()) { for(std::list<uint64>::const_iterator itr = m_waterElements.begin(); itr != m_waterElements.end(); ++itr) if(Creature* pTemp = Unit::GetCreature(*me, *itr)) if(pTemp->isAlive()) { bIsWaterElementsAlive = true; break; } } if(!bIsWaterElementsAlive) DoExplodeCompleted(); } uiBubbleCheckerTimer = 1000; } else uiBubbleCheckerTimer -= diff; } if(!bIsExploded) { if(uiWaterBoltVolleyTimer <= diff) { DoCast(me, SPELL_WATER_BOLT_VOLLEY); uiWaterBoltVolleyTimer = urand(10000, 15000); } else uiWaterBoltVolleyTimer -= diff; DoMeleeAttackIfReady(); } }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; if (instance && !instance->GetData(TYPE_MOROES)) { EnterEvadeMode(); return; } if (!Enrage && HealthBelowPct(30)) { DoCast(me, SPELL_FRENZY); Enrage = true; } if (CheckAdds_Timer <= diff) { for (uint8 i = 0; i < 4; ++i) { if (AddGUID[i]) { Creature* temp = Unit::GetCreature((*me), AddGUID[i]); if (temp && temp->IsAlive()) if (!temp->GetVictim()) temp->AI()->AttackStart(me->GetVictim()); } } CheckAdds_Timer = 5000; } else CheckAdds_Timer -= diff; if (!Enrage) { //Cast Vanish, then Garrote random victim if (Vanish_Timer <= diff) { DoCast(me, SPELL_VANISH); InVanish = true; Vanish_Timer = 30000; Wait_Timer = 5000; } else Vanish_Timer -= diff; if (Gouge_Timer <= diff) { DoCastVictim(SPELL_GOUGE); Gouge_Timer = 40000; } else Gouge_Timer -= diff; if (Blind_Timer <= diff) { std::list<Unit*> targets; SelectTargetList(targets, 5, SELECT_TARGET_RANDOM, me->GetMeleeReach()*5, true); for (std::list<Unit*>::const_iterator i = targets.begin(); i != targets.end(); ++i) if (!me->IsWithinMeleeRange(*i)) { DoCast(*i, SPELL_BLIND); break; } Blind_Timer = 40000; } else Blind_Timer -= diff; } if (InVanish) { if (Wait_Timer <= diff) { Talk(SAY_SPECIAL); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) target->CastSpell(target, SPELL_GARROTE, true); InVanish = false; } else Wait_Timer -= diff; } if (!InVanish) DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_MORTALCLEAVE: DoCastVictim(SPELL_MORTALCLEAVE, true); events.ScheduleEvent(EVENT_MORTALCLEAVE, urand(15000, 20000), 0, PHASE_ONE); break; case EVENT_SILENCE: DoCastVictim(SPELL_SILENCE, true); events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000), 0, PHASE_ONE); break; case EVENT_RESURRECT_TIMER: //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds. if (WasDead) { DoCast(me, SPELL_TIGER_FORM); // SPELL_AURA_TRANSFORM me->SetObjectScale(2.00f); me->SetStandState(UNIT_STAND_STATE_STAND); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); /* CreatureTemplate const* cinfo = me->GetCreatureTemplate(); me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40))); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40))); me->UpdateDamagePhysical(BASE_ATTACK); */ me->ApplyStatPctModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, DamageIncrease); // hack ResetThreatList(); events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_FORCEPUNCH, 4000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_SPELL_CHARGE, 12000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_ENRAGE, 32000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_SUMMONTIGERS, 25000, 0, PHASE_TWO); // Phase 2 events.SetPhase(PHASE_TWO); } events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE); break; case EVENT_CHECK_TIMER: //Check_Timer for the death of LorKhan and Zath. if (!WasDead) { if (instance->GetBossState(DATA_LORKHAN) == SPECIAL) { //Resurrect LorKhan if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LORKHAN))) { pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pLorKhan->SetFaction(FACTION_MONSTER); pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pLorKhan->SetFullHealth(); instance->SetData(DATA_LORKHAN, DONE); } } if (instance->GetBossState(DATA_ZATH) == SPECIAL) { //Resurrect Zath if (Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_ZATH))) { pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pZath->SetFaction(FACTION_MONSTER); pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pZath->SetFullHealth(); instance->SetBossState(DATA_ZATH, DONE); } } } events.ScheduleEvent(EVENT_CHECK_TIMER, 5000, 0, PHASE_ONE); break; case EVENT_FRENZY: DoCast(me, SPELL_FRENZY); events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); break; case EVENT_FORCEPUNCH: DoCastVictim(SPELL_FORCEPUNCH, true); events.ScheduleEvent(EVENT_FORCEPUNCH, urand(16000, 21000), 0, PHASE_TWO); break; case EVENT_CHARGE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_CHARGE); ResetThreatList(); AttackStart(target); } events.ScheduleEvent(EVENT_CHARGE, urand(15000, 22000), 0, PHASE_TWO); break; case EVENT_ENRAGE: if (HealthBelowPct(11) && !Enraged) { DoCast(me, SPELL_ENRAGE); Enraged = true; } events.ScheduleEvent(EVENT_ENRAGE, 30000); break; case EVENT_SUMMONTIGERS: DoCastVictim(SPELL_SUMMONTIGERS, true); events.ScheduleEvent(EVENT_SUMMONTIGERS, urand(10000, 14000), 0, PHASE_TWO); break; default: break; } if (me->IsFullHealth() && WasDead) WasDead = false; if ((events.IsInPhase(PHASE_ONE)) && !WasDead && !HealthAbovePct(5)) { me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE); me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetStandState(UNIT_STAND_STATE_SLEEP); me->AttackStop(); instance->SetBossState(DATA_THEKAL, SPECIAL); WasDead = true; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; if(uiChainLightningTimer <= diff) { if(Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_CHAIN_LIGHTING); uiChainLightningTimer = urand(12000, 15000); } else uiChainLightningTimer -= diff; if(uiStaticChargeTimer <= diff) { if(Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_STATIC_CHARGE); uiStaticChargeTimer = 25000; } else uiStaticChargeTimer -= diff; if(uiLightningRingTimer <= diff) { DoCast(me, SPELL_LIGHTING_RING); uiLightningRingTimer = urand(30000, 35000); } else uiLightningRingTimer -= diff; if(uiLightningShieldTimer <= diff) { CheckLightningShield(); uiLightningShieldTimer = urand(45000, 55000); } else uiLightningShieldTimer -= diff; if(uiCheckPhaseTimer <= diff) { if(HealthBelowPct(75) && uiSummonPhase == 1) { uiSummonEntry = CREATURE_FORGED_IRON_TROGG; uiSummonTimer = 1000; uiSummonPhase = 2; } else if(HealthBelowPct(50) && uiSummonPhase == 2) { uiSummonEntry = CREATURE_MALFORMED_OOZE; uiSummonTimer = 1000; uiSummonPhase = 3; } else if(HealthBelowPct(25) && uiSummonPhase == 3) { uiSummonEntry = CREATURE_EARTHEN_DWARF; uiSummonTimer = 1000; uiSummonPhase = 4; } uiCheckPhaseTimer = 1000; } else uiCheckPhaseTimer -= diff; if(uiSummonTimer <= diff) { uint32 rnd = urand(0, 1); if(uiSummonEntry) me->SummonCreature(uiSummonEntry, PipeLocations[rnd].x, PipeLocations[rnd].y, PipeLocations[rnd].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); switch(uiSummonPhase) { case 1: uiSummonTimer = 20000; break; case 2: uiSummonTimer = 7500; break; case 3: uiSummonTimer = 2500; break; case 4: uiSummonTimer = 5000; break; } } else uiSummonTimer -= diff; if(!bIsFrenzy) if(HealthBelowPct(25)) if(!me->IsNonMeleeSpellCasted(false)) { DoCast(me, SPELL_FRENZY); bIsFrenzy = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; // Check_Timer if (CheckTimer < diff) { if (me->IsWithinDist3d(&pos, 35.0f)) EnterEvadeMode(); else DoZoneInCombat(); CheckTimer = 3000; } else CheckTimer -= diff; if (CloseDoorTimer) { if (CloseDoorTimer <= diff) { instance->HandleGameObject(instance->GetData64(DATA_GO_LIBRARY_DOOR), false); CloseDoorTimer = 0; } else CloseDoorTimer -= diff; } //Cooldowns for casts if (ArcaneCooldown) { if (ArcaneCooldown >= diff) ArcaneCooldown -= diff; else ArcaneCooldown = 0; } if (FireCooldown) { if (FireCooldown >= diff) FireCooldown -= diff; else FireCooldown = 0; } if (FrostCooldown) { if (FrostCooldown >= diff) FrostCooldown -= diff; else FrostCooldown = 0; } if (DrinkingDelay) { if (DrinkingDelay <= diff) DrinkingDelay = 0; else DrinkingDelay -= diff; } if (!DrinkingDelay && Drinking == DRINKING_NO_DRINKING && (me->GetMaxPower(POWER_MANA) && (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA)) < 20) && !me->IsNonMeleeSpellCasted(true)) { DoScriptText(SAY_DRINK, me); DoCast(me, SPELL_MASS_POLY, true); Drinking = DRINKING_PREPARING; } if (Drinking == DRINKING_PREPARING && !me->IsNonMeleeSpellCasted(true)) { DoCast(me, SPELL_CONJURE, false); Drinking = DRINKING_PREPARING_2; } if (Drinking == DRINKING_PREPARING_2 && !me->IsNonMeleeSpellCasted(true)) { DoCast(me, SPELL_DRINKING, false); me->SetStandState(UNIT_STAND_STATE_SIT); Drinking = DRINKING_PREPARING_3; } if (Drinking == DRINKING_PREPARING_3 && !me->HasAura(SPELL_DRINKING, 0)) { DoCast(me, SPELL_POTION, false); me->SetStandState(UNIT_STAND_STATE_STAND); PyroblastTimer = 2000; Drinking = DRINKING_DONE_DRINKING; } if (PyroblastTimer) { if (PyroblastTimer <= diff) { DoCast(me, SPELL_AOE_PYROBLAST, false); Drinking = DRINKING_NO_DRINKING; PyroblastTimer = 0; } else PyroblastTimer -= diff; } // Don't execute any more code if we are drinking if (Drinking) return; if (Drinking = DRINKING_NO_DRINKING) { // Normal casts if (NormalCastTimer <= diff) { if (!me->IsNonMeleeSpellCasted(false)) { Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!pTarget) return; uint32 Spells[3]; uint8 AvailableSpells = 0; //Check for what spells are not on cooldown if (!ArcaneCooldown) Spells[AvailableSpells++] = SPELL_ARCMISSLE; if (!FireCooldown) Spells[AvailableSpells++] = SPELL_FIREBALL; if (!FrostCooldown) Spells[AvailableSpells] = SPELL_FROSTBOLT; // If no available spells wait 1 second and try again if (AvailableSpells) DoCast(pTarget, Spells[rand() % AvailableSpells]); } NormalCastTimer = 1000; } else NormalCastTimer -= diff; if (SecondarySpellTimer <= diff) { DoCast(me, SPELL_AOE_CS); SecondarySpellTimer = urand(10000, 40000); } else SecondarySpellTimer -= diff; if (SuperCastTimer <= diff) { uint8 Available[2]; switch (LastSuperSpell) { case SUPER_AE: Available[0] = SUPER_FLAME; Available[1] = SUPER_BLIZZARD; break; case SUPER_FLAME: Available[0] = SUPER_AE; Available[1] = SUPER_BLIZZARD; break; case SUPER_BLIZZARD: Available[0] = SUPER_FLAME; Available[1] = SUPER_AE; break; default: Available[0] = 0; Available[1] = 0; break; } LastSuperSpell = Available[urand(0, 1)]; switch (LastSuperSpell) { case SUPER_AE: DoScriptText(RAND(SAY_EXPLOSION1, SAY_EXPLOSION2), me); DoCast(me, SPELL_TELEPORT_MIDDLE, true); DoCast(me, SPELL_MAGNETIC_PULL, true); DoCast(me, SPELL_MASSSLOW, true); DoCast(me, SPELL_AEXPLOSION, false); DrinkingDelay = 15000; break; case SUPER_FLAME: DoScriptText(RAND(SAY_FLAMEWREATH1, SAY_FLAMEWREATH2), me); DrinkingDelay = 25000; break; case SUPER_BLIZZARD: DoScriptText(RAND(SAY_BLIZZARD1, SAY_BLIZZARD2), me); DrinkingDelay = 30000; break; } SuperCastTimer = urand(35000, 40000); } else SuperCastTimer -= diff; if (!ElementalsSpawned && HealthBelowPct(40)) { ElementalsSpawned = true; DoCast(me, SPELL_TELEPORT_MIDDLE, true); DoCast(me, SPELL_MAGNETIC_PULL, true); DoCast(me, SPELL_ELEMENTAL1, true); DoCast(me, SPELL_ELEMENTAL2, true); DoCast(me, SPELL_ELEMENTAL3, true); DoCast(me, SPELL_ELEMENTAL4, true); DoScriptText(SAY_ELEMENTALS, me); } } if (BerserkTimer <= diff) { for (uint32 i = 0; i < 8; ++i) { if (Creature* unit = me->SummonCreature(CREATURE_SHADOW_OF_ARAN, shadowOfAranSpawnPoints[i][0], shadowOfAranSpawnPoints[i][1], me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) { unit->Attack(me->getVictim(), true); unit->setFaction(me->getFaction()); } } DoScriptText(SAY_TIMEOVER, me); BerserkTimer = 60000; } else BerserkTimer -= diff; if (ArcaneCooldown && FireCooldown && FrostCooldown) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!UpdateVictim()) return; // Splitted if (!me->IsVisible()) { if (uiSplitTimer <= uiDiff) { uiSplitTimer = 2500; // Return sparks to where Ionar splitted if (bIsSplitPhase) { CallBackSparks(); bIsSplitPhase = false; } // Lightning effect and restore Ionar else if (lSparkList.empty()) { me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE); DoCast(me, SPELL_SPARK_DESPAWN, false); uiSplitTimer = 25*IN_MILLISECONDS; bIsSplitPhase = true; if (me->getVictim()) me->GetMotionMaster()->MoveChase(me->getVictim()); } } else uiSplitTimer -= uiDiff; return; } if (uiStaticOverloadTimer <= uiDiff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_STATIC_OVERLOAD); uiStaticOverloadTimer = urand(5*IN_MILLISECONDS, 6*IN_MILLISECONDS); } else uiStaticOverloadTimer -= uiDiff; if (uiBallLightningTimer <= uiDiff) { DoCast(me->getVictim(), SPELL_BALL_LIGHTNING); uiBallLightningTimer = urand(10*IN_MILLISECONDS, 11*IN_MILLISECONDS); } else uiBallLightningTimer -= uiDiff; // Health check if (!bHasDispersed && HealthBelowPct(uiDisperseHealth)) { bHasDispersed = true; DoScriptText(RAND(SAY_SPLIT_1, SAY_SPLIT_2), me); if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_DISPERSE, false); } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FREEZE_SLASH: DoCastVictim(SPELL_FREEZE_SLASH); events.ScheduleEvent(EVENT_FREEZE_SLASH, 15*IN_MILLISECONDS, 0, PHASE_MELEE); return; case EVENT_PENETRATING_COLD: { CastSpellExtraArgs args; args.AddSpellMod(SPELLVALUE_MAX_TARGETS, RAID_MODE(2, 5, 2, 5)); me->CastSpell(nullptr, SPELL_PENETRATING_COLD, args); events.ScheduleEvent(EVENT_PENETRATING_COLD, 20 * IN_MILLISECONDS, 0, PHASE_MELEE); return; } case EVENT_SUMMON_NERUBIAN: if (IsHeroic() || !_reachedPhase3) { CastSpellExtraArgs args; args.AddSpellMod(SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 2, 2, 4)); me->CastSpell(nullptr, SPELL_SUMMON_BURROWER, args); } events.ScheduleEvent(EVENT_SUMMON_NERUBIAN, 45*IN_MILLISECONDS, 0, PHASE_MELEE); return; case EVENT_NERUBIAN_SHADOW_STRIKE: { EntryCheckPredicate pred(NPC_BURROWER); summons.DoAction(ACTION_SHADOW_STRIKE, pred); events.ScheduleEvent(EVENT_NERUBIAN_SHADOW_STRIKE, 30*IN_MILLISECONDS, 0, PHASE_MELEE); break; } case EVENT_SUBMERGE: if (!_reachedPhase3 && !me->HasAura(SPELL_BERSERK)) { DoCast(me, SPELL_SUBMERGE_ANUBARAK); DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); Talk(EMOTE_BURROWER); events.SetPhase(PHASE_SUBMERGED); events.ScheduleEvent(EVENT_PURSUING_SPIKE, 2*IN_MILLISECONDS, 0, PHASE_SUBMERGED); events.ScheduleEvent(EVENT_SUMMON_SCARAB, 4*IN_MILLISECONDS, 0, PHASE_SUBMERGED); events.ScheduleEvent(EVENT_EMERGE, 1*MINUTE*IN_MILLISECONDS, 0, PHASE_SUBMERGED); } break; case EVENT_PURSUING_SPIKE: DoCast(SPELL_SPIKE_CALL); break; case EVENT_SUMMON_SCARAB: { /* WORKAROUND * - The correct implementation is more likely the comment below but it needs spell knowledge */ GuidList::iterator i = _burrowGUID.begin(); uint32 at = urand(0, _burrowGUID.size()-1); for (uint32 k = 0; k < at; k++) ++i; if (Creature* pBurrow = ObjectAccessor::GetCreature(*me, *i)) pBurrow->CastSpell(pBurrow, 66340, false); events.ScheduleEvent(EVENT_SUMMON_SCARAB, 4*IN_MILLISECONDS, 0, PHASE_SUBMERGED); /*It seems that this spell have something more that needs to be taken into account //Need more sniff info DoCast(SPELL_SUMMON_BEATLES); // Just to make sure it won't happen again in this phase m_uiSummonScarabTimer = 90*IN_MILLISECONDS;*/ break; } case EVENT_EMERGE: events.ScheduleEvent(EVENT_SUBMERGE, 80*IN_MILLISECONDS, 0, PHASE_MELEE); DoCast(SPELL_SPIKE_TELE); summons.DespawnEntry(NPC_SPIKE); me->RemoveAurasDueToSpell(SPELL_SUBMERGE_ANUBARAK); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); DoCast(me, SPELL_EMERGE_ANUBARAK); Talk(EMOTE_EMERGE); events.SetPhase(PHASE_MELEE); events.ScheduleEvent(EVENT_FREEZE_SLASH, 15*IN_MILLISECONDS, 0, PHASE_MELEE); events.ScheduleEvent(EVENT_PENETRATING_COLD, 20*IN_MILLISECONDS, PHASE_MELEE); events.ScheduleEvent(EVENT_SUMMON_NERUBIAN, 10*IN_MILLISECONDS, 0, PHASE_MELEE); events.ScheduleEvent(EVENT_SUBMERGE, 80*IN_MILLISECONDS, 0, PHASE_MELEE); if (IsHeroic()) events.ScheduleEvent(EVENT_NERUBIAN_SHADOW_STRIKE, 30*IN_MILLISECONDS, 0, PHASE_MELEE); return; case EVENT_SUMMON_FROST_SPHERE: { uint8 startAt = urand(0, 5); uint8 i = startAt; do { if (Unit* pSphere = ObjectAccessor::GetCreature(*me, _sphereGUID[i])) { if (!pSphere->HasAura(SPELL_FROST_SPHERE)) { if (Creature* summon = me->SummonCreature(NPC_FROST_SPHERE, SphereSpawn[i])) _sphereGUID[i] = summon->GetGUID(); break; } } i = (i + 1) % 6; } while (i != startAt); events.ScheduleEvent(EVENT_SUMMON_FROST_SPHERE, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS)); break; } case EVENT_BERSERK: DoCast(me, SPELL_BERSERK); break; default: break; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; } if (HealthBelowPct(30) && events.IsInPhase(PHASE_MELEE) && !_reachedPhase3) { _reachedPhase3 = true; DoCastAOE(SPELL_LEECHING_SWARM); Talk(EMOTE_LEECHING_SWARM); Talk(SAY_LEECHING_SWARM); } if (events.IsInPhase(PHASE_MELEE)) DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (bIsWaitingToAppear) { me->StopMoving(); me->AttackStop(); if (uiIsWaitingToAppearTimer <= diff) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); bIsWaitingToAppear = false; } else uiIsWaitingToAppearTimer -= diff; return; } if ((Phase == 1) ||(Phase == 3)) { if (bFireMagusDead && bFrostMagusDead && bArcaneMagusDead) { for (uint8 n = 0; n < 3; ++n) time[n] = 0; me->GetMotionMaster()->Clear(); me->SetPosition(CenterOfRoom.GetPositionX(), CenterOfRoom.GetPositionY(), CenterOfRoom.GetPositionZ(), CenterOfRoom.GetOrientation()); DoCast(me, SPELL_TELESTRA_BACK); me->SetVisible(true); if (Phase == 1) Phase = 2; if (Phase == 3) Phase = 4; uiFireMagusGUID = 0; uiFrostMagusGUID = 0; uiArcaneMagusGUID = 0; bIsWaitingToAppear = true; uiIsWaitingToAppearTimer = 4*IN_MILLISECONDS; Talk(SAY_MERGE); } else return; } if ((Phase == 0) && HealthBelowPct(50)) { Phase = 1; me->CastStop(); me->RemoveAllAuras(); me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); uiFireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS); uiFrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS); uiArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS); bFireMagusDead = false; bFrostMagusDead = false; bArcaneMagusDead = false; Talk(SAY_SPLIT); return; } if (IsHeroic() && (Phase == 2) && HealthBelowPct(10)) { Phase = 3; me->CastStop(); me->RemoveAllAuras(); me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); uiFireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS); uiFrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS); uiArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS); bFireMagusDead = false; bFrostMagusDead = false; bArcaneMagusDead = false; Talk(SAY_SPLIT); return; } if (uiCooldown) { if (uiCooldown <= diff) uiCooldown = 0; else { uiCooldown -= diff; return; } } if (uiIceNovaTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_ICE_NOVA, false); uiCooldown = 1500; } uiIceNovaTimer = 15*IN_MILLISECONDS; } else uiIceNovaTimer -= diff; if (uiGravityWellTimer <= diff) { if (Unit* target = me->getVictim()) { DoCast(target, SPELL_GRAVITY_WELL); uiCooldown = 6*IN_MILLISECONDS; } uiGravityWellTimer = 15*IN_MILLISECONDS; } else uiGravityWellTimer -= diff; if (uiFireBombTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_FIREBOMB, false); uiCooldown = 2*IN_MILLISECONDS; } uiFireBombTimer = 2*IN_MILLISECONDS; } else uiFireBombTimer -=diff; DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { if (events.IsInPhase(IDLE)) return; if (events.IsInPhase(NORMAL) && !UpdateVictim()) return; events.Update(diff); if (!_sacrificed && HealthBelowPct(50)) { _sacrificed = true; events.SetPhase(SACRIFICING); events.ScheduleEvent(EVENT_RITUAL_PREPARATION, 0, 0, SACRIFICING); } if (events.IsInPhase(NORMAL)) DoMeleeAttackIfReady(); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_INTRO_SVALA_TALK_0: Talk(SAY_SVALA_INTRO_0); events.ScheduleEvent(EVENT_INTRO_ARTHAS_TALK_0, 8.1 * IN_MILLISECONDS, 0, INTRO); break; case EVENT_INTRO_ARTHAS_TALK_0: if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_1); events.ScheduleEvent(EVENT_INTRO_TRANSFORM_0, 10 * IN_MILLISECONDS, 0, INTRO); break; case EVENT_INTRO_TRANSFORM_0: { if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, true); Position pos; pos.Relocate(me); pos.m_positionZ += 8.0f; me->GetMotionMaster()->MoveTakeoff(0, pos); // spectators flee event std::list<Creature*> lspectatorList; GetCreatureListWithEntryInGrid(lspectatorList, me, NPC_SPECTATOR, 100.0f); for (std::list<Creature*>::iterator itr = lspectatorList.begin(); itr != lspectatorList.end(); ++itr) { if ((*itr)->IsAlive()) { (*itr)->SetStandState(UNIT_STAND_STATE_STAND); (*itr)->SetWalk(false); (*itr)->GetMotionMaster()->MovePoint(1, spectatorWP[0]); } } events.ScheduleEvent(EVENT_INTRO_TRANSFORM_1, 4.2 * IN_MILLISECONDS, 0, INTRO); break; } case EVENT_INTRO_TRANSFORM_1: me->CastSpell(me, SPELL_SVALA_TRANSFORMING1, false); events.ScheduleEvent(EVENT_INTRO_TRANSFORM_2, 6.2 * IN_MILLISECONDS, 0, INTRO); break; case EVENT_INTRO_TRANSFORM_2: me->CastSpell(me, SPELL_SVALA_TRANSFORMING2, false); if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) { arthas->InterruptNonMeleeSpells(true); me->SetFacingToObject(arthas); } me->RemoveAllAuras(); me->UpdateEntry(NPC_SVALA_SORROWGRAVE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); events.ScheduleEvent(EVENT_INTRO_SVALA_TALK_1, 10 * IN_MILLISECONDS, 0, INTRO); break; case EVENT_INTRO_SVALA_TALK_1: Talk(SAY_SVALA_INTRO_1); events.ScheduleEvent(EVENT_INTRO_ARTHAS_TALK_1, 3.2 * IN_MILLISECONDS, 0, INTRO); break; case EVENT_INTRO_ARTHAS_TALK_1: if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_2); events.ScheduleEvent(EVENT_INTRO_SVALA_TALK_2, 7.2 * IN_MILLISECONDS, 0, INTRO); break; case EVENT_INTRO_SVALA_TALK_2: Talk(SAY_SVALA_INTRO_2); me->SetFacingTo(1.58f); if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) arthas->SetVisible(false); events.ScheduleEvent(EVENT_INTRO_RELOCATE_SVALA, 13.8 * IN_MILLISECONDS, 0, INTRO); break; case EVENT_INTRO_RELOCATE_SVALA: { Position pos; pos.Relocate(me); pos.m_positionX = me->GetHomePosition().GetPositionX(); pos.m_positionY = me->GetHomePosition().GetPositionY(); pos.m_positionZ = 90.6065f; me->GetMotionMaster()->MoveLand(0, pos); me->SetDisableGravity(false, true); me->SetHover(true); events.ScheduleEvent(EVENT_INTRO_DESPAWN_ARTHAS, 3 * IN_MILLISECONDS, 0, INTRO); break; } case EVENT_INTRO_DESPAWN_ARTHAS: if (GameObject* mirror = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_UTGARDE_MIRROR))) mirror->SetGoState(GO_STATE_ACTIVE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) arthas->DespawnOrUnsummon(); _arthasGUID.Clear(); events.SetPhase(NORMAL); _introCompleted = true; events.ScheduleEvent(EVENT_SINISTER_STRIKE, 7 * IN_MILLISECONDS, 0, NORMAL); events.ScheduleEvent(EVENT_CALL_FLAMES, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, NORMAL); break; case EVENT_SINISTER_STRIKE: DoCastVictim(SPELL_SINSTER_STRIKE); events.ScheduleEvent(EVENT_SINISTER_STRIKE, urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS), 0, NORMAL); break; case EVENT_CALL_FLAMES: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) DoCast(target, SPELL_CALL_FLAMES); events.ScheduleEvent(EVENT_CALL_FLAMES, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, NORMAL); break; case EVENT_RITUAL_PREPARATION: if (Unit* sacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 80.0f, true)) { instance->SetGuidData(DATA_SACRIFICED_PLAYER, sacrificeTarget->GetGUID()); Talk(SAY_SACRIFICE_PLAYER); DoCast(sacrificeTarget, SPELL_RITUAL_PREPARATION); SetCombatMovement(false); DoCast(me, SPELL_RITUAL_OF_THE_SWORD); } events.ScheduleEvent(EVENT_SPAWN_RITUAL_CHANNELERS, 1 * IN_MILLISECONDS, 0, SACRIFICING); break; case EVENT_SPAWN_RITUAL_CHANNELERS: DoCast(me, SPELL_RITUAL_CHANNELER_1, true); DoCast(me, SPELL_RITUAL_CHANNELER_2, true); DoCast(me, SPELL_RITUAL_CHANNELER_3, true); events.ScheduleEvent(EVENT_RITUAL_STRIKE, 2 * IN_MILLISECONDS, 0, SACRIFICING); break; case EVENT_RITUAL_STRIKE: me->StopMoving(); me->GetMotionMaster()->MoveIdle(); me->InterruptNonMeleeSpells(true); DoCast(me, SPELL_RITUAL_STRIKE_TRIGGER, true); events.ScheduleEvent(EVENT_RITUAL_DISARM, 200, 0, SACRIFICING); break; case EVENT_RITUAL_DISARM: DoCast(me, SPELL_RITUAL_DISARM); break; default: break; } } }
void UpdateAI(uint32 diff) override { if (!CanAttack && Intro) { if (AggroTimer <= diff) { CanAttack = true; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); AggroTimer=19000; } else { AggroTimer -= diff; return; } } // to prevent abuses during phase 2 if (Phase == 2 && !me->GetVictim() && me->IsInCombat()) { EnterEvadeMode(); return; } // Return since we have no target if (!UpdateVictim()) return; if (Phase == 1 || Phase == 3) { // ShockBlastTimer if (ShockBlastTimer <= diff) { // Shock Burst // Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. DoCastVictim(SPELL_SHOCK_BLAST); ShockBlastTimer = 1000 + rand32() % 14000; // random cooldown } else ShockBlastTimer -= diff; // StaticChargeTimer if (StaticChargeTimer <= diff) { // Static Charge // Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true); if (target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER)) DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); // cast Static Charge every 2 seconds for 20 seconds StaticChargeTimer = 10000 + rand32() % 20000; } else StaticChargeTimer -= diff; // EntangleTimer if (EntangleTimer <= diff) { if (!Entangle) { // Entangle // Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. DoCastVictim(SPELL_ENTANGLE); Entangle = true; EntangleTimer = 10000; } else { CastShootOrMultishot(); Entangle = false; EntangleTimer = 20000 + rand32() % 5000; } } else EntangleTimer -= diff; // Phase 1 if (Phase == 1) { // Start phase 2 if (HealthBelowPct(70)) { // Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. Phase = 2; me->GetMotionMaster()->Clear(); DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z); for (uint8 i = 0; i < 4; ++i) if (Creature* creature = me->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0)) ShieldGeneratorChannel[i] = creature->GetGUID(); Talk(SAY_PHASE2); } } // Phase 3 else { // SummonSporebatTimer if (SummonSporebatTimer <= diff) { if (Creature* sporebat = me->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0)) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) sporebat->AI()->AttackStart(target); // summon sporebats faster and faster if (SummonSporebatStaticTimer > 1000) SummonSporebatStaticTimer -= 1000; SummonSporebatTimer = SummonSporebatStaticTimer; if (SummonSporebatTimer < 5000) SummonSporebatTimer = 5000; } else SummonSporebatTimer -= diff; } // Melee attack DoMeleeAttackIfReady(); // CheckTimer - used to check if somebody is in melee range if (CheckTimer <= diff) { bool inMeleeRange = false; for (auto* ref : me->GetThreatManager().GetUnsortedThreatList()) { Unit* target = ref->GetVictim(); if (target->IsWithinMeleeRange(me)) // if in melee range { inMeleeRange = true; break; } } // if nobody is in melee range if (!inMeleeRange) CastShootOrMultishot(); CheckTimer = 5000; } else CheckTimer -= diff; } // Phase 2 else { // ForkedLightningTimer if (ForkedLightningTimer <= diff) { // Forked Lightning // Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target) target = me->GetVictim(); DoCast(target, SPELL_FORKED_LIGHTNING); ForkedLightningTimer = 2000 + rand32() % 6000; } else ForkedLightningTimer -= diff; // EnchantedElementalTimer if (EnchantedElementalTimer <= diff) { me->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElementalPos][0], ElementPos[EnchantedElementalPos][1], ElementPos[EnchantedElementalPos][2], ElementPos[EnchantedElementalPos][3], TEMPSUMMON_CORPSE_DESPAWN, 0); if (EnchantedElementalPos == 7) EnchantedElementalPos = 0; else ++EnchantedElementalPos; EnchantedElementalTimer = 10000 + rand32() % 5000; } else EnchantedElementalTimer -= diff; // TaintedElementalTimer if (TaintedElementalTimer <= diff) { uint32 pos = rand32() % 8; me->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0); TaintedElementalTimer = 120000; } else TaintedElementalTimer -= diff; // CoilfangEliteTimer if (CoilfangEliteTimer <= diff) { uint32 pos = rand32() % 3; Creature* coilfangElite = me->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if (coilfangElite) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) coilfangElite->AI()->AttackStart(target); else if (me->GetVictim()) coilfangElite->AI()->AttackStart(me->GetVictim()); } CoilfangEliteTimer = 45000 + rand32() % 5000; } else CoilfangEliteTimer -= diff; // CoilfangStriderTimer if (CoilfangStriderTimer <= diff) { uint32 pos = rand32() % 3; if (Creature* CoilfangStrider = me->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) CoilfangStrider->AI()->AttackStart(target); else if (me->GetVictim()) CoilfangStrider->AI()->AttackStart(me->GetVictim()); } CoilfangStriderTimer = 60000 + rand32() % 10000; } else CoilfangStriderTimer -= diff; // CheckTimer if (CheckTimer <= diff) { // Start Phase 3 if (instance->GetData(DATA_CANSTARTPHASE3)) { // set life 50% me->SetHealth(me->CountPctFromMaxHealth(50)); me->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); Talk(SAY_PHASE3); Phase = 3; // return to the tank me->GetMotionMaster()->MoveChase(me->GetVictim()); } CheckTimer = 1000; } else CheckTimer -= diff; } }
void UpdateAI(uint32 diff) { if (canDespawn && DespawnTimer <= diff) { if (instance) instance->SetBossState(BOSS_NEFARIAN, FAIL); std::list<Creature*> constructList; me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f); for (std::list<Creature*>::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr) (*itr)->DespawnOrUnsummon(); } else DespawnTimer -= diff; if (!UpdateVictim()) return; if (canDespawn) canDespawn = false; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_SHADOWFLAME: DoCastVictim(SPELL_SHADOWFLAME); events.ScheduleEvent(EVENT_SHADOWFLAME, 12000); break; case EVENT_FEAR: DoCastVictim(SPELL_BELLOWINGROAR); events.ScheduleEvent(EVENT_FEAR, urand(25000, 35000)); break; case EVENT_VEILOFSHADOW: DoCastVictim(SPELL_VEILOFSHADOW); events.ScheduleEvent(EVENT_VEILOFSHADOW, urand(25000, 35000)); break; case EVENT_CLEAVE: DoCastVictim(SPELL_CLEAVE); events.ScheduleEvent(EVENT_CLEAVE, 7000); break; case EVENT_TAILLASH: // Cast NYI since we need a better check for behind target DoCastVictim(SPELL_TAILLASH); events.ScheduleEvent(EVENT_TAILLASH, 10000); break; case EVENT_CLASSCALL: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) switch (target->getClass()) { case CLASS_MAGE: Talk(SAY_MAGE); DoCast(me, SPELL_MAGE); break; case CLASS_WARRIOR: Talk(SAY_WARRIOR); DoCast(me, SPELL_WARRIOR); break; case CLASS_DRUID: Talk(SAY_DRUID); DoCast(target, SPELL_DRUID); break; case CLASS_PRIEST: Talk(SAY_PRIEST); DoCast(me, SPELL_PRIEST); break; case CLASS_PALADIN: Talk(SAY_PALADIN); DoCast(me, SPELL_PALADIN); break; case CLASS_SHAMAN: Talk(SAY_SHAMAN); DoCast(me, SPELL_SHAMAN); break; case CLASS_WARLOCK: Talk(SAY_WARLOCK); DoCast(me, SPELL_WARLOCK); break; case CLASS_HUNTER: Talk(SAY_HUNTER); DoCast(me, SPELL_HUNTER); break; case CLASS_ROGUE: Talk(SAY_ROGUE); DoCast(me, SPELL_ROGUE); break; case CLASS_DEATH_KNIGHT: Talk(SAY_DEATH_KNIGHT); DoCast(me, SPELL_DEATH_KNIGHT); break; default: break; } events.ScheduleEvent(EVENT_CLASSCALL, urand(30000, 35000)); break; } } // Phase3 begins when health below 20 pct if (!Phase3 && HealthBelowPct(20)) { std::list<Creature*> constructList; me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f); for (std::list<Creature*>::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr) if ((*itr) && !(*itr)->IsAlive()) { (*itr)->Respawn(); (*itr)->SetInCombatWithZone(); (*itr)->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); (*itr)->SetReactState(REACT_AGGRESSIVE); (*itr)->SetStandState(UNIT_STAND_STATE_STAND); } Phase3 = true; Talk(SAY_RAISE_SKELETONS); } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; switch (Phase) { case 0: { // *Heroic mode only: if (IsHeroic()) { if (PyroblastTimer <= diff) { me->InterruptSpell(CURRENT_CHANNELED_SPELL); me->InterruptSpell(CURRENT_GENERIC_SPELL); DoCast(me, SPELL_SHOCK_BARRIER, true); DoCast(me->getVictim(), SPELL_PYROBLAST); PyroblastTimer = 60000; } else PyroblastTimer -= diff; } if (FireballTimer <= diff) { DoCast(me->getVictim(), SPELL_FIREBALL_NORMAL); FireballTimer = urand(2000, 6000); } else FireballTimer -= diff; if (PhoenixTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); uint8 random = urand(1, 2); float x = KaelLocations[random][0]; float y = KaelLocations[random][1]; Creature* Phoenix = me->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); if (Phoenix) { Phoenix->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE); SetThreatList(Phoenix); Phoenix->AI()->AttackStart(target); } DoScriptText(SAY_PHOENIX, me); PhoenixTimer = 60000; } else PhoenixTimer -= diff; if (FlameStrikeTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { me->InterruptSpell(CURRENT_CHANNELED_SPELL); me->InterruptSpell(CURRENT_GENERIC_SPELL); DoCast(target, SPELL_FLAMESTRIKE3, true); DoScriptText(SAY_FLAMESTRIKE, me); } FlameStrikeTimer = urand(15000, 25000); } else FlameStrikeTimer -= diff; // Below 50% if (HealthBelowPct(50)) { me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true); me->StopMoving(); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); GravityLapseTimer = 0; GravityLapsePhase = 0; Phase = 1; } DoMeleeAttackIfReady(); } break; case 1: { if (GravityLapseTimer <= diff) { switch (GravityLapsePhase) { case 0: if (FirstGravityLapse) // Different yells at 50%, and at every following Gravity Lapse { DoScriptText(SAY_GRAVITY_LAPSE, me); FirstGravityLapse = false; if (instance) { instance->HandleGameObject(instance->GetData64(DATA_KAEL_STATUE_LEFT), true); instance->HandleGameObject(instance->GetData64(DATA_KAEL_STATUE_RIGHT), true); } } else { DoScriptText(SAY_RECAST_GRAVITY, me); } DoCast(me, SPELL_GRAVITY_LAPSE_INITIAL); GravityLapseTimer = 2000 + diff;// Don't interrupt the visual spell GravityLapsePhase = 1; break; case 1: TeleportPlayersToSelf(); GravityLapseTimer = 1000; GravityLapsePhase = 2; break; case 2: CastGravityLapseKnockUp(); GravityLapseTimer = 1000; GravityLapsePhase = 3; break; case 3: CastGravityLapseFly(); GravityLapseTimer = 30000; GravityLapsePhase = 4; for (uint8 i = 0; i < 3; ++i) { Unit* target = NULL; target = SelectTarget(SELECT_TARGET_RANDOM, 0); Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); if (Orb && target) { Orb->SetSpeed(MOVE_RUN, 0.5f); Orb->AddThreat(target, 1000000.0f); Orb->AI()->AttackStart(target); } } DoCast(me, SPELL_GRAVITY_LAPSE_CHANNEL); break; case 4: me->InterruptNonMeleeSpells(false); DoScriptText(SAY_TIRED, me); DoCast(me, SPELL_POWER_FEEDBACK); RemoveGravityLapse(); GravityLapseTimer = 10000; GravityLapsePhase = 0; break; } } else GravityLapseTimer -= diff; } break; } }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (TeleportTimer <= diff) { DoScriptText(SAY_TELEPORT, me); std::list<HostileReference*>& threatlist = me->getThreatManager().getThreatList(); std::list<HostileReference*>::const_iterator i = threatlist.begin(); for (i = threatlist.begin(); i!= threatlist.end(); ++i) { Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+3, unit->GetOrientation()); } } DoResetThreat(); TeleportTimer = 30000; } else TeleportTimer -= diff; // //MarkOfFrostTimer // if (MarkOfFrostTimer <= diff) // { // DoCast(me->getVictim(), SPELL_MARKOFFROST); // MarkOfFrostTimer = 25000; // } else MarkOfFrostTimer -= diff; //ChillTimer if (ChillTimer <= diff) { DoCast(me->getVictim(), SPELL_CHILL); ChillTimer = urand(13000, 25000); } else ChillTimer -= diff; //BreathTimer if (BreathTimer <= diff) { DoCast(me->getVictim(), SPELL_FROSTBREATH); BreathTimer = urand(10000, 15000); } else BreathTimer -= diff; //ManaStormTimer if (ManaStormTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_MANASTORM); ManaStormTimer = urand(7500, 12500); } else ManaStormTimer -= diff; //ReflectTimer if (ReflectTimer <= diff) { DoCast(me, SPELL_REFLECT); ReflectTimer = urand(20000, 35000); } else ReflectTimer -= diff; //CleaveTimer if (CleaveTimer <= diff) { DoCast(me->getVictim(), SPELL_CLEAVE); CleaveTimer = 7000; } else CleaveTimer -= diff; //EnrageTimer if (HealthBelowPct(26) && !Enraged) { DoCast(me, SPELL_ENRAGE); Enraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; //Frenzy_Timer if (!Frenzy && Frenzy_Timer <= diff) { DoCast(me, SPELL_FRENZY); DoScriptText(EMOTE_GENERIC_FRENZY_KILL, me); Frenzy = true; PoisonBolt_Timer = 3000; Frenzy_Timer = urand(25000, 35000); } else Frenzy_Timer -= diff; // Wyvern Timer if (Wyvern_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_WYVERNSTING); Wyvern_Timer = urand(15000, 32000); } else Wyvern_Timer -= diff; //Spit Timer if (Spit_Timer <= diff) { DoCast(me->getVictim(), SPELL_ACIDSPIT); Spit_Timer = urand(5000, 10000); } else Spit_Timer -= diff; //NoxiousPoison_Timer if (NoxiousPoison_Timer <= diff) { DoCast(me->getVictim(), SPELL_NOXIOUSPOISON); NoxiousPoison_Timer = urand(12000, 24000); } else NoxiousPoison_Timer -= diff; //PoisonBolt only if frenzy or berserk if (Frenzy || Berserk) { if (PoisonBolt_Timer <= diff) { DoCast(me->getVictim(), SPELL_POISONBOLT); PoisonBolt_Timer = 3000; } else PoisonBolt_Timer -= diff; } //FrenzyBack_Timer if (Frenzy && FrenzyBack_Timer <= diff) { me->InterruptNonMeleeSpells(false); Frenzy = false; FrenzyBack_Timer = 15000; } else FrenzyBack_Timer -= diff; if (!Berserk && HealthBelowPct(31)) { me->InterruptNonMeleeSpells(false); DoScriptText(EMOTE_GENERIC_BERSERK, me); DoCast(me, SPELL_BERSERK); Berserk = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; if(bIsWaitingToAppear) { me->StopMoving(); me->AttackStop(); if(uiIsWaitingToAppearTimer <= diff) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); bIsWaitingToAppear = false; } else uiIsWaitingToAppearTimer -= diff; return; } if((Phase == 1) ||(Phase == 3)) { if(bIsAchievementTimerRunning) uiAchievementTimer += diff; if(bFireMagusDead && bFrostMagusDead && bArcaneMagusDead) { if(uiAchievementTimer <= ACHIEV_TIMER) uiAchievementProgress +=1; me->GetMotionMaster()->Clear(); me->GetMap()->CreatureRelocation(me, CenterOfRoom.GetPositionX(), CenterOfRoom.GetPositionY(), CenterOfRoom.GetPositionZ(), CenterOfRoom.GetOrientation()); DoCast(me, SPELL_TELESTRA_BACK); me->SetVisible(true); Phase++; uiFireMagusGUID = 0; uiFrostMagusGUID = 0; uiArcaneMagusGUID = 0; bIsWaitingToAppear = true; uiIsWaitingToAppearTimer = 4*IN_MILLISECONDS; DoScriptText(SAY_MERGE, me); bIsAchievementTimerRunning = false; uiAchievementTimer = 0; } else return; } if((Phase == 0) && HealthBelowPct(50)) { Phase = 1; me->CastStop(); me->RemoveAllAuras(); me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); uiFireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS); uiFrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS); uiArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS); bFireMagusDead = false; bFrostMagusDead = false; bArcaneMagusDead = false; DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), me); return; } if(IsHeroic() && (Phase == 2) && HealthBelowPct(15)) { Phase = 3; me->CastStop(); me->RemoveAllAuras(); me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); uiFireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS); uiFrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS); uiArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS); bFireMagusDead = false; bFrostMagusDead = false; bArcaneMagusDead = false; DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), me); return; } if(uiCooldown) { if(uiCooldown <= diff) uiCooldown = 0; else { uiCooldown -= diff; return; } } if(uiIceNovaTimer <= diff) { if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_ICE_NOVA, false); uiCooldown = 1500; } uiIceNovaTimer = 15*IN_MILLISECONDS; } else uiIceNovaTimer -= diff; if(uiGravityWellTimer <= diff) { if(Unit* target = me->getVictim()) { DoCast(target, SPELL_GRAVITY_WELL); uiCooldown = 6*IN_MILLISECONDS; } uiGravityWellTimer = 15*IN_MILLISECONDS; } else uiGravityWellTimer -= diff; if(uiFireBombTimer <= diff) { if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_FIREBOMB, false); uiCooldown = 2*IN_MILLISECONDS; } uiFireBombTimer = 2*IN_MILLISECONDS; } else uiFireBombTimer -=diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (instance && instance->GetBossState(BOSS_MAJORDOMO_EXECUTUS) != DONE) { if (!UpdateVictim()) return; events.Update(diff); if (!me->FindNearestCreature(NPC_FLAMEWAKER_HEALER, 100.0f) && !me->FindNearestCreature(NPC_FLAMEWAKER_ELITE, 100.0f)) { instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, me->GetEntry(), me); me->setFaction(35); me->AI()->EnterEvadeMode(); Talk(SAY_DEFEAT); _JustDied(); events.ScheduleEvent(EVENT_OUTRO_1, 32000); return; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; if (HealthBelowPct(50)) DoCast(me, SPELL_AEGIS_OF_RAGNAROS, true); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_MAGIC_REFLECTION: DoCast(me, SPELL_MAGIC_REFLECTION); events.ScheduleEvent(EVENT_MAGIC_REFLECTION, 30000); break; case EVENT_DAMAGE_REFLECTION: DoCast(me, SPELL_DAMAGE_REFLECTION); events.ScheduleEvent(EVENT_DAMAGE_REFLECTION, 30000); break; case EVENT_BLAST_WAVE: DoCastVictim(SPELL_BLAST_WAVE); events.ScheduleEvent(EVENT_BLAST_WAVE, 10000); break; case EVENT_TELEPORT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) DoCast(target, SPELL_TELEPORT); events.ScheduleEvent(EVENT_TELEPORT, 20000); break; default: break; } } DoMeleeAttackIfReady(); } else { events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_OUTRO_1: me->NearTeleportTo(RagnarosTelePos.GetPositionX(), RagnarosTelePos.GetPositionY(), RagnarosTelePos.GetPositionZ(), RagnarosTelePos.GetOrientation()); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); break; case EVENT_OUTRO_2: if (instance) instance->instance->SummonCreature(NPC_RAGNAROS, RagnarosSummonPos); break; case EVENT_OUTRO_3: Talk(SAY_ARRIVAL2_MAJ); break; default: break; } } } }
void UpdateAI(uint32 const Diff) { if (!UpdateVictim()) return; events.Update(Diff); if (HealthBelowPct(50) && !PermaGround) EnterPermaGround(); if (EnrageTimer <= Diff && !Enraged) { DoCast(me, SPELL_BERSERK); Enraged = true; } else EnrageTimer -= Diff; if (HarpoonCounter == RAID_MODE(2, 4)) { HarpoonCounter = 0; me->GetMotionMaster()->MovePoint(1, RazorGround); } 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_NOT_SELECTABLE); me->SetReactState(REACT_PASSIVE); me->AttackStop(); 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); ++FlyCount; return; case EVENT_LAND: me->SetFlying(false); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); if (Creature* commander = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_EXPEDITION_COMMANDER) : 0)) commander->AI()->DoAction(ACTION_GROUND_PHASE); 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_BREATH: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); me->RemoveAllAuras(); me->SetReactState(REACT_AGGRESSIVE); DoScriptText(EMOTE_BREATH, me, 0); DoCastAOE(SPELL_FLAMEBREATH); events.CancelEvent(EVENT_BREATH); return; case EVENT_BUFFET: DoCastAOE(SPELL_WINGBUFFET); if (Creature* controller = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_RAZORSCALE_CONTROL) : 0)) controller->CastSpell(controller, 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* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) DoCast(target, SPELL_FIREBALL); events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_PERMAGROUND); return; case EVENT_DEVOURING: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) DoCast(target, 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: DoCast(me->getVictim(), SPELL_FUSEARMOR); events.ScheduleEvent(EVENT_FUSE, 10000, 0, PHASE_PERMAGROUND); return; } } DoMeleeAttackIfReady(); } else { if (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FIREBALL: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) DoCast(target, SPELL_FIREBALL); events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_FLIGHT); return; case EVENT_DEVOURING: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) me->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), SPELL_DEVOURING_FLAME, true); events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT); return; case EVENT_SUMMON: SummonMoleMachines(); events.ScheduleEvent(EVENT_SUMMON, 45000, 0, PHASE_FLIGHT); return; } } } }
void boss_attumen::boss_attumenAI::UpdateAI(const uint32 diff) { if (ResetTimer) { if (ResetTimer <= diff) { ResetTimer = 0; Unit* midnight = Unit::GetUnit(*me, Midnight); if (midnight) { midnight->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); midnight->SetVisible(true); } Midnight = 0; me->SetVisible(false); me->Kill(me); } } else ResetTimer -= diff; //Return since we have no target if (!UpdateVictim()) return; if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) return; if (CleaveTimer <= diff) { DoCast(me->getVictim(), SPELL_SHADOWCLEAVE); CleaveTimer = urand(10000, 15000); } else CleaveTimer -= diff; if (CurseTimer <= diff) { DoCast(me->getVictim(), SPELL_INTANGIBLE_PRESENCE); CurseTimer = 30000; } else CurseTimer -= diff; if (RandomYellTimer <= diff) { DoScriptText(RAND(SAY_RANDOM1, SAY_RANDOM2), me); RandomYellTimer = urand(30000, 60000); } else RandomYellTimer -= diff; if (me->GetUInt32Value(UNIT_FIELD_DISPLAYID) == MOUNTED_DISPLAYID) { if (ChargeTimer <= diff) { Unit* target = NULL; std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); std::vector<Unit*> target_list; for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (target && !target->IsWithinDist(me, ATTACK_DISTANCE, false)) target_list.push_back(target); target = NULL; } if (!target_list.empty()) target = *(target_list.begin()+rand()%target_list.size()); DoCast(target, SPELL_BERSERKER_CHARGE); ChargeTimer = 20000; } else ChargeTimer -= diff; } else { if (HealthBelowPct(25)) { Creature* midnight = Unit::GetCreature(*me, Midnight); if (midnight && midnight->GetTypeId() == TYPEID_UNIT) { CAST_AI(boss_midnight::boss_midnightAI, (midnight->AI()))->Mount(me); me->SetHealth(midnight->GetHealth()); DoResetThreat(); } } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!Init) { if (EventProgress_Timer <= diff) { if (Phase < 8) { switch(Phase) { case 1: DoScriptText(SAY_INTRO_1, me); EventProgress_Timer = 18000; break; case 2: DoScriptText(SAY_INTRO_2, me); EventProgress_Timer = 18000; break; case 3: DoScriptText(SAY_WATER, me); DoCast(me, SPELL_CONJURE_WATER); EventProgress_Timer = 7000; break; case 4: DoScriptText(SAY_BUFFS, me); DoCast(me, SPELL_ICE_ARMOR); EventProgress_Timer = 7000; break; case 5: DoScriptText(SAY_DRINK, me); DoCast(me, SPELL_ARCANE_INTELLECT); EventProgress_Timer = 7000; break; case 6: DoScriptText(SAY_READY, me); EventProgress_Timer = 6000; break; case 7: if (pInstance) pInstance->SetData(TYPE_WARDEN_2, DONE); Init = true; break; } ++Phase; } } else EventProgress_Timer -= diff; } if (!UpdateVictim()) return; if (!LowHp && HealthBelowPct(20)) { DoScriptText(SAY_LOWHP, me); LowHp = true; } if (Pyroblast_Timer <= diff) { if (me->IsNonMeleeSpellCasted(false)) return; DoScriptText(SAY_PYRO, me); DoCast(me->getVictim(), SPELL_PYROBLAST); Pyroblast_Timer = 40000; } else Pyroblast_Timer -=diff; if (Fireball_Timer <= diff) { DoCast(me->getVictim(), SPELL_FIREBALL); Fireball_Timer = 4000; } else Fireball_Timer -=diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; //Earthquake_Timer if (Earthquake_Timer <= diff) { if (!Earthquake) { DoCast(me->getVictim(), SPELL_EARTHQUAKE); Earthquake = true; Earthquake_Timer = 10000; } else { DoScriptText(RAND(SAY_SUMMON1, SAY_SUMMON2), me); for (uint8 i = 0; i < 10; ++i) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); Creature* Murloc = me->SummonCreature(NPC_TIDEWALKER_LURKER, MurlocCords[i][0], MurlocCords[i][1], MurlocCords[i][2], MurlocCords[i][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); if (target && Murloc) Murloc->AI()->AttackStart(target); } DoScriptText(EMOTE_EARTHQUAKE, me); Earthquake = false; Earthquake_Timer = 40000+rand()%5000; } } else Earthquake_Timer -= diff; //TidalWave_Timer if (TidalWave_Timer <= diff) { DoCast(me->getVictim(), SPELL_TIDAL_WAVE); TidalWave_Timer = 20000; } else TidalWave_Timer -= diff; if (!Phase2) { //WateryGrave_Timer if (WateryGrave_Timer <= diff) { //Teleport 4 players under the waterfalls Unit* target; std::set<uint64> list; std::set<uint64>::const_iterator itr; for (uint8 i = 0; i < 4; ++i) { counter = 0; do { target = SelectTarget(SELECT_TARGET_RANDOM, 1, 50, true); //target players only if (counter < Playercount) break; if (target) itr = list.find(target->GetGUID()); ++counter; } while (itr != list.end()); if (target) { list.insert(target->GetGUID()); ApplyWateryGrave(target, i); } } DoScriptText(RAND(SAY_SUMMON_BUBL1, SAY_SUMMON_BUBL2), me); DoScriptText(EMOTE_WATERY_GRAVE, me); WateryGrave_Timer = 30000; } else WateryGrave_Timer -= diff; //Start Phase2 if (HealthBelowPct(25)) Phase2 = true; } else { //WateryGlobules_Timer if (WateryGlobules_Timer <= diff) { Unit* pGlobuleTarget; std::set<uint64> globulelist; std::set<uint64>::const_iterator itr; for (uint8 g = 0; g < 4; g++) //one unit can't cast more than one spell per update, so some players have to cast for us XD { counter = 0; do { pGlobuleTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true); if (pGlobuleTarget) itr = globulelist.find(pGlobuleTarget->GetGUID()); if (counter > Playercount) break; ++counter; } while (itr != globulelist.end()); if (pGlobuleTarget) { globulelist.insert(pGlobuleTarget->GetGUID()); pGlobuleTarget->CastSpell(pGlobuleTarget, globulespell[g], true); } } DoScriptText(EMOTE_WATERY_GLOBULES, me); WateryGlobules_Timer = 25000; } else WateryGlobules_Timer -= diff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (Summon_Timer <= diff) { for (uint8 i = 0; i < 3; ++i) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); Creature* Wraith = me->SummonCreature(21062, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); if (target && Wraith) Wraith->AI()->AttackStart(target); } DoScriptText(SAY_SUMMON, me); Summon_Timer = urand(30000, 45000); } else Summon_Timer -= diff; if (ManaTap_Timer <= diff) { DoCast(me->getVictim(), SPELL_MANA_TAP); ManaTap_Timer = urand(14000, 22000); } else ManaTap_Timer -= diff; if (ArcaneTorrent_Timer <= diff) { DoCast(me->getVictim(), SPELL_ARCANE_TORRENT); ArcaneTorrent_Timer = urand(12000, 18000); } else ArcaneTorrent_Timer -= diff; if (Domination_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) { DoScriptText(RAND(SAY_DOMINATION_1, SAY_DOMINATION_2), me); DoCast(target, SPELL_DOMINATION); } Domination_Timer = urand(25000, 30000); } else Domination_Timer -= diff; //Only casting if Heroic Mode is used if (IsHeroic()) { if (ArcaneExplosion_Timer <= diff) { DoCast(me->getVictim(), H_SPELL_ARCANE_EXPLOSION); ArcaneExplosion_Timer = urand(10000, 14000); } else ArcaneExplosion_Timer -= diff; } if (!Enraged && HealthBelowPct(21)) { DoCast(me, SPELL_FRENZY); DoScriptText(SAY_ENRAGE, me); Enraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { switch (Phase) { case COMBAT: //Return since we have no target if (!UpdateVictim()) return; if (!bYelled && HealthBelowPct(30)) { Talk(SAY_30HEALTH); bYelled = true; } if (!bYelled2 && HealthBelowPct(15)) { Talk(SAY_15HEALTH); bYelled2 = true; } if (HealthBelowPct(1)) { //Handle Escape Event: Don't forget to add Player::RewardPlayerAndGroupAtEvent me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); uiOutroStep = 1; Phase = OUTRO; return; } if (Creature* pArthas = me->GetCreature(*me, instance ? instance->GetData64(DATA_ARTHAS) : 0)) if (pArthas->isDead()) { EnterEvadeMode(); me->DisappearAndDie(); if (instance) instance->SetData(DATA_MAL_GANIS_EVENT, FAIL); } if (uiCarrionSwarmTimer < diff) { DoCastVictim(SPELL_CARRION_SWARM); uiCarrionSwarmTimer = 7000; } else uiCarrionSwarmTimer -= diff; if (uiMindBlastTimer < diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_MIND_BLAST); uiMindBlastTimer = 6000; } else uiMindBlastTimer -= diff; if (uiVampiricTouchTimer < diff) { DoCast(me, SPELL_VAMPIRIC_TOUCH); uiVampiricTouchTimer = 32000; } else uiVampiricTouchTimer -= diff; if (uiSleepTimer < diff) { Talk(SAY_SLEEP); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_SLEEP); uiSleepTimer = urand(15000, 20000); } else uiSleepTimer -= diff; DoMeleeAttackIfReady(); break; case OUTRO: if (uiOutroTimer < diff) { switch (uiOutroStep) { case 1: Talk(SAY_ESCAPE_SPEECH_1); me->GetMotionMaster()->MoveTargetedHome(); ++uiOutroStep; uiOutroTimer = 8000; break; case 2: me->SetTarget(instance ? instance->GetData64(DATA_ARTHAS) : 0); me->HandleEmoteCommand(29); Talk(SAY_ESCAPE_SPEECH_2); ++uiOutroStep; uiOutroTimer = 9000; break; case 3: Talk(SAY_OUTRO); ++uiOutroStep; uiOutroTimer = 16000; break; case 4: me->HandleEmoteCommand(33); ++uiOutroStep; uiOutroTimer = 500; break; case 5: me->SetVisible(false); me->Kill(me); break; } } else uiOutroTimer -= diff; break; } }
void UpdateEscortAI(const uint32 uiDiff) { if (uiPhaseTimer <= uiDiff) { switch (uiStep) { case 1: if (instance) { if (instance->GetData(DATA_BRANN_EVENT) != NOT_STARTED) return; instance->SetData(DATA_BRANN_EVENT, IN_PROGRESS); } bIsBattle = false; Talk(SAY_ESCORT_START); SetRun(true); JumpToNextStep(0); break; case 3: SetEscortPaused(false); JumpToNextStep(0); break; case 5: if (instance) if (Creature* temp = (Unit::GetCreature(*me, instance->GetData64(DATA_ABEDNEUM)))) temp->AI()->Talk(SAY_EVENT_INTRO_3_ABED); JumpToNextStep(8500); break; case 6: Talk(SAY_EVENT_A_1); JumpToNextStep(6500); break; case 7: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_KADDRAK))) temp->AI()->Talk(SAY_EVENT_A_2_KADD); JumpToNextStep(12500); break; case 8: Talk(SAY_EVENT_A_3); if (instance) instance->HandleGameObject(instance->GetData64(DATA_GO_KADDRAK), true); if (Creature* temp = Unit::GetCreature(*me, uiControllerGUID)) CAST_AI(mob_tribuna_controller::mob_tribuna_controllerAI, temp->AI())->bKaddrakActivated = true; JumpToNextStep(5000); break; case 9: me->SetReactState(REACT_PASSIVE); SpawnDwarf(1); JumpToNextStep(20000); break; case 10: Talk(SAY_EVENT_B_1); JumpToNextStep(6000); break; case 11: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_MARNAK))) temp->AI()->Talk(SAY_EVENT_B_2_MARN); SpawnDwarf(1); JumpToNextStep(20000); break; case 12: Talk(SAY_EVENT_B_3); if (instance) instance->HandleGameObject(instance->GetData64(DATA_GO_MARNAK), true); if (Creature* temp = Unit::GetCreature(*me, uiControllerGUID)) CAST_AI(mob_tribuna_controller::mob_tribuna_controllerAI, temp->AI())->bMarnakActivated = true; JumpToNextStep(10000); break; case 13: SpawnDwarf(1); JumpToNextStep(10000); break; case 14: SpawnDwarf(2); JumpToNextStep(20000); break; case 15: Talk(SAY_EVENT_C_1); SpawnDwarf(1); JumpToNextStep(10000); break; case 16: SpawnDwarf(2); JumpToNextStep(20000); break; case 17: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ABEDNEUM))) temp->AI()->Talk(SAY_EVENT_C_2_ABED); SpawnDwarf(1); JumpToNextStep(20000); break; case 18: Talk(SAY_EVENT_C_3); if (instance) instance->HandleGameObject(instance->GetData64(DATA_GO_ABEDNEUM), true); if (Creature* temp = Unit::GetCreature(*me, uiControllerGUID)) CAST_AI(mob_tribuna_controller::mob_tribuna_controllerAI, temp->AI())->bAbedneumActivated = true; JumpToNextStep(5000); break; case 19: SpawnDwarf(2); JumpToNextStep(10000); break; case 20: SpawnDwarf(1); JumpToNextStep(15000); break; case 21: Talk(SAY_EVENT_D_1); SpawnDwarf(3); JumpToNextStep(20000); break; case 22: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ABEDNEUM))) temp->AI()->Talk(SAY_EVENT_D_2_ABED); SpawnDwarf(1); JumpToNextStep(5000); break; case 23: SpawnDwarf(2); JumpToNextStep(15000); break; case 24: Talk(SAY_EVENT_D_3); SpawnDwarf(3); JumpToNextStep(5000); break; case 25: SpawnDwarf(1); JumpToNextStep(5000); break; case 26: SpawnDwarf(2); JumpToNextStep(10000); break; case 27: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ABEDNEUM))) temp->AI()->Talk(SAY_EVENT_D_4_ABED); SpawnDwarf(1); JumpToNextStep(10000); break; case 28: me->SetReactState(REACT_DEFENSIVE); Talk(SAY_EVENT_END_01); me->SetStandState(UNIT_STAND_STATE_STAND); if (instance) instance->HandleGameObject(instance->GetData64(DATA_GO_SKY_FLOOR), true); if (Creature* temp = Unit::GetCreature(*me, uiControllerGUID)) temp->DealDamage(temp, temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); bIsBattle = true; SetEscortPaused(false); JumpToNextStep(6500); break; case 29: Talk(SAY_EVENT_END_02); if (instance) instance->SetData(DATA_BRANN_EVENT, DONE); me->CastSpell(me, SPELL_REWARD_ACHIEVEMENT, true); JumpToNextStep(5500); break; case 30: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ABEDNEUM))) temp->AI()->Talk(SAY_EVENT_END_03_ABED); JumpToNextStep(8500); break; case 31: Talk(SAY_EVENT_END_04); JumpToNextStep(11500); break; case 32: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ABEDNEUM))) temp->AI()->Talk(SAY_EVENT_END_05_ABED); JumpToNextStep(11500); break; case 33: Talk(SAY_EVENT_END_06); JumpToNextStep(4500); break; case 34: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ABEDNEUM))) temp->AI()->Talk(SAY_EVENT_END_07_ABED); JumpToNextStep(22500); break; case 35: Talk(SAY_EVENT_END_08); JumpToNextStep(7500); break; case 36: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_KADDRAK))) temp->AI()->Talk(SAY_EVENT_END_09_KADD); JumpToNextStep(18500); break; case 37: Talk(SAY_EVENT_END_10); JumpToNextStep(5500); break; case 38: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_KADDRAK))) temp->AI()->Talk(SAY_EVENT_END_11_KADD); JumpToNextStep(20500); break; case 39: Talk(SAY_EVENT_END_12); JumpToNextStep(2500); break; case 40: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_KADDRAK))) temp->AI()->Talk(SAY_EVENT_END_13_KADD); JumpToNextStep(19500); break; case 41: Talk(SAY_EVENT_END_14); JumpToNextStep(10500); break; case 42: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_MARNAK))) temp->AI()->Talk(SAY_EVENT_END_15_MARN); JumpToNextStep(6500); break; case 43: Talk(SAY_EVENT_END_16); JumpToNextStep(6500); break; case 44: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_MARNAK))) temp->AI()->Talk(SAY_EVENT_END_17_MARN); JumpToNextStep(25500); break; case 45: Talk(SAY_EVENT_END_18); JumpToNextStep(23500); break; case 46: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_MARNAK))) temp->AI()->Talk(SAY_EVENT_END_19_MARN); JumpToNextStep(3500); break; case 47: Talk(SAY_EVENT_END_20); JumpToNextStep(8500); break; case 48: if (instance) if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ABEDNEUM))) temp->AI()->Talk(SAY_EVENT_END_21_ABED); JumpToNextStep(5500); break; case 49: { if (instance) { instance->HandleGameObject(instance->GetData64(DATA_GO_KADDRAK), false); instance->HandleGameObject(instance->GetData64(DATA_GO_MARNAK), false); instance->HandleGameObject(instance->GetData64(DATA_GO_ABEDNEUM), false); instance->HandleGameObject(instance->GetData64(DATA_GO_SKY_FLOOR), false); } Player* player = GetPlayerForEscort(); if (player) player->GroupEventHappens(QUEST_HALLS_OF_STONE, me); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); JumpToNextStep(180000); break; } case 50: SetEscortPaused(false); break; } } else uiPhaseTimer -= uiDiff; if (!bIsLowHP && HealthBelowPct(30)) { Talk(SAY_LOW_HEALTH); bIsLowHP = true; } else if (bIsLowHP && !HealthBelowPct(30)) bIsLowHP = false; if (!UpdateVictim()) return; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (BerserkTimer <= diff) { me->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(me, SOUND_BERSERK); DoCast(me, SPELL_BERSERK, true); BerserkTimer = 60000; } else BerserkTimer -= diff; if (Phase == PHASE_LYNX || Phase == PHASE_ENRAGE) { if (SaberlashTimer <= diff) { // A tank with more than 490 defense skills should receive no critical hit //DoCast(me, 41296, true); DoCast(me->getVictim(), SPELL_SABER_LASH, true); //me->RemoveAurasDueToSpell(41296); SaberlashTimer = 30000; } else SaberlashTimer -= diff; if (FrenzyTimer <= diff) { DoCast(me, SPELL_FRENZY); FrenzyTimer = urand(10000,15000); } else FrenzyTimer -= diff; if (Phase == PHASE_LYNX) { if (CheckTimer <= diff) { if (HealthBelowPct(25 * (3 - TransformCount))) EnterPhase(PHASE_SPLIT); CheckTimer = 1000; } else CheckTimer -= diff; } } if (Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE) { if (TotemTimer <= diff) { DoCast(me, SPELL_SUMMON_TOTEM); TotemTimer = 20000; } else TotemTimer -= diff; if (ShockTimer <= diff) { if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) { if (pTarget->IsNonMeleeSpellCasted(false)) DoCast(pTarget, SPELL_EARTHSHOCK); else DoCast(pTarget, SPELL_FLAMESHOCK); ShockTimer = 10000 + rand()%5000; } } else ShockTimer -= diff; if (Phase == PHASE_HUMAN) { if (CheckTimer <= diff) { if (!HealthAbovePct(20) /*HealthBelowPct(10)*/) EnterPhase(PHASE_MERGE); else { Unit *Lynx = Unit::GetUnit(*me, LynxGUID); if (Lynx && !Lynx->HealthAbovePct(20) /*Lynx->HealthBelowPct(10)*/) EnterPhase(PHASE_MERGE); } CheckTimer = 1000; } else CheckTimer -= diff; } } if (Phase == PHASE_MERGE) { if (CheckTimer <= diff) { Unit *Lynx = Unit::GetUnit(*me, LynxGUID); if (Lynx) { Lynx->GetMotionMaster()->MoveFollow(me, 0, 0); me->GetMotionMaster()->MoveFollow(Lynx, 0, 0); if (me->IsWithinDistInMap(Lynx, 6.0f)) { if (TransformCount < 3) EnterPhase(PHASE_LYNX); else EnterPhase(PHASE_ENRAGE); } } CheckTimer = 1000; } else CheckTimer -= diff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; //Shimmer_Timer Timer if (Shimmer_Timer <= diff) { //Remove old vulnerabilty spell if (CurrentVurln_Spell) me->RemoveAurasDueToSpell(CurrentVurln_Spell); //Cast new random vulnerabilty on self uint32 spell = RAND(SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY); DoCast(me, spell); CurrentVurln_Spell = spell; DoScriptText(EMOTE_SHIMMER, me); Shimmer_Timer = 45000; } else Shimmer_Timer -= diff; //Breath1_Timer if (Breath1_Timer <= diff) { DoCast(me->getVictim(), Breath1_Spell); Breath1_Timer = 60000; } else Breath1_Timer -= diff; //Breath2_Timer if (Breath2_Timer <= diff) { DoCast(me->getVictim(), Breath2_Spell); Breath2_Timer = 60000; } else Breath2_Timer -= diff; //Affliction_Timer if (Affliction_Timer <= diff) { std::list<HostileReference*> threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) { Unit* pUnit; if ((*i) && (*i)->getSource()) { pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); if (pUnit) { //Cast affliction DoCast(pUnit, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true); //Chromatic mutation if target is effected by all afflictions if (pUnit->HasAura(SPELL_BROODAF_BLUE) && pUnit->HasAura(SPELL_BROODAF_BLACK) && pUnit->HasAura(SPELL_BROODAF_RED) && pUnit->HasAura(SPELL_BROODAF_BRONZE) && pUnit->HasAura(SPELL_BROODAF_GREEN)) { //pTarget->RemoveAllAuras(); //DoCast(pTarget, SPELL_CHROMATIC_MUT_1); //Chromatic mutation is causing issues //Assuming it is caused by a lack of core support for Charm //So instead we instant kill our target //WORKAROUND if (pUnit->GetTypeId() == TYPEID_PLAYER) pUnit->CastSpell(pUnit, 5, false); } } } } Affliction_Timer = 10000; } else Affliction_Timer -= diff; //Frenzy_Timer if (Frenzy_Timer <= diff) { DoCast(me, SPELL_FRENZY); DoScriptText(EMOTE_FRENZY, me); Frenzy_Timer = urand(10000, 15000); } else Frenzy_Timer -= diff; //Enrage if not already enraged and below 20% if (!Enraged && HealthBelowPct(20)) { DoCast(me, SPELL_ENRAGE); Enraged = true; } DoMeleeAttackIfReady(); }