void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (TargetTimer <= diff && Enslaved == false) { EnslaveTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); TargetTimer = 1000; } else TargetTimer -= diff; if (EnslaveEndTimer <= diff && Enslaved == true) { me->SetReactState(REACT_AGGRESSIVE); EnslaveTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); EnslaveTarget->RemoveAurasDueToSpell(SPELL_ENSLAVE); EnslaveTarget->RemoveAurasDueToSpell(SPELL_ENSLAVE_BUFF); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Enslaved = false; EnslaveTimer = 30000; AbsorbMagicTimer = 20000; MindFogTimer = urand(6000,12000); UnrelentingAgonyTimer = 10000; EnslaveEndTimer = 90000; } else EnslaveEndTimer -= diff; if (EnslaveTimer <= diff && Enslaved == false) { if (EnslaveTarget) { DoZoneInCombat(); me->SetReactState(REACT_PASSIVE); DoCast(EnslaveTarget, SPELL_ENSLAVE); DoCast(EnslaveTarget, SPELL_ENSLAVE_BUFF); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoScriptText(RAND(SAY_MIND_CONTROL_1,SAY_MIND_CONTROL_2,SAY_MIND_CONTROL_3), me); Enslaved = true; EnslaveTimer = 180000; AbsorbMagicTimer = 180000; MindFogTimer = 180000; UnrelentingAgonyTimer = 180000; EnslaveEndTimer = DUNGEON_MODE(60000,30000); CastTimer = 2000; } EnslaveTimer = 1000; } else EnslaveTimer -= diff; if (EnslaveTarget && Enslaved == true) if (EnslaveTarget->HealthBelowPct(50)) { me->SetReactState(REACT_AGGRESSIVE); EnslaveTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); EnslaveTarget->RemoveAurasDueToSpell(SPELL_ENSLAVE); EnslaveTarget->RemoveAurasDueToSpell(SPELL_ENSLAVE_BUFF); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Enslaved = false; EnslaveTimer = 30000; AbsorbMagicTimer = 20000; MindFogTimer = urand(6000,12000); UnrelentingAgonyTimer = 10000; } if (CastTimer <= diff && Enslaved == true) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, NotCharmedTargetSelector())) { switch(EnslaveTarget->getClass()) { case CLASS_DRUID: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 8921, false); else EnslaveTarget->CastSpell(me, 774, false); break; case CLASS_HUNTER: EnslaveTarget->CastSpell(pTarget, RAND(2643, 1978), false); break; case CLASS_MAGE: EnslaveTarget->CastSpell(pTarget, RAND(44614, 30455), false); break; case CLASS_WARLOCK: EnslaveTarget->CastSpell(pTarget, RAND(980, 686), true); break; case CLASS_WARRIOR: EnslaveTarget->CastSpell(pTarget, RAND(46924, 845), false); break; case CLASS_PALADIN: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 853, false); else EnslaveTarget->CastSpell(me, 20473, false); break; case CLASS_PRIEST: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 34914, false); else EnslaveTarget->CastSpell(me, 139, false); break; case CLASS_SHAMAN: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 421, false); else EnslaveTarget->CastSpell(me, 61295, false); break; case CLASS_ROGUE: EnslaveTarget->CastSpell(pTarget, RAND(16511, 1329), false); break; case CLASS_DEATH_KNIGHT: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 45462, true); else EnslaveTarget->CastSpell(pTarget, 49184, true); break; } } CastTimer = 3000; } else CastTimer -= diff; if (AbsorbMagicTimer <= diff && Enslaved == false) { DoCast(me, SPELL_ABSORB_MAGIC); AbsorbMagicTimer = urand(15000,20000); } else AbsorbMagicTimer -= diff; if (MindFogTimer <= diff && Enslaved == false) { DoCast(me, SPELL_MIND_FOG_SUMMON); DoScriptText(SAY_MIND_FOG, me); MindFogTimer = 18000; } else MindFogTimer -= diff; if (UnrelentingAgonyTimer <= diff && Enslaved == false) { DoCastAOE(SPELL_UNRELENTING_AGONY); UnrelentingAgonyTimer = 20000; } else UnrelentingAgonyTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); if (Phase == 1) { while (uint32 eventId = events.GetEvent()) { switch (eventId) { case EVENT_WASTE: DoSummon(NPC_WASTE, Pos[RAND(0, 3, 6, 9)]); events.RepeatEvent(urand(2000, 5000)); break; case EVENT_ABOMIN: if (nAbomination < 8) { DoSummon(NPC_ABOMINATION, Pos[RAND(1, 4, 7, 10)]); nAbomination++; events.RepeatEvent(20000); } else events.PopEvent(); break; case EVENT_WEAVER: if (nWeaver < 8) { DoSummon(NPC_WEAVER, Pos[RAND(0, 3, 6, 9)]); nWeaver++; events.RepeatEvent(25000); } else events.PopEvent(); break; case EVENT_TRIGGER: if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID)) pKTTrigger->SetPhaseMask(2, true); events.PopEvent(); break; case EVENT_PHASE: events.Reset(); DoScriptText(RAND(SAY_AGGRO_1, SAY_AGGRO_2, SAY_AGGRO_3), me); spawns.DespawnAll(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE); me->CastStop(); DoStartMovement(me->getVictim()); events.ScheduleEvent(EVENT_BOLT, urand(5000, 10000)); events.ScheduleEvent(EVENT_NOVA, 15000); events.ScheduleEvent(EVENT_DETONATE, urand(30000, 40000)); events.ScheduleEvent(EVENT_FISSURE, urand(10000, 30000)); events.ScheduleEvent(EVENT_BLAST, urand(60000, 120000)); if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) events.ScheduleEvent(EVENT_CHAIN, urand(30000, 60000)); Phase = 2; break; default: events.PopEvent(); break; } } } else { //start phase 3 when we are 45% health if (Phase != 3) { if (HealthBelowPct(45)) { Phase = 3; DoScriptText(SAY_REQUEST_AID, me); //here Lich King should respond to KelThuzad but I don't know which Creature to make talk //so for now just make Kelthuzad says it. DoScriptText(SAY_ANSWER_REQUEST, me); for (uint8 i = 0; i <= 3; ++i) { if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i])) { if (pPortal->getLootState() == GO_READY) pPortal->UseDoorOrButton(); } } } } else if (nGuardiansOfIcecrownCount < RAID_MODE(2, 4)) { if (uiGuardiansOfIcecrownTimer <= diff) { // TODO : Add missing text if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)])) pGuardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2); ++nGuardiansOfIcecrownCount; uiGuardiansOfIcecrownTimer = 5000; } else uiGuardiansOfIcecrownTimer -= diff; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; if (uint32 eventId = events.GetEvent()) { switch (eventId) { case EVENT_BOLT: DoCastVictim(RAID_MODE(SPELL_FROST_BOLT, H_SPELL_FROST_BOLT)); events.RepeatEvent(urand(5000, 10000)); break; case EVENT_NOVA: DoCastAOE(RAID_MODE(SPELL_FROST_BOLT_AOE, H_SPELL_FROST_BOLT_AOE)); events.RepeatEvent(urand(15000, 30000)); break; case EVENT_CHAIN: { uint32 count = urand(1, 3); for (uint8 i = 1; i <= count; i++) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true); if (target && !target->isCharmed() && (chained.find(target->GetGUID()) == chained.end())) { DoCast(target, SPELL_CHAINS_OF_KELTHUZAD); float scale = target->GetFloatValue(OBJECT_FIELD_SCALE_X); chained.insert(std::make_pair(target->GetGUID(), scale)); target->SetFloatValue(OBJECT_FIELD_SCALE_X, scale * 2); events.ScheduleEvent(EVENT_CHAINED_SPELL, 2000); //core has 2000ms to set unit flag charm } } if (!chained.empty()) DoScriptText(RAND(SAY_CHAIN_1, SAY_CHAIN_2), me); events.RepeatEvent(urand(100000, 180000)); break; } case EVENT_CHAINED_SPELL: { std::map<uint64, float>::iterator itr; for (itr = chained.begin(); itr != chained.end();) { if (Unit* player = Unit::GetPlayer(*me, (*itr).first)) { if (!player->isCharmed()) { player->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second); std::map<uint64, float>::iterator next = itr; ++next; chained.erase(itr); itr = next; continue; } if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, NotCharmedTargetSelector())) { switch (player->getClass()) { case CLASS_DRUID: if (urand(0, 1)) player->CastSpell(target, SPELL_MOONFIRE, false); else player->CastSpell(me, SPELL_LIFEBLOOM, false); break; case CLASS_HUNTER: player->CastSpell(target, RAND(SPELL_MULTI_SHOT, SPELL_VOLLEY), false); break; case CLASS_MAGE: player->CastSpell(target, RAND(SPELL_FROST_FIREBOLT, SPELL_ARCANE_MISSILES), false); break; case CLASS_WARLOCK: player->CastSpell(target, RAND(SPELL_CURSE_OF_AGONY, SPELL_SHADOW_BOLT), true); break; case CLASS_WARRIOR: player->CastSpell(target, RAND(SPELL_BLADESTORM, SPELL_CLEAVE), false); break; case CLASS_PALADIN: if (urand(0, 1)) player->CastSpell(target, SPELL_HAMMER_OF_JUSTICE, false); else player->CastSpell(me, SPELL_HOLY_SHOCK, false); break; case CLASS_PRIEST: if (urand(0, 1)) player->CastSpell(target, SPELL_VAMPIRIC_TOUCH, false); else player->CastSpell(me, SPELL_RENEW, false); break; case CLASS_SHAMAN: if (urand(0, 1)) player->CastSpell(target, SPELL_EARTH_SHOCK, false); else player->CastSpell(me, SPELL_HEALING_WAVE, false); break; case CLASS_ROGUE: player->CastSpell(target, RAND(SPELL_HEMORRHAGE, SPELL_MUTILATE), false); break; case CLASS_DEATH_KNIGHT: if (urand(0, 1)) player->CastSpell(target, SPELL_PLAGUE_STRIKE, true); else player->CastSpell(target, SPELL_HOWLING_BLAST, true); break; } } } ++itr; } if (chained.empty()) events.PopEvent(); else events.RepeatEvent(5000); break; } case EVENT_DETONATE: { std::vector<Unit*> unitList; std::list<HostileReference*> *threatList = &me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = threatList->begin(); itr != threatList->end(); ++itr) { if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER && (*itr)->getTarget()->getPowerType() == POWER_MANA && (*itr)->getTarget()->GetPower(POWER_MANA)) unitList.push_back((*itr)->getTarget()); } if (!unitList.empty()) { std::vector<Unit*>::const_iterator itr = unitList.begin(); advance(itr, rand()%unitList.size()); DoCast(*itr, SPELL_MANA_DETONATION); DoScriptText(RAND(SAY_SPECIAL_1, SAY_SPECIAL_2, SAY_SPECIAL_3), me); } events.RepeatEvent(urand(20000, 50000)); break; } case EVENT_FISSURE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_SHADOW_FISURE); events.RepeatEvent(urand(10000, 45000)); break; case EVENT_BLAST: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, RAID_MODE(1, 0), 0, true)) DoCast(target, SPELL_FROST_BLAST); if (rand()%2) DoScriptText(SAY_FROST_BLAST, me); events.RepeatEvent(urand(30000, 90000)); break; default: events.PopEvent(); break; } } DoMeleeAttackIfReady(); } }