rendered paste body#include "../../sc_defines.h"
#include "../../../../../shared/WorldPacket.h"
#include "../../../../../game/TargetedMovementGenerator.h"
/*
#include "../../../../../game/Player.h"
#include "../../../../../game/GossipDef.h"
*/
// 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.
// Air 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!"
#define SAY_DEATH "!!DEATH!![debag]"
#define SOUND_DEATH 9454
#define SAY_PRE_AGGRO "!!PRE_AGGRO!![debag]"
#define SOUND_PRE_AGGRO 9455
#define SAY_AGGRO "!!AGGRO!![debag]"
#define SOUND_AGGRO 9456
#define SAY_ATTACK "!!ATTACK!![debag]"
#define SOUND_ATTACK 9451
#define SAY_WOUND "!!WOUND!![debag]"
#define SOUND_WOUND 9452
#define SAY_WOUND_CRIT "!!WOUND_CRIT!![debag]"
#define SOUND_WOUND_CRIT 9453
#define SAY_LOOP "!!LOOP!![debag]"
#define SOUND_LOOP 9457
#define SAY_PHASE1 "PHASE 1"
#define SAY_PHASE2 "PHASE 2"
#define SAY_PHASE3 "PHASE 3"
#define SAY_PHASE4 "PHASE 4"
#define SAY_PHASE5 "PHASE 5"
#define SAY_PHASE6 "PHASE 6"
#define SAY_PHASE7 "PHASE 7"
// summon (Air 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
#define AIR_MOVE_X -11174
#define AIR_MOVE_Y -1964
#define AIR_MOVE_Z 101
#define AIR_MOVE_O 0.5
#define GROUND_MOVE_X -11159
#define GROUND_MOVE_Y -1949
#define GROUND_MOVE_Z 93
#define GROUND_MOVE_O 0.5
struct Locations
{
float x, y, z;
};
// áóäóò ðàíäîñíûå òî÷êè =) ÷óòîê îñòàëîñü =)
static Locations Flight[]=
{
{-11174, -1964, 101},
{-11174, -1964, 101},
{-11174, -1964, 101},
{-11174, -1964, 101},
{-11174, -1964, 101}
};
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 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 = 1000;
// Fly State
Fly_Timer = 45000+rand()%15000;
Rain_Timer = 1000;
Smoking_Timer = 2000;
Fireball_Timer = 2500;
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;
DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
InCombat = true;
}
DoYell(SAY_ATTACK, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_ATTACK);
}
}
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
// Ground State
if ( Phase == 1 || Phase == 3 || Phase == 5 || Phase == 7 )
{
// Bellowing Roar -fear
Fly_Timer = 60000;
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
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)
{
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
uint32 random = rand()%5;
Move(Flight[random].x, Flight[random].y, Flight[random].z, 3000, m_creature);
if(Fly_Timer < diff)
{
Phase++;
}else Fly_Timer -= diff;
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);
Rain_Timer = 3500;
}else Rain_Timer -= diff;
if(Summon_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
// summon 3 mobs and attack random player
switch (rand()%2)
{
case 0:
Summoned = m_creature->SummonCreature(SUMMON,ADD_0X,ADD_0Y,ADD_0Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(SUMMON,ADD_0X,ADD_0Y,ADD_0Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(SUMMON,ADD_0X,ADD_0Y,ADD_0Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
case 1:
Summoned = m_creature->SummonCreature(SUMMON,ADD_1X,ADD_1Y,ADD_1Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(SUMMON,ADD_1X,ADD_1Y,ADD_1Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(SUMMON,ADD_1X,ADD_1Y,ADD_1Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
case 2:
Summoned = m_creature->SummonCreature(SUMMON,ADD_2X,ADD_2Y,ADD_2Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(SUMMON,ADD_2X,ADD_2Y,ADD_2Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
Summoned = m_creature->SummonCreature(SUMMON,ADD_2X,ADD_2Y,ADD_2Z,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000);
((CreatureAI*)Summoned->AI())->AttackStart(target);
break;
}
Summon_Timer = 15000;
}else Summon_Timer -= diff;
if (Smoking_Timer < diff)
{
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 = (30+rand()%10)*1000;
}else Smoking_Timer -= diff;
if (Fireball_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_FIREBALL_BARRAGE);
Fireball_Timer = 4000+rand()%1000;
}else Fireball_Timer -= diff;
}
if( Phase == 1 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 75))
Phase = 2;
if( Phase == 3 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 50) )
Phase = 4;
if( Phase == 5 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 25) )
Phase = 6;
/*
if ( Phase == 5 && (m_creature->GetHealth()*100) / m_creature->GetMaxHealth() < 25 )
{
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
SpecialMove(AIR_MOVE_X,AIR_MOVE_Y,AIR_MOVE_Z,7500);
m_creature->Relocate(AIR_MOVE_X,AIR_MOVE_Y,AIR_MOVE_Z,AIR_MOVE_O);
AirState_Timer = 60000;
Phase == 6;
}
if ( (m_creature->GetHealth()*100) / m_creature->GetMaxHealth() == 75 ||
(m_creature->GetHealth()*100) / m_creature->GetMaxHealth() == 50 ||
(m_creature->GetHealth()*100) / m_creature->GetMaxHealth() == 25 )
Phase = 2;
*/
}
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;
}