/* 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;
}