/*
 * Copyright (C) 
 * Copyright (C) 
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/* ScriptData
SDName: Isle_of_Queldanas
SD%Complete: 100
SDComment: Quest support: 11524, 11525, 11532, 11533, 11542, 11543, 11541
SDCategory: Isle Of Quel'Danas
EndScriptData */

/* ContentData
npc_converted_sentry
npc_greengill_slave
EndContentData */

#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "Player.h"
#include "Pet.h"
#include "SpellInfo.h"

/*###### OUR: ######*/

enum ThalorienNpcs
{
    NPC_THALORIEN_REMAINS = 37552,
    NPC_SUNWELL_DEFENDER = 37211,
    NPC_THALORIEN_KILL_CREDIT = 37601,
    NPC_MORLEN_COLDGRIP = 37542,
    NPC_SCOURGE_ZOMBIE = 37538,
    NPC_GHOUL_INVADER = 37539,
    NPC_CRYPT_RAIDER = 37541,
};

enum ThalorienEvents
{
    EVENT_NONE = 0,
    EVENT_CHECK_PLAYER,
    EVENT_SUMMON_SOLDIERS,
    EVENT_TALK_INTRO_0,
    EVENT_TALK_INTRO_1,
    EVENT_TALK_INTRO_2,
    EVENT_TALK_INTRO_3,
    EVENT_SALUTE,
    EVENT_SOLDIERS_RUN_AWAY,
    EVENT_GO_FIGHTPOINT,
    EVENT_TALK_SPAWN_0,
    EVENT_TALK_SPAWN_1,
    EVENT_SUMMON_MORLEN,
    EVENT_TALK_MORLEN_0,
    EVENT_TALK_MORLEN_1,
    EVENT_SPAWN_WAVE_1,
    EVENT_SPAWN_WAVE_2,
    EVENT_SPAWN_WAVE_3,
    EVENT_SUMMONS_ATTACK,
    EVENT_OUTRO_0,
    EVENT_OUTRO_1,
    EVENT_OUTRO_2,
    EVENT_OUTRO_3,
    EVENT_OUTRO_KNEEL,
    EVENT_DISAPPEAR,
    EVENT_SET_FACING,
    EVENT_SPELL_BLADESTORM,
    EVENT_SPELL_MORTAL_STRIKE,
    EVENT_SPELL_HEROIC_STRIKE,
};

enum ThalorienTexts
{
    SAY_INTRO_0 = 0,
    SAY_INTRO_1 = 1,
    SAY_INTRO_2 = 2,
    SAY_INTRO_3 = 3,
    SAY_SPAWN_0 = 4,
    SAY_SPAWN_1 = 5,
    SAY_MORLEN_0 = 0,
    SAY_MORLEN_1 = 1,
    SAY_MORLEN_2 = 2,
    SAY_MORLEN_3 = 3,
    SAY_MORLEN_4 = 4,
    SAY_OUTRO_0 = 6,
    SAY_OUTRO_1 = 7,
    SAY_OUTRO_2 = 8,
    SAY_OUTRO_3 = 9,
};

#define SUNWELL_DEFENDER_NUM 10
const Position SunwellDefenderPos[SUNWELL_DEFENDER_NUM] =
{
    {11801.6f, -7070.91f, 25.5347f, 2.7428f},
    {11800.8f, -7073.11f, 25.7903f, 2.78207f},
    {11799.9f, -7075.29f, 26.1329f, 2.78207f},
    {11799.1f, -7077.46f, 26.3211f, 2.78207f},
    {11798.1f, -7080.09f, 26.1556f, 2.78207f},
    {11795.1f, -7078.93f, 26.1822f, 2.77814f},
    {11796.0f, -7076.32f, 26.4659f, 2.79778f},
    {11797.0f, -7073.71f, 26.3534f, 2.79778f},
    {11797.8f, -7071.5f, 26.0573f, 2.79778f},
    {11798.7f, -7068.83f, 25.6424f, 2.79778f}
};

class npc_bh_thalorien_dawnseeker : public CreatureScript
{
public:
    npc_bh_thalorien_dawnseeker() : CreatureScript("npc_bh_thalorien_dawnseeker") { }

    CreatureAI *GetAI(Creature *creature) const
    {
        return new npc_bh_thalorien_dawnseekerAI(creature);
    }

    struct npc_bh_thalorien_dawnseekerAI : public ScriptedAI
    {
        npc_bh_thalorien_dawnseekerAI(Creature *c) : ScriptedAI(c), summons(me)
        {
        }

