Index: ScriptMgr.cpp =================================================================== --- ScriptMgr.cpp (revision 594) +++ ScriptMgr.cpp (working copy) @@ -300,7 +300,10 @@ extern void AddSC_boss_maiden_of_virtue(); extern void AddSC_boss_shade_of_aran(); extern void AddSC_boss_malchezaar(); +extern void AddSC_boss_netherspite(); extern void AddSC_boss_terestian_illhoof(); +extern void AddSC_boss_netherspite(); +extern void AddSC_mob_netherportal(); extern void AddSC_netherspite_infernal(); extern void AddSC_boss_moroes(); extern void AddSC_bosses_opera(); @@ -1235,6 +1238,7 @@ AddSC_boss_shade_of_aran(); AddSC_boss_malchezaar(); AddSC_boss_terestian_illhoof(); + AddSC_boss_netherspite(); AddSC_netherspite_infernal(); AddSC_boss_moroes(); AddSC_bosses_opera(); Index: scripts/zone/karazhan/boss_netherspite.cpp =================================================================== --- scripts/zone/karazhan/boss_netherspite.cpp (revision 594) +++ scripts/zone/karazhan/boss_netherspite.cpp (working copy) @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 - 2008 ScriptDev2 +/* 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 @@ -6,12 +6,12 @@ * * 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 +* 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 +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* ScriptData @@ -21,17 +21,280 @@ SDCategory: Karazhan EndScriptData */ -//Casts +//TODO: implement void zone + #include "precompiled.h" -#define SPELL_NETHERBURN_AURA 30522 -#define SPELL_VOIDZONE 37014 //Probably won't work -#define SPELL_BERSERK 26662 -#define SPELL_NETHERBREATH 36631 +#include "sc_creature.h" -//Beams (no idea how these are going to work in Mangos) -#define SPELL_DOMINANCE_ENEMY 30423 -#define SPELL_DOMINANCE_SELF 30468 -#define SPELL_PERSEVERANCE_ENEMY 30421 -#define SPELL_PERSEVERANCE_SELF 30466 -#define SPELL_SERENITY_ENEMY 30422 -#define SPELL_SERENITY_SELF 30467 +//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 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(PortalType[i], 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_mob_netherportal(Creature *_Creature) +{ + return new mob_netherportalAI (_Creature); +} + +CreatureAI* GetAI_boss_netherspite(Creature *_Creature) +{ + return new boss_netherspiteAI (_Creature); +} + + +void AddSC_boss_netherspite() +{ + Script *newscript; + newscript = new Script; + newscript->Name="mob_netherportal"; + newscript->GetAI = GetAI_mob_netherportal; + m_scripts[nrscripts++] = newscript; + + newscript = new Script; + newscript->Name="boss_netherspite"; + newscript->GetAI = GetAI_boss_netherspite; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file