/* Copyright © 2006 - 2008 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_Netherspite SD%Complete: 0 SDComment: Place Holder SDCategory: Karazhan EndScriptData */ //TODO: implement void zone #include "precompiled.h" #include "sc_creature.h" //Casts #define SPELL_NETHERBURN_AURA 30522 // works #define SPELL_VOIDZONE 30533 // taken spell ID from a thread a year ago #define SPELL_BERSERK 45078 #define SPELL_NETHERBREATH 38523 #define SPELL_EMPOWERMENT 38549 #define SPELL_BANISH 0 //TODO: get this spell id #define NETHER_PORTAL 0 //TODO: get id of portal with ScriptName as mob_netherportal #define RED 0 #define GREEN 1 #define BLUE 2 #define UNK 3 uint32 BeamAuraEnemy[3]={ 30421, //red 30422, //green 30423 //blue }; uint32 BeamAuraBoss[3]={ 30466, //red 30467, //green 30468 //blue }; uint32 BeamVisual[3]={ //TODO: check these spells 30400, //red 30401, //green 30402 //blue }; uint32 NetherExhaustion[3]={ 38637, //red 38638, //green 38639 //blue }; float PortalType[3]={17369,17367,17368}; float PortalPosX[3]={-11137.7,-11199.1,-11125.4}; //I have spawned 3 "portals-npcs" with coords I got from some guides and put it in float PortalPosY[3]={-1685.87,-1609.99,-1617.19}; float PortalPosZ = 278.794; Unit* NetherSpite = NULL; struct MANGOS_DLL_DECL mob_netherportalAI : public ScriptedAI { mob_netherportalAI(Creature *c) : ScriptedAI(c) {Reset();} uint8 Colour; Unit* target; uint32 Check_Timer; uint32 Buff_Timer; void Reset() { Colour = UNK; target = NetherSpite; Check_Timer = 0; Buff_Timer = 0; } void KilledUnit(Unit *victim) {} void JustDied(Unit *victim) {} void Aggro(Unit *who) { } void UpdateAI(const uint32 diff) { if(Colour == UNK) return; if(!NetherSpite->isAlive()) m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); if(Buff_Timer < diff) { if(target == NetherSpite) { DoCast(target, BeamAuraBoss[Colour]); } else { DoCast(target, BeamAuraEnemy[Colour]); } Buff_Timer = 1000; return; } else Buff_Timer -= 1000; if(Check_Timer < diff) { Unit* temp = NULL; float boss_dist = m_creature->GetDistance(NetherSpite); float cur_dist = boss_dist; float i_dist; float i_boss_dist; Check_Timer = 1000; //TODO : find a more efficient way of checking if anyone in between std::list& threatlist = NetherSpite->getThreatManager().getThreatList(); for(std::list::iterator i = threatlist.begin(); i!=threatlist.end(); i++) { Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); i_dist = m_creature->GetDistance(pUnit); i_boss_dist = NetherSpite->GetDistance(pUnit); if( i_dist + i_boss_dist <= boss_dist + 2 && i_dist < cur_dist && i_boss_dist < boss_dist) { if(pUnit->HasAura(NetherExhaustion[Colour],0)) continue; temp = pUnit; cur_dist = i_dist; } } if(temp) { if(target != temp) { if(target != NetherSpite) { DoCast(target, NetherExhaustion[Colour]); if(Colour == RED) { NetherSpite->AddThreat(target, -1000000); NetherSpite->AddThreat(temp, 1000000); } } target = temp; } } else { target = NetherSpite; DoCast(target, BeamVisual[Colour]); //TODO: is this spell interruptible by buff spell? } } else Check_Timer -= diff; } }; struct MANGOS_DLL_DECL boss_netherspiteAI : public ScriptedAI { boss_netherspiteAI(Creature *c) : ScriptedAI(c) {Reset();} bool Enraged; bool Banished; bool PortalSummoned; bool PortalAssigned; uint32 Enrage_Timer; uint32 Banish_Timer; uint32 Portal_Timer; uint32 NetherBreath_Timer; Creature* Portal[3]; void Reset() { Enrage_Timer = 540000; NetherBreath_Timer = 2500; Portal_Timer = 10000; Enraged = false; Banished = false; PortalSummoned = false; NetherSpite = m_creature; m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); } void KilledUnit(Unit *victim) {} void JustDied(Unit *victim) {} void Aggro(Unit *who) { } void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) return; if(Enrage_Timer < diff && !Enraged) { DoCast(m_creature, SPELL_BERSERK); Enraged = true; return; } else Enrage_Timer -= diff; if(Banished) { if(!m_creature->HasAura(SPELL_BANISH, 0)) //assuming banish aura dissapears in 30 secs { Banished = false; Banish_Timer = 60000; Portal_Timer = 10000; PortalSummoned = false; return; } if(NetherBreath_Timer < diff) { Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0); DoCast(target, SPELL_NETHERBREATH); NetherBreath_Timer = 2500; //TODO: is this timer off-like ? } else NetherBreath_Timer -= diff; } else { if(Banish_Timer < diff) { DoCast(m_creature, SPELL_BANISH); Banished = true; return; } else Banish_Timer -= diff; } if(!PortalSummoned) { PortalSummoned = true; for(int i=0; i<3; i++) Portal[i] = m_creature->SummonCreature(NETHER_PORTAL, PortalPosX[i], PortalPosY[i], PortalPosZ, 0, TEMPSUMMON_TIMED_DESPAWN, 60000); PortalAssigned = false; } //TODO : find a less confusing way to randomise portal colours if(!PortalAssigned) { if(Portal_Timer < diff) { PortalAssigned = true; int i[3]; i[RED]=rand()%3; do { i[GREEN]=rand()%3; }while (i[RED] == i[GREEN]); i[BLUE]= 3 - i[RED] - i[GREEN]; for(int colour=RED; colour<=BLUE; colour++) { ((mob_netherportalAI*)Portal[i[colour]]->AI())->Colour = colour; } } else Portal_Timer -= diff; } } }; CreatureAI* GetAI_boss_netherspite(Creature *_Creature) { return new boss_netherspiteAI (_Creature); } CreatureAI* GetAI_mob_netherportal(Creature *_Creature) { return new mob_netherportalAI (_Creature); } void AddSC_boss_netherspite() { Script *newscript; newscript = new Script; newscript->Name="boss_netherspite"; newscript->GetAI = GetAI_boss_netherspite; m_scripts[nrscripts++] = newscript; newscript = new Script; newscript->Name="mob_netherportal"; newscript->GetAI = GetAI_mob_netherportal; m_scripts[nrscripts++] = newscript; }