Example #1
0
void CreatureAI::DoZoneInCombatWithPlayers(bool force)
{
    Map* map = me->GetMap();

    if (!map->IsDungeon())
    {
        sLog.outError("CreatureAI::DoZoneInCombatWithPlayers called on a map that is not an instance (creature entry = %u)", me->GetEntry());
        return;
    }

    if (!force)
    {
        if (!me->CanHaveThreatList() || me->getThreatManager().isThreatListEmpty())
        {
            error_log("CreatureAI::DoZoneInCombatWithPlayers called for a creature that either cannot have a threat list or has empty threat list (creature entry = %u)", me->GetEntry());
            return;
        }
    }

    Map::PlayerList const &PlayerList = map->GetPlayers();
    for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
    {
        if (Player* pPlayer = i->GetSource())
        {
            if (pPlayer->IsGameMaster())
                continue;

            if (pPlayer->IsAlive())
            {
                me->SetInCombatWith(pPlayer);
                pPlayer->SetInCombatWith(me);
                me->AddThreat(pPlayer, 0.0f);
            }
        }
    }
}
    bool OnGossipHello(Player* player, Creature* creature)
    {
        if (creature->GetMap()->IsHeroic())
        {
            uint32 gongCounter = 0;

            if (Creature* nefarianHelperheroic = creature->FindNearestCreature(NPC_NEFARIAN_HELPER_HEROIC, 150.0f, true))
                nefarianHelperheroic->AI()->Talk(26);

            if (Creature* gong = creature->FindNearestCreature(42949, 20.0f))
                if(gongCounter < 3)
                {
                    creature->Kill(gong);
                    gongCounter++;
                }                
        }

        if(Creature* atramedes = creature->FindNearestCreature(BOSS_ATRAMEDES, 200.0f))
        {
            creature->CastSpell(atramedes, SPELL_RESONATING_DRAGON, true);
            creature->AddAura(SPELL_VERTIGO, atramedes);

            creature->AddAura(SPELL_NOISY, player);
            creature->CastSpell(player, SPELL_RESONATING_PLAYER, true);

            Map::PlayerList const &PlayerList = creature->GetMap()->GetPlayers();

            if (!PlayerList.isEmpty())
              for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                if (Player* playr = i->GetSource())
                    playr->AddAura(SPELL_SOUND_AURA, playr); // reset the bar.

            creature->setDeathState(JUST_DIED);
        }
        return true;
    }
		void JustDied(Unit* pPlayer)
		{

			
			Talk(SAY_DEAD);
			char msg[250];
			snprintf(msg, 250, "|cffff0000[Boss System]|r Boss|cffff6060 Lightshadow|r wurde getoetet! Respawn in 4h 33min. Darkshadow ist nun der rechtmaessige Prinz! %u", playerdie);
			sWorld->SendGlobalText(msg, NULL);
			Map::PlayerList const &PlList = pPlayer->GetMap()->GetPlayers();
			if (PlList.isEmpty())
				return;
			Lootchange(playerdie);
			for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
			{
				if (Player* player = i->GetSource())
				{
					if (player->IsGameMaster())
						continue;

					if (player->IsAlive())
					{
						player->RemoveAllAuras();
						if (player->hasQuest(899000) && playerdie == 0){
							Questcomplete();
							
						}
						else {
							player->SendQuestFailed(899000,EQUIP_ERR_OK);
														
						}
					
					}
				}
			}

		}
Example #4
0
void CreatureAI::DoZoneInCombat(Creature* creature /*= NULL*/, float maxRangeToNearestTarget /* = 50.0f*/)
{
    if (!creature)
        creature = me;

    if (!creature->CanHaveThreatList())
        return;

    Map* map = creature->GetMap();
    if (!map->IsDungeon())                                  //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
    {
        TC_LOG_ERROR("misc", "DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0);
        return;
    }

    if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim())
    {
        if (Unit* nearTarget = creature->SelectNearestTarget(maxRangeToNearestTarget))
            creature->AI()->AttackStart(nearTarget);
        else if (creature->IsSummon())
        {
            if (Unit* summoner = creature->ToTempSummon()->GetSummoner())
            {
                Unit* target = summoner->getAttackerForHelper();
                if (!target && summoner->CanHaveThreatList() && !summoner->getThreatManager().isThreatListEmpty())
                    target = summoner->getThreatManager().getHostilTarget();
                if (target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target)))
                    creature->AI()->AttackStart(target);
            }
        }
    }

    // Intended duplicated check, the code above this should select a victim
    // If it can't find a suitable attack target then we should error out.
    if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim())
    {
        TC_LOG_ERROR("misc", "DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry());
        return;
    }

    Map::PlayerList const& playerList = map->GetPlayers();

    if (playerList.isEmpty())
        return;

    for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
    {
        if (Player* player = itr->GetSource())
        {
            if (player->IsGameMaster())
                continue;

            if (player->IsAlive())
            {
                creature->SetInCombatWith(player);
                player->SetInCombatWith(creature);
                creature->AddThreat(player, 0.0f);
            }

            /* Causes certain things to never leave the threat list (Priest Lightwell, etc):
            for (Unit::ControlList::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr)
            {
                creature->SetInCombatWith(*itr);
                (*itr)->SetInCombatWith(creature);
                creature->AddThreat(*itr, 0.0f);
            }*/
        }
    }
}
Example #5
0
		void UpdateAI(uint32 diff)
		{
			if (!UpdateVictim())
				return;

			if( me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f )
			{
				EnterEvadeMode();
				return;
			}

			events.Update(diff);

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

			switch (events.GetEvent())
			{
				case 0:
					break;
				case EVENT_ACTIVATE_CONSTRUCT:
					me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, false);
					if (++counter >= 20)
					{
						me->MonsterYell(TEXT_BERSERK, LANG_UNIVERSAL, 0);
						me->PlayDirectSound(SOUND_BERSERK);
						me->CastSpell(me, SPELL_BERSERK, true);
						events.PopEvent();
						break;
					}
					events.RepeatEvent(RAID_MODE(40000,30000));
					break;
				case EVENT_SPELL_SCORCH:
					if( rand()%2 )
					{
						me->MonsterYell(TEXT_SCORCH_1, LANG_UNIVERSAL, 0);
						me->PlayDirectSound(SOUND_SCORCH_1);
					}
					else
					{
						me->MonsterYell(TEXT_SCORCH_2, LANG_UNIVERSAL, 0);
						me->PlayDirectSound(SOUND_SCORCH_2);
					}
					me->SetControlled(true, UNIT_STATE_ROOT);
					me->DisableRotate(true);
					me->SendMovementFlagUpdate();
					me->CastSpell(me->GetVictim(), S_SCORCH, false);
					events.RepeatEvent(20000);
					events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3001);
					break;
				case EVENT_ENABLE_ROTATE:
					me->SetControlled(false, UNIT_STATE_ROOT);
					me->DisableRotate(false);
					events.PopEvent();
					break;
				case EVENT_SPELL_FLAME_JETS:
					me->MonsterTextEmote(TEXT_FLAME_JETS, 0, true);
					me->CastSpell(me->GetVictim(), S_FLAME_JETS, false);
					events.RepeatEvent(25000);
					break;
				case EVENT_GRAB:
					{
						std::list<Creature*> icl;
						me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);

						std::vector<uint64> playerGUIDs;
						Map::PlayerList const& pl = me->GetMap()->GetPlayers();
						Player* temp = NULL;

						for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
						{
							temp = itr->GetSource();
							if( !temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f )
								continue;
							if( me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID() )
								continue;
							bool found = false;
							for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr )
								if( (*itr)->GetVictim() && (*itr)->GetVictim()->GetGUID() == temp->GetGUID() )
								{
									found = true;
									break;
								}

							if( !found )
								playerGUIDs.push_back(temp->GetGUID());
						}

						if( !playerGUIDs.empty() )
						{
							int8 pos = urand(0, playerGUIDs.size()-1);
							if( Player* pTarget = ObjectAccessor::GetPlayer(*me,playerGUIDs.at(pos)) )
							{
								me->MonsterYell(TEXT_SLAG_POT, LANG_UNIVERSAL, 0);
								me->PlayDirectSound(SOUND_SLAG_POT);
								me->CastSpell(pTarget, SPELL_GRAB, false);
							}
						}

						events.RepeatEvent(24000); // +6000 below
						events.DelayEvents(6000);
					}
					break;
			}

			DoMeleeAttackIfReady();
		}
