//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& 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(*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; }