        EventMap events;
        SummonList summons;
        uint64 playerGUID;
        uint64 morlenGUID;

        void Reset()
        {
            me->SetVisible(false);
            me->SetRegeneratingHealth(true);
            me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
            me->SetStandState(UNIT_STAND_STATE_STAND);
            playerGUID = 0;
            morlenGUID = 0;
            summons.DespawnAll();
            if (Creature* c = me->FindNearestCreature(NPC_THALORIEN_REMAINS, 100.0f, true))
                c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
            events.Reset();
            events.ScheduleEvent(EVENT_CHECK_PLAYER, 5000);
            events.ScheduleEvent(EVENT_SUMMON_SOLDIERS, 0);
            events.ScheduleEvent(EVENT_TALK_INTRO_0, 3000);
            events.ScheduleEvent(EVENT_TALK_INTRO_1, 8000);
            events.ScheduleEvent(EVENT_TALK_INTRO_2, 15000);
            events.ScheduleEvent(EVENT_TALK_INTRO_3, 22000);
            events.ScheduleEvent(EVENT_SALUTE, 24000);
            events.ScheduleEvent(EVENT_SOLDIERS_RUN_AWAY, 30000);
            events.ScheduleEvent(EVENT_GO_FIGHTPOINT, 31000);
            events.ScheduleEvent(EVENT_TALK_SPAWN_0, 38000);
            events.ScheduleEvent(EVENT_SUMMON_MORLEN, 44000);
            events.ScheduleEvent(EVENT_TALK_SPAWN_1, 47000);
            events.ScheduleEvent(EVENT_TALK_MORLEN_0, 52000);
            events.ScheduleEvent(EVENT_TALK_MORLEN_1, 58000);
            events.ScheduleEvent(EVENT_SPAWN_WAVE_1, 61000);

            events.ScheduleEvent(EVENT_SPELL_BLADESTORM, urand(6000, 15000));
            events.ScheduleEvent(EVENT_SPELL_MORTAL_STRIKE, urand(3000, 7000));
            events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, urand(4000, 10000));
        }

        void JustSummoned(Creature* summon)
        {
            summons.Summon(summon);
        }

        void SummonedCreatureDespawn(Creature* summon)
        {
            summons.Despawn(summon);
            if (summon->GetEntry() != NPC_SUNWELL_DEFENDER && me->isActiveObject())
            {
                if (summon->GetEntry() == NPC_MORLEN_COLDGRIP)
                {
                    me->RemoveAurasDueToSpell(67541);
                    me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
                    me->GetMotionMaster()->MoveCharge(11779.30f, -7065.43f, 24.92f, me->GetSpeed(MOVE_RUN), EVENT_CHARGE);
                    events.ScheduleEvent(EVENT_OUTRO_0, 0);
                    events.ScheduleEvent(EVENT_OUTRO_1, 5000);
                    events.ScheduleEvent(EVENT_OUTRO_2, 12000);
                    events.ScheduleEvent(EVENT_OUTRO_3, 19000);
                }
                else if (summons.size() == 1)
                {
                    me->RemoveAurasDueToSpell(67541);
                    me->GetMotionMaster()->MoveCharge(11779.30f, -7065.43f, 24.92f, me->GetSpeed(MOVE_RUN), EVENT_CHARGE);
                    switch(summon->GetEntry())
                    {
                        case NPC_SCOURGE_ZOMBIE:
                            events.ScheduleEvent(EVENT_SPAWN_WAVE_2, 3000);
                            break;
                        case NPC_GHOUL_INVADER:
                            events.ScheduleEvent(EVENT_SPAWN_WAVE_3, 3000);
                            break;
                        case NPC_CRYPT_RAIDER:
                            events.ScheduleEvent(EVENT_SUMMONS_ATTACK, 3000);
                            break;
                    }
                }
            }
        }

        void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
        {
            if (damage >= me->GetHealth())
            {
                damage = 0;
                me->setActive(false);
                EnterEvadeMode();
            }
        }