Example #6
0
bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
{
    Map const* oldMap = GetMap();

    if (oldMap->GetId() != newMapid)
    {
        Map* newMap = sMapMgr->CreateBaseMap(newMapid);
        Map::PlayerList const& oldPlayers = GetMap()->GetPlayers();
        if (!oldPlayers.isEmpty())
        {
            UpdateData data(GetMapId());
            BuildOutOfRangeUpdateBlock(&data);
            WorldPacket packet;
            data.BuildPacket(&packet);
            for (Map::PlayerList::const_iterator itr = oldPlayers.begin(); itr != oldPlayers.end(); ++itr)
                if (itr->GetSource()->GetTransport() != this)
                    itr->GetSource()->SendDirectMessage(&packet);
        }

        UnloadStaticPassengers();
        GetMap()->RemoveFromMap<Transport>(this, false);
        SetMap(newMap);

        Map::PlayerList const& newPlayers = GetMap()->GetPlayers();
        if (!newPlayers.isEmpty())
        {
            for (Map::PlayerList::const_iterator itr = newPlayers.begin(); itr != newPlayers.end(); ++itr)
            {
                if (itr->GetSource()->GetTransport() != this)
                {
                    UpdateData data(newMapid);
                    BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
                    WorldPacket packet;
                    data.BuildPacket(&packet);
                    itr->GetSource()->SendDirectMessage(&packet);
                }
            }
        }

        for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end();)
        {
            WorldObject* obj = (*itr++);

            float destX, destY, destZ, destO;
            obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO);
            TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation());

            switch (obj->GetTypeId())
            {
                case TYPEID_PLAYER:
                    if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT))
                        _passengers.erase(obj);
                    break;
                default:
                    RemovePassenger(obj);
                    break;
            }
        }

        Relocate(x, y, z, GetOrientation());
        GetMap()->AddToMap<Transport>(this);
        return true;
    }
    else
    {
        UpdatePosition(x, y, z, GetOrientation());
        return false;
    }
}
            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)
                    {
                        if (events.IsInPhase(PHASE_NORMAL))
                        {
                            case EVENT_BLOODTHIRST:
                                DoCast(me, SPELL_BLOODTHIRST);
                                events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
                                break;
                            case EVENT_FLAME_SPHERE:
                                DoCastVictim(SPELL_CONJURE_FLAME_SPHERE);
                                events.SetPhase(PHASE_SPECIAL);
                                events.ScheduleEvent(EVENT_CASTING_FLAME_SPHERES, 3000);
                                events.ScheduleEvent(EVENT_FLAME_SPHERE, 15000);
                                break;
                            case EVENT_VANISH:
                            {
                                Map::PlayerList const& players = me->GetMap()->GetPlayers();
                                uint32 targets = 0;
                                for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
                                {
                                    Player* player = i->GetSource();
                                    if (player && player->IsAlive())
                                        ++targets;
                                }

                                if (targets > 2)
                                {
                                    Talk(SAY_VANISH);
                                    DoCast(me, SPELL_VANISH);
                                    events.SetPhase(PHASE_SPECIAL);
                                    events.ScheduleEvent(EVENT_JUST_VANISHED, 500);
                                    if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                                        _embraceTargetGUID = embraceTarget->GetGUID();
                                }
                                events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
                                break;
                            }
                        }
                        case EVENT_CASTING_FLAME_SPHERES:
                        {
                            events.SetPhase(PHASE_NORMAL);
                            Unit* sphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
                            if (!sphereTarget)
                                break;

                            float angle, x, y;

                            //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1);
                            if (Creature* sphere = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
                            {
                                angle = sphere->GetAngle(sphereTarget);
                                x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE * std::cos(angle);
                                y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE * std::sin(angle);
                                sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
                            }

                            if (IsHeroic())
                            {
                                //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1);
                                if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
                                {
                                    angle = sphere->GetAngle(sphereTarget) + DATA_SPHERE_ANGLE_OFFSET;
                                    x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
                                    y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
                                    sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
                                }

                                //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2);
                                if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
                                {
                                    angle = sphere->GetAngle(sphereTarget) - DATA_SPHERE_ANGLE_OFFSET;
                                    x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
                                    y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
                                    sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
                                }
                            }
                            break;
                        }
                        case EVENT_JUST_VANISHED:
                            if (Unit* embraceTarget = GetEmbraceTarget())
                            {
                                me->GetMotionMaster()->Clear();
                                me->SetSpeed(MOVE_WALK, 2.0f, true);
                                me->GetMotionMaster()->MoveChase(embraceTarget);
                            }
                            events.ScheduleEvent(EVENT_VANISHED, 1300);
                            break;
                        case EVENT_VANISHED:
                            if (Unit* embraceTarget = GetEmbraceTarget())
                                DoCast(embraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR);
                            Talk(SAY_FEED);
                            me->GetMotionMaster()->Clear();
                            me->SetSpeed(MOVE_WALK, 1.0f, true);
                            me->GetMotionMaster()->MoveChase(me->GetVictim());
                            events.ScheduleEvent(EVENT_FEEDING, 20000);
                            break;
                        case EVENT_FEEDING:
                            _embraceTargetGUID = 0;
                            events.SetPhase(PHASE_NORMAL);
                            break;
                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, ChatMsg msgType, WorldObject const* whisperTarget, CreatureTextRange range, Team team, bool gmOnly) const
{
    float dist = GetRangeForChatType(msgType);

    switch (msgType)
    {
        case CHAT_MSG_MONSTER_WHISPER:
        case CHAT_MSG_RAID_BOSS_WHISPER:
        {
            if (range == TEXT_RANGE_NORMAL)//ignores team and gmOnly
            {
                if (!whisperTarget || whisperTarget->GetTypeId() != TYPEID_PLAYER)
                    return;

                whisperTarget->ToPlayer()->GetSession()->SendPacket(data);
                return;
            }
            break;
        }
        default:
            break;
    }

    switch (range)
    {
        case TEXT_RANGE_AREA:
        {
            uint32 areaId = source->GetAreaId();
            Map::PlayerList const& players = source->GetMap()->GetPlayers();
            for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                if (itr->GetSource()->GetAreaId() == areaId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
                    itr->GetSource()->GetSession()->SendPacket(data);
            return;
        }
        case TEXT_RANGE_ZONE:
        {
            uint32 zoneId = source->GetZoneId();
            Map::PlayerList const& players = source->GetMap()->GetPlayers();
            for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                if (itr->GetSource()->GetZoneId() == zoneId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
                    itr->GetSource()->GetSession()->SendPacket(data);
            return;
        }
        case TEXT_RANGE_MAP:
        {
            Map::PlayerList const& players = source->GetMap()->GetPlayers();
            for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                if ((!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
                    itr->GetSource()->GetSession()->SendPacket(data);
            return;
        }
        case TEXT_RANGE_WORLD:
        {
            SessionMap const& smap = sWorld->GetAllSessions();
            for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter)
                if (Player* player = iter->second->GetPlayer())
                    if (player->GetSession()  && (!team || Team(player->GetTeam()) == team) && (!gmOnly || player->IsGameMaster()))
                        player->GetSession()->SendPacket(data);
            return;
        }
        case TEXT_RANGE_NORMAL:
        default:
            break;
    }

    source->SendMessageToSetInRange(data, dist, true);
}
Example #9
0
            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_BLOODTHIRST:
                            DoCast(me, SPELL_BLOODTHIRST);
                            events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
                            break;
                        case EVENT_CONJURE_FLAME_SPHERES:
                            // random target?
                            if (Unit* victim = me->GetVictim())
                            {
                                _flameSphereTargetGUID = victim->GetGUID();
                                DoCast(victim, SPELL_CONJURE_FLAME_SPHERE);
                            }
                            events.ScheduleEvent(EVENT_CONJURE_FLAME_SPHERES, 15000);
                            break;
                        case EVENT_VANISH:
                        {
                            Map::PlayerList const& players = me->GetMap()->GetPlayers();
                            uint32 targets = 0;
                            for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
                            {
                                Player* player = i->GetSource();
                                if (player && player->IsAlive())
                                    ++targets;
                            }

                            if (targets > 2)
                            {
                                Talk(SAY_VANISH);
                                DoCast(me, SPELL_VANISH);
                                me->SetInCombatState(true); // Prevents the boss from resetting
                                events.DelayEvents(500);
                                events.ScheduleEvent(EVENT_JUST_VANISHED, 500);
                                if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
                                    _embraceTargetGUID = embraceTarget->GetGUID();
                            }
                            events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
                            break;
                        }
                        case EVENT_JUST_VANISHED:
                            if (Unit* embraceTarget = GetEmbraceTarget())
                            {
                                me->GetMotionMaster()->Clear();
                                me->SetSpeed(MOVE_WALK, 2.0f, true);
                                me->GetMotionMaster()->MoveChase(embraceTarget);
                            }
                            events.ScheduleEvent(EVENT_VANISHED, 1300);
                            break;
                        case EVENT_VANISHED:
                            if (Unit* embraceTarget = GetEmbraceTarget())
                                DoCast(embraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR);
                            Talk(SAY_FEED);
                            me->GetMotionMaster()->Clear();
                            me->SetSpeed(MOVE_WALK, 1.0f, true);
                            me->GetMotionMaster()->MoveChase(me->GetVictim());
                            events.ScheduleEvent(EVENT_FEEDING, 20000);
                            break;
                        case EVENT_FEEDING:
                            _embraceTargetGUID.Clear();
                            break;
                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
Example #10
0
        bool SetBossState(uint32 type, EncounterState state)
        {
            if (!InstanceScript::SetBossState(type, state))
                return false;

            switch (type)
            {
            case BOSS_LEVIATHAN:
            case BOSS_IGNIS:
            case BOSS_RAZORSCALE:
            case BOSS_XT002:
            case BOSS_AURIAYA:
                break;
            case BOSS_MIMIRON:
                if (state == DONE)
                    instance->SummonCreature(NPC_MIMIRON_OBSERVATION_RING, ObservationRingKeepersPos[3]);
                break;
            case BOSS_FREYA:
                if (state == DONE)
                    instance->SummonCreature(NPC_FREYA_OBSERVATION_RING, ObservationRingKeepersPos[0]);
                break;
            case BOSS_ASSEMBLY_OF_IRON:
                if (state == DONE)
                    HandleGameObject(ArchivumDoorGUID, true);
                break;
            case BOSS_VEZAX:
                if (state == DONE)
                    HandleGameObject(VezaxDoorGUID, true);
                break;
            case BOSS_YOGG_SARON:
                break;
            case BOSS_KOLOGARN:
                if (state == DONE)
                {
                    if (GameObject* gameObject = instance->GetGameObject(KologarnChestGUID))
                    {
                        gameObject->SetRespawnTime(gameObject->GetRespawnDelay());
                        gameObject->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
                    }
                    HandleGameObject(KologarnBridgeGUID, false);
                }
                break;
            case BOSS_HODIR:
                if (state == DONE)
                {
                    if (GameObject* HodirRareCache = instance->GetGameObject(HodirRareCacheGUID))
                        if (GetData(DATA_HODIR_RARE_CACHE))
                            HodirRareCache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
                    if (GameObject* HodirChest = instance->GetGameObject(HodirChestGUID))
                        HodirChest->SetRespawnTime(HodirChest->GetRespawnDelay());
                    HandleGameObject(HodirDoorGUID, true);
                    HandleGameObject(HodirIceDoorGUID, true);

                    instance->SummonCreature(NPC_HODIR_OBSERVATION_RING, ObservationRingKeepersPos[1]);
                }
                break;
            case BOSS_THORIM:
                if (state == DONE)
                {
                    if (GameObject* gameObject = instance->GetGameObject(ThorimChestGUID))
                        gameObject->SetRespawnTime(gameObject->GetRespawnDelay());

                    instance->SummonCreature(NPC_THORIM_OBSERVATION_RING, ObservationRingKeepersPos[2]);
                }
                break;
            case BOSS_ALGALON:
                if (state == DONE)
                {
                    _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER);
                    _events.CancelEvent(EVENT_DESPAWN_ALGALON);
                    DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0);
                    _algalonTimer = 61;
                    if (GameObject* gameObject = instance->GetGameObject(GiftOfTheObserverGUID))
                        gameObject->SetRespawnTime(gameObject->GetRespawnDelay());
                    // get item level (recheck weapons)
                    Map::PlayerList const& players = instance->GetPlayers();
                    for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                        if (Player* player = itr->GetSource())
                            for (uint8 slot = EQUIPMENT_SLOT_MAINHAND; slot <= EQUIPMENT_SLOT_RANGED; ++slot)
                                if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
                                    if (item->GetTemplate()->ItemLevel > _maxWeaponItemLevel)
                                        _maxWeaponItemLevel = item->GetTemplate()->ItemLevel;
                }
                else if (state == IN_PROGRESS)
                {
                    // get item level (armor cannot be swapped in combat)
                    Map::PlayerList const& players = instance->GetPlayers();
                    for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                    {
                        if (Player* player = itr->GetSource())
                        {
                            for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
                            {
                                if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
                                    continue;

                                if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
                                {
                                    if (slot >= EQUIPMENT_SLOT_MAINHAND && slot <= EQUIPMENT_SLOT_RANGED)
                                    {
                                        if (item->GetTemplate()->ItemLevel > _maxWeaponItemLevel)
                                            _maxWeaponItemLevel = item->GetTemplate()->ItemLevel;
                                    }
                                    else if (item->GetTemplate()->ItemLevel > _maxArmorItemLevel)
                                        _maxArmorItemLevel = item->GetTemplate()->ItemLevel;
                                }
                            }
                        }
                    }
                }
                break;
            }

            return true;
        }
		void UpdateAI(uint32 diff)
		{
			if (wipe_timer <= diff)
			{
				if (me->GetInstanceScript() && me->GetInstanceScript()->GetData(TYPE_IS_WIPE))
				{
					me->GetInstanceScript()->SetData(TYPE_IS_WIPE, 1);
					wipe_timer = 2000;
				}
			}
			else
				wipe_timer -= diff;

			if (!UpdateVictim())
				return;

			events.Update(diff);

			if (me->GetHealthPct() < 70.f && status == PHASE_1)
			{
				me->AddAura(SPELL_JADE_ESSENCE, me);

				events.Reset();
				events.ScheduleEvent(EVENT_JADE_SERPENT_STRIKE, 5000);
				events.ScheduleEvent(EVENT_JADE_SERPENT_KICK, 10000);
				Talk(TALK_EVENT_01);
				status = PHASE_2;
			}
			if (me->GetHealthPct() < 30.f && status == PHASE_2)
			{
				events.Reset();
				events.ScheduleEvent(EVENT_SUMMON_YULON, 500);
				Talk(TALK_EVENT_02);
				status = PHASE_3;
			}

			while (uint32 eventId = events.ExecuteEvent())
			{
				switch (eventId)
				{
				case EVENT_SERPENT_STRIKE:
				{
					me->CastSpell(me->GetVictim(), SPELL_SERPENT_STRIKE, false);
					Map::PlayerList const& PlayerList = me->GetInstanceScript()->instance->GetPlayers();

					if (!PlayerList.isEmpty())
					{
						for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
						{
							Player* plr = i->GetSource();
							if (!plr)
								continue;
							if (plr->GetDistance2d(me) < 10.f)
								plr->KnockbackFrom(me->GetPositionX(), me->GetPositionY(), 10, 10);
						}
					}
					events.ScheduleEvent(EVENT_SERPENT_STRIKE, 10000);
					events.ScheduleEvent(EVENT_SERPENT_WAVE, 4000);
				}
				break;
				case EVENT_SERPENT_KICK:
					me->CastSpell(me->GetVictim(), SPELL_SERPENT_KICK, false);
					events.ScheduleEvent(EVENT_SERPENT_KICK, 10000);
					break;
				case EVENT_SERPENT_WAVE:
				{
					TempSummon* sum = nullptr;
					sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 932.775f, -2548.743f, 179.821f, 1.254f);
					if (sum)
					{
						sum->SetDisplayId(11686);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_VISUAL, false);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false);
						sum->GetMotionMaster()->MovePoint(0, 939.796f, -2530.586f, 179.941f);
						sum->DespawnOrUnsummon(3200);
					}
					sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 940.014f, -2564.114f, 179.821f, 5.978f);
					if (sum)
					{
						sum->SetDisplayId(11686);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_VISUAL, false);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false);
						sum->GetMotionMaster()->MovePoint(0, 957.711f, -2570.030f, 179.941f);
						sum->DespawnOrUnsummon(3200);
					}
					sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 925.971f, -2572.423f, 179.821f, 4.395f);
					if (sum)
					{
						sum->SetDisplayId(11686);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_VISUAL, false);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false);
						sum->GetMotionMaster()->MovePoint(0, 919.606f, -2591.245f, 179.941f);
						sum->DespawnOrUnsummon(3200);
					}
					sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 918.923f, -2557.356f, 179.821f, 2.821f);
					if (sum)
					{
						sum->SetDisplayId(11686);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_VISUAL, false);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false);
						sum->GetMotionMaster()->MovePoint(0, 901.839f, -2551.843f, 179.941f);
						sum->DespawnOrUnsummon(3200);
					}
				}
				break;
				case EVENT_JADE_SERPENT_STRIKE:
				{
					me->CastSpell(me->GetVictim(), SPELL_JADE_SERPENT_STRIKE, false);

					Map::PlayerList const& PlayerList = me->GetInstanceScript()->instance->GetPlayers();

					if (!PlayerList.isEmpty())
					{
						for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
						{
							Player* plr = i->GetSource();
							if (!plr)
								continue;
							if (plr->GetDistance2d(me) < 10.f)
								plr->KnockbackFrom(me->GetPositionX(), me->GetPositionY(), 10, 10);
						}
					}
					events.ScheduleEvent(EVENT_JADE_SERPENT_STRIKE, 10000);
					events.ScheduleEvent(EVENT_JADE_SERPENT_WAVE, 4000);
				}
				break;
				case EVENT_JADE_SERPENT_KICK:
					me->CastSpell(me->GetVictim(), SPELL_JADE_SERPENT_KICK, false);
					events.ScheduleEvent(EVENT_JADE_SERPENT_KICK, 10000);
					break;
				case EVENT_JADE_SERPENT_WAVE:
				{
					TempSummon* sum = nullptr;
					sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 932.775f, -2548.743f, 179.821f, 1.254f);
					if (sum)
					{
						sum->SetDisplayId(11686);
						sum->CastSpell(sum, SPELL_JADE_SERPENT_WAVE_VISUAL, false);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false);
						sum->GetMotionMaster()->MovePoint(0, 939.796f, -2530.586f, 179.941f);
						sum->DespawnOrUnsummon(3200);
					}
					sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 940.014f, -2564.114f, 179.821f, 5.978f);
					if (sum)
					{
						sum->SetDisplayId(11686);
						sum->CastSpell(sum, SPELL_JADE_SERPENT_WAVE_VISUAL, false);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false);
						sum->GetMotionMaster()->MovePoint(0, 957.711f, -2570.030f, 179.941f);
						sum->DespawnOrUnsummon(3200);
					}
					sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 925.971f, -2572.423f, 179.821f, 4.395f);
					if (sum)
					{
						sum->SetDisplayId(11686);
						sum->CastSpell(sum, SPELL_JADE_SERPENT_WAVE_VISUAL, false);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false);
						sum->GetMotionMaster()->MovePoint(0, 919.606f, -2591.245f, 179.941f);
						sum->DespawnOrUnsummon(3200);
					}
					sum = me->SummonCreature(CREATURE_TRIGGER_WAVE, 918.923f, -2557.356f, 179.821f, 2.821f);
					if (sum)
					{
						sum->SetDisplayId(11686);
						sum->CastSpell(sum, SPELL_JADE_SERPENT_WAVE_VISUAL, false);
						sum->CastSpell(sum, SPELL_SERPENT_WAVE_PERIODIC, false);
						sum->GetMotionMaster()->MovePoint(0, 901.839f, -2551.843f, 179.941f);
						sum->DespawnOrUnsummon(3200);
					}
				}
				break;
				case EVENT_SUMMON_YULON:
					me->CastSpell(me, SPELL_SUMMON_JADE_SERPENT, false);
					me->CastSpell(me, SPELL_JADE_SOUL, false);
					me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
					me->ApplySpellImmune(SPELL_JADE_SOUL, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
					me->ApplySpellImmune(SPELL_JADE_SOUL, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
					me->SetReactState(REACT_PASSIVE);
					me->AddUnitState(UNIT_STATE_ROOT);
					events.ScheduleEvent(EVENT_AURA_JADE, 3000);
					break;

				case EVENT_AURA_JADE:
					me->CastSpell(me, SPELL_JADE_SOUL, false);
					events.ScheduleEvent(EVENT_AURA_JADE, 2500);
					break;
				}
			}

			DoMeleeAttackIfReady();
		}
        void UpdateAI(uint32 diff)
        {
			events.Update(diff);
			uint32 eventId = events.GetEvent();

			if (eventId == EVENT_SPELL_INHIBIT_MAGIC)
            {
                Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
                for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                    if (Player* player = i->GetSource())
					{
						float dist = me->GetDistance(player);
                        if (player->IsAlive() && dist < 45.0f)
                        {
                            Aura* aura = player->GetAura(SPELL_INHIBIT_MAGIC);
							if (!aura)
								aura = me->AddAura(SPELL_INHIBIT_MAGIC, player);
							else
								aura->RefreshDuration();

							if (aura)
								aura->SetStackAmount(getStackCount(dist));
                        }
						else
							player->RemoveAurasDueToSpell(SPELL_INHIBIT_MAGIC);
					}
				events.RepeatEvent(3000);
				return;
			}

            if (!UpdateVictim())
                return;


			switch (eventId)
			{
				case EVENT_SPELL_ATTRACT_MAGIC:
					me->CastSpell(me, SPELL_ATTRACT_MAGIC, false);
					events.RepeatEvent(30000);
					events.RescheduleEvent(EVENT_SPELL_CARNIVOROUS, 1500);
					break;
				case EVENT_SPELL_CARNIVOROUS:
					me->CastSpell(me, DUNGEON_MODE(SPELL_CARNIVOROUS_BITE_N, SPELL_CARNIVOROUS_BITE_H), false);
					events.RepeatEvent(10000);
					break;
				case EVENT_SPELL_FOCUS_FIRE:
					if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
					{
						if (Creature* cr = me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000))
							focusGUID = cr->GetGUID();
						Talk(EMOTE_FOCUSED, target);
					}
					events.RepeatEvent(urand(15000, 20000));
					events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 3000);
					events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 3500);
					events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 4000);
					events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_3, 5000);
					me->SetControlled(true, UNIT_STATE_ROOT);
					break;
				case EVENT_SPELL_FOCUS_FIRE_2:
					if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID))
						me->CastSpell(flare, SPELL_FOCUS_CAST, true);
					events.PopEvent();
					break;
				case EVENT_SPELL_FOCUS_FIRE_3:
					me->SetControlled(false, UNIT_STATE_ROOT);
					events.PopEvent();
					break;
			}

            DoMeleeAttackIfReady();
        }
        void UpdateAI(const uint32 diff)
        {
            //Inhibitmagic_Timer
            if (Inhibitmagic_Timer <= diff)
            {
                float dist;
                Map* map = me->GetMap();
                Map::PlayerList const &PlayerList = map->GetPlayers();
                for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                    if (Player* i_pl = i->GetSource())
                        if (i_pl->IsAlive() && (dist = i_pl->IsWithinDist(me, 45)))
                        {
                            i_pl->RemoveAurasDueToSpell(SPELL_INHIBITMAGIC);
                            me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                            if (dist < 35)
                                me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                            if (dist < 25)
                                me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                            if (dist < 15)
                                me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                        }
                Inhibitmagic_Timer = 3000+(rand()%1000);
            } else Inhibitmagic_Timer -= diff;

            //Return since we have no target
            if (!UpdateVictim())
                return;

            //Attractmagic_Timer
            if (Attractmagic_Timer <= diff)
            {
                DoCast(me, SPELL_ATTRACTMAGIC);
                Attractmagic_Timer = 30000;
                Carnivorousbite_Timer = 1500;
            } else Attractmagic_Timer -= diff;

            //Carnivorousbite_Timer
            if (Carnivorousbite_Timer <= diff)
            {
                DoCast(me, SPELL_CARNIVOROUSBITE);
                Carnivorousbite_Timer = 10000;
            } else Carnivorousbite_Timer -= diff;

            //FocusFire_Timer
            if (FocusFire_Timer <= diff)
            {
                // Summon Focus Fire & Emote
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                if (target && target->GetTypeId() == TYPEID_PLAYER && target->IsAlive())
                {
                    FocusedTargetGUID = target->GetGUID();
                    me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 5500);

                    // TODO: Find better way to handle emote
                    // Emote
                    std::string emote(EMOTE_FOCUSES_ON);
                    emote.append(target->GetName());
                    emote.push_back('!');
                    me->MonsterTextEmote(emote, 0, true);
                }
                FocusFire_Timer = 15000+(rand()%5000);
            } else FocusFire_Timer -= diff;

            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)
                {
                    case EVENT_SHIMMER:
                        {
                            // 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;
                            Talk(EMOTE_SHIMMER);
                            events.ScheduleEvent(EVENT_SHIMMER, 45000);
                            break;
                        }
                    case EVENT_BREATH_1:
                            DoCastVictim(Breath1_Spell);
                            events.ScheduleEvent(EVENT_BREATH_1, 60000);
                            break;
                    case EVENT_BREATH_2:
                            DoCastVictim(Breath2_Spell);
                            events.ScheduleEvent(EVENT_BREATH_2, 60000);
                            break;
                    case EVENT_AFFLICTION:
                        {
                            Map::PlayerList const &players = me->GetMap()->GetPlayers();
                            for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                            {
                                if (Player* player = itr->GetSource()->ToPlayer())
                                {
                                    DoCast(player, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true);

                                        if (player->HasAura(SPELL_BROODAF_BLUE) &&
                                            player->HasAura(SPELL_BROODAF_BLACK) &&
                                            player->HasAura(SPELL_BROODAF_RED) &&
                                            player->HasAura(SPELL_BROODAF_BRONZE) &&
                                            player->HasAura(SPELL_BROODAF_GREEN))
                                        {
                                            DoCast(player, SPELL_CHROMATIC_MUT_1);
                                        }

                                }
                            }
                        }
                        events.ScheduleEvent(EVENT_AFFLICTION, 10000);
                        break;
                    case EVENT_FRENZY:
                        DoCast(me, SPELL_FRENZY);
                        events.ScheduleEvent(EVENT_FRENZY, urand(10000, 15000));
                        break;
                }
            }

            // Enrage if not already enraged and below 20%
            if (!Enraged && HealthBelowPct(20))
            {
                DoCast(me, SPELL_ENRAGE);
                Enraged = true;
            }

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

                Summons.DespawnAll();
                events.Update(diff);

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                    case EVENT_LIGHTNING_BOLT:
                        if (me->HasUnitState(UNIT_STATE_CASTING))
                            return;
                        DoCastVictim(SPELL_LIGHTNING_BOLT);
                        events.ScheduleEvent(EVENT_LIGHTNING_BOLT, 2000);
                        break;
                    case EVENT_CALL_VORTEX:
                        for (uint8 i = 0; i < 8; i++)
                            if (_vortexes[i])
                            {
                                float _angle;
                                _angle = me->GetAngle(_vortexes[i]->GetPositionX(), _vortexes[i]->GetPositionY());
                                Position _pos = me->GetNearPosition(5.0f, _angle);
                                _vortexes[i]->GetMotionMaster()->MovementExpired(false);
                                _vortexes[i]->GetMotionMaster()->MovePoint(1, _pos);
                            }
                        
                        events.ScheduleEvent(EVENT_RESET_VORTEX, urand(14000, 17000));
                        break;
                    case EVENT_RESET_VORTEX:
                        for (uint8 i = 0; i < 8; i++)
                            if (_vortexes[i])
                            {
                                _vortexes[i]->GetMotionMaster()->MovementExpired(false);
                                _vortexes[i]->GetMotionMaster()->MovePoint(2, ertanvortexPos_1[i]);
                            }
                        events.ScheduleEvent(EVENT_CALL_VORTEX, urand(20000, 25000));
                        break;
                    case EVENT_STORM_EDGE:
                        _distance = me->GetDistance2d(_vortexes[1]);
                        if (me->GetMap()->GetPlayers().isEmpty())
                            return;
                        for (Map::PlayerList::const_iterator itr = me->GetMap()->GetPlayers().begin(); itr != me->GetMap()->GetPlayers().end(); ++itr)
                        {
                            if (Player* pPlayer = itr->GetSource())
                            {
                                if (me->GetDistance2d(pPlayer) > _distance)
                                {
                                    //uint8 i = urand(0, 7);
                                    //if (_vortexes[i])
                                        //_vortexes[i]->CastSpell(itr->GetSource(), SPELL_STORM_EDGE, true);
                                    DoCast(pPlayer, SPELL_STORM_EDGE, true);
                                }
                            }
                        }
                        events.ScheduleEvent(EVENT_STORM_EDGE, 2000);
                        break;
                    }
                }                    
            }
