/* Copyright (C) 2006,2007 ScriptDev2 * 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()); } } }