        void UpdateAI(uint32 diff)
        {
            if (!me->isActiveObject())
                return;

            UpdateVictim();

            events.Update(diff);

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

            switch (uint32 evId = events.GetEvent())
            {
                case 0:
                    break;
                case EVENT_CHECK_PLAYER:
                    if (Player* p = ObjectAccessor::GetPlayer(*me, playerGUID))
                        if (p->GetExactDist(me) <= 50.0f)
                        {
                            events.RepeatEvent(5000);
                            break;
                        }
                    events.PopEvent();
                    me->setActive(false);
                    EnterEvadeMode();
                    return;
                case EVENT_SUMMON_SOLDIERS:
                    for (uint8 i=0; i<SUNWELL_DEFENDER_NUM; ++i)
                        me->SummonCreature(NPC_SUNWELL_DEFENDER, SunwellDefenderPos[i], TEMPSUMMON_TIMED_DESPAWN, 33000+(i/5)*5000);
                    events.PopEvent();
                    break;
                case EVENT_TALK_INTRO_0:
                case EVENT_TALK_INTRO_1:
                case EVENT_TALK_INTRO_2:
                case EVENT_TALK_INTRO_3:
                    Talk(SAY_INTRO_0 + (evId-EVENT_TALK_INTRO_0));
                    events.PopEvent();
                    break;
                case EVENT_SALUTE:
                    me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
                    for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
                        if (Creature* c = ObjectAccessor::GetCreature(*me, *itr))
                            c->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
                    events.PopEvent();
                    break;
                case EVENT_SOLDIERS_RUN_AWAY:
                    {
                        uint8 count = 0;
                        for (SummonList::iterator itr = summons.begin(); itr != summons.end();)
                        {
                            ++count;
                            if (Creature* c = ObjectAccessor::GetCreature(*me, *itr))
                            {
                                c->SetWalk(false);
                                c->GetMotionMaster()->MovePoint(0, 11863.35f, -7073.44f, 27.40f);
                            }
                            SummonList::iterator itr2 = itr++;
                            summons.erase(itr2);
                            if (count >= 5)
                            {
                                if (!summons.empty())
                                {
                                    events.RepeatEvent(5000);
                                    return;
                                }
                                else
                                {
                                    events.PopEvent();
                                    return;
                                }
                            }
                        }
                    }
                    events.PopEvent();
                    break;
                case EVENT_GO_FIGHTPOINT:
                    me->SetWalk(true);
                    me->GetMotionMaster()->MovePoint(0, 11779.30f, -7065.43f, 24.92f);
                    me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
                    events.PopEvent();
                    break;
                case EVENT_TALK_SPAWN_0:
                case EVENT_TALK_SPAWN_1:
                    Talk(SAY_SPAWN_0 + (evId-EVENT_TALK_SPAWN_0));
                    events.PopEvent();
                    break;
                case EVENT_SUMMON_MORLEN:
                    if (Creature* c = me->SummonCreature(NPC_MORLEN_COLDGRIP, 11766.70f, -7050.57f, 25.17f, 5.56f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000))
                        morlenGUID = c->GetGUID();
                    events.PopEvent();
                    break;
                case EVENT_TALK_MORLEN_0:
                case EVENT_TALK_MORLEN_1:
                    if (Creature* c = ObjectAccessor::GetCreature(*me, morlenGUID))
                        c->AI()->Talk(SAY_MORLEN_0 + (evId-EVENT_TALK_MORLEN_0));
                    events.PopEvent();
                    break;
                case EVENT_SPAWN_WAVE_1:
                case EVENT_SPAWN_WAVE_2:
                case EVENT_SPAWN_WAVE_3:
                    if (Creature* c = ObjectAccessor::GetCreature(*me, morlenGUID))
                    {
                        c->AI()->Talk(SAY_MORLEN_1 + (evId-EVENT_SPAWN_WAVE_1));
                        switch (evId)
                        {
                            // emerge cast tr false 66947
                            case EVENT_SPAWN_WAVE_1:
                                {
                                    Position spawnPos;
                                    c->GetPosition(&spawnPos);
                                    spawnPos.m_orientation = 5.80f;
                                    spawnPos.m_positionX += 5.0f*cos(4.5f);
                                    spawnPos.m_positionY += 5.0f*sin(4.5f);
                                    for (uint8 i=0; i<5; ++i)
                                        if (Creature* s = me->SummonCreature(NPC_SCOURGE_ZOMBIE, spawnPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000))
                                        {
                                            spawnPos.m_positionX += 2.5f*cos(4.5f);
                                            spawnPos.m_positionY += 2.5f*sin(4.5f);
                                        }
                                }
                                break;
                            case EVENT_SPAWN_WAVE_2:
                                {
                                    Position spawnPos;
                                    c->GetPosition(&spawnPos);
                                    spawnPos.m_orientation = 5.80f;
                                    spawnPos.m_positionX += 7.0f*cos(4.0f);
                                    spawnPos.m_positionY += 7.0f*sin(4.0f);
                                    for (uint8 i=0; i<3; ++i)
                                        if (Creature* s = me->SummonCreature(NPC_GHOUL_INVADER, spawnPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000))
                                        {
                                            s->CastSpell(s, 66947, false); // emerge effect
                                            spawnPos.m_positionX += 4.0f*cos(4.5f);
                                            spawnPos.m_positionY += 4.0f*sin(4.5f);
                                        }
                                }
                                break;
                            case EVENT_SPAWN_WAVE_3:
                                {
                                    Position spawnPos;
                                    c->GetPosition(&spawnPos);
                                    spawnPos.m_orientation = 5.80f;
                                    spawnPos.m_positionX += 8.0f*cos(4.0f);
                                    spawnPos.m_positionY += 8.0f*sin(4.0f);
                                    for (uint8 i=0; i<3; ++i)
                                        if (Creature* s = me->SummonCreature(NPC_CRYPT_RAIDER, spawnPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000))
                                        {
                                            s->CastSpell(s, 66947, false); // emerge effect
                                            spawnPos.m_positionX += 4.0f*cos(4.5f);
                                            spawnPos.m_positionY += 4.0f*sin(4.5f);
                                        }
                                }
                                break;
                        }
                    }
                    events.PopEvent();
                    events.ScheduleEvent(EVENT_SUMMONS_ATTACK, 3000);
                    break;
                case EVENT_SUMMONS_ATTACK:
                    for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
                        if (Creature* c = ObjectAccessor::GetCreature(*me, *itr))
                        {
                            if (c->GetEntry() == NPC_MORLEN_COLDGRIP && summons.size() != 1)
                                continue;
                            else
                                c->AI()->Talk(SAY_MORLEN_4);
                            c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
                            c->AI()->AttackStart(me);
                        }
                    events.PopEvent();
                    break;
                case EVENT_OUTRO_0:
                case EVENT_OUTRO_1:
                case EVENT_OUTRO_2:
                case EVENT_OUTRO_3:
                    Talk(SAY_OUTRO_0 + (evId-EVENT_OUTRO_0));
                    events.PopEvent();
                    if (evId == EVENT_OUTRO_3)
                        events.ScheduleEvent(EVENT_OUTRO_KNEEL, 6000);
                    break;
                case EVENT_OUTRO_KNEEL:
                    if (Player* p = ObjectAccessor::GetPlayer(*me, playerGUID))
                        p->KilledMonsterCredit(NPC_THALORIEN_KILL_CREDIT, 0);
                    me->SetStandState(UNIT_STAND_STATE_KNEEL);
                    events.PopEvent();
                    events.ScheduleEvent(EVENT_DISAPPEAR, 6000);
                    break;
                case EVENT_DISAPPEAR:
                    events.PopEvent();
                    me->SetVisible(false);
                    me->setActive(false);
                    EnterEvadeMode();
                    break;
                case EVENT_SET_FACING:
                    me->SetFacingTo(2.45f);
                    events.PopEvent();
                    break;

                case EVENT_SPELL_BLADESTORM:
                    if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
                        me->CastSpell(me->GetVictim(), 67541, false);
                    events.RepeatEvent(urand(25000, 35000));
                    break;
                case EVENT_SPELL_MORTAL_STRIKE:
                    if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
                        me->CastSpell(me->GetVictim(), 67542, false);
                    events.RepeatEvent(urand(7000, 12000));
                    break;
                case EVENT_SPELL_HEROIC_STRIKE:
                    if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
                        me->CastSpell(me->GetVictim(), 57846, false);
                    events.RepeatEvent(urand(5000, 10000));
                    break;
            }

            DoMeleeAttackIfReady();
        }