Example #16
0
bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
{
    Map const* oldMap = GetMap();

    if (oldMap->GetId() != newMapid)
    {
        Map* newMap = sMapMgr->CreateBaseMap(newMapid);
        Map::PlayerList const& oldPlayers = GetMap()->GetPlayers();
        if (!oldPlayers.isEmpty())
        {
            UpdateData data;
            BuildOutOfRangeUpdateBlock(&data);
            WorldPacket packet;
            data.BuildPacket(&packet);
            for (Map::PlayerList::const_iterator itr = oldPlayers.begin(); itr != oldPlayers.end(); ++itr)
                if (itr->GetSource()->GetTransport() != this)
                    itr->GetSource()->SendDirectMessage(&packet);
        }

        UnloadStaticPassengers();
        GetMap()->RemoveFromMap<Transport>(this, false);
        SetMap(newMap);

        Map::PlayerList const& newPlayers = GetMap()->GetPlayers();
        if (!newPlayers.isEmpty())
        {
            for (Map::PlayerList::const_iterator itr = newPlayers.begin(); itr != newPlayers.end(); ++itr)
            {
                if (itr->GetSource()->GetTransport() != this)
                {
                    UpdateData data;
                    BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
                    WorldPacket packet;
                    data.BuildPacket(&packet);
                    itr->GetSource()->SendDirectMessage(&packet);
                }
            }
        }

        for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end();)
        {
            WorldObject* obj = (*itr++);

            float destX, destY, destZ, destO;
            obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO);
            TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation());

            switch (obj->GetTypeId())
            {
                case TYPEID_UNIT:
                    if (!IS_PLAYER_GUID(obj->ToUnit()->GetOwnerGUID()))  // pets should be teleported with player
                        obj->ToCreature()->FarTeleportTo(newMap, destX, destY, destZ, destO);
                    break;
                case TYPEID_GAMEOBJECT:
                {
                    GameObject* go = obj->ToGameObject();
                    go->GetMap()->RemoveFromMap(go, false);
                    go->Relocate(destX, destY, destZ, destO);
                    go->SetMap(newMap);
                    newMap->AddToMap(go);
                    break;
                }
                case TYPEID_PLAYER:
                    if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT))
                        _passengers.erase(obj);
                    break;
                default:
                    break;
            }
        }

        Relocate(x, y, z, GetOrientation());
        GetMap()->AddToMap<Transport>(this);
        return true;
    }
    else
    {
        // Teleport players, they need to know it
        for (std::set<WorldObject*>::iterator itr = _passengers.begin(); itr != _passengers.end(); ++itr)
        {
            if ((*itr)->GetTypeId() == TYPEID_PLAYER)
            {
                float destX, destY, destZ, destO;
                (*itr)->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO);
                TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, GetOrientation());

                (*itr)->ToUnit()->NearTeleportTo(destX, destY, destZ, destO);
            }
        }

        UpdatePosition(x, y, z, GetOrientation());
        return false;
    }
}
Example #17
0
        void UpdateAI(uint32 diff)
        {
            if (!IsInRoom(me))
                return;

            if (!UpdateVictim())
                return;

            events.Update(diff);
            //if (me->HasUnitState(UNIT_STATE_CASTING))
            //  return;

            switch (events.GetEvent())
            {
                case EVENT_SPELL_SPELL_DISRUPTION:
                    me->CastSpell(me, SPELL_SPELL_DISRUPTION, false);
                    events.RepeatEvent(10000);
                    break;
                case EVENT_SPELL_DECEPIT_FEVER:
                    me->CastSpell(me, RAID_MODE(SPELL_DECREPIT_FEVER_10, SPELL_DECREPIT_FEVER_25), false);
                    events.RepeatEvent(20000);
                    break;
                case EVENT_SWITCH_PHASE:
                    StartFightPhase(currentPhase == PHASE_SLOW_DANCE ? PHASE_FAST_DANCE : PHASE_SLOW_DANCE);
                    // no pop, there is reset in start fight
                    break;
                case EVENT_ERUPT_SECTION:
                    if (pInstance)
                    {
                        pInstance->SetData(DATA_HEIGAN_ERUPTION, currentSection);
                        if (currentSection == 3)
                            moveRight = false;
                        else if (currentSection == 0)
                            moveRight = true;

                        moveRight ? currentSection++ : currentSection--;
                    }

                    if (currentPhase == PHASE_SLOW_DANCE && !urand(0,3))
                        Talk(SAY_TAUNT);

                    events.RepeatEvent(currentPhase == PHASE_SLOW_DANCE ? 10000 : 4000);
                    break;
                case EVENT_SAFETY_DANCE:
                {
                    Map::PlayerList const& pList = me->GetMap()->GetPlayers();
                    for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
                    {
                        if (IsInRoom(itr->GetSource()) && !itr->GetSource()->IsAlive())
                        {
                            events.PopEvent();
                            pInstance->SetData(DATA_DANCE_FAIL, 0);
                            pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
                            return;
                        }

                    }
                    events.RepeatEvent(5000);
                    return;
                }
            }

            DoMeleeAttackIfReady();
        }
    void UpdateAI(const uint32 diff)
    {
        if (pInstance)
        {
            if (!leotherasGUID)
                leotherasGUID = pInstance->GetData64(DATA_LEOTHERAS);

            if (!me->IsInCombat() && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
            {
                Unit* victim = NULL;
                victim = Unit::GetUnit(*me, pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER));
                if (victim)
                    AttackStart(victim);
            }
        }

        if (!UpdateVictim())
        {
            CastChanneling();
            return;
        }

        if (pInstance && !pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
        {
            EnterEvadeMode();
            return;
        }

        if (Mindblast_Timer <= diff)
        {
            Unit* pTarget = NULL;
            pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);

            if (pTarget)DoCast(pTarget, SPELL_MINDBLAST);

            Mindblast_Timer = 10000 + rand() % 5000;
        }
        else Mindblast_Timer -= diff;

        if (Earthshock_Timer <= diff)
        {
            Map* pMap = me->GetMap();
            Map::PlayerList const& PlayerList = pMap->GetPlayers();
            for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
            {
                if (Player* i_pl = itr->GetSource())
                {
                    bool isCasting = false;
                    for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
                        if (i_pl->GetCurrentSpell(i))
                            isCasting = true;

                    if (isCasting)
                    {
                        DoCast(i_pl, SPELL_EARTHSHOCK);
                        break;
                    }
                }
            }
            Earthshock_Timer = 8000 + rand() % 7000;
        }
        else Earthshock_Timer -= diff;
        DoMeleeAttackIfReady();
    }
