All pastes #943768 Raw Edit

Anonym

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