All pastes #743871 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-10-20 20:59 UTC
rendered paste body
//Skeram - no text only sound
//8615 Are you so eager to die? I would be happy to accomodate you.
//8616 Cower mortals! The age of darkness is at hand.
//8617 Let your death serve as an example!
//8618 Prepare for the return of the ancient ones!
//8619 Spineless wretchers you will drown in rivers of blood!
//8620 The screams of the dying will fill the air. A symphony of terror is about to begin!
//8621 Tremble! The end is upon you.
//8622 You only delay... the inevetable
#include "../../sc_defines.h"
#include "../../../../../game/TargetedMovementGenerator.h"


#define SPELL_TRUE_FULFILLMENT1     785         // Charm is not handled by core
#define SPELL_TRUE_FULFILLMENT2     2313        // Charm is not handled by core
#define SPELL_TRUE_FULFILLMENT3     26525       // Charm is not handled by core
#define SPELL_TRUE_FULFILLMENT4     26526       // Charm is not handled by core

#define SPELL_ARCANE_EXPLOSION      26192       //Wrong id but only spell with cast time and similar damage
#define SPELL_EARTH_SHOCK           26194       //Unsure if this id is correct. Dmg is low but no others with higher
#define SKERAM_COORD1_X -8340.5f
#define SKERAM_COORD1_Y  2117.0f
#define SKERAM_COORD1_Z   133.06f
#define SKERAM_ORIENT       0.4f
#define SKERAM_COORD2_X -8327.6f
#define SKERAM_COORD2_Y  2089.3f
#define SKERAM_COORD2_Z   125.76f
#define SKERAM_COORD3_X -8315.0f
#define SKERAM_COORD3_Y  2061.2f
#define SKERAM_COORD3_Z   133.065f

struct MANGOS_DLL_DECL boss_skeramAI : public ScriptedAI
{

  boss_skeramAI(Creature *c) : ScriptedAI(c) {
    
    if (c->GetInstanceData())
    pInstance = (ScriptedInstance*)(m_creature->GetInstanceData());
    else pInstance = NULL;
    ihaveattackedsomeone = false;
    ImRealSkeram = false;
    EnterEvadeMode();
  }
  