        void MovementInform(uint32 type, uint32 id)
        {
            if (type == POINT_MOTION_TYPE && id == EVENT_CHARGE)
                events.ScheduleEvent(EVENT_SET_FACING, 0);
        }

        void EnterEvadeMode()
        {
            if (me->isActiveObject())
                return;
            ScriptedAI::EnterEvadeMode();
        }

        void SetData(uint32 type, uint32 id)
        {
            if (type == 1 && id == 1 && !me->isActiveObject())
                if (Player* p = me->SelectNearestPlayer(50.0f))
                {
                    me->SetVisible(true);
                    me->SetRegeneratingHealth(false);
                    me->setActive(true);
                    playerGUID = p->GetGUID();
                }
        }
    };
};

enum PurificationIds
{
    GO_QUEL_DELAR = 201794,
    NPC_SUNWELL_VISUAL_BUNNY = 37000,
    NPC_SUNWELL_HONOR_GUARD = 37781,
    NPC_ROMMATH = 37763,
    NPC_GALIROS = 38056,
    NPC_THERON = 37764,
    NPC_AURIC = 37765,
};

class spell_bh_cleanse_quel_delar : public SpellScriptLoader
{
public:
    spell_bh_cleanse_quel_delar() : SpellScriptLoader("spell_bh_cleanse_quel_delar") { }