Example #19
0
    void SetData(uint32 type, uint32 data)
    {
        switch (type)
        {
        case DATA_RAGEWINTERCHILLEVENT:
            Encounters[0] = data;
            break;
        case DATA_ANETHERONEVENT:
            Encounters[1] = data;
            break;
        case DATA_KAZROGALEVENT:
            Encounters[2] = data;
            break;
        case DATA_AZGALOREVENT:
            {
                Encounters[3] = data;
                if (data == DONE)
                {
                    if (ArchiYell)break;
                    ArchiYell = true;

                    Creature* pCreature = instance->GetCreature(Azgalor);
                    if (pCreature)
                    {
                        Creature* pUnit = pCreature->SummonCreature(21987, pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);

                        Map* pMap = pCreature->GetMap();
                        if (pMap->IsDungeon() && pUnit)
                        {
                            pUnit->SetVisible(false);
                            Map::PlayerList const& PlayerList = pMap->GetPlayers();
                            if (PlayerList.isEmpty())
                                return;

                            for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                            {
                                if (i->GetSource())
                                {
                                    WorldPacket data(SMSG_MESSAGECHAT, 200);
                                    pUnit->BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, YELL_EFFORTS, 0, YELL_EFFORTS_NAME, i->GetSource()->GetGUID());
                                    i->GetSource()->GetSession()->SendPacket(&data);

                                    WorldPacket data2(SMSG_PLAY_SOUND, 4);
                                    data2 << 10986;
                                    i->GetSource()->GetSession()->SendPacket(&data2);
                                }
                            }
                        }
                    }
                }
            }
            break;
        case DATA_ARCHIMONDEEVENT:
            Encounters[4] = data;
            break;
        case DATA_RESET_TRASH_COUNT:
            Trash = 0;
            break;

        case DATA_TRASH:
            if (data) Trash = data;
            else     Trash--;
            UpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash);
            break;
        case DATA_ALLIANCE_RETREAT:
            allianceRetreat = data;
            OpenDoor(HordeGate, true);
            SaveToDB();
            break;
        case DATA_HORDE_RETREAT:
            hordeRetreat = data;
            OpenDoor(ElfGate, true);
            SaveToDB();
            break;
        case DATA_RAIDDAMAGE:
            RaidDamage += data;
            if (RaidDamage >= MINRAIDDAMAGE)
                RaidDamage = MINRAIDDAMAGE;
            break;
        case DATA_RESET_RAIDDAMAGE:
            RaidDamage = 0;
            break;
        }

        debug_log("OSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)", type, data);

        if (data == DONE)
            SaveToDB();
    }
