All pastes #903023 Raw Edit

Shade of Akama

public cpp v1 · immutable
·published 2008-02-13 22:47 UTC
rendered paste body
/* Copyright (C) 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>* 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, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* ScriptDataSDName: Boss_Shade_of_AkamaSD%Complete: 0SDComment: VERIFY SCRIPTSDCategory: Black TempleEndScriptData */#include "../../sc_defines.h"#include "../../../../../shared/WorldPacket.h"#include "../../../../../game/TargetedMovementGenerator.h"#include "../../../../../game/Player.h"#include "../../../../../game/GossipDef.h"struct Location{    float x, y, o;};static Location ChannelerLocations[]={    {463.161285, 401.219757, 3.141592},    {457.377625, 391.227661, 2.106461},    {446.012421, 391.227661, 1.071904},    {439.533783, 401.219757, 0.000000},    {446.012421, 411.211853, 5.210546},    {457.377625, 411.211853, 4.177494}};static Location SpawnLocations[]={    {498.652740, 461.728119, 0},    {498.505003, 339.619324, 0}};// Locations#define Z1              118.543144#define Z2              120.783768#define Z_SPAWN         113.537949// Texts#define SOUND_LOW_HEALTH            11386#define SAY_LOW_HEALTH              "No! Not yet..."#define SOUND_EVEN_LOWER_HEALTH     11385#define SAY_EVEN_LOWER_HEALTH       "I will not last much longer..."// Gossips#define GOSSIP_ITEM                 "It is time to free your soul from Illidan's grasp!"// Spells#define SPELL_PASSIVE_SHADOWFORM    41913#define SPELL_BEAM                  39123#define SPELL_RED_BEAM              36295#define SPELL_DESTRUCTIVE_POISON    40874#define SPELL_LIGHTNING_BOLT        42024#define SPELL_AKAMA_SOUL_EXPEL      40855#define SPELL_AKAMA_SOUL_RETRIEVE   40447// Channeler entry#define CREATURE_CHANNELER          23421#define CREATURE_SORCERER           23215const uint32 spawnEntries[4]={    23216,    23523,    23318,    23524};struct MANGOS_DLL_DECL mob_ashtongue_channelerAI : public ScriptedAI{    mob_ashtongue_channelerAI(Creature* c) : ScriptedAI(c)    {        SetVariables();    }    uint64 ShadeGUID;    bool InCombat;    void SetVariables()    {        ShadeGUID = 0;    }    void EnterEvadeMode()    {        SetVariables();        InCombat = false;        m_creature->RemoveAllAuras();        m_creature->DeleteThreatList();        m_creature->CombatStop();        DoGoHome();    }    void SetShadeGUID(uint64 guid)    {        ShadeGUID = guid;        outstring_log("DEBUG: Shade GUID: %u set in Ashtongue Channeler script. Channeler GUID: %u", ShadeGUID, m_creature->GetGUID());    }    void JustDied(Unit* killer);    void AttackStart(Unit* who)    {        if(!InCombat) InCombat = true;    }    void MoveInLineOfSight(Unit* who)    {        if(!InCombat) InCombat = true;                if(ShadeGUID)        {            Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);            if(Shade)                DoCast(Shade, SPELL_BEAM);        }    }    void UpdateAI(const uint32 diff)    {        if(InCombat)            m_creature->SetInCombat();    }};struct MANGOS_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI{    mob_ashtongue_sorcererAI(Creature* c) : ScriptedAI(c)    {        SetVariables();        pInstance = ((ScriptedInstance*)c->GetInstanceData());    }    ScriptedInstance* pInstance;    uint64 ShadeGUID;    bool StartBanishing;    bool InCombat;    void SetVariables()    {        ShadeGUID = 0;        StartBanishing = false;    }    void EnterEvadeMode()    {        SetVariables();        InCombat = false;        m_creature->RemoveAllAuras();        m_creature->DeleteThreatList();        m_creature->CombatStop();        DoGoHome();    }    void JustDied(Unit* killer);    void AttackStart(Unit* who)    {        if(!InCombat) InCombat = true;    }    void MoveInLineOfSight(Unit* who)    {        if(!InCombat) InCombat = true;    }    void UpdateAI(const uint32 diff)    {        if(InCombat)            m_creature->SetInCombat();                if(ShadeGUID)        {            Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);            if(Shade)            {                if(m_creature->GetDistance2d(Shade) < 20)                {                    m_creature->GetMotionMaster()->Clear(false);                    m_creature->GetMotionMaster()->Idle();                    DoCast(Shade, SPELL_BEAM);                }            }        }else        {            error_log("ERROR: Shade GUID invalid in Sorcerer script");            if(pInstance)                ShadeGUID = pInstance->GetData64("ShadeOfAkama");        }    }};struct MANGOS_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI{    boss_shade_of_akamaAI(Creature* c) : ScriptedAI(c)    {        SetVariables();        pInstance = ((ScriptedInstance*)c->GetInstanceData());    }    ScriptedInstance* pInstance;    uint64 ChannelerGUID[6];    uint64 AkamaGUID;    uint32 DeathCount;    uint32 ReduceHealthTimer;    uint32 EnrageTimer;    uint32 SummonTimer;    uint32 ResetTimer;    bool Enrage;    bool SummonedChannelers;    bool IsBanished;    bool InCombat;    bool HasKilledAkama;    void SetVariables()    {        if(SummonedChannelers)        {            for(uint8 i = 0; i < 6; i++)            {                Creature* Channeler = NULL;                Channeler = ((Creature*)Unit::GetUnit((*m_creature), ChannelerGUID[i]));                if(Channeler && Channeler->isAlive())                {                    Channeler->SetVisibility(VISIBILITY_OFF);                    Channeler->DealDamage(Channeler, Channeler->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);                }                ChannelerGUID[i] = 0;            }            SummonedChannelers = false;        }        AkamaGUID = 0;        DeathCount = 0;        EnrageTimer = 600000;        SummonTimer = 20000;        ReduceHealthTimer = 0;        ResetTimer = 60000;        Enrage = false;        IsBanished = true;        InCombat = false;        HasKilledAkama = false;        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, SPELL_AURA_MOD_TAUNT, true);        m_creature->SetVisibility(VISIBILITY_ON);        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);        m_creature->GetMotionMaster()->Clear(false);        m_creature->GetMotionMaster()->Idle();        m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN);    }    void EnterEvadeMode()    {        SetVariables();        m_creature->DeleteThreatList();        m_creature->RemoveAllAuras();        DoCast(m_creature, SPELL_PASSIVE_SHADOWFORM);        m_creature->CombatStop();        DoGoHome();    }    void AttackStart(Unit* who)    {        if(!who || IsBanished)            return;                if(who->isTargetableForAttack() && who != m_creature)                DoStartMeleeAttack(who);    }    void MoveInLineOfSight(Unit* who)    {        if(who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))        {            float attackRadius = m_creature->GetAttackDistance(who);            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))            {                if(who->HasStealthAura())                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);                if(who && who->isAlive())                    m_creature->AddThreat(who, 1.0f);            }        }    }    void SummonCreature()    {        uint32 entry = spawnEntries[rand()%4];        uint32 random = rand()%2;        float X = SpawnLocations[random].x;        float Y = SpawnLocations[random].y;        if((rand()%5 == 0) && DeathCount > 0)        {            outstring_log("DEBUG: Summoning Ashtongue Sorcerer!");            Creature* Sorcerer = m_creature->SummonCreature(CREATURE_SORCERER, X, Y, Z_SPAWN, 0, TEMPSUMMON_DEAD_DESPAWN, 0);            if(Sorcerer)            {                outstring_log("DEBUG: Ashtongue Sorcerer summoned at X: %f, Y: %f, Z: %f", X,Y,Z_SPAWN);                Sorcerer->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature));                for(uint8 i = 0; i < 6; i++)                {                    if(!ChannelerGUID[i])                    {                        outstring_log("DEBUG: Ashtongue Sorcerer GUID set to ChannelerGUID %d, and is %u", i, Sorcerer->GetGUID());                        ChannelerGUID[i] = Sorcerer->GetGUID();                        break;                    }                }                DeathCount--;                outstring_log("DEBUG: Decremented Death Count. It is now %d", DeathCount);            }        }        else        {            Creature* Spawn = m_creature->SummonCreature(entry, X, Y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);            if(Spawn)                Spawn->AddThreat(SelectUnit(SELECT_TARGET_RANDOM, 0), 1.0f);        }    }    void SetSelectableChannelers()    {        if(!SummonedChannelers)             return;        for(uint8 i = 0; i < 6; i++)        {            Unit* Channeler = Unit::GetUnit((*m_creature), ChannelerGUID[i]);            if(Channeler && Channeler->isAlive())            {                Channeler->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                outstring_log("DEBUG: Shade of Akama Event - Removing unselectable flag from Channeler %u. GUID: %u",i, ChannelerGUID[i]);            }            else error_log("ERROR: Shade of Akama event - unable to find Channeler to set selectable. ChannelerGUID: %u", ChannelerGUID[i]);        }    }    void SetAkamaGUID(uint64 guid)    {        if(guid)        {            AkamaGUID = guid;            outstring_log("DEBUG: Shade of Akama - setting Akama's GUID to %u.", guid);        }    }    void UpdateAI(const uint32 diff)    {        if(!SummonedChannelers)        {            for(uint8 i = 0; i < 6; i++)            {                ChannelerGUID[i] = 0;                Creature* Channeler = NULL;                float x = ChannelerLocations[i].x;                float y = ChannelerLocations[i].y;                float o = ChannelerLocations[i].o;                Channeler = m_creature->SummonCreature(CREATURE_CHANNELER, x, y, m_creature->GetPositionZ(), o, TEMPSUMMON_DEAD_DESPAWN, 1000);                if(Channeler)                {                    outstring_log("DEBUG: Shade of Akama Encounter: Channeler %u summoned at X: %f, Y: %f, Z: %f, with orientation %f", i, x, y, m_creature->GetPositionZ(), o);                    Channeler->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                    Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                    Channeler->CastSpell(m_creature, SPELL_BEAM, false);                    ((mob_ashtongue_channelerAI*)Channeler->AI())->SetShadeGUID(m_creature->GetGUID());                    ChannelerGUID[i] = Channeler->GetGUID();                }                else // Debug                    error_log("ERROR: Shade Of Akama Encounter: Unable to spawn Channeler %u! X: %f, Y: %f, o: %f", i, x, y, o);            }            if(!m_creature->HasAura(SPELL_PASSIVE_SHADOWFORM, 0)) DoCast(m_creature, SPELL_PASSIVE_SHADOWFORM, true);            SummonedChannelers = true;        }        if(!InCombat)            return;        if(m_creature->getThreatManager().getThreatList().empty())            EnterEvadeMode();        if(IsBanished)        {            if(!m_creature->GetMotionMaster()->empty())            {                m_creature->GetMotionMaster()->Clear(false);                m_creature->GetMotionMaster()->Idle();            }            if(SummonTimer < diff)            {                SummonCreature();                SummonCreature();                SummonTimer = Enrage ? 10000 : 15000; // Spawn them faster if enraged            }else SummonTimer -= diff;            if(DeathCount >= 6)            {                for(uint8 i = 0; i < 6; i++)                    ChannelerGUID[i] = 0;                if(AkamaGUID)                {                    Unit* Akama = Unit::GetUnit((*m_creature), AkamaGUID);                    if(Akama && Akama->isAlive())                    {                        IsBanished = false;                        m_creature->GetMotionMaster()->Clear(false);                        m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*Akama));                        Akama->GetMotionMaster()->Clear(false);                        Akama->GetMotionMaster()->Idle(); // Shade should move to Akama, not the other way around                        m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);                        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                        m_creature->AddThreat(Akama, 1000000.0f); // Crazy amount of threat                        Akama->AddThreat(m_creature, 1000000.0f);                        m_creature->Attack(Akama);                        Akama->Attack(m_creature);                    }else // Debug                        error_log("ERROR: Shade of Akama free but Akama is dead or missing");                }else                {                    error_log("ERROR: Shade of Akama Event - Shade cannot initiate combat with Akama - Akama's GUID is missing");                    outstring_log("DEBUG: Attempting to acquire Akama's GUID using Instance Data.");                    if(pInstance)                    {                        AkamaGUID = pInstance->GetData64("Akama(Shade)");                        if(AkamaGUID)                            outstring_log("DEBUG: Akama's GUID acquired as: %u", AkamaGUID);                        else error_log("DEBUG: Akama GUID still invalid.");                    }else error_log("ERROR: Instance Data System not set properly. Unable to acquire Akama's GUID.");                }            }            // Only run this if we are not enraged            if(!Enrage)            {                if(EnrageTimer < diff)                    Enrage = true;                else EnrageTimer -= diff;            }        }        else // No longer banished, let's fight Akama now        {            if(ReduceHealthTimer < diff)            {                if(AkamaGUID)                {                    Unit* Akama = Unit::GetUnit((*m_creature), AkamaGUID);                    if(Akama && Akama->isAlive())                    {                        //10 % less health every few seconds.                        m_creature->DealDamage(Akama, Akama->GetMaxHealth()*0.1, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);                        ReduceHealthTimer = Enrage ? 5000 : 12000; // Reduce health more rapidly if enraged                    }                    else                    {                        HasKilledAkama = true; // Akama is dead or missing, we stop fighting and disappear                        m_creature->SetVisibility(VISIBILITY_OFF);                        DoGoHome();                        m_creature->SetHealth(m_creature->GetMaxHealth());                        m_creature->RemoveAllAuras();                        DoCast(m_creature, SPELL_PASSIVE_SHADOWFORM);                        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                    }                }                else // Debug                {                    error_log("ERROR: Shade of Akama Event - Shade is free but Akama's GUID is missing");                    outstring_log("DEBUG: Attempting to acquire Akama's GUID using Instance Data.");                    if(pInstance)                    {                        AkamaGUID = pInstance->GetData64("Akama(Shade)");                        if(AkamaGUID)                            outstring_log("DEBUG: Akama's GUID acquired as: %u", AkamaGUID);                        else error_log("DEBUG: Akama GUID still invalid.");                    }else error_log("ERROR: Instance Data System not set properly. Unable to acquire Akama's GUID.");                }            }else ReduceHealthTimer -= diff;            if(HasKilledAkama)            {                if(ResetTimer < diff)                    EnterEvadeMode(); // Reset a little while after killing Akama                else ResetTimer -= diff;            }            DoMeleeAttackIfReady();        }    }};void mob_ashtongue_channelerAI::JustDied(Unit* killer){    outstring_log("DEBUG: Ashtongue Channeler killed");    if(ShadeGUID)    {        Creature* Shade = ((Creature*)Unit::GetUnit((*m_creature), ShadeGUID));        if(Shade && Shade->isAlive())        {            ((boss_shade_of_akamaAI*)Shade->AI())->DeathCount++;        }else error_log("ERROR: Shade of Akama event: Channeler dead but Shade is dead or non-existant");    }else error_log("ERROR: Shade of Akama event: Channeler dead but Shade GUID is invalid.");}void mob_ashtongue_sorcererAI::JustDied(Unit* killer){    outstring_log("DEBUG: Ashtongue Sorcerer killed");    if(ShadeGUID)    {        Creature* Shade = ((Creature*)Unit::GetUnit((*m_creature), ShadeGUID));        if(Shade && Shade->isAlive())        {            ((boss_shade_of_akamaAI*)Shade->AI())->DeathCount++;        }else error_log("ERROR: Shade of Akama event: Sorcerer dead but Shade is dead or non-existant");    }else error_log("ERROR: Shade of Akama event: Sorcerer dead but Shade GUID is invalid.");}struct MANGOS_DLL_DECL npc_akamaAI : public ScriptedAI{    npc_akamaAI(Creature* c) : ScriptedAI(c)    {        SetVariables();        pInstance = ((ScriptedInstance*)c->GetInstanceData());    }    ScriptedInstance* pInstance;    uint64 ShadeGUID;    uint32 DestructivePoisonTimer;    uint32 LightningBoltTimer;    uint32 CheckTimer;    uint32 CastSoulRetrieveTimer;    bool InCombat;    bool EventBegun;    bool ShadeHasDied;    bool StartCombat;    bool HasYelledOnce;    bool HasYelledTwice;    void SetVariables()    {        DestructivePoisonTimer = 5000;        LightningBoltTimer = 10000;        CheckTimer = 2000;        CastSoulRetrieveTimer = 0;        InCombat = false;        EventBegun = false;        ShadeHasDied = false;        StartCombat = false;        HasYelledOnce = false;        HasYelledTwice = false;    }    void EnterEvadeMode()    {        SetVariables();        m_creature->RemoveAllAuras();        m_creature->DeleteThreatList();        m_creature->CombatStop();        DoGoHome();    }    void AttackStart(Unit* who)    {        if(!who)            return;        if(who->isTargetableForAttack() && who!=m_creature)            DoStartMeleeAttack(who);    }    void MoveInLineOfSight(Unit* who)    {        if(!who)            return;                if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))        {            float attackRadius = m_creature->GetAttackDistance(who);            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))            {                if(who->HasStealthAura())                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);                DoStartMeleeAttack(who);            }        }    }    void BeginEvent(Player* pl)    {        if(!pInstance)        {            error_log("ERROR: Unable to begin Shade of Akama event- Instance Data not set properly");            return;        }                ShadeGUID = pInstance->GetData64("ShadeOfAkama");        if(!ShadeGUID)        {            error_log("ERROR: Unable to begin Shade of Akama event- ShadeGUID is invalid");            return;        }        Creature* Shade = ((Creature*)Unit::GetUnit((*m_creature), ShadeGUID));        if(Shade)        {            pInstance->SetData("ShadeOfAkamaEvent", 1); // In Progress            m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Prevent players from trying to restart event            ((boss_shade_of_akamaAI*)Shade->AI())->SetAkamaGUID(m_creature->GetGUID());            ((boss_shade_of_akamaAI*)Shade->AI())->InCombat = true;            ((boss_shade_of_akamaAI*)Shade->AI())->SetSelectableChannelers();            if(pl)                Shade->AddThreat(pl, 1.0f);            outstring_log("DEBUG: Shade of Akama Event Begun. Shade GUID: %u, Akama GUID from Shade: %u, Akama GUID: %u. Player: %u, %c", ShadeGUID, ((boss_shade_of_akamaAI*)Shade->AI())->AkamaGUID, m_creature->GetGUID(), pl->GetGUID(), pl->GetName());            // DoCast(Shade, SPELL_AKAMA_SOUL_EXPEL);        }    }    void UpdateAI(const uint32 diff)    {        if(ShadeGUID && !StartCombat)        {            Creature* Shade = ((Creature*)Unit::GetUnit((*m_creature), ShadeGUID));            if(Shade && Shade->isAlive())            {                if(((boss_shade_of_akamaAI*)Shade->AI())->IsBanished)                {                    if(CastSoulRetrieveTimer < diff)                    {                        DoCast(Shade, SPELL_AKAMA_SOUL_RETRIEVE);                        CastSoulRetrieveTimer = 500;                    }else CastSoulRetrieveTimer -= diff;                }                else                {                    m_creature->InterruptNonMeleeSpells(false);                    m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);                    StartCombat = true;                }            }        }        if(ShadeHasDied)        {            outstring_log("DEBUG: Detected Shade's death");            //TODO: Cosmetics for Shade's death        }        if(!m_creature->getVictim() || !m_creature->SelectHostilTarget())            return;        if(DestructivePoisonTimer < diff)        {            // SPELL_DESTRUCTIVE_POISON is self-cast only for some reason so we make our target cast it on itself            m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_DESTRUCTIVE_POISON, true);            DestructivePoisonTimer = 15000;        }else DestructivePoisonTimer -= diff;        if(LightningBoltTimer < diff)        {            DoCast(m_creature->getVictim(), SPELL_LIGHTNING_BOLT);            LightningBoltTimer = 10000;        }else LightningBoltTimer -= diff;        if(!ShadeHasDied)        {            if(CheckTimer < diff)            {                if(ShadeGUID)                {                    Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);                    if(Shade && (!Shade->isAlive()))                        ShadeHasDied = true;                }            }else CheckTimer -= diff;        }        DoMeleeAttackIfReady();    }};CreatureAI* GetAI_boss_shade_of_akama(Creature *_Creature){    return new boss_shade_of_akamaAI (_Creature);}CreatureAI* GetAI_mob_ashtongue_channeler(Creature *_Creature){    return new mob_ashtongue_channelerAI (_Creature);}CreatureAI* GetAI_mob_ashtongue_sorcerer(Creature *_Creature){    return new mob_ashtongue_sorcererAI (_Creature);}CreatureAI* GetAI_npc_akama_shade(Creature *_Creature){    return new npc_akamaAI (_Creature);}bool GossipSelect_npc_akama(Player *player, Creature *_Creature, uint32 sender, uint32 action ){    if (action == GOSSIP_ACTION_INFO_DEF + 1)//Fight time    {        player->PlayerTalkClass->CloseGossip();        ((npc_akamaAI*)_Creature->AI())->BeginEvent(player);    }    return true;}bool GossipHello_npc_akama(Player *player, Creature *_Creature){        if(player->isAlive())    {        player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);        player->PlayerTalkClass->SendGossipMenu(907, _Creature->GetGUID());    }    return true;}void AddSC_boss_shade_of_akama(){    Script *newscript;    newscript = new Script;    newscript->Name="boss_shade_of_akama";    newscript->GetAI = GetAI_boss_shade_of_akama;    m_scripts[nrscripts++] = newscript;    newscript = new Script;    newscript->Name="mob_ashtongue_channeler";    newscript->GetAI = GetAI_mob_ashtongue_channeler;    m_scripts[nrscripts++] = newscript;        newscript = new Script;    newscript->Name="mob_ashtongue_sorcerer";    newscript->GetAI = GetAI_mob_ashtongue_sorcerer;    m_scripts[nrscripts++] = newscript;    newscript = new Script;    newscript->Name="npc_akama_shade";    newscript->GetAI = GetAI_npc_akama_shade;    newscript->pGossipHello = &GossipHello_npc_akama;    newscript->pGossipSelect = &GossipSelect_npc_akama;    m_scripts[nrscripts++] = newscript;}