All pastes #914493 Raw Edit

Moriquendu

public cpp v1 · immutable
·published 2008-02-22 22:44 UTC
rendered paste body
/* Copyright (C) 2006 - 2008 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: Illidari_CouncilSD%Complete: 85SDComment: Workarounds for Spellstealing Dampen Magic and Circle of Healing. Need more details on the enrage.SDCategory: Black TempleEndScriptData */#include "../../sc_defines.h"#include "../../../../../game/TargetedMovementGenerator.h"//Spells#define SPELL_FLAMESTRIKE          41481#define SPELL_BLIZZARD             41482#define SPELL_ARCANE_BOLT          41483#define SPELL_ARCANE_EXPLOSION     41524#define SPELL_DAMPEN_MAGIC         41478#define SPELL_EMPOWERED_SMITE      41471#define SPELL_CIRCLE_OF_HEALING    41455#define SPELL_REFLECTIVE_SHIELD    41475#define SPELL_DIVINE_WRATH         41472#define SPELL_HEAL_VISUAL          24171#define SPELL_BLESS_PROTECTION     41450#define SPELL_BLESS_SPELLWARD      41451#define SPELL_CONSECRATION         41541#define SPELL_HAMMER_OF_JUSTICE    41468#define SPELL_SEAL_OF_COMMAND      41469#define SPELL_SEAL_OF_BLOOD        41459#define SPELL_CHROMATIC_AURA       41453#define SPELL_DEVOTION_AURA        41452#define SPELL_DEADLY_POISON        41485#define SPELL_ENVENOM              41487#define SPELL_VANISH               41479//Speech'n'Sounds#define SAY_GATH_AGGRO            "I have better things to do!"#define SOUND_GATH_AGGRO          11422#define SAY_GATH_SLAY             "Selama am'oronor!"#define SOUND_GATH_SLAY           11423#define SAY_GATH_COMNT            "Well done!"#define SOUND_GATH_COMNT          11424#define SAY_GATH_DEATH            "Lord Illidan... I..."#define SOUND_GATH_DEATH          11425#define SAY_GATH_SPECIAL1         "Enjoy your final moments!"#define SOUND_GATH_SPECIAL1       11426#define SAY_GATH_SPECIAL2         "You are mine!"#define SOUND_GATH_SPECIAL2       11427#define SAY_GATH_ENRAGE           "Enough games!"#define SOUND_GATH_ENRAGE         11428#define SAY_MALA_AGGRO            "Flee, or die!"#define SOUND_MALA_AGGRO          11482#define SAY_MALA_SLAY             "My work is done."#define SOUND_MALA_SLAY           11483#define SAY_MALA_COMNT            "As it should be!"#define SOUND_MALA_COMNT          11484#define SAY_MALA_DEATH            "Destiny... awaits."#define SOUND_MALA_DEATH          11485#define SAY_MALA_SPECIAL1         "No second chances!"#define SOUND_MALA_SPECIAL1       11486#define SAY_MALA_SPECIAL2         "I'm full of surprises!"#define SOUND_MALA_SPECIAL2       11487#define SAY_MALA_ENRAGE           "For Quel'Thalas! For the Sunwell!"#define SOUND_MALA_ENRAGE         11488#define SAY_ZERE_AGGRO            "Common... such a crude language. Bandal!"#define SOUND_ZERE_AGGRO          11440#define SAY_ZERE_SLAY             "Shorel'aran."#define SOUND_ZERE_SLAY           11441#define SAY_ZERE_COMNT            "Belesa menoor!"#define SOUND_ZERE_COMNT          11442#define SAY_ZERE_DEATH            "Diel ma'ahn... oreindel'o"#define SOUND_ZERE_DEATH          11443#define SAY_ZERE_SPECIAL1         "Diel fin'al"#define SOUND_ZERE_SPECIAL1       11444#define SAY_ZERE_SPECIAL2         "Sha'amoor ara mashal?"#define SOUND_ZERE_SPECIAL2       11445#define SAY_ZERE_ENRAGE           "Sha'amoor sine menoor!"#define SOUND_ZERE_ENRAGE         11446#define SAY_VERA_AGGRO            "You wish to test me?"#define SOUND_VERA_AGGRO          11524#define SAY_VERA_SLAY             "Valiant effort!"#define SOUND_VERA_SLAY           11525#define SAY_VERA_COMNT            "A glorious kill!"#define SOUND_VERA_COMNT          11526#define SAY_VERA_DEATH            "You got lucky!"#define SOUND_VERA_DEATH          11527#define SAY_VERA_SPECIAL1         "You're not caught up for this!"#define SOUND_VERA_SPECIAL1       11528#define SAY_VERA_SPECIAL2         "Anar'alah belore!"#define SOUND_VERA_SPECIAL2       11529#define SAY_VERA_ENRAGE           "You wish to kill me? Hahaha, you first!"#define SOUND_VERA_ENRAGE         11530//Locations#define X_VANISH               111.643913#define Y_VANISH               561.843872#define Z_VANISH               98.430679struct MANGOS_DLL_DECL boss_illidari_councilAI : public ScriptedAI{    boss_illidari_councilAI(Creature *c) : ScriptedAI(c)     {        if(c->GetInstanceData())            pInstance = ((ScriptedInstance*)c->GetInstanceData());        else pInstance = NULL;        Council[0] = 0;        Council[1] = 0;        Council[2] = 0;        Council[3] = 0;        SetVariables();    }    ScriptedInstance* pInstance;    uint64 Council[4];    uint32 CheckTimer;    bool InCombat;    void SetVariables()    {             InCombat = false;        CheckTimer = 2000;        Creature* Member;        for(uint8 i = 0; i < 3; i++)        {            Member = ((Creature*)Unit::GetUnit((*m_creature), Council[i]));            if(Member)            {                ((Creature*)Member)->Respawn();                ((Creature*)Member)->AI()->EnterEvadeMode();            }        }        if(pInstance)            pInstance->SetData("IllidariCouncilEvent",0);    }    void EnterEvadeMode()    {        SetVariables();        InCombat = false;        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);        m_creature->SetVisibility(VISIBILITY_OFF);        DoGoHome();    }    void AttackStart(Unit *who)    {        return;    }    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(!InCombat)                {                    if(pInstance)                        pInstance->SetData("IllidariCouncil", 1);                    StartEvent(who);                    InCombat = true;                }            }        }    }    void StartEvent(Unit *target)    {        if(!pInstance) return;        if(target)        {            SetVariables();            Council[0] = pInstance->GetData64("GathiosTheShatterer");            Council[1] = pInstance->GetData64("HighNethermancerZerevor");            Council[2] = pInstance->GetData64("LadyMalande");            Council[3] = pInstance->GetData64("VerasDarkshadow");            if(!Council[0] || !Council[1] || !Council[2] || !Council[3])                return;            Creature* Gathios = NULL;            Creature* Zerevor = NULL;            Creature* Malande = NULL;            Creature* Veras = NULL;            Gathios = ((Creature*)Unit::GetUnit((*m_creature), Council[0]));            Zerevor = ((Creature*)Unit::GetUnit((*m_creature), Council[1]));            Malande = ((Creature*)Unit::GetUnit((*m_creature), Council[2]));            Veras = ((Creature*)Unit::GetUnit((*m_creature), Council[3]));            if(Gathios)                Gathios->AddThreat(target, 1.0f);            if(Zerevor)                Zerevor->AddThreat(target, 1.0f);            if(Malande)                Malande->AddThreat(target, 1.0f);            if(Veras)                Veras->AddThreat(target, 1.0f);            pInstance->SetData("IllidariCouncilEvent", 1);        }    }    void UpdateAI(const uint32 diff)    {        if(!InCombat) return;        if(CheckTimer < diff)        {            if(!Council[0] || !Council[1] || !Council[2] || !Council[3])                return;            Creature* Gathios = NULL;            Creature* Zerevor = NULL;            Creature* Malande = NULL;            Creature* Veras = NULL;            Gathios = ((Creature*)Unit::GetUnit((*m_creature), Council[0]));            Zerevor = ((Creature*)Unit::GetUnit((*m_creature), Council[1]));            Malande = ((Creature*)Unit::GetUnit((*m_creature), Council[2]));            Veras = ((Creature*)Unit::GetUnit((*m_creature), Council[3]));            // Don't allow players to pull one of the council's members, aggro another members' target if none present            if(Gathios->isAlive() && !Gathios->SelectHostilTarget())                Gathios->AddThreat(Veras->getVictim(), 1.0f);            if(Zerevor->isAlive() && !Zerevor->SelectHostilTarget())                Zerevor->AddThreat(Gathios->getVictim(), 1.0f);            if(Malande->isAlive() && !Malande->SelectHostilTarget())                Malande->AddThreat(Zerevor->getVictim(), 1.0f);            if(Veras->isAlive() && !Veras->SelectHostilTarget())                Veras->AddThreat(Malande->getVictim(), 1.0f);            if(!Gathios->isAlive() && !Zerevor->isAlive() && !Malande->isAlive() && !Veras->isAlive())            {                if(pInstance)                    pInstance->SetData("IllidariCouncilEvent", 3); // Completed                m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);            }            CheckTimer = 2000;        }else CheckTimer -= diff;    }};struct MANGOS_DLL_DECL boss_gathios_the_shattererAI : public ScriptedAI{    boss_gathios_the_shattererAI(Creature *c) : ScriptedAI(c)     {        pInstance = ((ScriptedInstance*)c->GetInstanceData());        Council[0] = 0;        Council[1] = 0;        Council[2] = 0;        SetVariables();    }    uint64 Council[3];    ScriptedInstance* pInstance;    uint32 ConsecrationTimer;    uint32 HammerOfJusticeTimer;    uint32 SealTimer;    uint32 AuraTimer;    uint32 BlessingTimer;    bool AcquiredGUIDs;    bool InCombat;    void SetVariables()    {        AcquiredGUIDs = false;        ConsecrationTimer = 40000;        HammerOfJusticeTimer = 10000;        SealTimer = 40000;        AuraTimer = 90000;        BlessingTimer = 60000;    }    void EnterEvadeMode()    {        SetVariables();        InCombat = false;        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);            if(!InCombat)            {                SetVariables();                DoYell(SAY_GATH_AGGRO,LANG_UNIVERSAL,NULL);                DoPlaySoundToSet(m_creature, SOUND_GATH_AGGRO);                InCombat = true;            }        }    }    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);                if(!InCombat)                {                    DoYell(SAY_GATH_AGGRO,LANG_UNIVERSAL,NULL);                    DoPlaySoundToSet(m_creature, SOUND_GATH_AGGRO);                    InCombat = true;                }            }        }    }    void KilledUnit(Unit *victim)    {        DoYell(SAY_GATH_SLAY,LANG_UNIVERSAL,NULL);        DoPlaySoundToSet(m_creature, SOUND_GATH_SLAY);    }    void JustDied(Unit *victim)    {        InCombat = false;        DoYell(SAY_GATH_DEATH, LANG_UNIVERSAL, NULL);        DoPlaySoundToSet(m_creature,SOUND_GATH_DEATH);    }    void DamageTaken(Unit *done_by, uint32 &damage)    {        if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 1)        {                damage *= 0.25;            for(uint8 i = 0; i < 3; i++)            {                Unit* pUnit = NULL;                if(Council[i])                {                    Unit* pUnit = NULL;                    pUnit = Unit::GetUnit((*m_creature), Council[i]);                    if(pUnit && (damage < pUnit->GetHealth()))                        pUnit->SetHealth(pUnit->GetHealth() - damage);                }            }        }    }    Unit* SelectCouncilMember()    {               Unit* pUnit = NULL;        uint32 member = 1;        if(rand()%10 == 0)        {            switch(rand()%3)            {                case 0:                    member = 0;                    break;                case 1:                    member = 1;                    break;                case 2:                    member = 5;                    break;            }        }        if(member != 5)            pUnit = Unit::GetUnit((*m_creature), Council[member]);          return pUnit;    }    void CastAuraOnCouncil()    {        uint32 spellid = 0;        switch(rand()%2)        {            case 0:                spellid = SPELL_DEVOTION_AURA;                break;            case 1:                spellid = SPELL_CHROMATIC_AURA;                break;        }        for(uint8 i = 0; i < 3; i++)        {            Unit* pUnit = Unit::GetUnit((*m_creature), Council[i]);            if(pUnit)                pUnit->CastSpell(pUnit, spellid, true, 0, 0, m_creature->GetGUID());        }        DoCast(m_creature, spellid);    }    void UpdateAI(const uint32 diff)    {        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())            return;        if(!AcquiredGUIDs)        {            if(pInstance)            {                Council[0] = pInstance->GetData64("HighNethermancerZerevor");                Council[1] = pInstance->GetData64("LadyMalande");                Council[2] = pInstance->GetData64("VerasDarkshadow");            }            AcquiredGUIDs = true;        }                if(BlessingTimer < diff)        {            Unit* pUnit = SelectCouncilMember();            if(pUnit)            {                switch(rand()%2)                {                    case 0:                        DoCast(pUnit, SPELL_BLESS_SPELLWARD);                        break;                    case 1:                        DoCast(pUnit, SPELL_BLESS_PROTECTION);                        break;                }            }            BlessingTimer = 60000;        }else BlessingTimer -= diff;                if(ConsecrationTimer < diff)        {            DoCast(m_creature, SPELL_CONSECRATION);            ConsecrationTimer = 40000;        }else ConsecrationTimer -= diff;        if(HammerOfJusticeTimer < diff)        {            Unit* target;            target = SelectUnit(SELECT_TARGET_RANDOM, 0);            if(target)            {                if(m_creature->GetDistance2dSq(target) > 196 && m_creature->GetDistance2dSq(target) < 1764) // is in ~10-40 yd range                {                    DoCast(target, SPELL_HAMMER_OF_JUSTICE);                    HammerOfJusticeTimer = 20000;                }            }        }else HammerOfJusticeTimer -= diff;        if(SealTimer < diff)        {            switch(rand()%2)            {                case 0:                    DoCast(m_creature, SPELL_SEAL_OF_COMMAND);                    break;                case 1:                    DoCast(m_creature, SPELL_SEAL_OF_BLOOD);                    break;            }            SealTimer = 40000;        }else SealTimer -= diff;        if(AuraTimer < diff)        {            CastAuraOnCouncil();            AuraTimer = 90000;        }else AuraTimer -= diff;        DoMeleeAttackIfReady();    }};struct MANGOS_DLL_DECL boss_high_nethermancer_zerevorAI : public ScriptedAI{    boss_high_nethermancer_zerevorAI(Creature *c) : ScriptedAI(c)     {        pInstance = ((ScriptedInstance*)c->GetInstanceData());        Council[0] = 0;        Council[1] = 0;        Council[2] = 0;        SetVariables();                                           }    ScriptedInstance* pInstance;    uint64 Council[3];    uint32 BlizzardTimer;    uint32 FlamestrikeTimer;    uint32 ArcaneBoltTimer;    uint32 DampenMagicTimer;    uint32 Cooldown;    uint32 AggroYellTimer;    uint32 ArcaneExplosionTimer;    bool AcquiredGUIDs;    bool InCombat;    void SetVariables()    {        m_creature->ApplySpellImmune( 0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);        AcquiredGUIDs = false;        BlizzardTimer = 30000 + rand()%61 * 1000;        FlamestrikeTimer = 30000 + rand()%61 * 1000;        ArcaneBoltTimer = 10000;        DampenMagicTimer = 2000;        ArcaneExplosionTimer = 14000;        Cooldown = 0;        AggroYellTimer = 0;    }    void EnterEvadeMode()    {        SetVariables();        InCombat = false;        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);            if(!InCombat)            {                SetVariables();                AggroYellTimer = 9000;                InCombat = true;            }        }    }    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);                if(!InCombat)                {                    AggroYellTimer = 9000;                    InCombat = true;                }            }        }    }    void KilledUnit(Unit *victim)    {        DoYell(SAY_ZERE_SLAY,LANG_UNIVERSAL,NULL);        DoPlaySoundToSet(m_creature, SOUND_ZERE_SLAY);    }    void JustDied(Unit *victim)    {        InCombat = false;        DoYell(SAY_ZERE_DEATH, LANG_UNIVERSAL, NULL);        DoPlaySoundToSet(m_creature,SOUND_ZERE_DEATH);    }    void DamageTaken(Unit *done_by, uint32 &damage)    {        if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 1)        {                damage *= 0.25;            for(uint8 i = 0; i < 3; i++)            {                Unit* pUnit = NULL;                if(Council[i])                {                    Unit* pUnit = NULL;                    pUnit = Unit::GetUnit((*m_creature), Council[i]);                    if(pUnit && (damage < pUnit->GetHealth()))                        pUnit->SetHealth(pUnit->GetHealth() - damage);                }            }        }    }    // THIS IS A WORKAROUND AS SPELLSTEAL DOES NOT WORK/DOES NOT ALLOW PLAYERS TO STEAL BUFFS OFF MOBS.    void CastDampenMagicWorkaround()    {        Unit* target = m_creature->getVictim();        if(target && (target->GetTypeId() == TYPEID_PLAYER))        {            if((target->getClass() == CLASS_MAGE) && (!target->HasAura(SPELL_DAMPEN_MAGIC, 0)))            {                target->CastSpell(target, SPELL_DAMPEN_MAGIC, true);                target->SetPower(POWER_MANA, target->GetPower(POWER_MANA) + 600);            }        }        else DoCast(m_creature, SPELL_DAMPEN_MAGIC);    }    void UpdateAI(const uint32 diff)    {        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())            return;        if(AggroYellTimer)        {            if(AggroYellTimer < diff)            {                DoYell(SAY_ZERE_AGGRO,LANG_UNIVERSAL,NULL);                DoPlaySoundToSet(m_creature, SOUND_ZERE_AGGRO);                AggroYellTimer = 0;            }else AggroYellTimer -= diff;        }        if(!AcquiredGUIDs)        {            if(pInstance)            {                Council[0] = pInstance->GetData64("GathiosTheShatterer");                Council[1] = pInstance->GetData64("LadyMalande");                Council[2] = pInstance->GetData64("VerasDarkshadow");            }            AcquiredGUIDs = true;        }        if(Cooldown)        {            if(Cooldown < diff) Cooldown = 0;            else            {                Cooldown -= diff;                return; // Don't cast any other spells if global cooldown is still ticking            }        }        if(DampenMagicTimer < diff)        {            CastDampenMagicWorkaround();            Cooldown = 1000;            DampenMagicTimer = 2000; // Should be ~2 minutes.            ArcaneBoltTimer += 2000;        }else DampenMagicTimer -= diff;                if(ArcaneExplosionTimer < diff)        {            DoCast(m_creature->getVictim(), SPELL_ARCANE_EXPLOSION);            Cooldown = 1000;            ArcaneExplosionTimer = 14000;        }else ArcaneExplosionTimer -= diff;        if(ArcaneBoltTimer < diff)        {            DoCast(m_creature->getVictim(), SPELL_ARCANE_BOLT);            ArcaneBoltTimer = 3000;            Cooldown = 2000;        }else ArcaneBoltTimer -= diff;        if(BlizzardTimer < diff)        {            Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);            if(target)            {                DoCast(target, SPELL_BLIZZARD);                BlizzardTimer = 45000 + rand()%46 * 1000;                FlamestrikeTimer += 10000;                Cooldown = 1000;            }        }else BlizzardTimer -= diff;        if(FlamestrikeTimer < diff)        {            Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);            if(target)            {                DoCast(target, SPELL_FLAMESTRIKE);                FlamestrikeTimer = 55000 + rand()%46 * 1000;                BlizzardTimer += 10000;                Cooldown = 2000;            }        }else FlamestrikeTimer -= diff;    }};struct MANGOS_DLL_DECL boss_lady_malandeAI : public ScriptedAI{    boss_lady_malandeAI(Creature *c) : ScriptedAI(c)     {        pInstance = ((ScriptedInstance*)c->GetInstanceData());        Council[0] = 0;        Council[1] = 0;        Council[2] = 0;        SetVariables();    }    ScriptedInstance* pInstance;    uint64 Council[3];    uint32 EmpoweredSmiteTimer;    uint32 CircleOfHealingTimer;    uint32 DivineWrathTimer;    uint32 ReflectiveShieldTimer;    uint32 AggroYellTimer;    bool AcquiredGUIDs;    bool InCombat;    void SetVariables()    {        AcquiredGUIDs = false;        EmpoweredSmiteTimer = 38000;        CircleOfHealingTimer = 20000;        DivineWrathTimer = 40000;        ReflectiveShieldTimer = 0;        AggroYellTimer = 0;    }    void EnterEvadeMode()    {        SetVariables();        InCombat = false;        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);            if(!InCombat)            {                SetVariables();                InCombat = true;            }        }    }    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);                if(!InCombat)                {                    AggroYellTimer = 5500;                    InCombat = true;                }            }        }    }    void KilledUnit(Unit *victim)    {        DoYell(SAY_MALA_SLAY,LANG_UNIVERSAL,NULL);        DoPlaySoundToSet(m_creature, SOUND_MALA_SLAY);    }    void JustDied(Unit *victim)    {        InCombat = false;        DoYell(SAY_MALA_DEATH, LANG_UNIVERSAL, NULL);        DoPlaySoundToSet(m_creature,SOUND_MALA_DEATH);    }    void DamageTaken(Unit *done_by, uint32 &damage)    {                  if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 1)        {                damage *= 0.25;            for(uint8 i = 0; i < 3; i++)            {                Unit* pUnit = NULL;                if(Council[i])                {                    Unit* pUnit = NULL;                    pUnit = Unit::GetUnit((*m_creature), Council[i]);                    if(pUnit && (damage < pUnit->GetHealth()))                        pUnit->SetHealth(pUnit->GetHealth() - damage);                }            }        }    }    /** This is a workaround as Circle of Healing puts Malande in the threat list of others.    Please remove this workaround when her Circle of Healing works properly */    void DoCircleOfHealingWorkaround()    {        uint32 heal;        for(uint8 i = 0; i < 3; i++)        {            heal = 5000 + rand()%5001; // 5 - 10k health healed            Unit* pUnit = NULL;            pUnit = Unit::GetUnit((*m_creature), Council[i]);            if(pUnit && ((pUnit->GetHealth()*100 / pUnit->GetMaxHealth()) > 1))            {                pUnit->SetHealth(pUnit->GetHealth() + heal);                pUnit->CastSpell(pUnit, SPELL_HEAL_VISUAL, true);            }        }    }    void UpdateAI(const uint32 diff)    {        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())            return;        if(AggroYellTimer)        {            if(AggroYellTimer < diff)            {                DoYell(SAY_MALA_AGGRO,LANG_UNIVERSAL,NULL);                DoPlaySoundToSet(m_creature, SOUND_MALA_AGGRO);                AggroYellTimer = 0;            }else AggroYellTimer -= diff;        }        if(!AcquiredGUIDs)        {            if(pInstance)            {                Council[0] = pInstance->GetData64("GathiosTheShatterer");                Council[1] = pInstance->GetData64("HighNethermancerZerevor");                Council[2] = pInstance->GetData64("VerasDarkshadow");            }            AcquiredGUIDs = true;        }        if(EmpoweredSmiteTimer < diff)        {            Unit* target = NULL;            target = SelectUnit(SELECT_TARGET_RANDOM, 0);            if(target)                DoCast(target, SPELL_EMPOWERED_SMITE);            EmpoweredSmiteTimer = 38000;        }else EmpoweredSmiteTimer -= diff;        if(CircleOfHealingTimer < diff)        {            // Currently bugged and puts Malande on the threatlist of the other council members. It also heals players.//            DoCast(m_creature, SPELL_CIRCLE_OF_HEALING);            DoCircleOfHealingWorkaround(); // Workaround till the actual spell works.            CircleOfHealingTimer = 60000;        }else CircleOfHealingTimer -= diff;        if(DivineWrathTimer < diff)        {            Unit* target;            target = SelectUnit(SELECT_TARGET_RANDOM, 0);            if(target)            {                DoCast(target, SPELL_DIVINE_WRATH);                DivineWrathTimer = 40000 + rand()%41 * 1000;            }        }else DivineWrathTimer -= diff;        if(ReflectiveShieldTimer < diff)        {            DoCast(m_creature, SPELL_REFLECTIVE_SHIELD);            ReflectiveShieldTimer = 65000;        }else ReflectiveShieldTimer -= diff;        DoMeleeAttackIfReady();    }};struct MANGOS_DLL_DECL boss_veras_darkshadowAI : public ScriptedAI{    boss_veras_darkshadowAI(Creature *c) : ScriptedAI(c)     {        pInstance = ((ScriptedInstance*)c->GetInstanceData());        Council[0] = 0;        Council[1] = 0;        Council[2] = 0;        SetVariables();    }    ScriptedInstance* pInstance;    uint64 Council[3];    uint64 EnvenomTargetGUID;    uint32 DeadlyPoisonTimer;    uint32 VanishTimer;    uint32 AppearEnvenomTimer;    uint32 AggroYellTimer;    bool AcquiredGUIDs;    bool InCombat;    bool HasVanished;    void SetVariables()    {        AcquiredGUIDs = false;        EnvenomTargetGUID = 0;        DeadlyPoisonTimer = 20000;        VanishTimer = 60000 + rand()%61 * 1000;        AppearEnvenomTimer = 150000;        AggroYellTimer = 0;        HasVanished = false;        (*m_creature).GetMotionMaster()->Clear(false);        m_creature->SetVisibility(VISIBILITY_ON);        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);    }    void EnterEvadeMode()    {        SetVariables();        InCombat = false;        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);            if(!InCombat)            {                SetVariables();                DoYell(SAY_VERA_AGGRO,LANG_UNIVERSAL,NULL);                DoPlaySoundToSet(m_creature, SOUND_VERA_AGGRO);                InCombat = true;            }        }    }    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);                if(!InCombat)                {                    AggroYellTimer = 3000;                    InCombat = true;                }            }        }    }    void KilledUnit(Unit *victim)    {        DoYell(SAY_VERA_SLAY,LANG_UNIVERSAL,NULL);        DoPlaySoundToSet(m_creature, SOUND_VERA_SLAY);    }    void JustDied(Unit *victim)    {        InCombat = false;        DoYell(SAY_VERA_DEATH, LANG_UNIVERSAL, NULL);        DoPlaySoundToSet(m_creature,SOUND_VERA_DEATH);    }    void DamageTaken(Unit *done_by, uint32 &damage)    {           if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 1)        {                damage *= 0.25;            for(uint8 i = 0; i < 3; i++)            {                Unit* pUnit = NULL;                if(Council[i])                {                    Unit* pUnit = NULL;                    pUnit = Unit::GetUnit((*m_creature), Council[i]);                    if(pUnit && (damage < pUnit->GetHealth()))                        pUnit->SetHealth(pUnit->GetHealth() - damage);                }            }        }    }    void ResetThreat()    {        std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();        std::list<HostilReference*>::iterator i = m_threatlist.begin();        for(i = m_threatlist.begin(); i != m_threatlist.end(); ++i)        {            Unit* pUnit = NULL;            pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());            if(pUnit)            {                m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);            }        }    }    void UpdateAI(const uint32 diff)    {        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())            return;                    if(AggroYellTimer)        {            if(AggroYellTimer < diff)            {                DoYell(SAY_VERA_AGGRO,LANG_UNIVERSAL,NULL);                DoPlaySoundToSet(m_creature, SOUND_VERA_AGGRO);                AggroYellTimer = 0;            }else AggroYellTimer -= diff;        }        if(!AcquiredGUIDs)        {            if(pInstance)            {                Council[0] = pInstance->GetData64("GathiosTheShatterer");                Council[1] = pInstance->GetData64("HighNethermancerZerevor");                Council[2] = pInstance->GetData64("LadyMalande");            }            AcquiredGUIDs = true;        }        if(!HasVanished)        {            if(DeadlyPoisonTimer < diff)            {                DoCast(m_creature->getVictim(), SPELL_DEADLY_POISON);                DeadlyPoisonTimer = 15000 + rand()%31 * 1000;            }else DeadlyPoisonTimer -= diff;            if(AppearEnvenomTimer < diff) // Cast Envenom. This is cast 4 seconds after Vanish is over            {                (*m_creature).GetMotionMaster()->Clear(false);                DoCast(m_creature->getVictim(), SPELL_ENVENOM);                AppearEnvenomTimer = 90000;            }else AppearEnvenomTimer -= diff;            if(VanishTimer < diff) // Disappear and stop attacking, but follow a random unit            {                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                (*m_creature).GetMotionMaster()->Clear();                Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);                if(target)                {                    ResetThreat();                    m_creature->AddThreat(target, 500000.0f); // Chase a unit. Check before DoMeleeAttackIfReady prevents from attacking                   (*m_creature).GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*target));                }                VanishTimer = 30000;                AppearEnvenomTimer= 28000;                HasVanished = true;                m_creature->SetVisibility(VISIBILITY_OFF);            }else VanishTimer -= diff;            DoMeleeAttackIfReady();        }        else        {            if(VanishTimer < diff) // Become attackable and poison current target            {                DoCast(m_creature->getVictim(), SPELL_DEADLY_POISON);                (*m_creature).GetMotionMaster()->Clear();                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                ResetThreat();                m_creature->AddThreat(m_creature->getVictim(), 3000.0f); // Make Veras attack his target for a while, he will cast Envenom 4 seconds after.                DeadlyPoisonTimer += 6000;                VanishTimer = 90000;                AppearEnvenomTimer = 4000;                HasVanished = false;            }else VanishTimer -= diff;            if(AppearEnvenomTimer < diff) // Appear 2 seconds before becoming attackable (Shifting out of vanish)            {                (*m_creature).GetMotionMaster()->Clear();                (*m_creature).GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature->getVictim()));                m_creature->SetVisibility(VISIBILITY_ON);                AppearEnvenomTimer = 6000;            }else AppearEnvenomTimer -= diff;        }    }};CreatureAI* GetAI_boss_illidari_council(Creature *_Creature){    return new boss_illidari_councilAI (_Creature);}CreatureAI* GetAI_boss_gathios_the_shatterer(Creature *_Creature){    return new boss_gathios_the_shattererAI (_Creature);}CreatureAI* GetAI_boss_lady_malande(Creature *_Creature){    return new boss_lady_malandeAI (_Creature);}CreatureAI* GetAI_boss_veras_darkshadow(Creature *_Creature){    return new boss_veras_darkshadowAI (_Creature);}CreatureAI* GetAI_boss_high_nethermancer_zerevor(Creature *_Creature){    return new boss_high_nethermancer_zerevorAI (_Creature);}void AddSC_boss_illidari_council(){    Script *newscript;    newscript = new Script;    newscript->Name="illidari_council";    newscript->GetAI = GetAI_boss_illidari_council;    m_scripts[nrscripts++] = newscript;    newscript = new Script;    newscript->Name="boss_gathios_the_shatterer";    newscript->GetAI = GetAI_boss_gathios_the_shatterer;    m_scripts[nrscripts++] = newscript;    newscript = new Script;    newscript->Name="boss_lady_malande";    newscript->GetAI = GetAI_boss_lady_malande;    m_scripts[nrscripts++] = newscript;    newscript = new Script;    newscript->Name="boss_veras_darkshadow";    newscript->GetAI = GetAI_boss_veras_darkshadow;    m_scripts[nrscripts++] = newscript;    newscript = new Script;    newscript->Name="boss_high_nethermancer_zerevor";    newscript->GetAI = GetAI_boss_high_nethermancer_zerevor;    m_scripts[nrscripts++] = newscript;}