Example #20
0
        void WaypointReached(uint32 waypointId) override
        {
            switch (waypointId)
            {
                case 8:
                    SetRun(false);
                    me->SummonCreature(18764, 2181.87f, 112.46f, 89.45f, 0.26f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 9:
                    Talk(SAY_TH_ARMORY);
                    me->SetVirtualItem(0, THRALL_WEAPON_ITEM);
                    //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO);
                    //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781);
                    me->SetVirtualItem(1, THRALL_SHIELD_ITEM);
                    //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO);
                    //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038);
                    break;
                case 10:
                    me->SetDisplayId(THRALL_MODEL_EQUIPPED);
                    break;
                case 11:
                    SetRun();
                    break;
                case 15:
                    me->SummonCreature(NPC_RIFLE, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_WARDEN, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_VETERAN, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 21:
                    me->SummonCreature(NPC_RIFLE, 2135.80f, 154.01f, 67.45f, 4.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_WARDEN, 2144.36f, 151.87f, 67.74f, 4.46f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_VETERAN, 2142.12f, 154.41f, 67.12f, 4.56f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_VETERAN, 2138.08f, 155.38f, 67.24f, 4.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 25:
                    me->SummonCreature(NPC_RIFLE, 2102.98f, 192.17f, 65.24f, 6.02f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_WARDEN, 2108.48f, 198.75f, 65.18f, 5.15f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_VETERAN, 2106.11f, 197.29f, 65.18f, 5.63f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_VETERAN, 2104.18f, 194.82f, 65.18f, 5.75f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 29:
                    Talk(SAY_TH_SKARLOC_MEET);
                    me->SummonCreature(ENTRY_SCARLOC, 2036.48f, 271.22f, 63.43f, 5.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
                    //temporary, skarloc should rather be triggered to walk up to thrall
                    break;
                case 30:
                    SetEscortPaused(true);
                    me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
                    SetRun(false);
                    break;
                case 31:
                    Talk(SAY_TH_MOUNTS_UP);
                    DoMount();
                    SetRun();
                    break;
                case 37:
                    //possibly regular patrollers? If so, remove this and let database handle them
                    me->SummonCreature(NPC_WATCHMAN, 2124.26f, 522.16f, 56.87f, 3.99f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_WATCHMAN, 2121.69f, 525.37f, 57.11f, 4.01f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_SENTRY, 2124.65f, 524.55f, 56.63f, 3.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 59:
                    me->SummonCreature(SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 10000);
                    DoUnmount();
                    HadMount = false;
                    SetRun(false);
                    break;
                case 60:
                    me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
                    //make horsie run off
                    SetEscortPaused(true);
                    me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
                    instance->SetData(TYPE_THRALL_PART2, DONE);
                    SetRun();
                    break;
                case 64:
                    SetRun(false);
                    break;
                case 68:
                    me->SummonCreature(NPC_BARN_PROTECTOR, 2500.22f, 692.60f, 55.50f, 2.84f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_BARN_LOOKOUT, 2500.13f, 696.55f, 55.51f, 3.38f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.55f, 693.64f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.94f, 695.81f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 71:
                    SetRun();
                    break;
                case 81:
                    SetRun(false);
                    break;
                case 83:
                    me->SummonCreature(NPC_CHURCH_PROTECTOR, 2627.33f, 646.82f, 56.03f, 4.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
                    me->SummonCreature(NPC_CHURCH_LOOKOUT, 2624.14f, 648.03f, 56.03f, 4.50f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
                    me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2625.32f, 649.60f, 56.03f, 4.38f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
                    me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2627.22f, 649.00f, 56.03f, 4.34f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000);
                    break;
                case 84:
                    Talk(SAY_TH_CHURCH_END);
                    SetRun();
                    break;
                case 91:
                    me->SetWalk(true);
                    SetRun(false);
                    break;
                case 93:
                    me->SummonCreature(NPC_INN_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_INN_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_INN_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    me->SummonCreature(NPC_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    break;
                case 94:
                    if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA)))
                        Taretha->AI()->Talk(SAY_TA_ESCAPED, me);
                    break;
                case 95:
                    Talk(SAY_TH_MEET_TARETHA);
                    instance->SetData(TYPE_THRALL_PART3, DONE);
                    SetEscortPaused(true);
                    break;
                case 96:
                    Talk(SAY_TH_EPOCH_WONDER);
                    break;
                case 97:
                    Talk(SAY_TH_EPOCH_KILL_TARETHA);
                    SetRun();
                    break;
                case 98:
                    //trigger epoch Yell("Thrall! Come outside and face your fate! ....")
                    //from here, thrall should not never be allowed to move to point 106 which he currently does.
                    break;
                case 106:
                    {
                        //trigger taretha to run down outside
                        if (Creature* Taretha = instance->instance->GetCreature(instance->GetGuidData(DATA_TARETHA)))
                        {
                            if (Player* player = GetPlayerForEscort())
                                ENSURE_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, player->GetGUID());
                        }

                        //kill credit Creature for quest
                        Map::PlayerList const& players = me->GetMap()->GetPlayers();
                        for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                        {
                            if (Player* player = itr->GetSource())
                                player->KilledMonsterCredit(20156);
                        }

                        //alot will happen here, thrall and taretha talk, erozion appear at spot to explain
                        me->SummonCreature(EROZION_ENTRY, 2646.47f, 680.416f, 55.38f, 4.16f, TEMPSUMMON_TIMED_DESPAWN, 120000);
                    }
                    break;
                case 108:
                    //last waypoint, just set Thrall invisible, respawn is turned off
                    me->SetVisible(false);
                    break;
            }
        }
Example #21
0
        void UpdateAI(uint32 diff)
        {
            if (!CanStartEvent) // boss is invisible, don't attack
            {
                if (CheckCanStart())
                {
                    if (Submerged)
                    {
                        me->SetVisible(true);
                        Submerged = false;
                        WaitTimer2 = 500;
                    }

                    if (!Submerged && WaitTimer2 <= diff) // wait 500ms before emerge anim
                    {
                        me->RemoveAllAuras();
                        me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
                        DoCast(me, SPELL_EMERGE, false);
                        WaitTimer2 = 60000; // never reached
                        WaitTimer = 3000;
                    }
                    else
                        WaitTimer2 -= diff;

                    if (WaitTimer <= diff) // wait 3secs for emerge anim, then attack
                    {
                        WaitTimer = 3000;
                        CanStartEvent = true; // fresh fished from pool
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    }
                    else
                        WaitTimer -= diff;
                }
                return;
            }

            if (me->getThreatManager().getThreatList().empty()) // check if should evade
            {
                if (me->IsInCombat())
                    EnterEvadeMode();
                return;
            }
            if (!Submerged)
            {
                if (PhaseTimer <= diff)
                {
                    me->InterruptNonMeleeSpells(false);
                    DoCast(me, SPELL_SUBMERGE);
                    PhaseTimer = 60000; // 60secs submerged
                    Submerged = true;
                } else PhaseTimer-=diff;

                if (SpoutTimer <= diff)
                {
                    me->MonsterTextEmote(EMOTE_SPOUT, 0, true);
                    me->SetReactState(REACT_PASSIVE);
                    me->GetMotionMaster()->MoveRotate(20000, urand(0, 1) ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
                    SpoutTimer = 45000;
                    WhirlTimer = 20000; // whirl directly after spout
                    RotTimer = 20000;
                    return;
                } else SpoutTimer -= diff;

                // Whirl directly after a Spout and at random times
                if (WhirlTimer <= diff)
                {
                    WhirlTimer = 18000;
                    DoCast(me, SPELL_WHIRL);
                } else WhirlTimer -= diff;

                if (CheckTimer <= diff)//check if there are players in melee range
                {
                    InRange = false;
                    Map* map = me->GetMap();
                    Map::PlayerList const &PlayerList = map->GetPlayers();
                    if (!PlayerList.isEmpty())
                    {
                        for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                        {
                            if (me->IsWithinMeleeRange(i->GetSource()))
                                InRange = true;
                        }
                    }
                    CheckTimer = 2000;
                } else CheckTimer -= diff;

                if (RotTimer)
                {
                    Map* map = me->GetMap();
                    if (map->IsDungeon())
                    {
                        Map::PlayerList const &PlayerList = map->GetPlayers();
                        for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                        {
                            if (i->GetSource() && i->GetSource()->IsAlive() && me->HasInArc(float(diff/20000*M_PI*2), i->GetSource()) && me->IsWithinDist(i->GetSource(), SPOUT_DIST) && !i->GetSource()->IsInWater())
                                DoCast(i->GetSource(), SPELL_SPOUT, true); // only knock back players in arc, in 100yards, not in water
                        }
                    }

                    if (SpoutAnimTimer <= diff)
                    {
                        DoCast(me, SPELL_SPOUT_ANIM, true);
                        SpoutAnimTimer = 1000;
                    } else SpoutAnimTimer -= diff;

                    if (RotTimer <= diff)
                    {
                        RotTimer = 0;
                    } else RotTimer -= diff;
                    return;
                }

                if (GeyserTimer <= diff)
                {
                    Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                    if (!target && me->GetVictim())
                        target = me->GetVictim();
                    if (target)
                        DoCast(target, SPELL_GEYSER, true);
                    GeyserTimer = rand()%5000 + 15000;
                } else GeyserTimer -= diff;

                if (!InRange) // if on players in melee range cast Waterbolt
                {
                    if (WaterboltTimer <= diff)
                    {
                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                        if (!target && me->GetVictim())
                            target = me->GetVictim();
                        if (target)
                            DoCast(target, SPELL_WATERBOLT, true);
                        WaterboltTimer = 3000;
                    } else WaterboltTimer -= diff;
                }

                if (!UpdateVictim())
                    return;

                DoMeleeAttackIfReady();

            }
            else // submerged
            {
                if (PhaseTimer <= diff)
                {
                    Submerged = false;
                    me->InterruptNonMeleeSpells(false); // shouldn't be any
                    me->RemoveAllAuras();
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
                    me->RemoveFlag(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED);
                    DoCast(me, SPELL_EMERGE, true);
                    Spawned = false;
                    SpoutTimer = 3000; // directly cast Spout after emerging!
                    PhaseTimer = 120000;
                    return;
                } else PhaseTimer-=diff;

                if (me->getThreatManager().getThreatList().empty()) // check if should evade
                {
                    EnterEvadeMode();
                    return;
                }

                if (!me->IsInCombat())
                    DoZoneInCombat();

                if (!Spawned)
                {
                    me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
                    // spawn adds
                    for (uint8 i = 0; i < 9; ++i)
                        if (Creature* summoned = me->SummonCreature(i < 6 ? NPC_COILFANG_AMBUSHER : NPC_COILFANG_GUARDIAN, AddPos[i][0], AddPos[i][1], AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0))
                            Summons.Summon(summoned);
                    Spawned = true;
                }
            }
        }
		void OnCreatureCreate(Creature* creature)
		{
			if (TeamIdInInstance == TEAM_NEUTRAL)
			{
				Map::PlayerList const &players = instance->GetPlayers();
				if (!players.isEmpty())
					for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
						if (Player* p = itr->GetSource())
							if (!p->IsGameMaster())
							{
								TeamIdInInstance = p->GetTeamId();
								break;
							}
			}

			switch(creature->GetEntry())
			{
				case NPC_SYLVANAS_PART1:
					creature->SetVisible(false);
					NPC_LeaderIntroGUID = creature->GetGUID();
					if (TeamIdInInstance == TEAM_ALLIANCE)
						creature->UpdateEntry(NPC_JAINA_PART1);
					creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
					creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
					break;
				case NPC_DARK_RANGER_LORALEN:
					creature->SetVisible(false);
					NPC_GuardGUID = creature->GetGUID();
					if (TeamIdInInstance == TEAM_ALLIANCE)
						creature->UpdateEntry(NPC_ARCHMAGE_ELANDRA);
					break;
				case NPC_UTHER:
					creature->SetVisible(false);
					NPC_UtherGUID = creature->GetGUID();
					creature->SetReactState(REACT_PASSIVE);
					break;
				case NPC_LICH_KING_EVENT:
					creature->SetVisible(false);
					NPC_LichKingIntroGUID = creature->GetGUID();
					creature->SetReactState(REACT_PASSIVE);
					creature->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
					break;
				case NPC_FALRIC:
					creature->SetVisible(false);
					NPC_FalricGUID = creature->GetGUID();
					creature->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
					break;
				case NPC_MARWYN:
					creature->SetVisible(false);
					NPC_MarwynGUID = creature->GetGUID();
					creature->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
					break;
				case NPC_WAVE_MERCENARY:
				case NPC_WAVE_FOOTMAN:
				case NPC_WAVE_RIFLEMAN:
				case NPC_WAVE_PRIEST:
				case NPC_WAVE_MAGE:
					if (TrashCounter < NUM_OF_TRASH)
						NPC_TrashGUID[TrashCounter++] = creature->GetGUID();
					if (!(EncounterMask & (1 << DATA_MARWYN)) && !creature->IsAlive())
						creature->Respawn();
					creature->SetVisible(false);
					break;
				case NPC_FROSTSWORN_GENERAL:
					if (!(EncounterMask & (1 << DATA_MARWYN)))
					{
						creature->SetVisible(false);
						creature->SetReactState(REACT_PASSIVE);
					}
					NPC_FrostswornGeneralGUID = creature->GetGUID();
					break;
				case NPC_SPIRITUAL_REFLECTION:
					for (uint8 i=0; i<5; ++i)
						if (!NPC_SpiritualReflectionGUID[i])
						{
							NPC_SpiritualReflectionGUID[i] = creature->GetGUID();
							break;
						}
					creature->SetVisible(false);
					break;
				case NPC_LICH_KING_BOSS:
					if (!(EncounterMask & (1 << DATA_FROSTSWORN_GENERAL)))
						creature->SetVisible(false);
					if (!(EncounterMask & (1 << DATA_LK_INTRO)))
					{
						creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK2HTIGHT);
						if (TeamIdInInstance != TEAM_ALLIANCE)
						{
							creature->StopMoving();
							creature->SetFacingTo(creature->GetAngle(&SylvanasFightPos));
						}
					}
					else if (!(EncounterMask & (1 << DATA_LICH_KING)))
						creature->AddAura(TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_PRISON : SPELL_SYLVANAS_DARK_BINDING, creature);
					else
						creature->SetVisible(false);

					NPC_LichKingGUID = creature->GetGUID();
					creature->SetHealth((creature->GetMaxHealth()*3)/4);
					creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
					break;
				case NPC_SYLVANAS_PART2:
					if (!creature->IsAlive())
						creature->Respawn();
					NPC_LeaderGUID = creature->GetGUID();
					if (TeamIdInInstance == TEAM_ALLIANCE)
						creature->UpdateEntry(NPC_JAINA_PART2);
					creature->SetHealth(creature->GetMaxHealth()/20);

					if (!(EncounterMask & (1 << DATA_FROSTSWORN_GENERAL)))
						creature->SetVisible(false);
					if (!(EncounterMask & (1 << DATA_LK_INTRO)))
					{
						creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, TeamIdInInstance == TEAM_ALLIANCE ? EMOTE_ONESHOT_ATTACK2HTIGHT : EMOTE_ONESHOT_ATTACK1H);
						creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
						creature->CastSpell(creature, TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_BARRIER : SPELL_SYLVANAS_CLOAK_OF_DARKNESS, true);
						if (TeamIdInInstance != TEAM_ALLIANCE)
						{
							creature->UpdatePosition(SylvanasFightPos, true);
							creature->StopMovingOnCurrentPos();
						}
					}
					else if (!(EncounterMask & (1 << DATA_LICH_KING)))
					{
						creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
						creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
						creature->UpdatePosition(LeaderEscapePos, true);
						creature->StopMovingOnCurrentPos();
					}
					else
					{
						instance->LoadGrid(PathWaypoints[PATH_WP_COUNT-1].GetPositionX(), PathWaypoints[PATH_WP_COUNT-1].GetPositionY());
						creature->UpdatePosition(PathWaypoints[PATH_WP_COUNT-1], true);
						creature->StopMovingOnCurrentPos();
					}
					creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
					break;
				case NPC_ICE_WALL_TARGET:
					if (creature->GetPositionX() > 5525.0f)
						NPC_IceWallTargetGUID[0] = creature->GetGUID();
					else if (creature->GetPositionX() > 5475.0f)
						NPC_IceWallTargetGUID[1] = creature->GetGUID();
					else if (creature->GetPositionX() > 5400.0f)
						NPC_IceWallTargetGUID[2] = creature->GetGUID();
					else
						NPC_IceWallTargetGUID[3] = creature->GetGUID();
					break;
				case NPC_ALTAR_BUNNY:
					NPC_AltarBunnyGUID = creature->GetGUID();
					break;
				case NPC_QUEL_DELAR:
					NPC_QuelDelarGUID = creature->GetGUID();
					creature->SetReactState(REACT_PASSIVE);
					break;
				case NPC_HIGH_CAPTAIN_JUSTIN_BARLETT:
				case NPC_SKY_REAVER_KORM_BLACKSKAR:
					NPC_ShipCaptainGUID = creature->GetGUID();
					break;
			}
		}
        void UpdateAI(uint32 diff)
        {
            if (spawnTimer)
            {
                spawnTimer += diff;
                if (spawnTimer >= 21500)
                {
                    me->SetVisible(true);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    me->SetReactState(REACT_AGGRESSIVE);
                    spawnTimer = 0;
                }
                return;
            }

            if (!IsInRoom())
                return;

            if (!UpdateVictim())
                return;

            events.Update(diff);
            if (me->HasUnitState(UNIT_STATE_CASTING))
                return;

            switch (events.GetEvent())
            {
                case EVENT_BERSERK:
                    Talk(EMOTE_ENRAGE);
                    me->CastSpell(me, SPELL_BERSERK, true);
                    events.PopEvent();
                    return;
                case EVENT_SPELL_CLEAVE:
                    me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
                    events.RepeatEvent(10000);
                    return;
                case EVENT_SPELL_TAIL_SWEEP:
                    me->CastSpell(me, RAID_MODE(SPELL_TAIL_SWEEP_10, SPELL_TAIL_SWEEP_25), false);
                    events.RepeatEvent(10000);
                    return;
                case EVENT_SPELL_LIFE_DRAIN:
                    me->CastCustomSpell(RAID_MODE(SPELL_LIFE_DRAIN_10, SPELL_LIFE_DRAIN_25), SPELLVALUE_MAX_TARGETS, RAID_MODE(2, 5), me, false);
                    events.RepeatEvent(24000);
                    return;
                case EVENT_SPELL_BLIZZARD:
                {
                    Creature* cr;
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
                        cr = me->SummonCreature(NPC_BLIZZARD, *target, TEMPSUMMON_TIMED_DESPAWN, 16000);
                    else
                        cr = me->SummonCreature(NPC_BLIZZARD, *me, TEMPSUMMON_TIMED_DESPAWN, 16000);
                        
                    if (cr)
                        cr->GetMotionMaster()->MoveRandom(40);
                    events.RepeatEvent(RAID_MODE(8000, 6500));
                    return;
                }
                case EVENT_FLIGHT_START:
                    if (me->HealthBelowPct(11))
                    {
                        events.PopEvent();
                        return;
                    }
                    events.RepeatEvent(45000);
                    events.DelayEvents(35000);
                    me->SetReactState(REACT_PASSIVE);
                    me->AttackStop();
                    float x, y, z, o;
                    me->GetHomePosition(x, y, z, o);
                    me->GetMotionMaster()->MovePoint(POINT_CENTER, x, y, z);
                    return;
                case EVENT_FLIGHT_LIFTOFF:
                    me->GetMotionMaster()->MoveIdle();
                    me->SendMeleeAttackStop(me->GetVictim());
                    me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
                    me->SetDisableGravity(true);
                    currentTarget = 0;
                    events.PopEvent();
                    events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, 3000);
                    iceboltCount = RAID_MODE(2, 3);
                    return;
                case EVENT_FLIGHT_ICEBOLT:
                {
                    events.PopEvent();
                    if (currentTarget)
                        if (Unit* target = ObjectAccessor::GetUnit(*me, currentTarget))
                            me->SummonGameObject(GO_ICE_BLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0);
            
                    std::vector<Unit*> targets;
                    ThreatContainer::StorageType::const_iterator i = me->getThreatManager().getThreatList().begin();
                    for (; i != me->getThreatManager().getThreatList().end(); ++i)
                        if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER)
                        {
                            bool inList = false;
                            if (!blockList.empty())
                                for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
                                    if ((*i)->getTarget()->GetGUID() == *itr)
                                    {
                                        inList = true;
                                        break;
                                    }
                            
                            if (!inList)
                                targets.push_back((*i)->getTarget());
                        }

                    if (!targets.empty() && iceboltCount)
                    {
                        std::vector<Unit*>::iterator itr = targets.begin();
                        advance(itr, urand(0, targets.size()-1));
                        me->CastSpell(*itr, SPELL_ICEBOLT_CAST, false);
                        blockList.push_back((*itr)->GetGUID());
                        currentTarget = (*itr)->GetGUID();
                        --iceboltCount;
                        events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, (me->GetExactDist(*itr) / 13.0f)*IN_MILLISECONDS);
                    }
                    else
                        events.ScheduleEvent(EVENT_FLIGHT_BREATH, 1000);
                    return;
                }
                case EVENT_FLIGHT_BREATH:
                    currentTarget = 0;
                    Talk(EMOTE_BREATH);
                    me->CastSpell(me, SPELL_FROST_MISSILE, false);
                    events.ScheduleEvent(EVENT_FLIGHT_SPELL_EXPLOSION, 8500);
                    events.PopEvent();
                    return;
                case EVENT_FLIGHT_SPELL_EXPLOSION:
                    me->CastSpell(me, SPELL_FROST_EXPLOSION, true);
                    events.PopEvent();
                    events.ScheduleEvent(EVENT_FLIGHT_START_LAND, 3000);
                    return;
                case EVENT_FLIGHT_START_LAND:
                    if (!blockList.empty())
                        for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
                            if (Unit* block = ObjectAccessor::GetUnit(*me, *itr))
                                block->RemoveAurasDueToSpell(SPELL_ICEBOLT_TRIGGER);

                    blockList.clear();
                    me->RemoveAllGameObjects();
                    events.ScheduleEvent(EVENT_LAND, 1000);
                    events.PopEvent();
                    return;
                case EVENT_LAND:
                    me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                    me->SetDisableGravity(false);

                    events.PopEvent();
                    events.ScheduleEvent(EVENT_GROUND, 1500);
                    return;
                case EVENT_GROUND:
                    me->SetReactState(REACT_AGGRESSIVE);
                    me->SetInCombatWithZone();
                    events.PopEvent();
                    return;
                case EVENT_HUNDRED_CLUB:
                {
                    Map::PlayerList const& pList = me->GetMap()->GetPlayers();
                    for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
                    {
                        if (itr->GetSource()->GetResistance(SPELL_SCHOOL_FROST) > 100 && pInstance)
                        {
                            events.PopEvent();
                            pInstance->SetData(DATA_HUNDRED_CLUB, 0);
                            return;
                        }

                    }
                    events.RepeatEvent(5000);
                    return;
                }
            }

            DoMeleeAttackIfReady();
        }
		void SetData(uint32 type, uint32 data)
		{
			switch(type)
			{
				case DATA_INTRO:
					EncounterMask |= (1 << DATA_INTRO);
					AddWave1();
					break;
				case ACTION_SHOW_TRASH:
					RandomizeCompositionsAndShow();
					break;
				case DATA_FALRIC:
					if (WaveNumber)
					{
						if (data == NOT_STARTED)
							DoWipe1();
						else if (data == DONE)
						{
							NextWaveTimer = 60000;
							EncounterMask |= (1 << DATA_FALRIC);
						}
					}
					break;
				case DATA_MARWYN:
					if (WaveNumber)
					{
						if (data == NOT_STARTED)
							DoWipe1();
						else if (data == DONE)
						{
							EncounterMask |= (1 << DATA_MARWYN);
							HandleGameObject(GO_FrontDoorGUID, true);
							HandleGameObject(GO_ArthasDoorGUID, true);
							if (Creature* c = instance->GetCreature(NPC_FrostswornGeneralGUID))
							{
								c->SetVisible(true);
								c->SetReactState(REACT_AGGRESSIVE);
							}
							WaveNumber = 0;
							DoUpdateWorldState(WORLD_STATE_HOR_COUNTER, 0);

							// give quest
							Map::PlayerList const& pl = instance->GetPlayers();
							for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
								if (Player* p = itr->GetSource())
									p->CastSpell(p, p->GetTeamId() == TEAM_ALLIANCE ? SPELL_HOR_START_QUEST_ALLY : SPELL_HOR_START_QUEST_HORDE, true);
						}
					}
					break;
				case DATA_FROSTSWORN_GENERAL:
					EncounterMask |= (1 << DATA_FROSTSWORN_GENERAL);
					if (data == DONE)
					{
						if (Creature* c = instance->GetCreature(NPC_LichKingGUID))
							c->SetVisible(true);
						if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
							c->SetVisible(true);
					}
					break;
				case ACTION_SPIRITUAL_REFLECTIONS_COPY:
					{
						uint8 i=0;
						Map::PlayerList const& pl = instance->GetPlayers();
						for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
							if (Player* p = itr->GetSource())
								if (p->IsAlive() && !p->IsGameMaster())
									if (Creature* c = instance->GetCreature(NPC_SpiritualReflectionGUID[i++]))
									{
										if (!c->IsAlive())
											c->Respawn();
										c->SetDisableGravity(true);
										c->SetCanFly(true);
										c->SetVisible(true);

										Item* i;
										i = p->GetWeaponForAttack(BASE_ATTACK);
										c->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, i ? i->GetEntry() : 0);
										i = p->GetWeaponForAttack(OFF_ATTACK);
										c->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, i ? i->GetEntry() : 0);
										i = p->GetWeaponForAttack(RANGED_ATTACK);
										c->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, i ? i->GetEntry() : 0);
										p->CastSpell(c, SPELL_HOR_CLONE, true);
										p->CastSpell(c, SPELL_HOR_CLONE_NAME, true);
									}
					}
					break;
				case ACTION_SPIRITUAL_REFLECTIONS_ACTIVATE:
					if (Creature* fg = instance->GetCreature(NPC_FrostswornGeneralGUID))
						for (uint8 i=0; i<5; ++i)
							if (Creature* c = instance->GetCreature(NPC_SpiritualReflectionGUID[i]))
								if (c->IsVisible())
								{
									c->SetInCombatWithZone();
									c->SetDisableGravity(false);
									c->SetCanFly(false);
									c->GetMotionMaster()->MoveJump(fg->GetPositionX(), fg->GetPositionY(), fg->GetPositionZ(), 20.0f, 10.0f);
								}
					break;
				case ACTION_SPIRITUAL_REFLECTIONS_HIDE:
					for (uint8 i=0; i<5; ++i)
						if (Creature* c = instance->GetCreature(NPC_SpiritualReflectionGUID[i]))
							c->AI()->EnterEvadeMode();
					break;
				case DATA_LK_INTRO:
					EncounterMask |= (1 << DATA_LK_INTRO);
					if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
						c->AI()->DoAction(ACTION_START_INTRO);
					break;
				case ACTION_START_LK_FIGHT:
					IsDuringLKFight = true;
					DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_RETREATING_TIMED_EVENT);
					DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_RETREATING_TIMED_EVENT);
					break;
				case ACTION_STOP_LK_FIGHT:
					if (!IsDuringLKFight)
						break;
					instance->LoadGrid(LeaderEscapePos.GetPositionX(), LeaderEscapePos.GetPositionY());
					if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
					{
						if (!c->IsAlive())
						{
							c->Respawn();
							if (TeamIdInInstance == TEAM_ALLIANCE)
								c->UpdateEntry(NPC_JAINA_PART2);
						}
						c->DeleteThreatList();
						c->CombatStop(true);
						c->InterruptNonMeleeSpells(true);
						c->GetMotionMaster()->Clear();
						c->GetMotionMaster()->MoveIdle();
						c->UpdatePosition(LeaderEscapePos, true);
						c->StopMovingOnCurrentPos();
						c->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
						c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
						c->SetHealth(c->GetMaxHealth()/20);
						c->AI()->Reset();
						c->setActive(false);
						c->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
						c->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
					}
					if (Creature* c = instance->GetCreature(NPC_LichKingGUID))
					{
						c->DeleteThreatList();
						c->CombatStop(true);
						c->InterruptNonMeleeSpells(true);
						c->GetMotionMaster()->Clear();
						c->GetMotionMaster()->MoveIdle();
						c->UpdatePosition(c->GetHomePosition(), true);
						c->StopMovingOnCurrentPos();
						c->RemoveAllAuras();
						c->AddAura(TeamIdInInstance == TEAM_ALLIANCE ? SPELL_JAINA_ICE_PRISON : SPELL_SYLVANAS_DARK_BINDING, c);
						c->AI()->Reset();
						c->setActive(false);
						c->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
						c->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
						c->SetSpeed(MOVE_RUN, c->GetCreatureTemplate()->speed_run);
					}
					IsDuringLKFight = false;
					outroTimer = 0;
					outroStep = 0;
					// no break intended
				case ACTION_DELETE_ICE_WALL:
					HandleGameObject(GO_IceWallGUID, true);
					GO_IceWallGUID = 0;
					break;
				case DATA_LICH_KING:
					if (data == DONE)
					{
						instance->LoadGrid(PathWaypoints[0].GetPositionX(), PathWaypoints[0].GetPositionY());
						EncounterMask |= (1 << DATA_LICH_KING);
						if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
							c->setActive(false);
						if (Creature* c = instance->GetCreature(NPC_LichKingGUID))
							c->setActive(false);
						IsDuringLKFight = false;
						outroStep = 1;
						outroTimer = 0;
					}
					break;
				case DATA_BATTERED_HILT:
					{
						if (EncounterMask & (1 << DATA_BATTERED_HILT))
							return;

						switch(data)
						{
							case 1: // talked to leader
								EncounterMask |= (1 << DATA_BATTERED_HILT);
								SaveToDB();
								break;
							case 2:
								if (BatteredHiltStatus)
									break;
								BatteredHiltStatus |= BHSF_STARTED;
								if (Creature* c = instance->GetCreature(NPC_AltarBunnyGUID))
									c->CastSpell(c, 70720, true);
								if (Creature* c = instance->GetCreature(NPC_UtherGUID))
									c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 1), c->m_Events.CalculateTime(3000));
								break;
							case 3:
								if ((BatteredHiltStatus & BHSF_STARTED) == 0 || (BatteredHiltStatus & BHSF_THROWN))
									break;
								BatteredHiltStatus |= BHSF_THROWN;
								if (Creature* c = instance->GetCreature(NPC_UtherGUID))
								{
									c->AI()->Talk(SAY_BATTERED_HILT_LEAP);
									c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 3), c->m_Events.CalculateTime(1500));
								}
								break;
							case 4:
								if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID))
								{
									c->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
									c->SetSpeed(MOVE_RUN, 2.5f);
								}
								break;
							case 5:
								if (Creature* c = instance->GetCreature(NPC_UtherGUID))
									c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 6), c->m_Events.CalculateTime(3000));
								break;
							case 6:
								if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID))
								{
									c->SetSpeed(MOVE_RUN, c->GetCreatureTemplate()->speed_run);
									c->GetMotionMaster()->MoveLand(0, c->GetPositionX(), c->GetPositionY(), 707.70f, 7.0f);
								}
								break;
							case 7:
								if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID))
								{
									c->SetReactState(REACT_AGGRESSIVE);
									c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
									c->RemoveAurasDueToSpell(70300);
								}
								break;
							case 8:
								if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID))
									c->SetInCombatWithZone();
								break;
							case 9:
								EncounterMask |= (1 << DATA_BATTERED_HILT);
								BatteredHiltStatus |= BHSF_FINISHED;
								SaveToDB();
								break;
						}
					}
					return;
			}

			if (data == DONE)
				SaveToDB();
		}