    class spell_bh_cleanse_quel_delar_SpellScript : public SpellScript
    {
        PrepareSpellScript(spell_bh_cleanse_quel_delar_SpellScript);

        void OnEffect(SpellEffIndex effIndex)
        {
            if (Unit* caster = GetCaster())
                if (Creature* c = caster->FindNearestCreature(NPC_ROMMATH, 50.0f, true))
                    c->AI()->DoAction(-1);
        }

        void Register()
        {
            OnEffectLaunch += SpellEffectFn(spell_bh_cleanse_quel_delar_SpellScript::OnEffect, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
        }
    };

    SpellScript* GetSpellScript() const
    {
        return new spell_bh_cleanse_quel_delar_SpellScript();
    }
};

class npc_grand_magister_rommath : public CreatureScript
{
public:
    npc_grand_magister_rommath() : CreatureScript("npc_grand_magister_rommath") { }

    CreatureAI *GetAI(Creature *creature) const
    {
        return new npc_grand_magister_rommathAI(creature);
    }

    struct npc_grand_magister_rommathAI : public NullCreatureAI
    {
        npc_grand_magister_rommathAI(Creature *c) : NullCreatureAI(c)
        {
            announced = false;
            playerGUID = 0;
            me->SetReactState(REACT_AGGRESSIVE);
        }

        EventMap events;
        bool announced;
        uint64 playerGUID;

        void MoveInLineOfSight(Unit* who)
        {
            if (!announced && who->GetTypeId() == TYPEID_PLAYER && who->GetPositionZ() < 30.0f)
            {
                announced = true;
                playerGUID = who->GetGUID();
                if (Creature* c = me->FindNearestCreature(NPC_GALIROS, 100.0f, true))
                    c->AI()->Talk(0, who);
            }
        }

        void DoAction(int32 a)
        {
            if (a == -1 && !me->isActiveObject())
            {
                me->SummonGameObject(GO_QUEL_DELAR, 1688.24f, 621.769f, 29.1745f, 0.523177f, 0.0f, 0.0f, 0.0f, 0.0f, 86400);
                me->SummonCreature(NPC_SUNWELL_VISUAL_BUNNY, 1688.24f, 621.769f, 29.1745f, 0.523177f, TEMPSUMMON_MANUAL_DESPAWN);
                me->setActive(true);
                events.Reset();
                events.ScheduleEvent(1, 1000); // guard talk
                events.ScheduleEvent(2, 4000); // theron talk
                events.ScheduleEvent(3, 10000); // npcs walk
                events.ScheduleEvent(4, 17000); // rommath talk
                events.ScheduleEvent(5, 20000); // theron talk
                events.ScheduleEvent(6, 28000); // theron talk
                events.ScheduleEvent(7, 37000); // rommath talk
                events.ScheduleEvent(8, 44000); // rommath talk
                events.ScheduleEvent(9, 52000); // rommath talk
                events.ScheduleEvent(10, 60000); // auric talk
                events.ScheduleEvent(11, 66000); // auric talk
                events.ScheduleEvent(12, 76000); // rommath talk
                events.ScheduleEvent(13, 80000); // move home
            }
        }

