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
*/
/* ScriptData
SDName: Boss_moroes
SD%Complete: 100
SDComment:
EndScriptData */
#include "def_karazhan.h"
#include "../../../../../game/TargetedMovementGenerator.h"
#include "../../../../../game/IdleMovementGenerator.h"
#define SAY_AGGRO "Hmm, unannounced visitors? Preparations must be made."
#define SOUND_AGGRO 9211
#define SAY_SPECIAL_1 "Now, where was I? Oh yes..."
#define SOUND_SPECIAL_1 9215
#define SAY_SPECIAL_2 "You rang?"
#define SOUND_SPECIAL_2 9316
#define SAY_KILL_1 "One more for dinner this evening"
#define SOUND_KILL_1 9214
#define SAY_KILL_2 "Time... Never enough time."
#define SOUND_KILL_2 9314
#define SAY_KILL_3 "I've gone and made a mess."
#define SOUND_KILL_3 9315
#define SAY_DEATH "How terribly clumsy of me..."
#define SOUND_DEATH 9213
#define SPELL_VANISH 41476
#define SPELL_GARROTE 37066
#define SPELL_BLIND 34654
#define SPELL_GOUGE 28456
#define SPELL_ENRAGE 19953
#define ORIENT 4.5784
#define SPAWN1_X -10976.27929
#define SPAWN1_Y -1878.17358
#define SPAWN1_Z 81.73
#define SPAWN2_X -10979.7587
#define SPAWN2_Y -1877.8706
#define SPAWN2_Z 81.73
#define SPAWN3_X -10985.665
#define SPAWN3_Y -1877.2458
#define SPAWN3_Z 81.73
#define SPAWN4_X -10989.136719
#define SPAWN4_Y -1876.8309
#define SPAWN4_Z 81.73
uint32 Adds[6] = {19875, 19874, 19872, 17007, 19876, 19873};
uint64 AddGuid[4] = {0,0,0,0};
uint32 AddType[4] = {0,0,0,0};
struct MANGOS_DLL_DECL boss_moroesAI : public ScriptedAI
{
boss_moroesAI(Creature *c) : ScriptedAI(c)
{
pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
EnterEvadeMode();
}
ScriptedInstance *pInstance;
uint32 Vanish_Timer;
uint32 Blind_Timer;
uint32 Gouge_Timer;
uint32 Wait_Timer;
uint32 CheckAdds_Timer;
bool InCombat;
bool InVanish;
bool Enrage;
void Reset()
{
Vanish_Timer = 52000;
Blind_Timer = 35000;
Gouge_Timer = 23000;
Wait_Timer = 999999999;
CheckAdds_Timer = 5000;
InCombat = false;
Enrage = false;
InVanish = false;
DeSpawnAdds();
SpawnAdds();
if (pInstance)
pInstance->SetData(DATA_MOROES_EVENT, 0);
}
void StartEvent()
{
if (!pInstance)
return;
DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
if (pInstance)
pInstance->SetData(DATA_MOROES_EVENT, 1);
}
void Aggro(Unit *who)
{
StartEvent();
}
void MoveInLineOfSight(Unit *who)
{
if (!who || m_creature->getVictim())
return;
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);
DoStartMeleeAttack(who);
if (!InCombat)
{
DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
InCombat = true;
AddsAttack();
}
}
}
}
void KilledUnit(Unit *victim)
{
switch (rand()%3)
{
case 0:
DoYell(SAY_KILL_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(victim, SOUND_KILL_1);
break;
case 1:
DoYell(SAY_KILL_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(victim, SOUND_KILL_2);
break;
case 2:
DoYell(SAY_KILL_3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(victim, SOUND_KILL_3);
break;
}
}
void JustDied(Unit *victim)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(NULL, SOUND_DEATH);
if (pInstance)
pInstance->SetData(DATA_MOROES_EVENT, 0);
DeSpawnAdds();
}
void SpawnAdds()
{
uint32 i1;
uint32 i2;
uint32 i3;
uint32 i = rand()%6;
Unit *pCreature;
if (AddType[0])
{
pCreature = m_creature->SummonCreature(AddType[0], SPAWN1_X, SPAWN1_Y, SPAWN1_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
i1 = i;
}
else
{
pCreature = m_creature->SummonCreature(Adds[i], SPAWN1_X, SPAWN1_Y, SPAWN1_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
AddType[0] = Adds[i];
}
AddGuid[0] = pCreature->GetGUID();
while (i == i1)
{
i = rand()%6;
}
if (AddType[1])
pCreature = m_creature->SummonCreature(AddType[1], SPAWN2_X, SPAWN2_Y, SPAWN2_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
else
{
pCreature = m_creature->SummonCreature(Adds[i], SPAWN2_X, SPAWN2_Y, SPAWN2_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
AddType[1] = Adds[i];
}
AddGuid[1] = pCreature->GetGUID();
i2 = i;
while (i == i1 || i == i2)
{
i = rand()%6;
}
if (AddType[2])
pCreature = m_creature->SummonCreature(AddType[2], SPAWN3_X, SPAWN3_Y, SPAWN3_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
else
{
pCreature = m_creature->SummonCreature(Adds[i], SPAWN3_X, SPAWN3_Y, SPAWN3_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
AddType[2] = Adds[i];
}
AddGuid[2] = pCreature->GetGUID();
i3 = i;
while (i == i1 || i == i2 || i == i3)
{
i = rand()%6;
}
if (AddType[3])
pCreature = m_creature->SummonCreature(AddType[3], SPAWN4_X, SPAWN4_Y, SPAWN4_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
else
{
pCreature = m_creature->SummonCreature(Adds[i], SPAWN4_X, SPAWN4_Y, SPAWN4_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
AddType[3] = Adds[i];
}
AddGuid[3] = pCreature->GetGUID();
}
void DeSpawnAdds()
{
for (uint32 i =0;i<4;i++)
{
Unit *Temp;
if (AddGuid[i])
{
Temp = Unit::GetUnit((*m_creature),AddGuid[i]);
if (Temp)
Temp->DealDamage(Temp, Temp->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);
}
}
}
void AddsAttack()
{
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 99)
for (uint32 i =0;i<4;i++)
{
Unit *Temp;
if (AddGuid[i])
{
Temp = Unit::GetUnit((*m_creature),AddGuid[i]);
if (Temp && Temp->isAlive())
((Creature*)Temp)->AI()->AttackStart(m_creature->getVictim());
else
EnterEvadeMode();
}
}
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
if (pInstance && !pInstance->GetData(DATA_MOROES_EVENT))
EnterEvadeMode();
if (!Enrage && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30)
{
DoCast(m_creature, SPELL_ENRAGE);
Enrage = true;
}
if (CheckAdds_Timer < diff)
{
for (uint32 i =0;i<4;i++)
{
Unit *Temp;
if (AddGuid[i])
{
Temp = Unit::GetUnit((*m_creature),AddGuid[i]);
if (Temp && Temp->isAlive())
if (!Temp->SelectHostilTarget() || !Temp->getVictim() )
((Creature*)Temp)->AI()->AttackStart(m_creature->getVictim());
}
}
CheckAdds_Timer = 5000;
}else CheckAdds_Timer -= diff;
if (!Enrage)
{
//Cast Vanish, then Garrote random victim
if (Vanish_Timer < diff)
{
m_creature->setFaction(35);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoCast(m_creature, SPELL_VANISH);
InVanish = true;
Vanish_Timer = 60000;
Wait_Timer = 5000;
}else Vanish_Timer -= diff;
if (Wait_Timer < diff)
{
Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (target)
target->CastSpell(target, SPELL_GARROTE, true);
m_creature->setFaction(14);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
InVanish = false;
Wait_Timer = 999999999;
}else Wait_Timer -= diff;
//Blind highest aggro, and attack second highest
if (Gouge_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_GOUGE);
Unit *target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
if (target)
m_creature->getThreatManager().modifyThreatPercent(target,-100);
Gouge_Timer = 40000;
}else Gouge_Timer -= diff;
if (Blind_Timer < diff)
{
Unit *target;
std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
std::vector<Unit *> target_list;
for (std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
{
target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if (target && target->GetDistance2dSq(m_creature) < 25)
target_list.push_back(target);
target = NULL;
}
if (target_list.size())
target = *(target_list.begin()+rand()%target_list.size());
DoCast(target, SPELL_BLIND);
Blind_Timer = 40000;
}else Blind_Timer -= diff;
}
if (!InVanish)
DoMeleeAttackIfReady();
}
};
#define SPELL_MANABURN 29405
#define SPELL_MINDFLY 29570
#define SPELL_SWPAIN 34441
#define SPELL_SHADOWFORM 29406
struct MANGOS_DLL_DECL boss_baroness_dorothea_millstipeAI : public ScriptedAI
{
//Shadow Priest
boss_baroness_dorothea_millstipeAI(Creature *c) : ScriptedAI(c)
{
pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
EnterEvadeMode();
}
ScriptedInstance *pInstance;
uint32 ManaBurn_Timer;
uint32 MindFlay_Timer;
uint32 ShadowWordPain_Timer;
bool InCombat;
void Reset()
{
ManaBurn_Timer = 7000;
MindFlay_Timer = 1000;
ShadowWordPain_Timer = 6000;
InCombat = false;
if (pInstance)
pInstance->SetData(DATA_MOROES_EVENT, 0);
}
void Aggro(Unit *who)
{
return;
}
void MoveInLineOfSight(Unit *who)
{
if (!who || m_creature->getVictim())
return;
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);
DoStartMeleeAttack(who);
if (!InCombat)
{
InCombat=true;
DoCast(m_creature,SPELL_SHADOWFORM);
if (pInstance)
pInstance->SetData(DATA_MOROES_EVENT, 1);
}
}
}
}
void KilledUnit(Unit *victim)
{
}
void JustDied(Unit *victim)
{
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
if (pInstance && !pInstance->GetData(DATA_MOROES_EVENT))
EnterEvadeMode();
if (MindFlay_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_MINDFLY);
MindFlay_Timer = 12000; //3sec channeled
}else MindFlay_Timer -= diff;
if (ManaBurn_Timer < diff)
{
Unit *target;
std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
std::vector<Unit *> target_list;
for (std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
{
target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if (target && target->GetPower(POWER_MANA))
{
DoCast(target,SPELL_MANABURN);
itr= t_list.end();
}
}
ManaBurn_Timer = 5000; //3 sec cast
}else ManaBurn_Timer -= diff;
if (ShadowWordPain_Timer < diff)
{
Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (target)
DoCast(m_creature->getVictim(),SPELL_SWPAIN);
ShadowWordPain_Timer = 7000;
}else ShadowWordPain_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_moroes(Creature *_Creature)
{
return new boss_moroesAI (_Creature);
}
CreatureAI* GetAI_baroness_dorothea_millstipe(Creature *_Creature)
{
return new boss_baroness_dorothea_millstipeAI (_Creature);
}
void AddSC_boss_moroes()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_moroes";
newscript->GetAI = GetAI_boss_moroes;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="baroness_dorothea_millstipe";
newscript->GetAI = GetAI_baroness_dorothea_millstipe;
m_scripts[nrscripts++] = newscript;
}