Example #25
0
    void UpdateAI(const uint32 diff)
    {
        npc_escortAI::UpdateAI(diff);

        if (HasEscortState(STATE_ESCORT_PAUSED))
        {
            if (TalkTimer <= diff)
            {
                if (TalkCount > 3)
                {
                    if (Creature* pSpotlight = Unit::GetCreature(*me, m_uiSpotlightGUID))
                        pSpotlight->ForcedDespawn();

                    SetEscortPaused(false);
                    return;
                }

                Talk(TalkCount);
                ++TalkCount;
            }
            else TalkTimer -= diff;
        }

        if (PerformanceReady)
        {
            if (!RaidWiped)
            {
                if (WipeTimer <= diff)
                {
                    Map* pMap = me->GetMap();
                    if (!pMap->IsDungeon())
                        return;

                    Map::PlayerList const& PlayerList = pMap->GetPlayers();
                    if (PlayerList.isEmpty())
                        return;

                    RaidWiped = true;
                    for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                    {
                        if (i->GetSource()->IsAlive() && !i->GetSource()->IsGameMaster())
                        {
                            RaidWiped = false;
                            break;
                        }
                    }

                    if (RaidWiped)
                    {
                        RaidWiped = true;
                        EnterEvadeMode();
                        return;
                    }

                    WipeTimer = 15000;
                }
                else WipeTimer -= diff;
            }

        }
    }
		void Update(uint32 diff)
		{
			if (!instance->HavePlayers())
				return;

			if (CheckPlayersTimer <= diff)
			{
				CheckPlayersTimer = 5000;
				if ((EncounterMask & (1 << DATA_INTRO)) && !(EncounterMask & (1 << DATA_MARWYN))) // first event
				{
					Map::PlayerList const& pl = instance->GetPlayers();
					if (WaveNumber || NextWaveTimer)
					{
						bool allDead = true;
						bool outOfRange = false;
						for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
							if (Player* p = itr->GetSource())
							{
								if (p->IsGameMaster())
									continue;
								if (p->IsAlive())
									allDead = false;
								if (p->GetExactDist2d(&CenterPos) > MAX_DIST_FROM_CENTER_IN_COMBAT)
								{
									outOfRange = true;
									break;
								}
							}
						if (allDead || outOfRange)
							DoWipe1();
					}
					else if (!ResumeFirstEventTimer)
					{
						bool allInRangeAndAlive = (instance->GetPlayersCountExceptGMs() > 0 ? true : false);
						for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
							if (Player* p = itr->GetSource())
								if (!p->IsGameMaster() && (p->GetExactDist2d(&CenterPos) > MAX_DIST_FROM_CENTER_TO_START || !p->IsAlive()))
								{
									allInRangeAndAlive = false;
									break;
								}
						if (allInRangeAndAlive)
						{
							ResumeFirstEventTimer = 1;
							ResumeFirstEventStep = 0;
						}
					}
				}
			}
			else
				CheckPlayersTimer -= diff;

			if (NextWaveTimer)
			{
				if (NextWaveTimer <= diff)
				{
					NextWaveTimer = 0;
					AddWave1();
				}
				else
					NextWaveTimer -= diff;
			}

			if (ResumeFirstEventTimer)
			{
				if (ResumeFirstEventTimer <= diff)
				{
					switch (ResumeFirstEventStep)
					{
						case 0:
							if (Creature* pFalric = instance->GetCreature(NPC_FalricGUID))
							{
								pFalric->UpdatePosition(5274.9f, 2039.2f, 709.319f, 5.4619f, true);
								pFalric->StopMovingOnCurrentPos();
								pFalric->SetVisible(true);
								if (pFalric->IsAlive())
								{
									pFalric->GetMotionMaster()->MovePoint(0, FalricMovePos);
									if (Aura* a = pFalric->AddAura(SPELL_SHADOWMOURNE_VISUAL, pFalric))
										a->SetDuration(8000);
								}
							}
							if (Creature* pMarwyn = instance->GetCreature(NPC_MarwynGUID))
							{
								pMarwyn->UpdatePosition(5343.77f, 1973.86f, 709.319f, 2.35173f, true);
								pMarwyn->StopMovingOnCurrentPos();
								pMarwyn->SetVisible(true);
								if (pMarwyn->IsAlive())
								{
									pMarwyn->GetMotionMaster()->MovePoint(0, MarwynMovePos);
									if (Aura* a = pMarwyn->AddAura(SPELL_SHADOWMOURNE_VISUAL, pMarwyn))
										a->SetDuration(8000);
								}

								pMarwyn->MonsterTextEmote("Spirits appear and surround the altar!", 0, true);
							}
							++ResumeFirstEventStep;
							ResumeFirstEventTimer = 7500;
							break;
						case 1:
							if (Creature* pFalric = instance->GetCreature(NPC_FalricGUID))
								pFalric->AI()->Talk(SAY_FALRIC_INTRO_2);
							SetData(ACTION_SHOW_TRASH, 1);
							ResumeFirstEventStep = 0;
							ResumeFirstEventTimer = 0;
							NextWaveTimer = 7000;
							break;
						default:
							for (uint8 i=0; i<NUM_OF_TRASH; ++i)
								if (Creature* c = instance->GetCreature(NPC_TrashGUID[i]))
									c->SetVisible(false);
							if (Creature* falric = instance->GetCreature(NPC_FalricGUID))
								falric->SetVisible(false);
							if (Creature* marwyn = instance->GetCreature(NPC_MarwynGUID))
								marwyn->SetVisible(false);
							ResumeFirstEventStep = 0;
							ResumeFirstEventTimer = 0;
							break;
					}
				}
				else
					ResumeFirstEventTimer -= diff;
			}

			if (outroStep)
			{
				if (outroTimer <= diff)
				{
					switch (outroStep)
					{
						case 1:
							if (Creature* lk = instance->GetCreature(NPC_LichKingGUID))
							{
								lk->UpdatePosition(PathWaypoints[PATH_WP_COUNT-2], true);
								lk->StopMovingOnCurrentPos();
								lk->RemoveAllAuras();
								lk->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CUSTOM_SPELL_02);
								if (!lk->IsVisible())
									lk->SetVisible(true);
								if (Creature* leader = instance->GetCreature(NPC_LeaderGUID))
								{
									leader->UpdatePosition(PathWaypoints[PATH_WP_COUNT-1], true);
									leader->StopMovingOnCurrentPos();
									leader->RemoveAllAuras();
									leader->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_READY1H);
									if (!leader->IsVisible())
										leader->SetVisible(true);
									lk->CastSpell(leader, SPELL_HARVEST_SOUL, false);
								}
							}
							++outroStep;
							outroTimer = 500;
							break;
						case 2:
							{
								uint32 entry = TeamIdInInstance == TEAM_ALLIANCE ? GO_THE_SKYBREAKER : GO_ORGRIMS_HAMMER;
								T1 = sTransportMgr->CreateTransport(entry, 0, instance);

								++outroStep;
								outroTimer = TeamIdInInstance == TEAM_ALLIANCE ? 10000 : 10500;
							}
							break;
						case 3:
							if (T1)
								T1->EnableMovement(false);
							if (Creature* c = instance->GetCreature(NPC_ShipCaptainGUID))
								c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_FIRE_ALLY : SAY_FIRE_HORDE);
							if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
							{
								c->RemoveAllAuras();
								c->CastSpell(c, SPELL_GUNSHIP_CANNON_FIRE_PERIODIC, true);
							}
							if (Creature* c = instance->GetCreature(NPC_LichKingGUID))
							{
								c->InterruptNonMeleeSpells(true);
								c->RemoveAllAuras();
							}
							++outroStep;
							outroTimer = 5000;
							break;
						case 4:
							HandleGameObject(GO_CaveInGUID, false);
							++outroStep;
							outroTimer = 3000;
							break;
						case 5:
							if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
								c->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
							if (Creature* c = instance->GetCreature(NPC_LichKingGUID))
							{
								c->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
								c->DeleteThreatList();
								c->CombatStop(true);
								c->InterruptNonMeleeSpells(true);
								c->SetVisible(false);
							}
							if (instance->IsHeroic())
								instance->ToInstanceMap()->PermBindAllPlayers();
							if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
								c->CastSpell(c, SPELL_ACHIEVEMENT_CHECK, true);
							++outroStep;
							outroTimer = 1000;
							break;
						case 6:
							if (T1)
								T1->EnableMovement(true);
							++outroStep;
							outroTimer = 3500;
							break;
						case 7:
							if (T1)
								T1->EnableMovement(false);
							if (Creature* leader = instance->GetCreature(NPC_LeaderGUID))
							{
								uint8 index = TeamIdInInstance == TEAM_ALLIANCE ? 0 : 1;
								for (uint8 i=0; i<3; ++i)
									if (StairsPos[index][i].GetPositionX())
										if (GameObject* go = leader->SummonGameObject(TeamIdInInstance == TEAM_ALLIANCE ? GO_STAIRS_ALLIANCE : GO_STAIRS_HORDE, StairsPos[index][i].GetPositionX(), StairsPos[index][i].GetPositionY(), StairsPos[index][i].GetPositionZ(), StairsPos[index][i].GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400, false))
											go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE);

								//Position pos = TeamIdInInstance == TEAM_ALLIANCE ? AllyPortalPos : HordePortalPos;
								//leader->SummonGameObject(GO_PORTAL_TO_DALARAN, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400);
								//pos = TeamIdInInstance == TEAM_ALLIANCE ? AllyChestPos : HordeChestPos;
								//leader->SummonGameObject(instance->GetSpawnMode() ? GO_CHEST_HEROIC : GO_CHEST_NORMAL, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 86400);
							}
							++outroStep;
							outroTimer = 1000;
							break;
						case 8:
							if (Creature* c = instance->GetCreature(NPC_ShipCaptainGUID))
								c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_ONBOARD_ALLY : SAY_ONBOARD_HORDE);
							if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
							{
								c->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
								c->GetMotionMaster()->MovePoint(0, WalkCaveInPos);
							}
							++outroStep;
							outroTimer = 6000;
							break;
						case 9:
							if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
								c->AI()->Talk(TeamIdInInstance == TEAM_ALLIANCE ? SAY_FINAL_ALLY : SAY_FINAL_HORDE);
							HandleGameObject(GO_CaveInGUID, true);
							++outroStep;
							outroTimer = 11000;
							break;
						case 10:
							++outroStep;
							outroTimer = 0;
							for (Map::PlayerList::const_iterator itr = instance->GetPlayers().begin(); itr != instance->GetPlayers().end(); ++itr)
								if (Player* p = itr->GetSource())
									p->KilledMonsterCredit(NPC_WRATH_OF_THE_LICH_KING_CREDIT, 0);
							if (TeamIdInInstance == TEAM_ALLIANCE)
								if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
								{
									c->AI()->Talk(SAY_FINAL_ALLY_SECOND);
									outroTimer = 10000;
								}
							break;
						case 11:
							if (Creature* c = instance->GetCreature(NPC_LeaderGUID))
								c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
							++outroStep;
							outroTimer = 300*1000;
							break;
						case 12:
							outroStep = 0;
							outroTimer = 0;
							if (T1)
								T1->setActive(false);
							break;
					}
				}
				else
					outroTimer -= diff;
			}
		}
        void UpdateAI(uint32 diff) override
        {
            if (!UpdateVictim())
            {
                events.Update(diff);

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_RESPAWN:
                        {
                            // Respawn all Blackhand Incarcerators
                            std::list<Creature*> creatureList;
                            GetCreatureListWithEntryInGrid(creatureList, me, NPC_BLACKHAND_INCARCERATOR, 35.0f);
                            for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
                                if (Creature* creature = *itr)
                                {
                                    if (!creature->IsAlive())
                                        creature->Respawn();

                                    creature->AI()->SetData(1, 1);
                                }
                            me->AddAura(SPELL_ENCAGED_EMBERSEER, me);
                            instance->SetBossState(DATA_PYROGAURD_EMBERSEER, NOT_STARTED);
                            break;
                        }
                        case EVENT_PRE_FIGHT_1:
                        {
                            // Set data on all Blackhand Incarcerators
                            std::list<Creature*> creatureList;
                            GetCreatureListWithEntryInGrid(creatureList, me, NPC_BLACKHAND_INCARCERATOR, 35.0f);
                            for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
                            {
                                if (Creature* creature = *itr)
                                    creature->AI()->SetData(1, 1);
                            }
                            events.ScheduleEvent(EVENT_PRE_FIGHT_2, 32000);
                            break;
                        }
                        case EVENT_PRE_FIGHT_2:
                            me->CastSpell(me, SPELL_FREEZE_ANIM);
                            me->CastSpell(me, SPELL_EMBERSEER_GROWING);
                            Talk(EMOTE_ONE_STACK);
                            break;
                        case EVENT_FIRE_SHIELD:
                            // #### Spell isn't doing any damage ??? ####
                            DoCast(me, SPELL_FIRE_SHIELD);
                            events.ScheduleEvent(EVENT_FIRE_SHIELD, 3000);
                            break;
                        case EVENT_PLAYER_CHECK:
                        {
                            // Check to see if all players in instance have aura SPELL_EMBERSEER_START before starting event
                            bool _hasAura = true;
                            Map::PlayerList const &players = me->GetMap()->GetPlayers();
                            for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                                if (Player* player = itr->GetSource()->ToPlayer())
                                    if (!player->HasAura(SPELL_EMBERSEER_OBJECT_VISUAL))
                                        _hasAura = false;

                            if (_hasAura)
                            {
                                events.ScheduleEvent(EVENT_PRE_FIGHT_1, 1000);
                                instance->SetBossState(DATA_PYROGAURD_EMBERSEER, IN_PROGRESS);
                            }
                            break;
                        }
                        case EVENT_ENTER_COMBAT:
                            AttackStart(me->SelectNearestPlayer(30.0f));
                            break;
                        default:
                            break;
                    }
                }
                return;
            }

            events.Update(diff);

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch (eventId)
                {
                    case EVENT_FIRE_SHIELD:
                        DoCast(me, SPELL_FIRE_SHIELD);
                        events.ScheduleEvent(EVENT_FIRE_SHIELD, 3000);
                        break;
                    case EVENT_FIRENOVA:
                        DoCast(me, SPELL_FIRENOVA);
                        events.ScheduleEvent(EVENT_FIRENOVA, 6000);
                        break;
                    case EVENT_FLAMEBUFFET:
                        DoCast(me, SPELL_FLAMEBUFFET);
                        events.ScheduleEvent(EVENT_FLAMEBUFFET, 14000);
                        break;
                    case EVENT_PYROBLAST:
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                            DoCast(target, SPELL_PYROBLAST);
                        events.ScheduleEvent(EVENT_PYROBLAST, 15000);
                        break;
                    default:
                        break;
                }
            }
            DoMeleeAttackIfReady();
        }