        void UpdateAI(uint32 diff)
        {
            if (!me->isActiveObject())
                return;

            events.Update(diff);

            switch (events.ExecuteEvent())
            {
                case 1:
                    if (Creature* c = me->FindNearestCreature(NPC_SUNWELL_HONOR_GUARD, 60.0f, true))
                        c->AI()->Talk(0);
                    break;
                case 2:
                    if (Creature* c = me->FindNearestCreature(NPC_THERON, 60.0f, true))
                        c->AI()->Talk(0);
                    break;
                case 3:
                    me->SetWalk(true);
                    me->GetMotionMaster()->MovePath(me->GetEntry()*100, false);
                    if (Creature* c = me->FindNearestCreature(NPC_THERON, 60.0f, true))
                    {
                        c->SetWalk(true);
                        c->GetMotionMaster()->MovePath(c->GetEntry()*100, false);
                    }
                    if (Creature* c = me->FindNearestCreature(NPC_AURIC, 60.0f, true))
                    {
                        c->SetWalk(true);
                        c->GetMotionMaster()->MovePath(c->GetEntry()*100, false);
                    }
                    break;
                case 4:
                    Talk(0);
                    break;
                case 5:
                    if (Creature* c = me->FindNearestCreature(NPC_THERON, 60.0f, true))
                        c->AI()->Talk(1);
                    break;
                case 6:
                    if (Creature* c = me->FindNearestCreature(NPC_THERON, 60.0f, true))
                        c->AI()->Talk(2, ObjectAccessor::GetPlayer(*me, playerGUID));
                    break;
                case 7:
                    Talk(1, ObjectAccessor::GetPlayer(*me, playerGUID));
                    break;
                case 8:
                    Talk(2);
                    break;
                case 9:
                    Talk(3);
                    break;
                case 10:
                    if (Creature* c = me->FindNearestCreature(NPC_AURIC, 60.0f, true))
                        c->AI()->Talk(0);
                    break;
                case 11:
                    if (Creature* c = me->FindNearestCreature(NPC_AURIC, 60.0f, true))
                        c->AI()->Talk(1);
                    break;
                case 12:
                    if (Player* p = ObjectAccessor::GetPlayer(*me, playerGUID))
                        Talk(p->GetTeamId() == TEAM_ALLIANCE ? 5 : 4, p);
                    break;
                case 13:
                    me->setActive(false);
                    if (Creature* c = me->FindNearestCreature(NPC_SUNWELL_VISUAL_BUNNY, 60.0f, true))
                        c->DespawnOrUnsummon(1);
                    if (GameObject* go = me->FindNearestGameObject(GO_QUEL_DELAR, 60.0f))
                        go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
                    me->SetWalk(true);
                    if (me->GetCreatureData())
                        me->GetMotionMaster()->MovePoint(0, me->GetCreatureData()->posX, me->GetCreatureData()->posY, me->GetCreatureData()->posZ);
                    if (Creature* c = me->FindNearestCreature(NPC_THERON, 60.0f, true))
                    {
                        c->SetWalk(true);
                        if (c->GetCreatureData())
                            c->GetMotionMaster()->MovePoint(0, c->GetCreatureData()->posX, c->GetCreatureData()->posY, c->GetCreatureData()->posZ);
                    }
                    if (Creature* c = me->FindNearestCreature(NPC_AURIC, 60.0f, true))
                    {
                        c->SetWalk(true);
                        if (c->GetCreatureData())
                            c->GetMotionMaster()->MovePoint(0, c->GetCreatureData()->posX, c->GetCreatureData()->posY, c->GetCreatureData()->posZ);
                    }
                    break;
            }
        }
    };
};



/*###### THEIR: ######*/

/*######
## npc_greengill_slave
######*/

#define ENRAGE  45111
#define ORB     45109
#define QUESTG  11541
#define DM      25060

class npc_greengill_slave : public CreatureScript
{
public:
    npc_greengill_slave() : CreatureScript("npc_greengill_slave") { }

    CreatureAI* GetAI(Creature* creature) const
    {
        return new npc_greengill_slaveAI(creature);
    }

    struct npc_greengill_slaveAI : public ScriptedAI
    {
        npc_greengill_slaveAI(Creature* creature) : ScriptedAI(creature) { }

        void EnterCombat(Unit* /*who*/) { }

        void SpellHit(Unit* caster, SpellInfo const* spellInfo)
        {
            Player* player = caster->ToPlayer();
            if (!player)
                return;

            if (spellInfo->Id == ORB && !me->HasAura(ENRAGE))
            {
                if (player->GetQuestStatus(QUESTG) == QUEST_STATUS_INCOMPLETE)
                    DoCast(player, 45110, true);

                DoCast(me, ENRAGE);

                if (Creature* Myrmidon = me->FindNearestCreature(DM, 70))
                {
                    me->AddThreat(Myrmidon, 100000.0f);
                    AttackStart(Myrmidon);
                }
            }
        }

        void UpdateAI(uint32 /*diff*/)
        {
            DoMeleeAttackIfReady();
        }
    };
};

void AddSC_isle_of_queldanas()
{
    // OUR:
    new npc_bh_thalorien_dawnseeker();
    new spell_bh_cleanse_quel_delar();
    new npc_grand_magister_rommath();

    // THEIR:
    new npc_greengill_slave();
}
