void UpdateAI(const uint32 diff) { //Freya wont reset unless this is done if (!UpdateVictim()) { me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(false); me->GetMotionMaster()->MoveTargetedHome(); Reset(); return; } if (uiSunbeamTimer <= 0) { Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM); DoCast(pTarget, RAID_MODE(RAID_10_SPELL_SUNBEAM, RAID_25_SPELL_SUNBEAM)); uiSunbeamTimer = refreshTimer(SUNBEAM_TIMER_MIN, SUNBEAM_TIMER_MAX); } else uiSunbeamTimer -= diff; if (uiEonarsTimer <= 0) { int8 randomX = -25 + rand() % 50; int8 randomY = -25 + rand() % 50; me->SummonCreature(NPC_EONARS_GIFT, me->GetPositionX() + randomX, me->GetPositionY() + randomY, me->GetPositionZ() + 5, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); uiEonarsTimer = refreshTimer(EONARS_GIFT_TIMER_MIN, EONARS_GIFT_TIMER_MAX); } else uiEonarsTimer -= diff; if (uiGroundTremorTimer <= 0) { DoCastAOE(RAID_MODE(RAID_10_SPELL_FREYA_GROUND_TREMOR, RAID_25_SPELL_FREYA_GROUND_TREMOR)); uiGroundTremorTimer = refreshTimer(FREYA_GROUND_TREMOR_TIMER_MIN, FREYA_GROUND_TREMOR_TIMER_MAX); } else if (pStonebark->isAlive()) uiGroundTremorTimer -= diff; if (uiIronRootTimer <= 0) { pRootTarget = SelectTarget(SELECT_TARGET_RANDOM); pRootTarget->CastSpell(me, RAID_MODE(RAID_10_SPELL_IRON_ROOTS, RAID_25_SPELL_IRON_ROOTS), false); uiIronRootTimer = refreshTimer(IRON_ROOTS_TIMER_MIN, IRON_ROOTS_TIMER_MAX); } else if (pIronbranch->isAlive()) uiIronRootTimer -= diff; if (uiUnstableSunBeamTimer <= 0) { for (int8 n = 0; n < 3; n++) { Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM); me->SummonCreature(NPC_SUN_BEAM, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, SUN_BEAM_DESPAWN_TIME); } uiUnstableSunBeamTimer = refreshTimer(FREYA_SUN_BEAM_TIMER_MIN, FREYA_SUN_BEAM_TIMER_MAX); } else if (pBrightleaf->isAlive()) uiUnstableSunBeamTimer -= diff; if (uiEnrageTimer <= 0 && !bEnraged) { DoCast(me, SPELL_ENRAGE); me->MonsterYell("You have strayed too far, wasted too much time!", 0, 0); bEnraged = true; } else uiEnrageTimer -= diff; if (phase == 1) { if (uiSpawnAddTimer <= 0) { spawnAdd(); uiSpawnAddTimer = SPAWN_ADD_TIMER; } else uiSpawnAddTimer -= diff; if (uiEnterPhaseTwoTimer <= 0 && phase == 1) phase = 2; else uiEnterPhaseTwoTimer -= diff; potentPheromones(); } else { if (uiNatureBombTimer <= 0) { spawnNatureBomb(); uiNatureBombTimer = NATURE_BOMB_TIMER; } else uiNatureBombTimer -= diff; } //Ressurrection of elemental adds handler - works even if both waves of elemental adds are alive at the same time! if (bElementalAddKilled[0]) uiRessTimer[0] -= diff; else if (bElementalAddKilled[1]) uiRessTimer[1] -= diff; if (uiRessTimer[0] <= 0) { //Im not 100% sure that this is neccessary bool swap = false; if (!bFirstWave) { bFirstWave = true; swap = true; } bElementalAddKilled[0] = false; if (elementalAdds[0]->isAlive() || elementalAdds[1]->isAlive() || elementalAdds[2]->isAlive()) { //Resurrect those mobs that are dead - if not dead, give full health. if (!elementalAdds[0]->isAlive()) { elementalAdds[0]->Respawn(); attunedToNatureStacks += 10; } else elementalAdds[0]->SetHealth(elementalAdds[0]->GetMaxHealth()); if (!elementalAdds[1]->isAlive()) { elementalAdds[1]->Respawn(); attunedToNatureStacks += 10; } else elementalAdds[1]->SetHealth(elementalAdds[0]->GetMaxHealth()); if (!elementalAdds[2]->isAlive()) { elementalAdds[2]->Respawn(); attunedToNatureStacks += 10; } else elementalAdds[2]->SetHealth(elementalAdds[0]->GetMaxHealth()); updateAttunedToNatureStacks(); } if (swap) bFirstWave = false; uiRessTimer[0] = RESURRECTION_TIMER; } else if (uiRessTimer[1] <= 0) { bElementalAddKilled[1] = false; if (elementalAdds[3]->isAlive() || elementalAdds[4]->isAlive() || elementalAdds[5]->isAlive()) { //Ress those mobs that are dead if (!elementalAdds[3]->isAlive()) { elementalAdds[3]->Respawn(); attunedToNatureStacks += 10; } else elementalAdds[3]->SetHealth(elementalAdds[0]->GetMaxHealth()); if (!elementalAdds[4]->isAlive()) { elementalAdds[4]->Respawn(); attunedToNatureStacks += 10; } else elementalAdds[4]->SetHealth(elementalAdds[0]->GetMaxHealth()); if (!elementalAdds[5]->isAlive()) { elementalAdds[5]->Respawn(); attunedToNatureStacks += 10; } else elementalAdds[5]->SetHealth(elementalAdds[0]->GetMaxHealth()); updateAttunedToNatureStacks(); } uiRessTimer[1] = RESURRECTION_TIMER; } //Become friendly and give loot if (HealthBelowPct(1)) { me->setFaction(FACTION_FRIENDLY); me->MonsterYell("His hold on me dissipates. I can see clearly once more. Thank you, heroes.", 0, 0); if (m_pInstance) m_pInstance->SetData(TYPE_FREYA, DONE); float x = me->GetPositionX(); float y = me->GetPositionY(); float z = me->GetPositionZ(); float ang = me->GetOrientation(); float rot2 = sin(ang/2); float rot3 = cos(ang/2); me->SummonGameObject(RAID_MODE(OBJECT_FREYAS_GIFT_N, OBJECT_FREYAS_GIFT_H), x, y, z, ang, 0, 0, rot2, rot3, 0); //Resets me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(false); me->GetMotionMaster()->MoveTargetedHome(); Reset(); } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; // Elementals must be killed within 12 seconds of each other, or they will all revive and heal if (checkElementalAlive) uiElemTimer = 0; else { uiElemTimer += diff; if (uiElemTimer > 12000) { for (uint32 i = 0; i < 3; i++) { if (Elemental[i]->isAlive()) Elemental[i]->SetHealth(Elemental[i]->GetMaxHealth()); else Elemental[i]->Respawn(); } checkElementalAlive = true; } else { if (Elemental[0]->isDead()) if (Elemental[1]->isDead()) if (Elemental[2]->isDead()) { for (uint32 i = 0; i < 3; i++) Elemental[i]->ForcedDespawn(3000); if (Creature* Freya = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_FREYA) : 0)) Freya->AI()->DoAction(ACTION_ELEMENTAL); } } } if (me->getVictim() && !me->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()) me->Kill(me->getVictim()); events.Update(diff); if (events.GetTimer() > 360000) events.CancelEvent(EVENT_SUMMON_ALLIES); if (me->hasUnitState(UNIT_STAT_CASTING)) return; while(uint32 eventId = events.ExecuteEvent()) { switch(eventId) { case EVENT_SUNBEAM: if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) if (pTarget->isAlive()) DoCast(pTarget, RAID_MODE(RAID_10_SPELL_SUNBEAM, RAID_25_SPELL_SUNBEAM)); events.ScheduleEvent(EVENT_SUNBEAM, urand(10000, 15000)); break; case EVENT_EONAR_GIFT: me->MonsterTextEmote(EMOTE_GIFT, 0, true); DoCast(SPELL_EONAR_GIFT); events.ScheduleEvent(EVENT_EONAR_GIFT, urand(35000, 45000)); break; case EVENT_SUMMON_ALLIES: me->MonsterTextEmote(EMOTE_ALLIES, 0, true); DoCast(me, SPELL_SUMMON_ALLIES); spawnAdd(); events.ScheduleEvent(EVENT_SUMMON_ALLIES, 60000); break; case EVENT_NATURE_BOMB: DoCastAOE(SPELL_NATURE_BOMB_VISUAL); DoCastAOE(SPELL_NATURE_BOMB); events.ScheduleEvent(EVENT_NATURE_BOMB, urand(15000, 20000)); break; case EVENT_BRIGHTLEAF: for (int8 n = 0; n < 3; n++) if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_SUN_BEAM_SUMMON); events.ScheduleEvent(EVENT_BRIGHTLEAF, urand(35000, 45000)); break; case EVENT_IRONBRANCH: if (pRootTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) pRootTarget->CastSpell(pRootTarget,RAID_MODE(RAID_10_SPELL_IRON_ROOTS, RAID_25_SPELL_IRON_ROOTS),true); events.ScheduleEvent(EVENT_IRONBRANCH, urand(45000, 60000)); break; case EVENT_STONEBARK: DoCastAOE(RAID_MODE(RAID_10_SPELL_FREYA_GROUND_TREMOR, RAID_25_SPELL_FREYA_GROUND_TREMOR)); events.ScheduleEvent(EVENT_STONEBARK, urand(25000, 30000)); break; case EVENT_BERSERK: DoCast(me, SPELL_BERSERK, true); DoScriptText(SAY_BERSERK, me); events.CancelEvent(EVENT_BERSERK); break; } } DoMeleeAttackIfReady(); }