示例#1
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
        {
            if (events.IsInPhase(PHASE_FLIGHT) && !me->IsInEvadeMode())
                EnterEvadeMode();
            return;
        }

        if (me->IsNonMeleeSpellCast(false))
            return;

        events.Update(diff);

        switch (events.ExecuteEvent())
        {
            case EVENT_BERSERK:
                if (!me->HasAura(SPELL_BERSERK))
                {
                    DoScriptText(YELL_BERSERK, me);
                    DoCast(me, SPELL_BERSERK, true);
                }
                events.ScheduleEvent(EVENT_BERSERK, 10000);
                break;
            case EVENT_CLEAVE:
                DoCastVictim( SPELL_CLEAVE, false);
                events.ScheduleEvent(EVENT_CLEAVE, urand(5000, 10000), 0, PHASE_GROUND);
                break;
            case EVENT_CORROSION:
                DoCastVictim( SPELL_CORROSION, false);
                events.ScheduleEvent(EVENT_CORROSION, urand(20000, 30000), 0, PHASE_GROUND);
                break;
            case EVENT_GAS_NOVA:
                DoCast(me, SPELL_GAS_NOVA, false);
                events.ScheduleEvent(EVENT_GAS_NOVA, urand(21000, 26000), 0, PHASE_GROUND);
                break;
            case EVENT_ENCAPSULATE:
                if (Unit* encapsTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true))
                    DoCast(encapsTarget, SPELL_ENCAPSULATE_CHANNEL, false);

                if (Unit* tank = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 150.0f, true))
                    me->SetTarget(tank->GetGUID());

                events.ScheduleEvent(EVENT_ENCAPSULATE, 33000, 0, PHASE_GROUND);
                break;
            case EVENT_DEMONIC_VAPOR:
                DoCast(me, SPELL_VAPOR_SELECT, true);

                demonicCount++;

                if (demonicCount < 2)
                    events.ScheduleEvent(EVENT_DEMONIC_VAPOR, 11000, 0, PHASE_FLIGHT);
                else
                    events.CancelEvent(EVENT_DEMONIC_VAPOR);

                break;
            case EVENT_FLIGHT:
                EnterPhase(PHASE_FLIGHT);
                break;
            case EVENT_FOG_CORRUPTION:
                if (!fogactivated)
                {
                    events.CancelEvent(EVENT_FOG_CORRUPTION);
                    break;
                }

                if (pInstance)
                {
                    switch (chosenLane)
                    {
                        case 0:
                            pInstance->SetData((direction ? DATA_ACTIVATE_SOUTH_TO_LEFT : DATA_ACTIVATE_SOUTH_TO_RIGHT), (uint32) me->GetPositionY());
                            break;
                        case 1:
                            pInstance->SetData((direction ? DATA_ACTIVATE_CENTER_TO_LEFT : DATA_ACTIVATE_CENTER_TO_RIGHT), (uint32) me->GetPositionY());
                            break;
                        case 2:
                            pInstance->SetData((direction ? DATA_ACTIVATE_NORTH_TO_LEFT : DATA_ACTIVATE_NORTH_TO_RIGHT), (uint32) me->GetPositionY());
                            break;
                    }
                }
                events.ScheduleEvent(EVENT_FOG_CORRUPTION, 50, 0, PHASE_FLIGHT);
                break;
            default:
                if (events.IsInPhase(PHASE_GROUND))
                    DoMeleeAttackIfReady();
                else if (events.IsInPhase(PHASE_FLIGHT))
                {
                    if (uiFlightTimer)
                    {
                        if (uiFlightTimer <= diff)
                        {
                            uiFlightTimer = 0;
                            HandleFlightSequence();
                        }
                        else
                            uiFlightTimer -= diff;
                    }
                }
                break;
        }
    }
示例#2
0
 void MoveInLineOfSight(Unit* who)
 {
     if (events.IsInPhase(PHASE_GROUND))
         ScriptedAI::MoveInLineOfSight(who);
 }
