void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; if (insanityHandled) { if (!Summons.empty()) return; insanityHandled = 0; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(false, UNIT_STAT_STUNNED); me->RemoveAurasDueToSpell(INSANITY_VISUAL); } if (uiMindFlayTimer <= diff) { DoCast(me->getVictim(), SPELL_MIND_FLAY); uiMindFlayTimer = 20*IN_MILLISECONDS; } else uiMindFlayTimer -= diff; if (uiShadowBoltVolleyTimer <= diff) { DoCast(me->getVictim(), SPELL_SHADOW_BOLT_VOLLEY); uiShadowBoltVolleyTimer = 5*IN_MILLISECONDS; } else uiShadowBoltVolleyTimer -= diff; if (uiShiverTimer <= diff) { if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(pTarget, SPELL_SHIVER); uiShiverTimer = 15*IN_MILLISECONDS; } else uiShiverTimer -= diff; DoMeleeAttackIfReady(); }
//make sparks come back void CallBackSparks() { //should never be empty here, but check if (lSparkList.empty()) return; Position pos = me->GetPosition(); for (std::list<uint64>::const_iterator itr = lSparkList.begin(); itr != lSparkList.end(); ++itr) { if (Creature* pSpark = ObjectAccessor::GetCreature(*me, *itr)) { if (pSpark->IsAlive()) { pSpark->SetSpeed(MOVE_RUN, 2.0f); pSpark->GetMotionMaster()->Clear(); pSpark->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } else pSpark->DespawnOrUnsummon(); } } }
//make sparks come back void CallBackSparks() { //should never be empty here, but check if (lSparkList.empty()) return; Position pos = me->GetPosition(); for (ObjectGuid guid : lSparkList) { if (Creature* pSpark = ObjectAccessor::GetCreature(*me, guid)) { if (pSpark->IsAlive()) { pSpark->SetSpeedRate(MOVE_RUN, 2.0f); pSpark->GetMotionMaster()->Clear(); pSpark->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } else pSpark->DespawnOrUnsummon(); } } }
void UpdateAI(uint32 uiDiff) { if (!UpdateVictim()) return; if (!bIsFrenzy && !bIsExploded && HealthBelowPct(25)) { Talk(SAY_ENRAGE); me->CastSpell(me, SPELL_FRENZY, true); bIsFrenzy = true; } if (!bIsFrenzy) { if (!bIsExploded) { if (!me->HasAura(SPELL_PROTECTIVE_BUBBLE)) { me->InterruptNonMeleeSpells(false); Talk(SAY_SHATTER); DoZoneInCombat(); IchoronDoCastToAllHostilePlayers(SPELL_WATER_BLAST, true); me->CastSpell(me, SPELL_DRAINED, true); bIsExploded = true; uiDrainedTimer = 15000; me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetDisplayId(11686); for (uint8 i=0; i<MAX_SPAWN_LOC; ++i) { float angle = rand_norm()*2*M_PI; Position p1(SpawnLoc[i]), p2(SpawnLoc[i]); p1.m_positionX += 2.5f*cos(angle); p1.m_positionY += 2.5f*sin(angle); p2.m_positionX -= 2.5f*cos(angle); p2.m_positionY -= 2.5f*sin(angle); DoSummon(NPC_ICHOR_GLOBULE, p1, 60000, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN); DoSummon(NPC_ICHOR_GLOBULE, p2, 60000, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN); } } } else { if (uiDrainedTimer <= uiDiff) DoExplodeCompleted(); else { uiDrainedTimer -= uiDiff; bool bIsWaterElementsAlive = false; if (!globules.empty()) { for (std::list<uint64>::const_iterator itr = globules.begin(); itr != globules.end(); ++itr) if (Creature* pTemp = ObjectAccessor::GetCreature(*me, *itr)) if (pTemp->IsAlive()) { bIsWaterElementsAlive = true; break; } } if (!bIsWaterElementsAlive) DoExplodeCompleted(); } } } if (!bIsExploded) { if (uiWaterBoltVolleyTimer <= uiDiff) { me->CastSpell((Unit*)NULL, SPELL_WATER_BOLT_VOLLEY, false); uiWaterBoltVolleyTimer = urand(10000, 15000); } else uiWaterBoltVolleyTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!UpdateVictim()) return; if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded) { DoScriptText(SAY_ENRAGE, me); DoCast(me, SPELL_FRENZY, true); bIsFrenzy = true; } if (!bIsFrenzy) { if (uiBubbleCheckerTimer <= uiDiff) { 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* temp = Unit::GetCreature(*me, *itr)) if (temp->isAlive()) { bIsWaterElementsAlive = true; break; } } if (!bIsWaterElementsAlive) DoExplodeCompleted(); } uiBubbleCheckerTimer = 1000; } else uiBubbleCheckerTimer -= uiDiff; } if (!bIsExploded) { if (uiWaterBoltVolleyTimer <= uiDiff) { DoCast(me, SPELL_WATER_BOLT_VOLLEY); uiWaterBoltVolleyTimer = urand(10000, 15000); } else uiWaterBoltVolleyTimer -= uiDiff; DoMeleeAttackIfReady(); } }
void SummonedCreatureDies(Creature* creature, Unit*) { summons.Despawn(creature); if (summons.empty()) Talk(textCounter++, GetPlayerForEscort()); }
void UpdateAI(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; Talk(SAY_SPLIT); if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_DISPERSE, false); } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (Phase == NORMAL) { //Return since we have no target if (!UpdateVictim()) return; if (uiSinsterStrikeTimer <= diff) { DoCast(me->getVictim(), SPELL_SINSTER_STRIKE); uiSinsterStrikeTimer = urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS); } else uiSinsterStrikeTimer -= diff; if (uiCallFlamesTimer <= diff) { if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { DoCast(pTarget, SPELL_CALL_FLAMES); uiCallFlamesTimer = urand(8 * IN_MILLISECONDS, 12 * IN_MILLISECONDS); } } else uiCallFlamesTimer -= diff; if (!bSacrificed) { if (uiRitualOfSwordTimer <= diff) { if (Unit* pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { DoScriptText( RAND(SAY_SACRIFICE_PLAYER_1, SAY_SACRIFICE_PLAYER_2, SAY_SACRIFICE_PLAYER_3, SAY_SACRIFICE_PLAYER_4, SAY_SACRIFICE_PLAYER_5), me); DoCast(pSacrificeTarget, SPELL_RITUAL_OF_THE_SWORD); //Spell doesn't teleport DoTeleportPlayer(pSacrificeTarget, 296.632f, -346.075f, 90.63f, 4.6f); me->SetUnitMovementFlags(MOVEMENTFLAG_CAN_FLY); DoTeleportTo(296.632f, -346.075f, 120.85f); Phase = SACRIFICING; if (pInstance) { pInstance->SetData64(DATA_SACRIFICED_PLAYER, pSacrificeTarget->GetGUID()); for (uint8 i = 0; i < 3; ++i) if (Creature* pSummon = me->SummonCreature(CREATURE_RITUAL_CHANNELER, RitualChannelerPos[i], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000)) pSummon->AI()->DoAction(0); } bSacrificed = true; } } else uiRitualOfSwordTimer -= diff; } DoMeleeAttackIfReady(); } else //SACRIFICING { if (uiSacrificeTimer <= diff) { Unit* pSacrificeTarget = pInstance ? Unit::GetUnit( *me, pInstance->GetData64( DATA_SACRIFICED_PLAYER)) : NULL; if (pInstance && !summons.empty() && pSacrificeTarget && pSacrificeTarget->isAlive()) me->Kill(pSacrificeTarget, false); // durability damage? //go down Phase = NORMAL; pSacrificeTarget = NULL; me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) me->GetMotionMaster()->MoveChase(pTarget); uiSacrificeTimer = 8 * IN_MILLISECONDS; } else uiSacrificeTimer -= diff; } }
void OozesMeetCheck() { if (summons.empty() || summons.size()==1) return; for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) { Creature* ooze = ObjectAccessor::GetCreatureOrPetOrVehicle((*me), (*itr)); if (!ooze || !ooze->isAlive()) continue; if (ooze->GetEntry() != CREATURE_LITTLE_OOZE && ooze->GetEntry() != CREATURE_OOZE_BIG) continue; bool little = (ooze->GetEntry() == CREATURE_LITTLE_OOZE); for(SummonList::const_iterator itr2 = summons.begin(); itr2 != summons.end(); ++itr2) { Creature* ooze2 = ObjectAccessor::GetCreatureOrPetOrVehicle((*me), (*itr2)); if (!ooze2 || !ooze2->isAlive()) continue; if (ooze2->GetEntry() != CREATURE_LITTLE_OOZE && ooze2->GetEntry() != CREATURE_OOZE_BIG) continue; if (ooze2 == ooze) continue; if (ooze->GetDistance2d(ooze2) > 5.0f) continue; bool little2 = (ooze2->GetEntry() == CREATURE_LITTLE_OOZE); //if first ooze is big ooze if (!little) { //and if second ooze is little if (little2) { ooze->CastSpell(ooze, SPELL_UNSTABLE_OOZE, false); if (ooze->GetAura(SPELL_UNSTABLE_OOZE) && ooze->GetAura(SPELL_UNSTABLE_OOZE)->GetStackAmount() >= 5) ooze->CastSpell(ooze2->getVictim(), SPELL_UNSTABLE_EXPLOSION, true); continue; } else //big ooze meet another big ooze, check wich one have more buff stack and despawn second one { uint8 stack1, stack2 = 0; if (Aura* aura = ooze->GetAura(SPELL_UNSTABLE_OOZE)) stack1 = aura->GetStackAmount(); if (Aura* aura = ooze2->GetAura(SPELL_UNSTABLE_OOZE)) stack2 = aura->GetStackAmount(); if (stack1 < stack2) { ooze2->CastSpell(ooze, SPELL_UNSTABLE_OOZE, false); ooze->ForcedDespawn(); if (ooze2->GetAura(SPELL_UNSTABLE_OOZE) && ooze2->GetAura(SPELL_UNSTABLE_OOZE)->GetStackAmount() >= 5) { ooze2->CastSpell(ooze2->getVictim(), SPELL_UNSTABLE_EXPLOSION, true); ooze2->ForcedDespawn(); } break; } else { ooze->CastSpell(ooze, SPELL_UNSTABLE_OOZE, false); ooze2->ForcedDespawn(); if (ooze->GetAura(SPELL_UNSTABLE_OOZE) && ooze->GetAura(SPELL_UNSTABLE_OOZE)->GetStackAmount() >= 5) { ooze->CastSpell(ooze2->getVictim(), SPELL_UNSTABLE_EXPLOSION, true); ooze->ForcedDespawn(); } continue; } } } else //if first ooze is little { if (little2) //and second ooze is little, despawn both and summon big ooze { DoSummon(CREATURE_OOZE_BIG, (*ooze)); ooze->ForcedDespawn(); ooze2->ForcedDespawn(); break; } else { ooze2->CastSpell(ooze, SPELL_UNSTABLE_OOZE, false); ooze->ForcedDespawn(); if (ooze2->GetAura(SPELL_UNSTABLE_OOZE) && ooze2->GetAura(SPELL_UNSTABLE_OOZE)->GetStackAmount() >= 5) { ooze2->CastSpell(ooze2->getVictim(), SPELL_UNSTABLE_EXPLOSION, true); ooze2->ForcedDespawn(); } break; } } } } }
void UpdateAI(const uint32 diff) { //Return since we have no target or we are casting if (!UpdateVictim() || me->HasUnitState(UNIT_STATE_CASTING)) return; if (resurrectInProgress) { if (uiResurrectTimer <= diff) { me->SetFullHealth(); switch (uiPhase) { case PHASE_UNDEAD: Talk(SAY_SKELETON); me->SetDisplayId(MODEL_SKELETON); break; case PHASE_SKELETON: Talk(SAY_GHOST); me->SetDisplayId(MODEL_GHOST); SetEquipmentSlots(false, EQUIP_UNEQUIP); me->GetMotionMaster()->MoveChase(me->getVictim()); break; } DoCast(me, SPELL_BLACK_KNIGHT_RES, true); uiPhase++; uiResurrectTimer = 4000; resurrectInProgress = false; me->ClearUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED); } else uiResurrectTimer -= diff; return; } switch (uiPhase) { case PHASE_UNDEAD: case PHASE_SKELETON: { if (uiIcyTouchTimer <= diff) { DoCastVictim(SPELL_ICY_TOUCH); uiIcyTouchTimer = urand(5000, 7000); } else uiIcyTouchTimer -= diff; if (uiPlagueStrikeTimer <= diff) { DoCastVictim(SPELL_PLAGUE_STRIKE); uiPlagueStrikeTimer = urand(12000, 15000); } else uiPlagueStrikeTimer -= diff; if (uiObliterateTimer <= diff) { DoCastVictim(SPELL_OBLITERATE); uiObliterateTimer = urand(17000, 19000); } else uiObliterateTimer -= diff; switch (uiPhase) { case PHASE_UNDEAD: { if (uiDeathRespiteTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { if (target && target->isAlive()) DoCast(target, SPELL_DEATH_RESPITE); } uiDeathRespiteTimer = urand(15000, 16000); } else uiDeathRespiteTimer -= diff; break; } case PHASE_SKELETON: { if (!bSummonArmy) { bSummonArmy = true; me->AddUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED); DoCast(me, SPELL_ARMY_DEAD); } if (!bDeathArmyDone) { if (uiDeathArmyCheckTimer <= diff) { me->GetMotionMaster()->MoveChase(me->getVictim()); uiDeathArmyCheckTimer = 0; bDeathArmyDone = true; } else uiDeathArmyCheckTimer -= diff; } if (uiDesecration <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { if (target && target->isAlive()) DoCast(target, SPELL_DESECRATION); } uiDesecration = urand(15000, 16000); } else uiDesecration -= diff; if (!summons.empty() && uiGhoulExplodeTimer <= diff) { DoCast(me, SPELL_GHOUL_EXPLODE); uiGhoulExplodeTimer = 8000; } else uiGhoulExplodeTimer -= diff; break; } break; } break; } case PHASE_GHOST: { if (uiDeathBiteTimer <= diff) { DoCastAOE(SPELL_DEATH_BITE); uiDeathBiteTimer = urand (8000, 12000); } else uiDeathBiteTimer -= diff; if (uiMarkedDeathTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { if (target && target->isAlive()) DoCast(target, SPELL_MARKED_DEATH); } uiMarkedDeathTimer = urand (5000, 7000); } else uiMarkedDeathTimer -= diff; break; } } if (!me->HasUnitState(UNIT_STATE_ROOT) && !me->HealthBelowPct(1)) 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 (!me->IsNonMeleeSpellCasted(false)) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(pTarget, DUNGEON_MODE(SPELL_STATIC_OVERLOAD,H_SPELL_STATIC_OVERLOAD)); uiStaticOverloadTimer = 11*IN_MILLISECONDS; } } else uiStaticOverloadTimer -= uiDiff; if (uiBallLightningTimer <= uiDiff) { if (!me->IsNonMeleeSpellCasted(false)) { if (Unit* pTemp = SelectTarget(SELECT_TARGET_RANDOM,1,100,true)) DoCast(pTemp, DUNGEON_MODE(SPELL_BALL_LIGHTNING,H_SPELL_BALL_LIGHTNING)); else DoCast(me->getVictim(), DUNGEON_MODE(SPELL_BALL_LIGHTNING,H_SPELL_BALL_LIGHTNING)); uiBallLightningTimer = 10*IN_MILLISECONDS; } } else uiBallLightningTimer -= uiDiff; // Health check if (me->HealthBelowPct(100 - 20 * uiHealthAmountModifier)) { ++uiHealthAmountModifier; DoScriptText(RAND(SAY_SPLIT_1, SAY_SPLIT_2), me); if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false); DoCast(me, SPELL_DISPERSE, false); } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { if (!instance) //Massive usage of instance, global check return; if (instance->GetData(DATA_REMOVE_NPC) == 1) { me->DespawnOrUnsummon(); instance->SetData(DATA_REMOVE_NPC, 0); } uint8 uiWaveCount = instance->GetData(DATA_WAVE_COUNT); if ((uiWaveCount == 6) || (uiWaveCount == 12)) //Don't spawn mobs on boss encounters return; switch (uiTypeOfMobsPortal) { // spawn elite mobs and then set portals visibility to make it look like it dissapeard case 0: if (!bPortalGuardianOrKeeperOrEliteSpawn) { if (uiSpawnTimer <= diff) { bPortalGuardianOrKeeperOrEliteSpawn = true; uint8 k = uiWaveCount < 12 ? 2 : 3; for (uint8 i = 0; i < k; ++i) { uint32 entry = RAND(CREATURE_AZURE_CAPTAIN, CREATURE_AZURE_RAIDER, CREATURE_AZURE_STALKER, CREATURE_AZURE_SORCEROR); DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN); } me->SetVisible(false); } else uiSpawnTimer -= diff; } else { // if all spawned elites have died kill portal if (listOfMobs.empty()) { me->Kill(me, false); me->RemoveCorpse(); } } break; // spawn portal guardian or portal keeper with regular mobs case 1: if (uiSpawnTimer <= diff) { if (bPortalGuardianOrKeeperOrEliteSpawn) { uint8 k = instance->GetData(DATA_WAVE_COUNT) < 12 ? 3 : 4; for (uint8 i = 0; i < k; ++i) { uint32 entry = RAND(CREATURE_AZURE_INVADER_1, CREATURE_AZURE_INVADER_2, CREATURE_AZURE_SPELLBREAKER_1, CREATURE_AZURE_SPELLBREAKER_2, CREATURE_AZURE_MAGE_SLAYER_1, CREATURE_AZURE_MAGE_SLAYER_2, CREATURE_AZURE_BINDER_1, CREATURE_AZURE_BINDER_2); DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN); } } else { bPortalGuardianOrKeeperOrEliteSpawn = true; uint32 entry = RAND(CREATURE_PORTAL_GUARDIAN, CREATURE_PORTAL_KEEPER); if (Creature* pPortalKeeper = DoSummon(entry, me, 2.0f, 0, TEMPSUMMON_DEAD_DESPAWN)) me->CastSpell(pPortalKeeper, SPELL_PORTAL_CHANNEL, false); } uiSpawnTimer = SPAWN_TIME; } else uiSpawnTimer -= diff; if (bPortalGuardianOrKeeperOrEliteSpawn && !me->IsNonMeleeSpellCasted(false)) { me->Kill(me, false); me->RemoveCorpse(); } break; } }
void UpdateAI(uint32 diff) { if (!me->isActiveObject()) return; UpdateVictim(); events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (uint32 evId = events.GetEvent()) { case 0: break; case EVENT_CHECK_PLAYER: if (Player* p = ObjectAccessor::GetPlayer(*me, playerGUID)) if (p->GetExactDist(me) <= 50.0f) { events.RepeatEvent(5000); break; } events.PopEvent(); me->setActive(false); EnterEvadeMode(); return; case EVENT_SUMMON_SOLDIERS: for (uint8 i=0; i<SUNWELL_DEFENDER_NUM; ++i) me->SummonCreature(NPC_SUNWELL_DEFENDER, SunwellDefenderPos[i], TEMPSUMMON_TIMED_DESPAWN, 33000+(i/5)*5000); events.PopEvent(); break; case EVENT_TALK_INTRO_0: case EVENT_TALK_INTRO_1: case EVENT_TALK_INTRO_2: case EVENT_TALK_INTRO_3: Talk(SAY_INTRO_0 + (evId-EVENT_TALK_INTRO_0)); events.PopEvent(); break; case EVENT_SALUTE: me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) if (Creature* c = ObjectAccessor::GetCreature(*me, *itr)) c->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); events.PopEvent(); break; case EVENT_SOLDIERS_RUN_AWAY: { uint8 count = 0; for (SummonList::iterator itr = summons.begin(); itr != summons.end();) { ++count; if (Creature* c = ObjectAccessor::GetCreature(*me, *itr)) { c->SetWalk(false); c->GetMotionMaster()->MovePoint(0, 11863.35f, -7073.44f, 27.40f); } SummonList::iterator itr2 = itr++; summons.erase(itr2); if (count >= 5) { if (!summons.empty()) { events.RepeatEvent(5000); return; } else { events.PopEvent(); return; } } } } events.PopEvent(); break; case EVENT_GO_FIGHTPOINT: me->SetWalk(true); me->GetMotionMaster()->MovePoint(0, 11779.30f, -7065.43f, 24.92f); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); events.PopEvent(); break; case EVENT_TALK_SPAWN_0: case EVENT_TALK_SPAWN_1: Talk(SAY_SPAWN_0 + (evId-EVENT_TALK_SPAWN_0)); events.PopEvent(); break; case EVENT_SUMMON_MORLEN: if (Creature* c = me->SummonCreature(NPC_MORLEN_COLDGRIP, 11766.70f, -7050.57f, 25.17f, 5.56f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000)) morlenGUID = c->GetGUID(); events.PopEvent(); break; case EVENT_TALK_MORLEN_0: case EVENT_TALK_MORLEN_1: if (Creature* c = ObjectAccessor::GetCreature(*me, morlenGUID)) c->AI()->Talk(SAY_MORLEN_0 + (evId-EVENT_TALK_MORLEN_0)); events.PopEvent(); break; case EVENT_SPAWN_WAVE_1: case EVENT_SPAWN_WAVE_2: case EVENT_SPAWN_WAVE_3: if (Creature* c = ObjectAccessor::GetCreature(*me, morlenGUID)) { c->AI()->Talk(SAY_MORLEN_1 + (evId-EVENT_SPAWN_WAVE_1)); switch (evId) { // emerge cast tr false 66947 case EVENT_SPAWN_WAVE_1: { Position spawnPos; c->GetPosition(&spawnPos); spawnPos.m_orientation = 5.80f; spawnPos.m_positionX += 5.0f*cos(4.5f); spawnPos.m_positionY += 5.0f*sin(4.5f); for (uint8 i=0; i<5; ++i) if (Creature* s = me->SummonCreature(NPC_SCOURGE_ZOMBIE, spawnPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) { spawnPos.m_positionX += 2.5f*cos(4.5f); spawnPos.m_positionY += 2.5f*sin(4.5f); } } break; case EVENT_SPAWN_WAVE_2: { Position spawnPos; c->GetPosition(&spawnPos); spawnPos.m_orientation = 5.80f; spawnPos.m_positionX += 7.0f*cos(4.0f); spawnPos.m_positionY += 7.0f*sin(4.0f); for (uint8 i=0; i<3; ++i) if (Creature* s = me->SummonCreature(NPC_GHOUL_INVADER, spawnPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) { s->CastSpell(s, 66947, false); // emerge effect spawnPos.m_positionX += 4.0f*cos(4.5f); spawnPos.m_positionY += 4.0f*sin(4.5f); } } break; case EVENT_SPAWN_WAVE_3: { Position spawnPos; c->GetPosition(&spawnPos); spawnPos.m_orientation = 5.80f; spawnPos.m_positionX += 8.0f*cos(4.0f); spawnPos.m_positionY += 8.0f*sin(4.0f); for (uint8 i=0; i<3; ++i) if (Creature* s = me->SummonCreature(NPC_CRYPT_RAIDER, spawnPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) { s->CastSpell(s, 66947, false); // emerge effect spawnPos.m_positionX += 4.0f*cos(4.5f); spawnPos.m_positionY += 4.0f*sin(4.5f); } } break; } } events.PopEvent(); events.ScheduleEvent(EVENT_SUMMONS_ATTACK, 3000); break; case EVENT_SUMMONS_ATTACK: for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) if (Creature* c = ObjectAccessor::GetCreature(*me, *itr)) { if (c->GetEntry() == NPC_MORLEN_COLDGRIP && summons.size() != 1) continue; else c->AI()->Talk(SAY_MORLEN_4); c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); c->AI()->AttackStart(me); } events.PopEvent(); break; case EVENT_OUTRO_0: case EVENT_OUTRO_1: case EVENT_OUTRO_2: case EVENT_OUTRO_3: Talk(SAY_OUTRO_0 + (evId-EVENT_OUTRO_0)); events.PopEvent(); if (evId == EVENT_OUTRO_3) events.ScheduleEvent(EVENT_OUTRO_KNEEL, 6000); break; case EVENT_OUTRO_KNEEL: if (Player* p = ObjectAccessor::GetPlayer(*me, playerGUID)) p->KilledMonsterCredit(NPC_THALORIEN_KILL_CREDIT, 0); me->SetStandState(UNIT_STAND_STATE_KNEEL); events.PopEvent(); events.ScheduleEvent(EVENT_DISAPPEAR, 6000); break; case EVENT_DISAPPEAR: events.PopEvent(); me->SetVisible(false); me->setActive(false); EnterEvadeMode(); break; case EVENT_SET_FACING: me->SetFacingTo(2.45f); events.PopEvent(); break; case EVENT_SPELL_BLADESTORM: if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) me->CastSpell(me->GetVictim(), 67541, false); events.RepeatEvent(urand(25000, 35000)); break; case EVENT_SPELL_MORTAL_STRIKE: if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) me->CastSpell(me->GetVictim(), 67542, false); events.RepeatEvent(urand(7000, 12000)); break; case EVENT_SPELL_HEROIC_STRIKE: if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) me->CastSpell(me->GetVictim(), 57846, false); events.RepeatEvent(urand(5000, 10000)); break; } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { if (!pInstance) return; events.Update(diff); switch(events.GetEvent()) { case 0: break; case EVENT_SUMMON_KEEPER_OR_GUARDIAN: bKorG = true; spawned = true; if (Creature *c = DoSummon(RAND(NPC_PORTAL_GUARDIAN, NPC_PORTAL_KEEPER), me, 2.0f, 0, TEMPSUMMON_DEAD_DESPAWN)) me->CastSpell(c, SPELL_PORTAL_CHANNEL, false); events.PopEvent(); events.RescheduleEvent(EVENT_SUMMON_KEEPER_TRASH, 20000); break; case EVENT_SUMMON_KEEPER_TRASH: for (uint8 i=0; i<3+addValue; ++i) { uint32 entry = RAND(NPC_AZURE_INVADER_1, NPC_AZURE_INVADER_2, NPC_AZURE_SPELLBREAKER_1, NPC_AZURE_SPELLBREAKER_2, NPC_AZURE_MAGE_SLAYER_1, NPC_AZURE_MAGE_SLAYER_2, NPC_AZURE_BINDER_1, NPC_AZURE_BINDER_2); DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN); } events.RepeatEvent(20000); break; case EVENT_SUMMON_ELITES: spawned = true; for (uint8 i=0; i<2+addValue; ++i) { uint32 entry = RAND(NPC_AZURE_CAPTAIN, NPC_AZURE_RAIDER, NPC_AZURE_STALKER, NPC_AZURE_SORCEROR); DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN); } me->SetVisible(false); events.PopEvent(); break; case EVENT_SUMMON_SABOTEOUR: DoSummon(NPC_SABOTEOUR, me, 2.0f, 0, TEMPSUMMON_CORPSE_DESPAWN); me->DespawnOrUnsummon(3000); events.PopEvent(); break; } if (!spawned) return; if (bKorG) { if (!me->IsNonMeleeSpellCast(false)) // keeper/guardian died => channeled spell interrupted { // if keeper/guard lost all victims, in enterevademode linking aura is removed, restore it: if (pInstance) for (SummonList::iterator itr = listOfMobs.begin(); itr != listOfMobs.end(); ++itr) if (Creature* c = pInstance->instance->GetCreature(*itr)) if (c->IsAlive() && (c->GetEntry() == NPC_PORTAL_GUARDIAN || c->GetEntry() == NPC_PORTAL_KEEPER)) { me->CastSpell(c, SPELL_PORTAL_CHANNEL, false); return; } Unit::Kill(me, me, false); } } else { if (listOfMobs.empty()) Unit::Kill(me, me, false); } }
void UpdateAI(const uint32 diff) { if (Phase == NORMAL) { //Return since we have no target if (!UpdateVictim()) return; if (uiSinsterStrikeTimer <= diff) { DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_SINSTER_STRIKE, H_SPELL_SINSTER_STRIKE)); uiSinsterStrikeTimer = urand(5000,9000); } else uiSinsterStrikeTimer -= diff; if (uiCallFlamesTimer <= diff) { if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { DoCast(pTarget, SPELL_CALL_FLAMES); uiCallFlamesTimer = urand(8000,12000); } } else uiCallFlamesTimer -= diff; if (!bSacrificed) if (uiRitualOfSwordTimer <= diff) { pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (pSacrificeTarget) { DoScriptText(RAND(SAY_SACRIFICE_PLAYER_1,SAY_SACRIFICE_PLAYER_2,SAY_SACRIFICE_PLAYER_3,SAY_SACRIFICE_PLAYER_4,SAY_SACRIFICE_PLAYER_5),m_creature); DoCast(pSacrificeTarget, SPELL_RITUAL_OF_THE_SWORD); //Spell doesn't teleport DoTeleportPlayer(pSacrificeTarget, 296.632, -346.075, 90.63, 4.6); m_creature->SetUnitMovementFlags(MOVEMENTFLAG_FLY_MODE); DoTeleportTo(296.632, -346.075, 120.85); Phase = SACRIFICING; for (uint8 i = 0; i < 3; ++i) if (Creature* pRitualChanneler = m_creature->SummonCreature(CREATURE_RITUAL_CHANNELER, RitualChannelerPos[i], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000)) if (pRitualChanneler->AI()) pRitualChanneler->AI()->SetGUID(pSacrificeTarget->GetGUID()); bSacrificed = true; } } else uiRitualOfSwordTimer -= diff; DoMeleeAttackIfReady(); } else //SACRIFICING { if (uiSacrificeTimer <= diff) { if (!summons.empty() && pSacrificeTarget && pSacrificeTarget->isAlive()) m_creature->Kill(pSacrificeTarget, false); // durability damage? //go down Phase = NORMAL; pSacrificeTarget = NULL; m_creature->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE); if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) m_creature->GetMotionMaster()->MoveChase(pTarget); uiSacrificeTimer = 8000; } else uiSacrificeTimer -= diff; } }