rendered paste body#include "../../sc_defines.h"
#include "../../../../../shared/WorldPacket.h"
#include "../../../../../game/TargetedMovementGenerator.h"
/* for SD2 */
// Ground Abilities
#define SPELL_BELLOWING_ROAR 36922 // Bellowing Roar1.5 sec cast 8 sec cooldown - Fleeing in fear. 4 seconds remaining
#define SPELL_BONE_SHARDS 17014
//#define SPELL_CLEAVE ???????
#define SPELL_CHARRED_EARTH 30129 // Chars the ground, setting it flame, 2188 to 2812 Fire damage every 3 sec
#define SPELL_DISTRACTING_ASH 30130 // Reduces the chance to hit with spells and abilities by 30%.
#define SPELL_SMOLDERING_BREATH 39385 // Inflicts 3700 to 4300 Fire damage to enemies in a cone in front of the caster and ~1700 tvery 3 sec (5 ticks)
//#define SPELL_TAIL_SWEEP 25653 // Inflicts 450 damage on enemies in a cone behind the caster, knocking them back.
// Fly Abilities
#define SPELL_RAIN_OF_BONES 37098 // Bombards the target and nearby allies with bone fragments, summoning 3 skeletons in the process.
#define SPELL_SMOKING_BLAST 37057 // Deals 1850 to 2150 physical damage to the target and additional fire damage over time.
#define SPELL_RIGHTEOUS_FURY 25780
#define SPELL_FIREBALL_BARRAGE 30282 // Throws fireballs at any enemies farther than 40 yards away.
#define SAY_DIED "Ihr seid meiner halt unwuerdig!" // used(145)
//#define SOUND_DIED ???
#define SAY_DEATH "!!DEATH!![debag]" //used (150-151)
#define SOUND_DEATH 9454
#define SAY_PRE_AGGRO "!!PRE_AGGRO!![debag]"
#define SOUND_PRE_AGGRO 9455
#define SAY_AGGRO "!!AGGRO!![debag]" // no used
#define SOUND_AGGRO 9456 // no used
#define SAY_ATTACK "!!ATTACK!![debag]" // no used
#define SOUND_ATTACK 9451 // no used
#define SAY_WOUND "!!WOUND!![debag]" // no used
#define SOUND_WOUND 9452 // no used
#define SAY_WOUND_CRIT "!!WOUND_CRIT!![debag]" // no used
#define SOUND_WOUND_CRIT 9453 // no used
#define SAY_LOOP "!!LOOP!![debag]" // no used
#define SOUND_LOOP 9457 // no used
// summon (Fly Phase)
#define SUMMON 17261
#define ADD_0X -11173.214
#define ADD_0Y -1929.956
#define ADD_0Z 91.473
#define ADD_1X -11168.723
#define ADD_1Y -1927.489
#define ADD_1Z 91.473
#define ADD_2X -11163.718
#define ADD_2Y -1924.036
#define ADD_2Z 91.473
// Move boss - new
struct Locations
{
float x, y, z;
};
// random point
static Locations Flight[]=
{
{-11132, -1889, 104},
};
static Locations Summons[]=
{
{-11086, -1897, 92},
{-11088, -1901, 92},
{-11093, -1907, 92},
{-11107, -1892, 92},
{-11108, -1885, 92},
{-11103, -1883, 92}
};
struct MANGOS_DLL_DECL boss_nightbaneAI : public ScriptedAI
{
boss_nightbaneAI(Creature *c) : ScriptedAI(c) {Reset();}
// Ground State
uint32 Bellowing_Timer;
uint32 Charred_Timer;
uint32 Distracting_Timer;
uint32 Smoldering_Timer;
uint32 Boneshards_Timer;
//uint32 Tail_Timer;
// Air State
uint32 Global_Timer;
uint32 Fly_Timer;
uint32 Rain_Timer;
uint32 Smoking_Timer;
uint32 Fireball_Timer;
uint32 Phase;
Creature* Summoned;
uint32 Summon_Timer;
bool InCombat;
void Reset()
{
// Ground State
Bellowing_Timer = 50000;
Charred_Timer = 90000;
Distracting_Timer = 70000;
Smoldering_Timer = 70000;
Boneshards_Timer = (10+rand()%5)*1000;
// Fly State
Fly_Timer = 45000+rand()%15000;
Rain_Timer = 2000;
Smoking_Timer = 5000;
Fireball_Timer = 8500;
Phase = 1;
InCombat = false;
}
void KilledUnit(Unit* Victim)
{
if(rand()%2)
return;
DoYell(SAY_DIED,LANG_UNIVERSAL,Victim);
}
void JustDied(Unit* Killer)
{
DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_DEATH);
}
void AttackStart(Unit *who)
{
if (!who)
return;
if (who->isTargetableForAttack() && who!= m_creature)
{
if (!InCombat)
{
DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
InCombat = true;
}
DoStartMeleeAttack(who);
}
}
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;
}
}
}
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
// Ground State
if ( Phase == 1 || Phase == 3 || Phase == 5 || Phase == 7 )
{
Fly_Timer = 45000+rand()%15000;
// Bellowing Roar -fear
if (Bellowing_Timer < diff)
{
DoCast(m_creature,SPELL_BELLOWING_ROAR);
Bellowing_Timer = (30+rand()%50)*1000;
}else Bellowing_Timer -= diff;
// Distracting Ash - 30% mele/spell attack power (30 sec)
if (Distracting_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_DISTRACTING_ASH);
Distracting_Timer = (30+rand()%60)*1000;
}else Distracting_Timer -= diff;
// Charred Earth ~2.8 fire damage every 3 sec (10 ticks*2.8k dmg)
if (Charred_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target)
DoCast(target,SPELL_CHARRED_EARTH);
else
DoCast(m_creature->getVictim(),SPELL_CHARRED_EARTH);
Charred_Timer = (30+rand()%25)*1000;
}else Charred_Timer -= diff;
// Bone Shards -12-14 dmg per second all player with mele radius
if (Boneshards_Timer < diff)
{
DoCast(m_creature,SPELL_BONE_SHARDS);
Boneshards_Timer = (10+rand()%5)*1000;
}else Boneshards_Timer -= diff;
// Smoldering Breath(3k + 1.2k fire dmg per tick, 15 sec)
if(Smoldering_Timer <diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target)
DoCast(target,SPELL_SMOLDERING_BREATH);
else
DoCast(m_creature->getVictim(),SPELL_SMOLDERING_BREATH);
Smoldering_Timer = (30+rand()%15)*1000;
}else Smoldering_Timer -= diff;
DoMeleeAttackIfReady();
}
// Fly State
if (Phase == 2 || Phase == 4 || Phase == 6)
{
// Fly State timer
uint32 random = rand()%1;
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
Move(Flight[random].x, Flight[random].y, Flight[random].z, 3000, m_creature);
while( Fly_Timer > diff )
{
// Rain of Bones - Bombards the target and nearby allies with bone fragments, summoning 3 skeletons in the process.
if (Rain_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target)
DoCast(target,SPELL_RAIN_OF_BONES);
else
DoCast(m_creature->getVictim(),SPELL_RAIN_OF_BONES);
// summon 3 mobs and attack random player
random = rand()%6;
Summoned = m_creature->SummonCreature(SUMMON,Summons[random].x, Summons[random].y, Summons[random].z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
/*
random = rand()%3;
Summoned = m_creature->SummonCreature(SUMMON,Summons[random].x, Summons[random].y, Summons[random].z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
random = rand()%3;
Summoned = m_creature->SummonCreature(SUMMON,Summons[random].x, Summons[random].y, Summons[random].z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
*/
Rain_Timer = 3500;
}else Rain_Timer -= diff;
// Smoking Blast - Deals 1850 to 2150 phys dmg + 500 dmg per tick
if (Smoking_Timer < diff)
{
if( Rain_Timer > 1500 )
{
Rain_Timer = 60000;
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target)
DoCast(target,SPELL_SMOKING_BLAST);
else
DoCast(m_creature->getVictim(),SPELL_SMOKING_BLAST);
}
Smoking_Timer = 3000;
}else Smoking_Timer -= diff;
// Fireball Barrage - fire balls 2550-3450 dmg all in radius 40 yd
if (Fireball_Timer < diff)
{
Rain_Timer += 60000;
DoCast(m_creature->getVictim(),SPELL_FIREBALL_BARRAGE);
Fireball_Timer = 1000+rand()%500;
}else Fireball_Timer -= diff;
//if () - SPELL_RIGHTEOUS_FURY
Fly_Timer -= diff;
}
Phase++;
}
if( Phase == 1 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 75))
{
Fly_Timer = 45000+rand()%15000;
Phase = 2;
}
if( Phase == 3 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 50) )
{
Fly_Timer = 45000+rand()%15000;
Phase = 4;
}
if( Phase == 5 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 25) )
{
Fly_Timer = 45000+rand()%15000;
Phase = 6;
}
}
void Move(float X, float Y, float Z, uint32 Time, Unit* c, uint32 flags = 0x0200)
{
WorldPacket data( SMSG_MONSTER_MOVE, (41+c->GetPackGUID().size()) );
data.append(c->GetPackGUID());
data << c->GetPositionX() << c->GetPositionY() << c->GetPositionZ();
// unknown field - unrelated to orientation
// seems to increment about 1000 for every 1.7 seconds
// for now, we'll just use mstime
data << getMSTime();
data << uint8(0); // walkback when walking from A to B
data << uint32(flags); // flags
data << Time; // Time in between points
data << uint32(1); // 1 single waypoint
data << X << Y << Z; // the single waypoint Point B
c->SendMessageToSet( &data, true );
c->Relocate(X, Y, Z);
}
};
CreatureAI* GetAI_boss_nightbane(Creature *_Creature)
{
return new boss_nightbaneAI (_Creature);
}
void AddSC_boss_nightbane()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_nightbane";
newscript->GetAI = GetAI_boss_nightbane;
m_scripts[nrscripts++] = newscript;
}