示例#3
0
 void DamageTaken(Unit* /*pDone_by*/, uint32& damage)
 {
     if (!events.IsInPhase(PHASE_GROUND) && damage >= me->GetHealth())
         damage = 0;
 }
示例#4
0
 void AttackStart(Unit* who)
 {
     if (events.IsInPhase(PHASE_GROUND))
         ScriptedAI::AttackStart(who);
 }
		void UpdateAI(uint32 diff)
		{
			if(!UpdateVictim())
				return;

			events.Update(diff);

			if (me->HasUnitState(UNIT_STATE_CASTING))
				return;

			while(uint32 eventId = events.ExecuteEvent())
			{
				switch(eventId)
				{
					if (instance)
					{
						case EVENT_STATIC_FIELD:
							if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
								if(target->GetTypeId() == TYPEID_PLAYER)
								{
									DoCast(target, SPELL_STATIC_FIELD);
								}
								
							events.ScheduleEvent(EVENT_STATIC_FIELD, 8*IN_MILLISECONDS, 0, PHASE_1);
							break;
							
						case EVENT_LIGHTNING_BREATH:
							DoCast(me, SPELL_LIGHTNING_BREATH);
							
							events.ScheduleEvent(EVENT_LIGHTNING_BREATH, 8*IN_MILLISECONDS, 0, PHASE_2);
							break;
							
						case EVENT_MAGNETIC_SHROUD:
							DoCast(me, SPELL_MAGNETIC_SHROUD);
							
							events.ScheduleEvent(EVENT_MAGNETIC_SHROUD, 12*IN_MILLISECONDS, 0, PHASE_2);
							break;

						case EVENT_MOVE:
							me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
							events.CancelEvent(EVENT_MOVE);
							break;

						default:
							break;
					}
				}
			}
			
			if (Creature* gu = me->GetCreature(*me, instance->GetData64(DATA_BOSS_GU_CLOUDSTRIKE)))
				if(gu->HealthBelowPct(50) && !events.IsInPhase(PHASE_2))
				{
					me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
					me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
					me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
					events.ScheduleEvent(EVENT_MOVE, 3*IN_MILLISECONDS, 0, PHASE_2);
					events.ScheduleEvent(EVENT_LIGHTNING_BREATH, 5*IN_MILLISECONDS, 0, PHASE_2);
					events.ScheduleEvent(EVENT_MAGNETIC_SHROUD, 9*IN_MILLISECONDS, 0, PHASE_2);
					events.SetPhase(PHASE_2);
				}

			DoMeleeAttackIfReady();
		}
		void UpdateAI(uint32 diff)
		{
			if(!UpdateVictim())
				return;

			events.Update(diff);

			if (me->HasUnitState(UNIT_STATE_CASTING))
				return;

			while(uint32 eventId = events.ExecuteEvent())
			{
				switch(eventId)
				{
					if (instance)
					{
						case EVENT_INTRO_1:
							Talk(SAY_INTRO_1);
							events.CancelEvent(EVENT_INTRO_1);
							break;

						case EVENT_INTRO_2:
							Talk(SAY_INTRO_2);
							events.CancelEvent(EVENT_INTRO_2);
							break;

						case EVENT_AGGRO_PART_1:
							Talk(SAY_ENTERCOMBAT_1);
							events.CancelEvent(EVENT_AGGRO_PART_1);
							break;
						
						case EVENT_AGGRO_PART_2:
							Talk(SAY_ENTERCOMBAT_2);
							events.CancelEvent(EVENT_AGGRO_PART_2);
							break;
						
						case EVENT_AGGRO_PART_3:
							if (Creature* serpent = me->GetCreature(*me, instance->GetData64(DATA_NPC_AZURE_SERPENT)))
								if (serpent->AI())
										serpent->AI()->DoAction(ACTION_VISIBLE);

							events.SetPhase(PHASE_1);
							events.ScheduleEvent(EVENT_INVOKE_LIGHTNING, 2*IN_MILLISECONDS, 0, PHASE_1);
							events.CancelEvent(EVENT_AGGRO_PART_3);
							break;
						
						case EVENT_INVOKE_LIGHTNING:
							if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
								if(target->GetTypeId() == TYPEID_PLAYER)
								{
									DoCast(target, SPELL_INVOKE_LIGHTNING);
								}
							events.ScheduleEvent(EVENT_INVOKE_LIGHTNING, 16*IN_MILLISECONDS, 0, PHASE_1);
							break;
							
						case EVENT_PHASE_2:
							DoCast(me, SPELL_CHARGING_SOUL);
							events.CancelEvent(EVENT_PHASE_2);							
							break;
						
						case EVENT_OVERCHARGED_SOUL:
							DoCast(me, SPELL_OVERCHARGED_SOUL);
							events.CancelEvent(EVENT_OVERCHARGED_SOUL);	
							break;
						
						case EVENT_LIGHTNING_PURGE:
							DoCast(me, SPELL_LIGHTNING_PURGE);	
							events.CancelEvent(EVENT_LIGHTNING_PURGE);	
							break;

						case EVENT_PHASE_3:
							Talk(SAY_PHASE_3);
							events.CancelEvent(EVENT_PHASE_3);	
							break;

						default:
							break;
					}
				}
			}
			
			if(me->HealthBelowPct(50) && !events.IsInPhase(PHASE_2) && !events.IsInPhase(PHASE_3))
			{
				events.ScheduleEvent(EVENT_PHASE_2, 1*IN_MILLISECONDS, 0, PHASE_2);
				events.SetPhase(PHASE_2);
			}
			
			if (Creature* serpent = me->GetCreature(*me, instance->GetData64(DATA_NPC_AZURE_SERPENT)))
			{
				if(serpent->HealthBelowPct(55) && !checkSaySerpentLife)
				{
					Talk(SAY_HALF_LIFE_SERPENT);
					checkSaySerpentLife = true;
				}
		
				if(!checkAzureSerpentAlive)
				{
					Talk(SAY_SERPENT_DEATH);
					if(Aura* aura = me->GetAura(SPELL_CHARGING_SOUL))
						me->RemoveAura(aura);
					events.SetPhase(PHASE_3);
					events.ScheduleEvent(EVENT_PHASE_3, 2*IN_MILLISECONDS, 0, PHASE_3);
					events.ScheduleEvent(EVENT_INVOKE_LIGHTNING, 3*IN_MILLISECONDS, 0, PHASE_3);
					events.ScheduleEvent(EVENT_OVERCHARGED_SOUL, 25*IN_MILLISECONDS, 0, PHASE_3);
					events.ScheduleEvent(EVENT_LIGHTNING_PURGE, 60*IN_MILLISECONDS, 0, PHASE_3);
				}
			}

			DoMeleeAttackIfReady();
		}
		void UpdateAI(const uint32 diff) 
		{
			if(!UpdateVictim())
				return;

			if (me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_WASH_AWAY))
				return;

			events.Update(diff);

			/*Map* map = me->GetMap();
			if (map && map->IsDungeon())
			{
				Map::PlayerList const &PlayerList = map->GetPlayers();

				if (!PlayerList.isEmpty())
					for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
					{
						if (i->getSource()->isAlive() && i->getSource()->IsInWater() && !i->getSource()->HasAura(SPELL_CORRUPTED_WATERS))
							i->getSource()->CastSpell(i->getSource(), SPELL_CORRUPTED_WATERS);

						if (i->getSource()->isAlive() && !i->getSource()->IsInWater() && i->getSource()->HasAura(SPELL_CORRUPTED_WATERS))
							i->getSource()->RemoveAurasDueToSpell(SPELL_CORRUPTED_WATERS);
					}
			}*/

			if (instance)
			{
				if (washAway)
					if (Creature* washAwayTrigger = me->FindNearestCreature(NPC_WASH_AWAY_TRIGGER, 500, true))
					{
						me->CastSpell(washAwayTrigger, SPELL_TRACK_ROTATE);
						me->SetFacingToObject(washAwayTrigger);
					}

				if (hydrolanceWaterCount == 5 && corruptWaterCount == 0) // First corrupt living water
				{
					events.ScheduleEvent(EVENT_CALL_SECOND_WATER, 2*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
					hydrolanceWaterCount = 0;
				}
						
				if (hydrolanceWaterCount == 5 && corruptWaterCount == 1) // Second corrupt living water
				{
					events.ScheduleEvent(EVENT_CALL_THIRD_WATER, 2*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
					hydrolanceWaterCount = 0;
				}

				if (hydrolanceWaterCount == 5 && corruptWaterCount == 2) // Third corrupt living water
				{
					events.ScheduleEvent(EVENT_CALL_FOURTH_WATER, 2*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
					hydrolanceWaterCount = 0;
				}

				if (hydrolanceWaterCount == 5 && corruptWaterCount == 3) // Fourth corrupt living water
				{
					events.SetPhase(PHASE_WASH_AWAY);
					events.ScheduleEvent(EVENT_BUBBLE_BURST, 3*IN_MILLISECONDS, 0, PHASE_WASH_AWAY);
					hydrolanceWaterCount = 0;
				}

				while (uint32 eventId = events.ExecuteEvent())
				{
					switch (eventId)
					{
						if (instance)
						{
							case EVENT_CALL_FIRST_WATER:
								me->InterruptSpell(CURRENT_GENERIC_SPELL);
								if (Creature* firstTrigger = me->FindNearestCreature(NPC_FIRST_TRIGGER_WATER, 500, true))
									me->CastSpell(firstTrigger, SPELL_CALL_WATER);

								Talk(SAY_CALL_FIRST_WATER);

								events.ScheduleEvent(EVENT_FIRST_TRIGGER_WATER_AURA, 0);
								events.CancelEvent(EVENT_CALL_FIRST_WATER);
								break;
									
							case EVENT_FIRST_TRIGGER_WATER_AURA:
								if (Creature* firstTrigger = me->FindNearestCreature(NPC_FIRST_TRIGGER_WATER, 500, true))
									firstTrigger->CastSpell(firstTrigger, SPELL_HYDROLANCE_PRECAST);
									
								events.ScheduleEvent(EVENT_FIRST_TRIGGER_WATER_AURA, 1*IN_MILLISECONDS);
								break;

							case EVENT_CALL_SECOND_WATER:
								me->InterruptSpell(CURRENT_GENERIC_SPELL);
								if (Creature* secondTrigger = me->FindNearestCreature(NPC_SECOND_TRIGGER_WATER, 500, true))
									me->CastSpell(secondTrigger, SPELL_CALL_WATER);

								Talk(SAY_CALL_SECOND_WATER);
								corruptWaterCount = 1;

								events.ScheduleEvent(EVENT_SECOND_TRIGGER_WATER_AURA, 0);
								events.CancelEvent(EVENT_CALL_SECOND_WATER);
								break;

							case EVENT_SECOND_TRIGGER_WATER_AURA:
								if (Creature* secondTrigger = me->FindNearestCreature(NPC_SECOND_TRIGGER_WATER, 500, true))
									secondTrigger->CastSpell(secondTrigger, SPELL_HYDROLANCE_PRECAST);

								events.ScheduleEvent(EVENT_SECOND_TRIGGER_WATER_AURA, 1*IN_MILLISECONDS);
								break;

							case EVENT_CALL_THIRD_WATER:
								me->InterruptSpell(CURRENT_GENERIC_SPELL);
								if (Creature* thirdTrigger = me->FindNearestCreature(NPC_THIRD_TRIGGER_WATER, 500, true))
									me->CastSpell(thirdTrigger, SPELL_CALL_WATER);

								Talk(SAY_CALL_THIRD_WATER);
								corruptWaterCount = 2;

								events.ScheduleEvent(EVENT_THIRD_TRIGGER_WATER_AURA, 0);
								events.CancelEvent(EVENT_CALL_THIRD_WATER);
								break;

							case EVENT_THIRD_TRIGGER_WATER_AURA:
								if (Creature* thirdTrigger = me->FindNearestCreature(NPC_THIRD_TRIGGER_WATER, 500, true))
									thirdTrigger->CastSpell(thirdTrigger, SPELL_HYDROLANCE_PRECAST);
								
								events.ScheduleEvent(EVENT_THIRD_TRIGGER_WATER_AURA, 4*IN_MILLISECONDS);
								break;

							case EVENT_CALL_FOURTH_WATER:
								me->InterruptSpell(CURRENT_GENERIC_SPELL);
								if (Creature* fourthTrigger = me->FindNearestCreature(NPC_FOURTH_TRIGGER_WATER, 500, true))
									me->CastSpell(fourthTrigger, SPELL_CALL_WATER);

								Talk(SAY_CALL_FOURTH_WATER);
								corruptWaterCount = 3;

								events.ScheduleEvent(EVENT_FOURTH_TRIGGER_WATER_AURA, 0);
								events.CancelEvent(EVENT_CALL_FOURTH_WATER);
								break;
	
							case EVENT_FOURTH_TRIGGER_WATER_AURA:
								if (Creature* fourthTrigger = me->FindNearestCreature(NPC_FOURTH_TRIGGER_WATER, 500, true))
									fourthTrigger->CastSpell(fourthTrigger, SPELL_HYDROLANCE_PRECAST);

								events.ScheduleEvent(EVENT_FOURTH_TRIGGER_WATER_AURA, 1*IN_MILLISECONDS);
								break;

							case EVENT_HYDROLANCE:
							{
								if (hydrolanceCount == 0) // Front
								{
									me->SetFacingTo(1.250952f);

									std::list<Creature*> hydrolanceTriggers;
						            me->GetCreatureListWithEntryInGrid(hydrolanceTriggers, NPC_HYDROLANCE_TRIGGER_FRONT, 99999.0f);
							        if (!hydrolanceTriggers.empty())
								    {
									    for (std::list<Creature*>::iterator itr = hydrolanceTriggers.begin(); itr != hydrolanceTriggers.end(); ++itr)
										{
											if ((*itr)->isAlive())
												me->CastSpell((*itr), SPELL_HYDROLANCE_PRECAST);
										}
									}

									events.ScheduleEvent(EVENT_HYDROTRIGGER_ONE_FRONT, 1*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
									events.ScheduleEvent(EVENT_HYDROTRIGGER_TWO_FRONT, 1500, 0, PHASE_CORRUPT_LIVING_WATERS);
									events.ScheduleEvent(EVENT_HYDROLANCE_FRONT, 2*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
									DoCast(SPELL_HYDROLANCE);
								}

								if (hydrolanceCount == 1) // Left
								{
									me->SetFacingTo(5.240993f);
									
									std::list<Creature*> hydrolanceTriggers;
						            me->GetCreatureListWithEntryInGrid(hydrolanceTriggers, NPC_HYDROLANCE_TRIGGER_LEFT, 99999.0f);
							        if (!hydrolanceTriggers.empty())
								    {
									    for (std::list<Creature*>::iterator itr = hydrolanceTriggers.begin(); itr != hydrolanceTriggers.end(); ++itr)
										{
											if ((*itr)->isAlive())
												me->CastSpell((*itr), SPELL_HYDROLANCE_PRECAST);
										}
									}

									events.ScheduleEvent(EVENT_HYDROTRIGGER_ONE_LEFT, 1*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
									events.ScheduleEvent(EVENT_HYDROTRIGGER_TWO_LEFT, 1500, 0, PHASE_CORRUPT_LIVING_WATERS);
									events.ScheduleEvent(EVENT_HYDROLANCE_LEFT, 2*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
									DoCast(SPELL_HYDROLANCE);
								}

								if (hydrolanceCount == 2) // Right
								{
									me->SetFacingTo(3.504827f);
									
									std::list<Creature*> hydrolanceTriggers;
						            me->GetCreatureListWithEntryInGrid(hydrolanceTriggers, NPC_HYDROLANCE_TRIGGER_RIGHT, 99999.0f);
							        if (!hydrolanceTriggers.empty())
								    {
									    for (std::list<Creature*>::iterator itr = hydrolanceTriggers.begin(); itr != hydrolanceTriggers.end(); ++itr)
										{
											if ((*itr)->isAlive())
												me->CastSpell((*itr), SPELL_HYDROLANCE_PRECAST);
										}
									}

									events.ScheduleEvent(EVENT_HYDROTRIGGER_ONE_RIGHT, 1*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
									events.ScheduleEvent(EVENT_HYDROTRIGGER_TWO_RIGHT, 1500, 0, PHASE_CORRUPT_LIVING_WATERS);
									events.ScheduleEvent(EVENT_HYDROLANCE_RIGHT, 2*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
									DoCast(SPELL_HYDROLANCE);
								}

								hydrolanceWaterCount++;
								events.ScheduleEvent(EVENT_HYDROLANCE, 4*IN_MILLISECONDS, 0, PHASE_CORRUPT_LIVING_WATERS);
								break;
							}

							case EVENT_HYDROTRIGGER_ONE_FRONT:
								if (Creature* hydroTriggerOneFront = me->FindNearestCreature(NPC_HYDROTRIGGER_ONE_FRONT, 500, true))
									hydroTriggerOneFront->CastSpell(hydroTriggerOneFront, SPELL_HYDROLANCE_PULSE_SMALL);

								events.CancelEvent(EVENT_HYDROTRIGGER_ONE_FRONT);
								break;

							case EVENT_HYDROTRIGGER_TWO_FRONT:
								if (Creature* hydroTriggerTwoFront = me->FindNearestCreature(NPC_HYDROTRIGGER_TWO_FRONT, 500, true))
									hydroTriggerTwoFront->CastSpell(hydroTriggerTwoFront, SPELL_HYDROLANCE_PULSE_SMALL);

								events.CancelEvent(EVENT_HYDROTRIGGER_TWO_FRONT);
								break;

							case EVENT_HYDROTRIGGER_ONE_LEFT:
								if (Creature* hydroTriggerOneLeft = me->FindNearestCreature(NPC_HYDROTRIGGER_ONE_LEFT, 500, true))
									hydroTriggerOneLeft->CastSpell(hydroTriggerOneLeft, SPELL_HYDROLANCE_PULSE_SMALL);

								events.CancelEvent(EVENT_HYDROTRIGGER_ONE_LEFT);
								break;
								
							case EVENT_HYDROTRIGGER_TWO_LEFT:
								if (Creature* hydroTriggerTwoLeft = me->FindNearestCreature(NPC_HYDROTRIGGER_TWO_LEFT, 500, true))
									hydroTriggerTwoLeft->CastSpell(hydroTriggerTwoLeft, SPELL_HYDROLANCE_PULSE_SMALL);

								events.CancelEvent(EVENT_HYDROTRIGGER_TWO_LEFT);
								break;

							case EVENT_HYDROTRIGGER_ONE_RIGHT:
								if (Creature* hydroTriggerOneRight = me->FindNearestCreature(NPC_HYDROTRIGGER_ONE_RIGHT, 500, true))
									hydroTriggerOneRight->CastSpell(hydroTriggerOneRight, SPELL_HYDROLANCE_PULSE_SMALL);

								events.CancelEvent(EVENT_HYDROTRIGGER_ONE_RIGHT);
								break;

							case EVENT_HYDROTRIGGER_TWO_RIGHT:
								if (Creature* hydroTriggerTwoRight = me->FindNearestCreature(NPC_HYDROTRIGGER_TWO_RIGHT, 500, true))
									hydroTriggerTwoRight->CastSpell(hydroTriggerTwoRight, SPELL_HYDROLANCE_PULSE_SMALL);

								events.CancelEvent(EVENT_HYDROTRIGGER_TWO_RIGHT);
								break;

							case EVENT_HYDROLANCE_FRONT:
							{
								std::list<Creature*> hydrolanceTriggers;
								me->GetCreatureListWithEntryInGrid(hydrolanceTriggers, NPC_HYDROLANCE_TRIGGER_FRONT, 99999.0f);
								if (!hydrolanceTriggers.empty())
								{
									for (std::list<Creature*>::iterator itr = hydrolanceTriggers.begin(); itr != hydrolanceTriggers.end(); ++itr)
									{
										if ((*itr)->isAlive())
											(*itr)->CastSpell((*itr), SPELL_HYDROLANCE_PULSE_BIG);
									}
								}

								hydrolanceCount = 1; // Next => left
								events.CancelEvent(EVENT_HYDROLANCE_FRONT);
								break;
							}

							case EVENT_HYDROLANCE_LEFT:
							{
								std::list<Creature*> hydrolanceTriggers;
								me->GetCreatureListWithEntryInGrid(hydrolanceTriggers, NPC_HYDROLANCE_TRIGGER_LEFT, 99999.0f);
								if (!hydrolanceTriggers.empty())
								{
									for (std::list<Creature*>::iterator itr = hydrolanceTriggers.begin(); itr != hydrolanceTriggers.end(); ++itr)
									{
										if ((*itr)->isAlive())
											(*itr)->CastSpell((*itr), SPELL_HYDROLANCE_PULSE_BIG);
									}
								}
							
								hydrolanceCount = 2; // Next => right
								events.CancelEvent(EVENT_HYDROLANCE_LEFT);
								break;
							}

							case EVENT_HYDROLANCE_RIGHT:
							{
								std::list<Creature*> hydrolanceTriggers;
								me->GetCreatureListWithEntryInGrid(hydrolanceTriggers, NPC_HYDROLANCE_TRIGGER_RIGHT, 99999.0f);
								if (!hydrolanceTriggers.empty())
								{
									for (std::list<Creature*>::iterator itr = hydrolanceTriggers.begin(); itr != hydrolanceTriggers.end(); ++itr)
									{
										if ((*itr)->isAlive())
											(*itr)->CastSpell((*itr), SPELL_HYDROLANCE_PULSE_BIG);
									}
								}

								hydrolanceCount = 0; // Next => front
								events.CancelEvent(EVENT_HYDROLANCE_RIGHT);
								break;
							}

							case EVENT_BUBBLE_BURST:
								DoCast(SPELL_BUBBLE_BURST);
								Talk(SAY_PHASE_WASH_AWAY);

								events.ScheduleEvent(EVENT_WASH_AWAY, 4*IN_MILLISECONDS, 0, PHASE_WASH_AWAY);
								events.CancelEvent(EVENT_BUBBLE_BURST);
								break;
	
							case EVENT_WASH_AWAY:
								me->RemoveAurasDueToSpell(SPELL_WATER_BUBBLE, me->GetGUID());
								me->CastSpell(me, SPELL_WASH_AWAY_VISUAL, true);
								DoCast(SPELL_WASH_AWAY);
								
								events.ScheduleEvent(EVENT_SAY_TAUNT, 18*IN_MILLISECONDS, 0, PHASE_WASH_AWAY);
								washAway = true;

								events.CancelEvent(EVENT_WASH_AWAY);
								break;

							case EVENT_SAY_TAUNT:
								Talk(irand(SAY_TAUNT_1, SAY_TAUNT_3));

								events.ScheduleEvent(EVENT_SAY_TAUNT, 18*IN_MILLISECONDS, 0, PHASE_WASH_AWAY);
								break;
						}

						default:
								break;
					}
				}
			}
		}
		void UpdateAI(uint32 diff)
		{
			events.Update(diff);

			if (!emote)
			{
				me->HandleEmoteCommand(EMOTE_STATE_READY_UNARMED);
				emote = true;
			}

			if (Creature* trigger = me->FindNearestCreature(NPC_LOREWALKER_TRIGGER, 0.1f, true))
				if (!events.IsInPhase(PHASE_BOSSES))
				{
					me->Relocate(824.674438f, -2453.281738f, 176.302979f, 5.957958f);
					me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
					me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
					me->HandleEmoteCommand(EMOTE_ONESHOT_NONE);
					me->SetFacingTo(5.957958f);
					events.CancelEvent(EVENT_SPINNING_CRANE_KICK);
					events.CancelEvent(EVENT_SAY_INTRO_2_3_4_5);
					events.SetPhase(PHASE_BOSSES);
				}

			if (me->FindNearestCreature(NPC_STRIFE, 99999.0f, false) && me->FindNearestCreature(NPC_PERIL, 99999.0f, false) && !end)
			{
				events.ScheduleEvent(EVENT_SAY_END_1, 0, 0, PHASE_BOSSES);
				end = true;
			}

			if (me->FindNearestCreature(NPC_LOREWALKER_TRIGGER, 99999.0f, false) && events.IsInPhase(PHASE_ATTACK_SCROLL))
				events.SetPhase(PHASE_NULL);

			while(uint32 eventId = events.ExecuteEvent())
			{
				switch(eventId)
				{
					if (instance)
					{
						case EVENT_SPINNING_CRANE_KICK:
							me->CastSpell(me, SPELL_SPINNING_CRANE_KICK);

							events.ScheduleEvent(EVENT_SPINNING_CRANE_KICK, 16*IN_MILLISECONDS, 0, PHASE_ATTACK_SCROLL);
							break;

						case EVENT_SAY_INTRO_2_3_4_5:
							Talk(irand(SAY_INTRO_2, SAY_INTRO_5));

							events.ScheduleEvent(EVENT_SAY_INTRO_2_3_4_5, 20*IN_MILLISECONDS, 0, PHASE_ATTACK_SCROLL);
							break;

						case EVENT_SAY_END_1:
							if (Creature* trigger = me->FindNearestCreature(NPC_LOREWALKER_TRIGGER, 99999.0f, true))
								trigger->Kill(trigger);

							if (Creature* wiseMari = me->FindNearestCreature(BOSS_WISE_MARI, 99999.0f, false))
							{
								if (GameObject* lorewalkerDoor = me->FindNearestGameObject(GO_MARI_LOREWALKER_GATE, 99999.0f))
									lorewalkerDoor->UseDoorOrButton();

								if (GameObject* wiseMariDoor = wiseMari->FindNearestGameObject(GO_MARI_LOREWALKER_GATE, 99999.0f))
									wiseMariDoor->UseDoorOrButton();

								if (GameObject* go = me->FindNearestGameObject(GO_LIU_GATE, 99999.0f))
									go->UseDoorOrButton();
							}

							Talk(SAY_END_1);

							me->SetWalk(true);
							me->GetMotionMaster()->MovePoint(0, me->GetHomePosition());
							
							events.ScheduleEvent(EVENT_SAY_END_2, 9*IN_MILLISECONDS, 0, PHASE_BOSSES);
							events.CancelEvent(EVENT_SAY_END_1);
							break;

						case EVENT_SAY_END_2:
							Talk(SAY_END_2);
							me->SetFacingTo(1.261891f);
							me->CastSpell(me, SPELL_MEDITATE);

							events.CancelEvent(EVENT_SAY_END_2); // End of the script
							break;

						default:
							break;
					}
				}
			}
		}