All pastes #885831 Raw Edit

Shade of Akama

public text v1 · immutable
#885831 ·published 2008-01-31 04:12 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
*/

/* ScriptData
SDName: Boss_Shade_of_Akama
SD%Complete: 0
SDComment: VERIFY SCRIPT
SDCategory: Black Temple
EndScriptData */

#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.652740, 337.368103, 0}
};

// Locations
#define Z1              118.543144
#define Z2              120.783768

#define X_SHADE         451.347534
#define Y_SHADE         401.219757

#define Z_SPAWN         113.537949

#define X_AKAMA         466.161285
#define Y_AKAMA         401.219757

#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..."

#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 CREATURE_CHANNELER          23421

struct SpawnEntry
{
    uint32 entry;
};

static SpawnEntry Spawns[]=
{
    {23216},
    {23523},
    {23318},
    {23524}
};

struct MANGOS_DLL_DECL npc_ashtongue_channelerAI : public ScriptedAI
{
    npc_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 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();
    }

    void DamageTaken(Unit *done_by, uint32 &damage);
};

struct MANGOS_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
{
    boss_shade_of_akamaAI(Creature* c) : ScriptedAI(c)
    {
        SetVariables();
    }

    uint64 ChannelerGUID[6];

    uint32 DeathCount;

    uint32 ReduceHealthTimer;
    uint32 EnrageTimer;
    uint32 SummonTimer;

    bool Enrage;
    bool SummonedChannelers;
    bool IsBanished;
    bool InCombat;
    bool HasKilledAkama;

    void SetVariables()
    {
        if(SummonedChannelers)
        {
            for(uint8 i = 0; i < 7; 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;
        }

        DeathCount = 0;

        EnrageTimer = 600000;
        SummonTimer = 20000;
        ReduceHealthTimer = 0;

        Enrage = false;
        IsBanished = false;
        InCombat = false;
        HasKilledAkama = false;

        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();
        m_creature->CombatStop();
        DoGoHome();
    }

    void AttackStart(Unit* who)
    {
        if(IsBanished)
            return;
    }

    void MoveInLineOfSight(Unit* who)
    {
    }

    void SummonCreature()
    {
        uint32 entry = Spawns[rand()%4].entry;
        uint32 random = rand()%2;
        float X = SpawnLocations[random].x;
        float Y = SpawnLocations[random].y;
        m_creature->SummonCreature(entry, X, Y, Z_SPAWN, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
    }

    void UpdateAI(const uint32 diff)
    {
        if(!SummonedChannelers)
        {
            for(uint8 i = 0; i < 7; 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)
                    ChannelerGUID[i] = Channeler->GetGUID();
                else // Debug
                    error_log("ERROR: Shade Of Akama Encounter: Unable to spawn Channeler %u!", i);
            }
            SummonedChannelers = true;
        }

        if(IsBanished)
        {
            if(!m_creature->GetMotionMaster()->empty())
            {
                m_creature->GetMotionMaster()->Clear(false);
                m_creature->GetMotionMaster()->Idle();
            }

            if(SummonTimer < diff)
            {
                SummonCreature();
                SummonCreature();
                SummonTimer = 15000;
            }else SummonTimer -= diff;
        }
    }
};

void npc_ashtongue_channelerAI::DamageTaken(Unit *done_by, uint32 &damage)
{
    if(damage > m_creature->GetHealth())
    {
        if(ShadeGUID)
        {
            Creature* Shade = NULL;
            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; Ashtongue Channeler was killed but Shade of Akama is not found. Killer: %u, %c", done_by->GetGUID(), done_by->GetName());
        }
    }
}