Example #28
0
        void UpdateAI(uint32 diff) override
        {
            //Check if we have a target
            if (!UpdateVictim())
            {
                //No target so we'll use this section to do our random wispers instance wide
                //WisperTimer
                if (WisperTimer <= diff)
                {
                    //Play random sound to the zone
                    Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
                    for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
                        me->PlayDirectSound(RANDOM_SOUND_WHISPER, itr->GetSource());

                    //One random wisper every 90 - 300 seconds
                    WisperTimer = urand(90000, 300000);
                } else WisperTimer -= diff;

                return;
            }

            me->SetTarget(ObjectGuid::Empty);

            uint32 currentPhase = instance->GetData(DATA_CTHUN_PHASE);
            if (currentPhase == PHASE_CTHUN_STOMACH || currentPhase == PHASE_CTHUN_WEAK)
            {
                // EyeTentacleTimer
                if (EyeTentacleTimer <= diff)
                {
                    //Spawn the 8 Eye Tentacles in the corret spots
                    SpawnEyeTentacle(0, 20);                //south
                    SpawnEyeTentacle(10, 10);               //south west
                    SpawnEyeTentacle(20, 0);                //west
                    SpawnEyeTentacle(10, -10);              //north west

                    SpawnEyeTentacle(0, -20);               //north
                    SpawnEyeTentacle(-10, -10);             //north east
                    SpawnEyeTentacle(-20, 0);               // east
                    SpawnEyeTentacle(-10, 10);              // south east

                    EyeTentacleTimer = 30000; // every 30sec in phase 2
                } else EyeTentacleTimer -= diff;
            }

            switch (currentPhase)
            {
                //Transition phase
                case PHASE_CTHUN_TRANSITION:
                    //PhaseTimer
                    if (PhaseTimer <= diff)
                    {
                        //Switch
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH);

                        //Switch to c'thun model
                        me->InterruptNonMeleeSpells(false);
                        DoCast(me, SPELL_TRANSFORM, false);
                        me->SetFullHealth();

                        me->SetVisible(true);
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);

                        //Emerging phase
                        //AttackStart(ObjectAccessor::GetUnit(*me, HoldpPlayer));
                        DoZoneInCombat();

                        //Place all units in threat list on outside of stomach
                        Stomach_Map.clear();

                        for (std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i)
                            Stomach_Map[(*i)->getUnitGuid()] = false;   //Outside stomach

                        //Spawn 2 flesh tentacles
                        FleshTentaclesKilled = 0;

                        //Spawn flesh tentacle
                        for (uint8 i = 0; i < 2; i++)
                        {
                            Creature* spawned = me->SummonCreature(NPC_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN);
                            if (!spawned)
                                ++FleshTentaclesKilled;
                        }

                        PhaseTimer = 0;
                    } else PhaseTimer -= diff;

                    break;

                //Body Phase
                case PHASE_CTHUN_STOMACH:
                    //Remove Target field
                    me->SetTarget(ObjectGuid::Empty);

                    //Weaken
                    if (FleshTentaclesKilled > 1)
                    {
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_WEAK);

                        Talk(EMOTE_WEAKENED);
                        PhaseTimer = 45000;

                        DoCast(me, SPELL_PURPLE_COLORATION, true);

                        std::unordered_map<ObjectGuid, bool>::iterator i = Stomach_Map.begin();

                        //Kick all players out of stomach
                        while (i != Stomach_Map.end())
                        {
                            //Check for valid player
                            Unit* unit = ObjectAccessor::GetUnit(*me, i->first);

                            //Only move units in stomach
                            if (unit && i->second == true)
                            {
                                //Teleport each player out
                                DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10, float(rand32() % 6));

                                //Cast knockback on them
                                DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true);

                                //Remove the acid debuff
                                unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID);

                                i->second = false;
                            }
                            ++i;
                        }

                        return;
                    }

                    //Stomach acid
                    if (StomachAcidTimer <= diff)
                    {
                        //Apply aura to all players in stomach
                        std::unordered_map<ObjectGuid, bool>::iterator i = Stomach_Map.begin();

                        while (i != Stomach_Map.end())
                        {
                            //Check for valid player
                            Unit* unit = ObjectAccessor::GetUnit(*me, i->first);

                            //Only apply to units in stomach
                            if (unit && i->second == true)
                            {
                                //Cast digestive acid on them
                                DoCast(unit, SPELL_DIGESTIVE_ACID, true);

                                //Check if player should be kicked from stomach
                                if (unit->IsWithinDist3d(&KickPos, 15.0f))
                                {
                                    //Teleport each player out
                                    DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10, float(rand32() % 6));

                                    //Cast knockback on them
                                    DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true);

                                    //Remove the acid debuff
                                    unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID);

                                    i->second = false;
                                }
                            }
                            ++i;
                        }

                        StomachAcidTimer = 4000;
                    } else StomachAcidTimer -= diff;

                    //Stomach Enter Timer
                    if (StomachEnterTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Set target in stomach
                            Stomach_Map[target->GetGUID()] = true;
                            target->InterruptNonMeleeSpells(false);
                            target->CastSpell(target, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID());
                            StomachEnterTarget = target->GetGUID();
                            StomachEnterVisTimer = 3800;
                        }

                        StomachEnterTimer = 13800;
                    } else StomachEnterTimer -= diff;

                    if (StomachEnterVisTimer && !StomachEnterTarget.IsEmpty())
                    {
                        if (StomachEnterVisTimer <= diff)
                        {
                            //Check for valid player
                            Unit* unit = ObjectAccessor::GetUnit(*me, StomachEnterTarget);

                            if (unit)
                            {
                                DoTeleportPlayer(unit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O);
                            }

                            StomachEnterTarget.Clear();
                            StomachEnterVisTimer = 0;
                        } else StomachEnterVisTimer -= diff;
                    }

                    //GientClawTentacleTimer
                    if (GiantClawTentacleTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Spawn claw tentacle on the random target
                            if (Creature* spawned = me->SummonCreature(NPC_GIANT_CLAW_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500))
                                if (spawned->AI())
                                    spawned->AI()->AttackStart(target);
                        }

                        //One giant claw tentacle every minute
                        GiantClawTentacleTimer = 60000;
                    } else GiantClawTentacleTimer -= diff;

                    //GiantEyeTentacleTimer
                    if (GiantEyeTentacleTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Spawn claw tentacle on the random target
                            if (Creature* spawned = me->SummonCreature(NPC_GIANT_EYE_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500))
                                if (spawned->AI())
                                    spawned->AI()->AttackStart(target);
                        }

                        //One giant eye tentacle every minute
                        GiantEyeTentacleTimer = 60000;
                    } else GiantEyeTentacleTimer -= diff;

                    break;

                //Weakened state
                case PHASE_CTHUN_WEAK:
                    //PhaseTimer
                    if (PhaseTimer <= diff)
                    {
                        //Switch
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH);

                        //Remove purple coloration
                        me->RemoveAurasDueToSpell(SPELL_PURPLE_COLORATION);

                        //Spawn 2 flesh tentacles
                        FleshTentaclesKilled = 0;

                        //Spawn flesh tentacle
                        for (uint8 i = 0; i < 2; i++)
                        {
                            Creature* spawned = me->SummonCreature(NPC_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN);
                            if (!spawned)
                                ++FleshTentaclesKilled;
                        }

                        PhaseTimer = 0;
                    } else PhaseTimer -= diff;

                    break;
            }
        }
        void SetData(uint32 type, uint32 data) override
        {
            switch (type)
            {
            case TYPE_MEDIVH:
                if (data == SPECIAL && m_auiEncounter[0] == IN_PROGRESS)
                {
                    --mShieldPercent;

                    DoUpdateWorldState(WORLD_STATE_BM_SHIELD, mShieldPercent);

                    if (!mShieldPercent)
                    {
                        if (Creature* medivh = instance->GetCreature(_medivhGUID))
                        {
                            if (medivh->IsAlive())
                            {
                                medivh->DealDamage(medivh, medivh->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                                m_auiEncounter[0] = FAIL;
                                m_auiEncounter[1] = NOT_STARTED;
                            }
                        }
                    }
                }
                else
                {
                    if (data == IN_PROGRESS)
                    {
                        TC_LOG_DEBUG("scripts", "Instance The Black Morass: Starting event.");
                        InitWorldState();
                        m_auiEncounter[1] = IN_PROGRESS;
                        ScheduleEventNextPortal(15000);
                    }

                    if (data == DONE)
                    {
                        //this may be completed further out in the post-event
                        TC_LOG_DEBUG("scripts", "Instance The Black Morass: Event completed.");
                        Map::PlayerList const& players = instance->GetPlayers();

                        if (!players.isEmpty())
                        {
                            for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
                            {
                                if (Player* player = itr->GetSource())
                                {
                                    if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE)
                                        player->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL);

                                    if (player->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE)
                                        player->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH);
                                }
                            }
                        }
                    }

                    m_auiEncounter[0] = data;
                }
                break;
            case TYPE_RIFT:
                if (data == SPECIAL)
                {
                    if (mRiftPortalCount < 7)
                        ScheduleEventNextPortal(5000);
                }
                else
                    m_auiEncounter[1] = data;
                break;
            }
        }
            void UpdateAI(uint32 diff) override
            {
                if (!UpdateVictim())
                    return;

                events.Update(diff);

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

                switch (_stage)
                {
                    case 0:
                    {
                        while (uint32 eventId = events.ExecuteEvent())
                        {
                            switch (eventId)
                            {
                                case EVENT_FEROCIOUS_BUTT:
                                    DoCastVictim(SPELL_FEROCIOUS_BUTT);
                                    events.ScheduleEvent(EVENT_FEROCIOUS_BUTT, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
                                    return;
                                case EVENT_ARCTIC_BREATH:
                                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
                                        DoCast(target, SPELL_ARCTIC_BREATH);
                                    return;
                                case EVENT_WHIRL:
                                    DoCastAOE(SPELL_WHIRL);
                                    events.ScheduleEvent(EVENT_WHIRL, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
                                    return;
                                case EVENT_MASSIVE_CRASH:
                                    me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 20.0f, 20.0f, 0); // 1: Middle of the room
                                    SetCombatMovement(false);
                                    me->AttackStop();
                                    _stage = 7; //Invalid (Do nothing more than move)
                                    return;
                                default:
                                    break;
                            }
                        }
                        DoMeleeAttackIfReady();
                        break;
                    }
                    case 1:
                        DoCastAOE(SPELL_MASSIVE_CRASH);
                        me->StopMoving();
                        me->AttackStop();
                        _stage = 2;
                        break;
                    case 2:
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
                        {
                            me->StopMoving();
                            me->AttackStop();
                            _trampleTargetGUID = target->GetGUID();
                            me->SetTarget(_trampleTargetGUID);
                            _trampleCasted = false;
                            SetCombatMovement(false);
                            me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
                            me->GetMotionMaster()->Clear();
                            me->GetMotionMaster()->MoveIdle();
                            events.ScheduleEvent(EVENT_TRAMPLE, 4*IN_MILLISECONDS);
                            _stage = 3;
                        }
                        else
                            _stage = 6;
                        break;
                    case 3:
                        while (uint32 eventId = events.ExecuteEvent())
                        {
                            switch (eventId)
                            {
                                case EVENT_TRAMPLE:
                                {
                                    if (Unit* target = ObjectAccessor::GetPlayer(*me, _trampleTargetGUID))
                                    {
                                        me->StopMoving();
                                        me->AttackStop();
                                        _trampleCasted = false;
                                        _movementStarted = true;
                                        _trampleTargetX = target->GetPositionX();
                                        _trampleTargetY = target->GetPositionY();
                                        _trampleTargetZ = target->GetPositionZ();
                                        // 2: Hop Backwards
                                        me->GetMotionMaster()->MoveJump(2*me->GetPositionX() - _trampleTargetX, 2*me->GetPositionY() - _trampleTargetY, me->GetPositionZ(), 30.0f, 20.0f, 0);
                                        _stage = 7; //Invalid (Do nothing more than move)
                                    }
                                    else
                                        _stage = 6;
                                    break;
                                }
                                default:
                                    break;
                            }
                        }
                        break;
                    case 4:
                        me->StopMoving();
                        me->AttackStop();
                        Talk(EMOTE_TRAMPLE_START, sObjectAccessor->GetUnit(*me, _trampleTargetGUID));
                        me->GetMotionMaster()->MoveCharge(_trampleTargetX, _trampleTargetY, _trampleTargetZ, 42, 1);
                        me->SetTarget(0);
                        _stage = 5;
                        break;
                    case 5:
                        if (_movementFinish)
                        {
                            DoCastAOE(SPELL_TRAMPLE);
                            _movementFinish = false;
                            _stage = 6;
                            return;
                        }
                        if (events.ExecuteEvent() == EVENT_TRAMPLE)
                        {
                            Map::PlayerList const &lPlayers = me->GetMap()->GetPlayers();
                            for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
                            {
                                if (Unit* player = itr->GetSource())
                                {
                                    if (player->IsAlive() && player->IsWithinDistInMap(me, 6.0f))
                                    {
                                        DoCastAOE(SPELL_TRAMPLE);
                                        events.ScheduleEvent(EVENT_TRAMPLE, 4*IN_MILLISECONDS);
                                        break;
                                    }
                                }
                            }
                        }
                        break;
                    case 6:
                        if (!_trampleCasted)
                        {
                            DoCast(me, SPELL_STAGGERED_DAZE);
                            Talk(EMOTE_TRAMPLE_CRASH);
                        }
                        else
                        {
                            DoCast(me, SPELL_FROTHING_RAGE, true);
                            Talk(EMOTE_TRAMPLE_FAIL);
                        }
                        _movementStarted = false;
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
                        SetCombatMovement(true);
                        me->GetMotionMaster()->MovementExpired();
                        me->GetMotionMaster()->Clear();
                        me->GetMotionMaster()->MoveChase(me->GetVictim());
                        AttackStart(me->GetVictim());
                        events.ScheduleEvent(EVENT_MASSIVE_CRASH, 40*IN_MILLISECONDS);
                        events.ScheduleEvent(EVENT_ARCTIC_BREATH, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
                        _stage = 0;
                        break;
                    default:
                        break;
                }
            }