  ScriptedInstance* pInstance; 
  uint32 skeramsplitcount;
  uint32 earth_shock_timer;
  uint32 arcane_explosion_timer;
  uint32 blink_timer;
  uint32 check_attacker_timer;
  Creature *SkeramSplit;
  uint32 afterblink_timer;
  bool ImRealSkeram;
  bool ihaveattackedsomeone;
  void EnterEvadeMode()
  {
    skeramsplitcount = 0;
    earth_shock_timer = 1000;
    arcane_explosion_timer = 10000;
    blink_timer = 7000;
    check_attacker_timer = 1000;
    afterblink_timer = 999999;
    
    m_creature->RemoveAllAuras();
    m_creature->DeleteThreatList();
    m_creature->CombatStop();

    if (ImRealSkeram && pInstance && pInstance->GetData("Event_Skeram_Status"))
      pInstance->SetData("Event_Skeram_Stopped",0);
		
	      DoGoHome();
            // should be immune to all CC, as any other instance boss
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);
        m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);
  }

  void AttackStart(Unit *who)
  {
    if (!who)
      return;

    if (who->isTargetableForAttack() && who!= m_creature)
    {
      //Begin melee attack if we are within range
      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);

        if (pInstance && !pInstance->GetData("Event_Skeram_Status")) // I'm the real prophet
        {
          pInstance->SetData("Event_Skeram_Started",m_creature->GetGUID());
          ImRealSkeram = true;
        }
        
        //Begin melee attack if we are within range
        DoStartMeleeAttack(who);

      }
    }
  }
  
  void ResetThreat()
  {
    std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
    
    for(uint32 i = 0; i <= (m_threatlist.size()-1); i++)
    {
      Unit* pUnit = SelectUnit(SELECT_TARGET_TOPAGGRO, i);
      if(pUnit)
        (m_creature->getThreatManager()).modifyThreatPercent(pUnit, -99);
    }
 
  }
  
  void DespawnCreatureIfExists(Creature *pUnit)
  {
    if(pUnit && pUnit->isAlive())
      pUnit->DealDamage(pUnit, pUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);
  }

  void UpdateAI(const uint32 diff)
  {
    uint32 skeramhealthperc;
    float realskeram_x,realskeram_y,realskeram_z;
    float skeramsplit1_x,skeramsplit1_y,skeramsplit1_z;
    float skeramsplit2_x,skeramsplit2_y,skeramsplit2_z;
    Unit *RealSkeramAttacker;
    
    if(check_attacker_timer < diff)
    {
      if (ImRealSkeram && m_creature && m_creature->getVictim() && m_creature->getVictim()->isAlive())
      {
        pInstance->SetData("Skeram_Attacker_Guid", m_creature->getVictim()->GetGUIDLow());
        pInstance->SetData("Skeram_Attacker_Guid_data2", m_creature->getVictim()->GetGUIDHigh());
      }

      check_attacker_timer = 1000;
    }else check_attacker_timer -= diff;
    
    //Return since we have no target but if im not real Skeram, i must attack someone
    if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
    {
        if (!ImRealSkeram && pInstance)
        {
          Unit* pSkeramAttacker = Unit::GetUnit((*m_creature), pInstance->GetUnitGUID("Skeram_Attacker_Guid"));

          if (pSkeramAttacker && pSkeramAttacker->isAlive())
	    			DoStartMeleeAttack(pSkeramAttacker);
	    		else
	      		if (ihaveattackedsomeone) DespawnCreatureIfExists(m_creature);
        }
      return;
    }
    
    ihaveattackedsomeone = true;
    
    //Earth Shock only if tank is not in melee range very 2 sec?
    //Skeram do 2500+ damage clone much low
    if(earth_shock_timer < diff)
    {
      int32 basePointsES = 2500;
        if (!m_creature->IsWithinDistInMap(m_creature->getVictim(), 8))
          if(ImRealSkeram)
            m_creature->CastCustomSpell(m_creature->getVictim(),SPELL_EARTH_SHOCK,&basePointsES, NULL, NULL, true);
          else
            DoCast(m_creature->getVictim(), SPELL_EARTH_SHOCK);
      earth_shock_timer = 2000;
    }else earth_shock_timer -= diff;
    
    //Arcane Explosion
    //Skeram do 1500+ damage clone much low
    if(arcane_explosion_timer < diff)
    {
      int32 basePointsEX = 1500;
      if(ImRealSkeram) m_creature->CastCustomSpell(m_creature,SPELL_ARCANE_EXPLOSION,&basePointsEX, NULL, NULL, true);
      else DoCast(m_creature, SPELL_ARCANE_EXPLOSION);
      arcane_explosion_timer = 20000;
    }else arcane_explosion_timer -= diff;
    
    if (afterblink_timer < diff)
    	{
	      (*m_creature).GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature->getVictim()));
         afterblink_timer = 999999;
    	} afterblink_timer -= diff;
    	
    //Skeram Blink and reset his threat - i need right visual effect and coding effect
    if(blink_timer < diff)
    {
      ResetThreat();
      m_creature->Relocate(-8327.62f,2089.35f,125.76f,0.4f);
      m_creature->SendMonsterMove(-8327.62f, 2089.35f, 125.76f, 0, true, 0);
      afterblink_timer = 1000;
      blink_timer = (rand()%10000) + 20000;
    }else blink_timer -= diff;

    if (ImRealSkeram) // I'm the real prophet?
    {
      skeramhealthperc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth();
      Unit* pUnit;
      if     ((skeramhealthperc < 76 && skeramsplitcount == 0)
           || (skeramhealthperc < 51 && skeramsplitcount == 1)
           || (skeramhealthperc < 26 && skeramsplitcount == 2)) 
      {
        //Skeram Blink, reset his threat and spawn his clone from the platform
        switch(rand()%3)
        {
          case 0:
            realskeram_x = SKERAM_COORD1_X;realskeram_y = SKERAM_COORD1_Y;realskeram_z = SKERAM_COORD1_Z;
            skeramsplit1_x = SKERAM_COORD2_X;skeramsplit1_y = SKERAM_COORD2_Y;skeramsplit1_z = SKERAM_COORD2_Z;
            skeramsplit2_x = SKERAM_COORD3_X;skeramsplit2_y = SKERAM_COORD3_Y;skeramsplit2_z = SKERAM_COORD3_Z;
            break;
  
          case 1:
            realskeram_x = SKERAM_COORD2_X;realskeram_y = SKERAM_COORD2_Y;realskeram_z = SKERAM_COORD2_Z;
            skeramsplit1_x = SKERAM_COORD1_X;skeramsplit1_y = SKERAM_COORD1_Y;skeramsplit1_z = SKERAM_COORD1_Z;
            skeramsplit2_x = SKERAM_COORD3_X;skeramsplit2_y = SKERAM_COORD3_Y;skeramsplit2_z = SKERAM_COORD3_Z;
            break;
          
          case 2:
            realskeram_x = SKERAM_COORD3_X;realskeram_y = SKERAM_COORD3_Y;realskeram_z = SKERAM_COORD3_Z;
            skeramsplit1_x = SKERAM_COORD2_X;skeramsplit1_y = SKERAM_COORD2_Y;skeramsplit1_z = SKERAM_COORD2_Z;
            skeramsplit2_x = SKERAM_COORD1_X;skeramsplit2_y = SKERAM_COORD1_Y;skeramsplit2_z = SKERAM_COORD1_Z;
            break;
        }
        
        skeramsplitcount++;
        SkeramSplit = m_creature->SummonCreature(15263,skeramsplit1_x,skeramsplit1_y,skeramsplit1_z,SKERAM_ORIENT,TEMPSUMMON_CORPSE_DESPAWN,900000);
        if (SkeramSplit)
        {
          SkeramSplit->SetHealth(m_creature->GetHealth());
          pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0);
          if (pUnit)
            SkeramSplit->AI()->AttackStart(pUnit);
        }
        
        SkeramSplit = m_creature->SummonCreature(15263,skeramsplit2_x,skeramsplit2_y,skeramsplit2_z,SKERAM_ORIENT,TEMPSUMMON_CORPSE_DESPAWN,900000);
        if (SkeramSplit)
        {
          SkeramSplit->SetHealth(m_creature->GetHealth());
          pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0);
          if (pUnit)
            SkeramSplit->AI()->AttackStart(pUnit);
        }
        
        ResetThreat();

        m_creature->Relocate(realskeram_x,realskeram_y,realskeram_z,SKERAM_ORIENT);
        m_creature->SendMonsterMove(realskeram_x, realskeram_y, realskeram_z, SKERAM_ORIENT, true, 0);
        afterblink_timer = 1000;
      }
    }
    
    DoMeleeAttackIfReady();
  }
};

CreatureAI* GetAI_boss_skeram(Creature *_Creature)
{
  return new boss_skeramAI (_Creature);
}


void AddSC_boss_skeram()
{
  Script *newscript;
  newscript = new Script;
  newscript->Name="boss_skeram";
  newscript->GetAI = GetAI_boss_skeram;
  m_scripts[nrscripts++] = newscript;
}