All pastes #968973 Raw Edit

Etwas

public text v1 · immutable
·published 2008-04-03 12:51 UTC
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;
}