From c260b3f77848dc02518712a319f1daa94ef94ebe Mon Sep 17 00:00:00 2001 From: Supabad Date: Sun, 8 Aug 2010 00:49:40 +0200 Subject: [PATCH] convert Magtheridons Lair and Shattered Halls to new format --HG-- branch : trunk --- .../MagtheridonsLair/boss_magtheridon.cpp | 1020 +++++++++-------- .../instance_magtheridons_lair.cpp | 389 ++++--- .../ShatteredHalls/boss_nethekurse.cpp | 663 ++++++----- .../ShatteredHalls/boss_warbringer_omrogg.cpp | 577 +++++----- .../boss_warchief_kargath_bladefist.cpp | 475 ++++---- .../instance_shattered_halls.cpp | 146 +-- 6 files changed, 1721 insertions(+), 1549 deletions(-) diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp index 123636a503c..a5fe18352aa 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp @@ -41,532 +41,606 @@ static Yell RandomTaunt[]= {-1544005}, }; -#define SAY_FREED -1544006 -#define SAY_AGGRO -1544007 -#define SAY_BANISH -1544008 -#define SAY_CHAMBER_DESTROY -1544009 -#define SAY_PLAYER_KILLED -1544010 -#define SAY_DEATH -1544011 +enum eSays +{ + SAY_FREED = -1544006, + SAY_AGGRO = -1544007, + SAY_BANISH = -1544008, + SAY_CHAMBER_DESTROY = -1544009, + SAY_PLAYER_KILLED = -1544010, + SAY_DEATH = -1544011, +}; -#define EMOTE_BERSERK -1544012 -#define EMOTE_BLASTNOVA -1544013 -#define EMOTE_BEGIN -1544014 +enum eEmotes +{ + EMOTE_BERSERK = -1544012, + EMOTE_BLASTNOVA = -1544013, + EMOTE_BEGIN = -1544014, +}; -#define MOB_MAGTHERIDON 17257 -#define MOB_ROOM 17516 -#define MOB_CHANNELLER 17256 -#define MOB_ABYSSAL 17454 +enum eCreatures +{ + MOB_MAGTHERIDON = 17257, + MOB_ROOM = 17516, + MOB_CHANNELLER = 17256, + MOB_ABYSSAL = 17454, +}; -#define SPELL_BLASTNOVA 30616 -#define SPELL_CLEAVE 30619 -#define SPELL_QUAKE_TRIGGER 30657 // must be cast with 30561 as the proc spell -#define SPELL_QUAKE_KNOCKBACK 30571 -#define SPELL_BLAZE_TARGET 30541 // core bug, does not support target 7 -#define SPELL_BLAZE_TRAP 30542 -#define SPELL_DEBRIS_KNOCKDOWN 36449 -#define SPELL_DEBRIS_VISUAL 30632 -#define SPELL_DEBRIS_DAMAGE 30631 // core bug, does not support target 8 -#define SPELL_CAMERA_SHAKE 36455 -#define SPELL_BERSERK 27680 +enum eSpells +{ + SPELL_BLASTNOVA = 30616, + SPELL_CLEAVE = 30619, + SPELL_QUAKE_TRIGGER = 30657, //must be cast with 30561 as the proc spell + SPELL_QUAKE_KNOCKBACK = 30571, + SPELL_BLAZE_TARGET = 30541, //core bug, does not support target 7 + SPELL_BLAZE_TRAP = 30542, + SPELL_DEBRIS_KNOCKDOWN = 36449, + SPELL_DEBRIS_VISUAL = 30632, + SPELL_DEBRIS_DAMAGE = 30631, //core bug, does not support target 8 + SPELL_CAMERA_SHAKE = 36455, + SPELL_BERSERK = 27680, + SPELL_SHADOW_CAGE = 30168, + SPELL_SHADOW_GRASP = 30410, + SPELL_SHADOW_GRASP_VISUAL = 30166, + SPELL_MIND_EXHAUSTION = 44032, //Casted by the cubes when channeling ends + SPELL_SHADOW_CAGE_C = 30205, + SPELL_SHADOW_GRASP_C = 30207, + SPELL_SHADOW_BOLT_VOLLEY = 30510, + SPELL_DARK_MENDING = 30528, + SPELL_FEAR = 30530, //39176 + SPELL_BURNING_ABYSSAL = 30511, + SPELL_SOUL_TRANSFER = 30531, //core bug, does not support target 7 + SPELL_FIRE_BLAST = 37110, +}; -#define SPELL_SHADOW_CAGE 30168 -#define SPELL_SHADOW_GRASP 30410 -#define SPELL_SHADOW_GRASP_VISUAL 30166 -#define SPELL_MIND_EXHAUSTION 44032 //Casted by the cubes when channeling ends - -#define SPELL_SHADOW_CAGE_C 30205 -#define SPELL_SHADOW_GRASP_C 30207 - -#define SPELL_SHADOW_BOLT_VOLLEY 30510 -#define SPELL_DARK_MENDING 30528 -#define SPELL_FEAR 30530 //39176 -#define SPELL_BURNING_ABYSSAL 30511 -#define SPELL_SOUL_TRANSFER 30531 // core bug, does not support target 7 - -#define SPELL_FIRE_BLAST 37110 - -// count of clickers needed to interrupt blast nova +//count of clickers needed to interrupt blast nova #define CLICKERS_COUNT 5 typedef std::map CubeMap; -struct mob_abyssalAI : public ScriptedAI +class mob_abyssal : public CreatureScript { - mob_abyssalAI(Creature *c) : ScriptedAI(c) - { - trigger = 0; - Despawn_Timer = 60000; - } + public: - uint32 FireBlast_Timer; - uint32 Despawn_Timer; - uint32 trigger; - - void Reset() - { - FireBlast_Timer = 6000; - } - - void SpellHit(Unit*, const SpellEntry *spell) - { - if (trigger == 2 && spell->Id == SPELL_BLAZE_TARGET) + mob_abyssal() + : CreatureScript("mob_abyssal") { - DoCast(me, SPELL_BLAZE_TRAP, true); - me->SetVisibility(VISIBILITY_OFF); - Despawn_Timer = 130000; } - } - void SetTrigger(uint32 _trigger) - { - trigger = _trigger; - me->SetDisplayId(11686); - if (trigger == 1) //debris + struct mob_abyssalAI : public ScriptedAI { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - DoCast(me, SPELL_DEBRIS_VISUAL, true); - FireBlast_Timer = 5000; - Despawn_Timer = 10000; - } - } - - void EnterCombat(Unit* /*who*/) {DoZoneInCombat();} - void AttackStart(Unit *who) {if (!trigger) ScriptedAI::AttackStart(who);} - void MoveInLineOfSight(Unit *who) {if (!trigger) ScriptedAI::MoveInLineOfSight(who);} - - void UpdateAI(const uint32 diff) - { - if (trigger) - { - if (trigger == 1) + mob_abyssalAI(Creature* pCreature) : ScriptedAI(pCreature) { + trigger = 0; + Despawn_Timer = 60000; + } + + uint32 FireBlast_Timer; + uint32 Despawn_Timer; + uint32 trigger; + + void Reset() + { + FireBlast_Timer = 6000; + } + + void SpellHit(Unit*, const SpellEntry *spell) + { + if (trigger == 2 && spell->Id == SPELL_BLAZE_TARGET) + { + DoCast(me, SPELL_BLAZE_TRAP, true); + me->SetVisibility(VISIBILITY_OFF); + Despawn_Timer = 130000; + } + } + + void SetTrigger(uint32 _trigger) + { + trigger = _trigger; + me->SetDisplayId(11686); + if (trigger == 1) //debris + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_DEBRIS_VISUAL, true); + FireBlast_Timer = 5000; + Despawn_Timer = 10000; + } + } + + void EnterCombat(Unit* /*who*/) + { + DoZoneInCombat(); + } + void AttackStart(Unit *who) + { + if (!trigger) + ScriptedAI::AttackStart(who); + } + void MoveInLineOfSight(Unit *who) + { + if (!trigger) + ScriptedAI::MoveInLineOfSight(who); + } + + void UpdateAI(const uint32 diff) + { + if (trigger) + { + if (trigger == 1) + { + if (FireBlast_Timer <= diff) + { + DoCast(me, SPELL_DEBRIS_DAMAGE, true); + trigger = 3; + } + else FireBlast_Timer -= diff; + } + return; + } + + if (Despawn_Timer <= diff) + { + me->ForcedDespawn(); + } + else Despawn_Timer -= diff; + + if (!UpdateVictim()) + return; + if (FireBlast_Timer <= diff) { - DoCast(me, SPELL_DEBRIS_DAMAGE, true); - trigger = 3; - } else FireBlast_Timer -= diff; + DoCast(me->getVictim(), SPELL_FIRE_BLAST); + FireBlast_Timer = 5000+rand()%10000; + } + else FireBlast_Timer -= diff; + + DoMeleeAttackIfReady(); } - return; + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new mob_abyssalAI(Creature); } - - if (Despawn_Timer <= diff) - { - me->ForcedDespawn(); - } else Despawn_Timer -= diff; - - if (!UpdateVictim()) - return; - - if (FireBlast_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_FIRE_BLAST); - FireBlast_Timer = 5000+rand()%10000; - } else FireBlast_Timer -= diff; - - DoMeleeAttackIfReady(); - } }; -struct boss_magtheridonAI : public ScriptedAI +class boss_magtheridon : public CreatureScript { - boss_magtheridonAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); - me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); + public: - // target 7, random target with certain entry spell, need core fix - SpellEntry *TempSpell; - TempSpell = GET_SPELL(SPELL_BLAZE_TARGET); - if (TempSpell && TempSpell->EffectImplicitTargetA[0] != 6) + boss_magtheridon() + : CreatureScript("boss_magtheridon") { - TempSpell->EffectImplicitTargetA[0] = 6; - TempSpell->EffectImplicitTargetB[0] = 0; } - TempSpell = GET_SPELL(SPELL_QUAKE_TRIGGER); - if (TempSpell && TempSpell->EffectTriggerSpell[0] != SPELL_QUAKE_KNOCKBACK) + + struct boss_magtheridonAI : public ScriptedAI { - TempSpell->EffectTriggerSpell[0] = SPELL_QUAKE_KNOCKBACK; - } - } - - CubeMap Cube; - - ScriptedInstance* pInstance; - - uint32 Berserk_Timer; - uint32 Quake_Timer; - uint32 Cleave_Timer; - uint32 BlastNova_Timer; - uint32 Blaze_Timer; - uint32 Debris_Timer; - uint32 RandChat_Timer; - - bool Phase3; - bool NeedCheckCube; - - void Reset() - { - Berserk_Timer = 1320000; - Quake_Timer = 40000; - Debris_Timer = 10000; - Blaze_Timer = 10000+rand()%20000; - BlastNova_Timer = 60000; - Cleave_Timer = 15000; - RandChat_Timer = 90000; - - Phase3 = false; - NeedCheckCube = false; - - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); - me->addUnitState(UNIT_STAT_STUNNED); - DoCast(me, SPELL_SHADOW_CAGE_C, true); - } - - void JustReachedHome() - { - if (pInstance) - { - pInstance->SetData(DATA_MAGTHERIDON_EVENT, NOT_STARTED); - pInstance->SetData(DATA_COLLAPSE, false); - } - } - - void SetClicker(uint64 cubeGUID, uint64 clickerGUID) - { - // to avoid multiclicks from 1 cube - if (uint64 guid = Cube[cubeGUID]) - DebuffClicker(Unit::GetUnit(*me, guid)); - Cube[cubeGUID] = clickerGUID; - NeedCheckCube = true; - } - - //function to interrupt channeling and debuff clicker with mind exh(used if second person clicks with same cube or after dispeling/ending shadow grasp DoT) - void DebuffClicker(Unit *clicker) - { - if (!clicker || !clicker->isAlive()) - return; - - clicker->RemoveAurasDueToSpell(SPELL_SHADOW_GRASP); // cannot interrupt triggered spells - clicker->InterruptNonMeleeSpells(false); - clicker->CastSpell(clicker, SPELL_MIND_EXHAUSTION, true); - } - - void NeedCheckCubeStatus() - { - uint32 ClickerNum = 0; - // now checking if every clicker has debuff from manticron(it is dispelable atm rev 6110 : S) - // if not - apply mind exhaustion and delete from clicker's list - for (CubeMap::iterator i = Cube.begin(); i != Cube.end(); ++i) - { - Unit *clicker = Unit::GetUnit(*me, (*i).second); - if (!clicker || !clicker->HasAura(SPELL_SHADOW_GRASP)) + boss_magtheridonAI(Creature* pCreature) : ScriptedAI(pCreature) { - DebuffClicker(clicker); - (*i).second = 0; - } else ++ClickerNum; - } + pInstance = pCreature->GetInstanceData(); + me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); + me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); - // if 5 clickers from other cubes apply shadow cage - if (ClickerNum >= CLICKERS_COUNT && !me->HasAura(SPELL_SHADOW_CAGE)) - { - DoScriptText(SAY_BANISH, me); - DoCast(me, SPELL_SHADOW_CAGE, true); - } - else if (ClickerNum < CLICKERS_COUNT && me->HasAura(SPELL_SHADOW_CAGE)) - me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE); - - if (!ClickerNum) NeedCheckCube = false; - } - - void KilledUnit(Unit* /*victim*/) - { - DoScriptText(SAY_PLAYER_KILLED, me); - } - - void JustDied(Unit* /*Killer*/) - { - if (pInstance) - pInstance->SetData(DATA_MAGTHERIDON_EVENT, DONE); - - DoScriptText(SAY_DEATH, me); - } - - void MoveInLineOfSight(Unit* /*who*/) {} - - void AttackStart(Unit *who) - { - if (!me->hasUnitState(UNIT_STAT_STUNNED)) - ScriptedAI::AttackStart(who); - } - - void EnterCombat(Unit * /*who*/) - { - if (pInstance) - pInstance->SetData(DATA_MAGTHERIDON_EVENT, IN_PROGRESS); - DoZoneInCombat(); - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE_C); - - DoScriptText(SAY_FREED, me); - } - - void UpdateAI(const uint32 diff) - { - if (!me->isInCombat()) - { - if (RandChat_Timer <= diff) - { - DoScriptText(RandomTaunt[rand()%6].id, me); - RandChat_Timer = 90000; - } else RandChat_Timer -= diff; - } - - if (!UpdateVictim()) - return; - - if (NeedCheckCube) NeedCheckCubeStatus(); - - if (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - DoScriptText(EMOTE_BERSERK, me); - Berserk_Timer = 60000; - } else Berserk_Timer -= diff; - - if (Cleave_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_CLEAVE); - Cleave_Timer = 10000; - } else Cleave_Timer -= diff; - - if (BlastNova_Timer <= diff) - { - // to avoid earthquake interruption - if (!me->hasUnitState(UNIT_STAT_STUNNED)) - { - DoScriptText(EMOTE_BLASTNOVA, me); - DoCast(me, SPELL_BLASTNOVA); - BlastNova_Timer = 60000; - } - } else BlastNova_Timer -= diff; - - if (Quake_Timer <= diff) - { - // to avoid blastnova interruption - if (!me->IsNonMeleeSpellCasted(false)) - { - DoCast(me, SPELL_QUAKE_TRIGGER, true); - Quake_Timer = 50000; - } - } else Quake_Timer -= diff; - - if (Blaze_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - { - float x, y, z; - pTarget->GetPosition(x, y, z); - Creature *summon = me->SummonCreature(MOB_ABYSSAL, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); - if (summon) + // target 7, random target with certain entry spell, need core fix + SpellEntry *TempSpell; + TempSpell = GET_SPELL(SPELL_BLAZE_TARGET); + if (TempSpell && TempSpell->EffectImplicitTargetA[0] != 6) { - CAST_AI(mob_abyssalAI, summon->AI())->SetTrigger(2); - DoCast(summon, SPELL_BLAZE_TARGET, true); - summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + TempSpell->EffectImplicitTargetA[0] = 6; + TempSpell->EffectImplicitTargetB[0] = 0; + } + TempSpell = GET_SPELL(SPELL_QUAKE_TRIGGER); + if (TempSpell && TempSpell->EffectTriggerSpell[0] != SPELL_QUAKE_KNOCKBACK) + { + TempSpell->EffectTriggerSpell[0] = SPELL_QUAKE_KNOCKBACK; } } - Blaze_Timer = 20000 + rand()%20000; - } else Blaze_Timer -= diff; - if (!Phase3 && me->GetHealth()*10 < me->GetMaxHealth()*3 - && !me->IsNonMeleeSpellCasted(false) // blast nova - && !me->hasUnitState(UNIT_STAT_STUNNED)) // shadow cage and earthquake - { - Phase3 = true; - DoScriptText(SAY_CHAMBER_DESTROY, me); - DoCast(me, SPELL_CAMERA_SHAKE, true); - DoCast(me, SPELL_DEBRIS_KNOCKDOWN, true); + CubeMap Cube; - if (pInstance) - pInstance->SetData(DATA_COLLAPSE, true); - } + ScriptedInstance* pInstance; - if (Phase3) - { - if (Debris_Timer <= diff) + uint32 Berserk_Timer; + uint32 Quake_Timer; + uint32 Cleave_Timer; + uint32 BlastNova_Timer; + uint32 Blaze_Timer; + uint32 Debris_Timer; + uint32 RandChat_Timer; + + bool Phase3; + bool NeedCheckCube; + + void Reset() { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - { - float x, y, z; - pTarget->GetPosition(x, y, z); - Creature *summon = me->SummonCreature(MOB_ABYSSAL, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); - if (summon) CAST_AI(mob_abyssalAI, summon->AI())->SetTrigger(1); - } + Berserk_Timer = 1320000; + Quake_Timer = 40000; Debris_Timer = 10000; - } else Debris_Timer -= diff; - } + Blaze_Timer = 10000+rand()%20000; + BlastNova_Timer = 60000; + Cleave_Timer = 15000; + RandChat_Timer = 90000; - DoMeleeAttackIfReady(); - } + Phase3 = false; + NeedCheckCube = false; + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + me->addUnitState(UNIT_STAT_STUNNED); + DoCast(me, SPELL_SHADOW_CAGE_C, true); + } + + void JustReachedHome() + { + if (pInstance) + { + pInstance->SetData(DATA_MAGTHERIDON_EVENT, NOT_STARTED); + pInstance->SetData(DATA_COLLAPSE, false); + } + } + + void SetClicker(uint64 cubeGUID, uint64 clickerGUID) + { + // to avoid multiclicks from 1 cube + if (uint64 guid = Cube[cubeGUID]) + DebuffClicker(Unit::GetUnit(*me, guid)); + Cube[cubeGUID] = clickerGUID; + NeedCheckCube = true; + } + + //function to interrupt channeling and debuff clicker with mind exh(used if second person clicks with same cube or after dispeling/ending shadow grasp DoT) + void DebuffClicker(Unit *clicker) + { + if (!clicker || !clicker->isAlive()) + return; + + clicker->RemoveAurasDueToSpell(SPELL_SHADOW_GRASP); // cannot interrupt triggered spells + clicker->InterruptNonMeleeSpells(false); + clicker->CastSpell(clicker, SPELL_MIND_EXHAUSTION, true); + } + + void NeedCheckCubeStatus() + { + uint32 ClickerNum = 0; + // now checking if every clicker has debuff from manticron(it is dispelable atm rev 6110 : S) + // if not - apply mind exhaustion and delete from clicker's list + for (CubeMap::iterator i = Cube.begin(); i != Cube.end(); ++i) + { + Unit *clicker = Unit::GetUnit(*me, (*i).second); + if (!clicker || !clicker->HasAura(SPELL_SHADOW_GRASP)) + { + DebuffClicker(clicker); + (*i).second = 0; + } + else + ++ClickerNum; + } + + // if 5 clickers from other cubes apply shadow cage + if (ClickerNum >= CLICKERS_COUNT && !me->HasAura(SPELL_SHADOW_CAGE)) + { + DoScriptText(SAY_BANISH, me); + DoCast(me, SPELL_SHADOW_CAGE, true); + } + else + if (ClickerNum < CLICKERS_COUNT && me->HasAura(SPELL_SHADOW_CAGE)) + me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE); + + if (!ClickerNum) + NeedCheckCube = false; + } + + void KilledUnit(Unit* /*victim*/) + { + DoScriptText(SAY_PLAYER_KILLED, me); + } + + void JustDied(Unit* /*Killer*/) + { + if (pInstance) + pInstance->SetData(DATA_MAGTHERIDON_EVENT, DONE); + + DoScriptText(SAY_DEATH, me); + } + + void MoveInLineOfSight(Unit* /*who*/) {} + + void AttackStart(Unit *who) + { + if (!me->hasUnitState(UNIT_STAT_STUNNED)) + ScriptedAI::AttackStart(who); + } + + void EnterCombat(Unit * /*who*/) + { + if (pInstance) + pInstance->SetData(DATA_MAGTHERIDON_EVENT, IN_PROGRESS); + DoZoneInCombat(); + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE_C); + + DoScriptText(SAY_FREED, me); + } + + void UpdateAI(const uint32 diff) + { + if (!me->isInCombat()) + { + if (RandChat_Timer <= diff) + { + DoScriptText(RandomTaunt[rand()%6].id, me); + RandChat_Timer = 90000; + } + else + RandChat_Timer -= diff; + } + + if (!UpdateVictim()) + return; + + if (NeedCheckCube) NeedCheckCubeStatus(); + + if (Berserk_Timer <= diff) + { + DoCast(me, SPELL_BERSERK, true); + DoScriptText(EMOTE_BERSERK, me); + Berserk_Timer = 60000; + } + else + Berserk_Timer -= diff; + + if (Cleave_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_CLEAVE); + Cleave_Timer = 10000; + } + else + Cleave_Timer -= diff; + + if (BlastNova_Timer <= diff) + { + // to avoid earthquake interruption + if (!me->hasUnitState(UNIT_STAT_STUNNED)) + { + DoScriptText(EMOTE_BLASTNOVA, me); + DoCast(me, SPELL_BLASTNOVA); + BlastNova_Timer = 60000; + } + } + else + BlastNova_Timer -= diff; + + if (Quake_Timer <= diff) + { + // to avoid blastnova interruption + if (!me->IsNonMeleeSpellCasted(false)) + { + DoCast(me, SPELL_QUAKE_TRIGGER, true); + Quake_Timer = 50000; + } + } + else + Quake_Timer -= diff; + + if (Blaze_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + { + float x, y, z; + pTarget->GetPosition(x, y, z); + Creature *summon = me->SummonCreature(MOB_ABYSSAL, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + if (summon) + { + CAST_AI(mob_abyssal::mob_abyssalAI, summon->AI())->SetTrigger(2); + DoCast(summon, SPELL_BLAZE_TARGET, true); + summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + } + Blaze_Timer = 20000 + rand()%20000; + } + else + Blaze_Timer -= diff; + + if (!Phase3 && me->GetHealth()*10 < me->GetMaxHealth()*3 + && !me->IsNonMeleeSpellCasted(false) // blast nova + && !me->hasUnitState(UNIT_STAT_STUNNED)) // shadow cage and earthquake + { + Phase3 = true; + DoScriptText(SAY_CHAMBER_DESTROY, me); + DoCast(me, SPELL_CAMERA_SHAKE, true); + DoCast(me, SPELL_DEBRIS_KNOCKDOWN, true); + + if (pInstance) + pInstance->SetData(DATA_COLLAPSE, true); + } + + if (Phase3) + { + if (Debris_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + { + float x, y, z; + pTarget->GetPosition(x, y, z); + Creature *summon = me->SummonCreature(MOB_ABYSSAL, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + if (summon) + CAST_AI(mob_abyssal::mob_abyssalAI, summon->AI())->SetTrigger(1); + } + Debris_Timer = 10000; + } + else + Debris_Timer -= diff; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new boss_magtheridonAI(Creature); + } }; -struct mob_hellfire_channelerAI : public ScriptedAI +class mob_hellfire_channeler : public CreatureScript { - mob_hellfire_channelerAI(Creature *c) : ScriptedAI(c) - { - pInstance =me->GetInstanceData(); - } + public: - ScriptedInstance* pInstance; - - uint32 ShadowBoltVolley_Timer; - uint32 DarkMending_Timer; - uint32 Fear_Timer; - uint32 Infernal_Timer; - - uint32 Check_Timer; - - void Reset() - { - ShadowBoltVolley_Timer = 8000 + rand()%2000; - DarkMending_Timer = 10000; - Fear_Timer = 15000 + rand()%5000; - Infernal_Timer = 10000 + rand()%40000; - - Check_Timer = 5000; - } - - void EnterCombat(Unit * /*who*/) - { - if (pInstance) - pInstance->SetData(DATA_CHANNELER_EVENT, IN_PROGRESS); - - me->InterruptNonMeleeSpells(false); - DoZoneInCombat(); - } - - void JustReachedHome() - { - if (pInstance) - pInstance->SetData(DATA_CHANNELER_EVENT, NOT_STARTED); - - DoCast(me, SPELL_SHADOW_GRASP_C, false); - } - - void JustSummoned(Creature *summon) - { - summon->AI()->AttackStart(me->getVictim()); - } - - void DamageTaken(Unit*, uint32 &damage) - { - if (damage >= me->GetHealth()) - DoCast(me, SPELL_SOUL_TRANSFER, true); - } - - void JustDied(Unit* /*who*/) - { - if (pInstance) - pInstance->SetData(DATA_CHANNELER_EVENT, DONE); - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (ShadowBoltVolley_Timer <= diff) + mob_hellfire_channeler() + : CreatureScript("mob_hellfire_channeler") { - DoCast(me, SPELL_SHADOW_BOLT_VOLLEY); - ShadowBoltVolley_Timer = 10000 + rand()%10000; - } else ShadowBoltVolley_Timer -= diff; + } - if (DarkMending_Timer <= diff) + struct mob_hellfire_channelerAI : public ScriptedAI { - if ((me->GetHealth()*100 / me->GetMaxHealth()) < 50) - DoCast(me, SPELL_DARK_MENDING); - DarkMending_Timer = 10000 +(rand() % 10000); - } else DarkMending_Timer -= diff; + mob_hellfire_channelerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceData(); + } - if (Fear_Timer <= diff) + ScriptedInstance* pInstance; + + uint32 ShadowBoltVolley_Timer; + uint32 DarkMending_Timer; + uint32 Fear_Timer; + uint32 Infernal_Timer; + + uint32 Check_Timer; + + void Reset() + { + ShadowBoltVolley_Timer = 8000 + rand()%2000; + DarkMending_Timer = 10000; + Fear_Timer = 15000 + rand()%5000; + Infernal_Timer = 10000 + rand()%40000; + + Check_Timer = 5000; + } + + void EnterCombat(Unit * /*who*/) + { + if (pInstance) + pInstance->SetData(DATA_CHANNELER_EVENT, IN_PROGRESS); + + me->InterruptNonMeleeSpells(false); + DoZoneInCombat(); + } + + void JustReachedHome() + { + if (pInstance) + pInstance->SetData(DATA_CHANNELER_EVENT, NOT_STARTED); + + DoCast(me, SPELL_SHADOW_GRASP_C, false); + } + + void JustSummoned(Creature *summon) + { + summon->AI()->AttackStart(me->getVictim()); + } + + void DamageTaken(Unit*, uint32 &damage) + { + if (damage >= me->GetHealth()) + DoCast(me, SPELL_SOUL_TRANSFER, true); + } + + void JustDied(Unit* /*who*/) + { + if (pInstance) + pInstance->SetData(DATA_CHANNELER_EVENT, DONE); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (ShadowBoltVolley_Timer <= diff) + { + DoCast(me, SPELL_SHADOW_BOLT_VOLLEY); + ShadowBoltVolley_Timer = 10000 + rand()%10000; + } + else + ShadowBoltVolley_Timer -= diff; + + if (DarkMending_Timer <= diff) + { + if ((me->GetHealth()*100 / me->GetMaxHealth()) < 50) + DoCast(me, SPELL_DARK_MENDING); + DarkMending_Timer = 10000 +(rand() % 10000); + } + else + DarkMending_Timer -= diff; + + if (Fear_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1)) + DoCast(pTarget, SPELL_FEAR); + Fear_Timer = 25000 + rand()%15000; + } + else + Fear_Timer -= diff; + + if (Infernal_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_BURNING_ABYSSAL, true); + Infernal_Timer = 30000 + rand()%10000; + } + else + Infernal_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* Creature) const { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1)) - DoCast(pTarget, SPELL_FEAR); - Fear_Timer = 25000 + rand()%15000; - } else Fear_Timer -= diff; - - if (Infernal_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pTarget, SPELL_BURNING_ABYSSAL, true); - Infernal_Timer = 30000 + rand()%10000; - } else Infernal_Timer -= diff; - - DoMeleeAttackIfReady(); - } + return new mob_hellfire_channelerAI(Creature); + } }; //Manticron Cube -bool GOHello_go_Manticron_Cube(Player* pPlayer, GameObject* pGo) +class go_manticron_cube : public GameObjectScript { - ScriptedInstance* pInstance = pGo->GetInstanceData(); - if (!pInstance) +public: + go_manticron_cube() : GameObjectScript("go_manticron_cube") + { + } + + bool OnGossipHello(Player *pPlayer, GameObject * pGO) + { + ScriptedInstance* pInstance = pGO->GetInstanceData(); + + if (!pInstance) + return true; + + if (pInstance->GetData(DATA_MAGTHERIDON_EVENT) != IN_PROGRESS) + return true; + Creature *Magtheridon =Unit::GetCreature(*pGO, pInstance->GetData64(DATA_MAGTHERIDON)); + if (!Magtheridon || !Magtheridon->isAlive()) + return true; + + // if exhausted or already channeling return + if (pPlayer->HasAura(SPELL_MIND_EXHAUSTION) || pPlayer->HasAura(SPELL_SHADOW_GRASP)) + return true; + + pPlayer->InterruptNonMeleeSpells(false); + pPlayer->CastSpell(pPlayer, SPELL_SHADOW_GRASP, true); + pPlayer->CastSpell(pPlayer, SPELL_SHADOW_GRASP_VISUAL, false); + CAST_AI(boss_magtheridon::boss_magtheridonAI, Magtheridon->AI())->SetClicker(pGO->GetGUID(), pPlayer->GetGUID()); return true; - if (pInstance->GetData(DATA_MAGTHERIDON_EVENT) != IN_PROGRESS) return true; - Creature *Magtheridon =Unit::GetCreature(*pGo, pInstance->GetData64(DATA_MAGTHERIDON)); - if (!Magtheridon || !Magtheridon->isAlive()) return true; - - // if exhausted or already channeling return - if (pPlayer->HasAura(SPELL_MIND_EXHAUSTION) || pPlayer->HasAura(SPELL_SHADOW_GRASP)) - return true; - - pPlayer->InterruptNonMeleeSpells(false); - pPlayer->CastSpell(pPlayer, SPELL_SHADOW_GRASP, true); - pPlayer->CastSpell(pPlayer, SPELL_SHADOW_GRASP_VISUAL, false); - CAST_AI(boss_magtheridonAI, Magtheridon->AI())->SetClicker(pGo->GetGUID(), pPlayer->GetGUID()); - return true; -} - -CreatureAI* GetAI_boss_magtheridon(Creature* pCreature) -{ - return new boss_magtheridonAI(pCreature); -} - -CreatureAI* GetAI_mob_hellfire_channeler(Creature* pCreature) -{ - return new mob_hellfire_channelerAI(pCreature); -} - -CreatureAI* GetAI_mob_abyssalAI(Creature* pCreature) -{ - return new mob_abyssalAI(pCreature); -} + } +}; void AddSC_boss_magtheridon() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_magtheridon"; - newscript->GetAI = &GetAI_boss_magtheridon; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_hellfire_channeler"; - newscript->GetAI = &GetAI_mob_hellfire_channeler; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "go_manticron_cube"; - newscript->pGOHello = &GOHello_go_Manticron_Cube; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_abyssal"; - newscript->GetAI = &GetAI_mob_abyssalAI; - newscript->RegisterSelf(); - + new boss_magtheridon(); + new mob_hellfire_channeler(); + new mob_abyssal(); + new go_manticron_cube(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp index aa655588d3b..38b861539d8 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp @@ -26,8 +26,11 @@ EndScriptData */ #include "ScriptPCH.h" #include "magtheridons_lair.h" -#define SPELL_SOUL_TRANSFER 30531 // core bug, does not support target 7 -#define SPELL_BLAZE_TARGET 30541 // core bug, does not support target 7 +enum eSpells +{ + SPELL_SOUL_TRANSFER = 30531, // core bug, does not support target 7 + SPELL_BLAZE_TARGET = 30541, // core bug, does not support target 7 +}; #define CHAMBER_CENTER_X -15.14 #define CHAMBER_CENTER_Y 1.8 @@ -37,220 +40,226 @@ EndScriptData */ #define EMOTE_BONDS_WEAKEN "'s bonds begin to weaken!" -struct instance_magtheridons_lair : public ScriptedInstance +class instance_magtheridons_lair : public InstanceMapScript { - instance_magtheridons_lair(Map* pMap) : ScriptedInstance(pMap) - { - Initialize(); - } - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - - uint64 MagtheridonGUID; - std::set ChannelerGUID; - uint64 DoorGUID; - std::set ColumnGUID; - - uint32 CageTimer; - uint32 RespawnTimer; - - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - MagtheridonGUID = 0; - ChannelerGUID.clear(); - DoorGUID = 0; - ColumnGUID.clear(); - - CageTimer = 0; - RespawnTimer = 0; - } - - bool IsEncounterInProgress() const - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) return true; - return false; - } - - void OnCreatureCreate(Creature* pCreature, bool /*add*/) - { - switch(pCreature->GetEntry()) + public: + instance_magtheridons_lair() + : InstanceMapScript("instance_magtheridons_lair") { - case 17257: - MagtheridonGUID = pCreature->GetGUID(); - break; - case 17256: - ChannelerGUID.insert(pCreature->GetGUID()); - break; } - } - void OnGameObjectCreate(GameObject* pGo, bool /*add*/) - { - switch(pGo->GetEntry()) + struct instance_magtheridons_lair_InstanceMapScript : public ScriptedInstance { - case 181713: - pGo->SetUInt32Value(GAMEOBJECT_FLAGS, 0); - break; - case 183847: - DoorGUID = pGo->GetGUID(); - break; - case 184653: // hall - case 184634: // six columns - case 184635: - case 184636: - case 184637: - case 184638: - case 184639: - ColumnGUID.insert(pGo->GetGUID()); - break; - } - } - - uint64 GetData64(uint32 type) - { - switch(type) - { - case DATA_MAGTHERIDON: - return MagtheridonGUID; - } - return 0; - } - - void SetData(uint32 type, uint32 data) - { - switch(type) - { - case DATA_MAGTHERIDON_EVENT: - m_auiEncounter[0] = data; - if (data == NOT_STARTED) - RespawnTimer = 10000; - if (data != IN_PROGRESS) - HandleGameObject(DoorGUID, true); - break; - case DATA_CHANNELER_EVENT: - switch(data) + instance_magtheridons_lair_InstanceMapScript(Map* pMap) : ScriptedInstance(pMap) { - case NOT_STARTED: // Reset all channelers once one is reset. - if (m_auiEncounter[1] != NOT_STARTED) + Initialize(); + } + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + + uint64 MagtheridonGUID; + std::set ChannelerGUID; + uint64 DoorGUID; + std::set ColumnGUID; + + uint32 CageTimer; + uint32 RespawnTimer; + + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + + MagtheridonGUID = 0; + ChannelerGUID.clear(); + DoorGUID = 0; + ColumnGUID.clear(); + + CageTimer = 0; + RespawnTimer = 0; + } + + bool IsEncounterInProgress() const + { + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) return true; + return false; + } + + void OnCreatureCreate(Creature* pCreature, bool /*add*/) + { + switch(pCreature->GetEntry()) { - m_auiEncounter[1] = NOT_STARTED; - for (std::set::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) + case 17257: + MagtheridonGUID = pCreature->GetGUID(); + break; + case 17256: + ChannelerGUID.insert(pCreature->GetGUID()); + break; + } + } + + void OnGameObjectCreate(GameObject* pGo, bool /*add*/) + { + switch(pGo->GetEntry()) + { + case 181713: + pGo->SetUInt32Value(GAMEOBJECT_FLAGS, 0); + break; + case 183847: + DoorGUID = pGo->GetGUID(); + break; + case 184653: // hall + case 184634: // six columns + case 184635: + case 184636: + case 184637: + case 184638: + case 184639: + ColumnGUID.insert(pGo->GetGUID()); + break; + } + } + + uint64 GetData64(uint32 type) + { + switch(type) + { + case DATA_MAGTHERIDON: + return MagtheridonGUID; + } + return 0; + } + + void SetData(uint32 type, uint32 data) + { + switch(type) + { + case DATA_MAGTHERIDON_EVENT: + m_auiEncounter[0] = data; + if (data == NOT_STARTED) + RespawnTimer = 10000; + if (data != IN_PROGRESS) + HandleGameObject(DoorGUID, true); + break; + case DATA_CHANNELER_EVENT: + switch(data) { - if (Creature *Channeler = instance->GetCreature(*i)) + case NOT_STARTED: // Reset all channelers once one is reset. + if (m_auiEncounter[1] != NOT_STARTED) { - if (Channeler->isAlive()) - Channeler->AI()->EnterEvadeMode(); - else - Channeler->Respawn(); + m_auiEncounter[1] = NOT_STARTED; + for (std::set::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) + { + if (Creature *Channeler = instance->GetCreature(*i)) + { + if (Channeler->isAlive()) + Channeler->AI()->EnterEvadeMode(); + else + Channeler->Respawn(); + } + } + CageTimer = 0; + HandleGameObject(DoorGUID, true); + } + break; + case IN_PROGRESS: // Event start. + if (m_auiEncounter[1] != IN_PROGRESS) + { + m_auiEncounter[1] = IN_PROGRESS; + // Let all five channelers aggro. + for (std::set::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) + { + Creature *Channeler = instance->GetCreature(*i); + if (Channeler && Channeler->isAlive()) + Channeler->AI()->AttackStart(Channeler->SelectNearestTarget(999)); + } + // Release Magtheridon after two minutes. + Creature *Magtheridon = instance->GetCreature(MagtheridonGUID); + if (Magtheridon && Magtheridon->isAlive()) + { + Magtheridon->MonsterTextEmote(EMOTE_BONDS_WEAKEN, 0); + CageTimer = 120000; + } + HandleGameObject(DoorGUID, false); + } + break; + case DONE: // Add buff and check if all channelers are dead. + for (std::set::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) + { + Creature *Channeler = instance->GetCreature(*i); + if (Channeler && Channeler->isAlive()) + { + //Channeler->CastSpell(Channeler, SPELL_SOUL_TRANSFER, true); + data = IN_PROGRESS; + break; + } } - } - CageTimer = 0; - HandleGameObject(DoorGUID, true); - } - break; - case IN_PROGRESS: // Event start. - if (m_auiEncounter[1] != IN_PROGRESS) - { - m_auiEncounter[1] = IN_PROGRESS; - // Let all five channelers aggro. - for (std::set::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) - { - Creature *Channeler = instance->GetCreature(*i); - if (Channeler && Channeler->isAlive()) - Channeler->AI()->AttackStart(Channeler->SelectNearestTarget(999)); - } - // Release Magtheridon after two minutes. - Creature *Magtheridon = instance->GetCreature(MagtheridonGUID); - if (Magtheridon && Magtheridon->isAlive()) - { - Magtheridon->MonsterTextEmote(EMOTE_BONDS_WEAKEN, 0); - CageTimer = 120000; - } - HandleGameObject(DoorGUID, false); - } - break; - case DONE: // Add buff and check if all channelers are dead. - for (std::set::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) - { - Creature *Channeler = instance->GetCreature(*i); - if (Channeler && Channeler->isAlive()) - { - //Channeler->CastSpell(Channeler, SPELL_SOUL_TRANSFER, true); - data = IN_PROGRESS; break; } + m_auiEncounter[1] = data; + break; + case DATA_COLLAPSE: + // true - collapse / false - reset + for (std::set::const_iterator i = ColumnGUID.begin(); i != ColumnGUID.end(); ++i) + DoUseDoorOrButton(*i); + break; + default: + break; } - break; } - m_auiEncounter[1] = data; - break; - case DATA_COLLAPSE: - // true - collapse / false - reset - for (std::set::const_iterator i = ColumnGUID.begin(); i != ColumnGUID.end(); ++i) - DoUseDoorOrButton(*i); - break; - default: - break; - } - } - uint32 GetData(uint32 type) - { - if (type == DATA_MAGTHERIDON_EVENT) - return m_auiEncounter[0]; - return 0; - } - - void Update(uint32 diff) - { - if (CageTimer) - { - if (CageTimer <= diff) + uint32 GetData(uint32 type) { - Creature *Magtheridon = instance->GetCreature(MagtheridonGUID); - if (Magtheridon && Magtheridon->isAlive()) - { - Magtheridon->clearUnitState(UNIT_STAT_STUNNED); - Magtheridon->AI()->AttackStart(Magtheridon->SelectNearestTarget(999)); - } - CageTimer = 0; - } else CageTimer -= diff; - } + if (type == DATA_MAGTHERIDON_EVENT) + return m_auiEncounter[0]; + return 0; + } - if (RespawnTimer) - { - if (RespawnTimer <= diff) + void Update(uint32 diff) { - for (std::set::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) + if (CageTimer) { - if (Creature *Channeler = instance->GetCreature(*i)) + if (CageTimer <= diff) { - if (Channeler->isAlive()) - Channeler->AI()->EnterEvadeMode(); - else - Channeler->Respawn(); - } + Creature *Magtheridon = instance->GetCreature(MagtheridonGUID); + if (Magtheridon && Magtheridon->isAlive()) + { + Magtheridon->clearUnitState(UNIT_STAT_STUNNED); + Magtheridon->AI()->AttackStart(Magtheridon->SelectNearestTarget(999)); + } + CageTimer = 0; + } else CageTimer -= diff; } - RespawnTimer = 0; - } else RespawnTimer -= diff; + + if (RespawnTimer) + { + if (RespawnTimer <= diff) + { + for (std::set::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) + { + if (Creature *Channeler = instance->GetCreature(*i)) + { + if (Channeler->isAlive()) + Channeler->AI()->EnterEvadeMode(); + else + Channeler->Respawn(); + } + } + RespawnTimer = 0; + } else RespawnTimer -= diff; + } + } + }; + + InstanceData* GetInstanceData(Map* pMap) const + { + return new instance_magtheridons_lair_InstanceMapScript(pMap); } - } }; -InstanceData* GetInstanceData_instance_magtheridons_lair(Map* pMap) -{ - return new instance_magtheridons_lair(pMap); -} void AddSC_instance_magtheridons_lair() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_magtheridons_lair"; - newscript->GetInstanceData = &GetInstanceData_instance_magtheridons_lair; - newscript->RegisterSelf(); + new instance_magtheridons_lair(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp index 64ad5c7b130..6ca6cbea0d1 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp @@ -52,347 +52,374 @@ static Say PeonDies[]= {-1540008}, }; -#define SAY_INTRO -1540000 -#define SAY_TAUNT_1 -1540009 -#define SAY_TAUNT_2 -1540010 -#define SAY_TAUNT_3 -1540011 -#define SAY_AGGRO_1 -1540012 -#define SAY_AGGRO_2 -1540013 -#define SAY_AGGRO_3 -1540014 -#define SAY_SLAY_1 -1540015 -#define SAY_SLAY_2 -1540016 -#define SAY_DIE -1540017 - -#define SPELL_DEATH_COIL 30500 -#define SPELL_DARK_SPIN 30502 // core bug spell attack caster :D -#define SPELL_SHADOW_FISSURE 30496 // Summon the ShadowFissure NPC - -#define SPELL_SHADOW_CLEAVE 30495 -#define H_SPELL_SHADOW_SLAM 35953 - -#define SPELL_HEMORRHAGE 30478 - -#define SPELL_CONSUMPTION 30497 -#define SPELL_TEMPORARY_VISUAL 39312 // this is wrong, a temporary solution. spell consumption already has the purple visual, but doesn't display as it should - -struct boss_grand_warlock_nethekurseAI : public ScriptedAI -{ - boss_grand_warlock_nethekurseAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance* pInstance; - - bool IntroOnce; - bool IsIntroEvent; - bool IsMainEvent; - bool SpinOnce; - //bool HasTaunted; - bool Phase; - - uint32 PeonEngagedCount; - uint32 PeonKilledCount; - - uint32 IntroEvent_Timer; - uint32 DeathCoil_Timer; - uint32 ShadowFissure_Timer; - uint32 Cleave_Timer; - - void Reset() - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - - IsIntroEvent = false; - IntroOnce = false; - IsMainEvent = false; - //HasTaunted = false; - SpinOnce = false; - Phase = false; - - PeonEngagedCount = 0; - PeonKilledCount = 0; - - IntroEvent_Timer = 90000; //how long before getting bored and kills his minions? - DeathCoil_Timer = 20000; - ShadowFissure_Timer = 8000; - Cleave_Timer = 5000; - } - - void DoYellForPeonAggro() - { - if (PeonEngagedCount >= 4) - return; - - DoScriptText(PeonAttacked[PeonEngagedCount].id, me); - ++PeonEngagedCount; - } - - void DoYellForPeonDeath() - { - if (PeonKilledCount >= 4) - return; - - DoScriptText(PeonDies[PeonKilledCount].id, me); - ++PeonKilledCount; - - if (PeonKilledCount == 4) - { - IsIntroEvent = false; - IsMainEvent = true; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - } - - void DoTauntPeons() - { - DoScriptText(RAND(SAY_TAUNT_1,SAY_TAUNT_2,SAY_TAUNT_3), me); - - //TODO: kill the peons first - IsIntroEvent = false; - PeonEngagedCount = 4; - PeonKilledCount = 4; - IsMainEvent = true; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - - void AttackStart(Unit* who) - { - if (IsIntroEvent || !IsMainEvent) - return; - - if (me->Attack(who, true)) - { - if (Phase) - DoStartNoMovement(who); - else - DoStartMovement(who); - } - } - - void MoveInLineOfSight(Unit *who) - { - if (!IntroOnce && me->IsWithinDistInMap(who, 50.0f)) - { - if (who->GetTypeId() != TYPEID_PLAYER) - return; - - DoScriptText(SAY_INTRO, me); - IntroOnce = true; - IsIntroEvent = true; - - if (pInstance) - pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS); - } - - if (IsIntroEvent || !IsMainEvent) - return; - - ScriptedAI::MoveInLineOfSight(who); - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me); - } - - void JustSummoned(Creature *summoned) - { - summoned->setFaction(16); - summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - //triggered spell of consumption does not properly show it's SpellVisual, wrong spellid? - summoned->CastSpell(summoned,SPELL_TEMPORARY_VISUAL,true); - summoned->CastSpell(summoned,SPELL_CONSUMPTION,false,0,0,me->GetGUID()); - } - - void KilledUnit(Unit* /*victim*/) - { - DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me); - } - - void JustDied(Unit* /*Killer*/) - { - DoScriptText(SAY_DIE, me); - - if (!pInstance) - return; - - pInstance->SetData(TYPE_NETHEKURSE,DONE); - pInstance->HandleGameObject(pInstance->GetData64(DATA_NETHEKURSE_DOOR), true); - } - - void UpdateAI(const uint32 diff) - { - if (IsIntroEvent) - { - if (!pInstance) - return; - - if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS) - { - if (IntroEvent_Timer <= diff) - DoTauntPeons(); - else - IntroEvent_Timer -= diff; - } - } - - if (!UpdateVictim()) - return; - - if (!IsMainEvent) - return; - - if (Phase) - { - if (!SpinOnce) - { - DoCast(me->getVictim(), SPELL_DARK_SPIN); - SpinOnce = true; - } - - if (Cleave_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_SHADOW_CLEAVE); - Cleave_Timer = 6000+rand()%2500; - } else Cleave_Timer -= diff; - } - else - { - if (ShadowFissure_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_SHADOW_FISSURE); - ShadowFissure_Timer = urand(7500,15000); - } else ShadowFissure_Timer -= diff; - - if (DeathCoil_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_DEATH_COIL); - DeathCoil_Timer = urand(15000,20000); - } else DeathCoil_Timer -= diff; - - if ((me->GetHealth()*100) / me->GetMaxHealth() <= 20) - Phase = true; - - DoMeleeAttackIfReady(); - } - } +enum eSays +{ + SAY_INTRO = -1540000, + SAY_TAUNT_1 = -1540009, + SAY_TAUNT_2 = -1540010, + SAY_TAUNT_3 = -1540011, + SAY_AGGRO_1 = -1540012, + SAY_AGGRO_2 = -1540013, + SAY_AGGRO_3 = -1540014, + SAY_SLAY_1 = -1540015, + SAY_SLAY_2 = -1540016, + SAY_DIE = -1540017, }; -struct mob_fel_orc_convertAI : public ScriptedAI +enum eSpells +{ + SPELL_DEATH_COIL = 30500, + SPELL_DARK_SPIN = 30502, // core bug spell attack caster :D + SPELL_SHADOW_FISSURE = 30496, // Summon the ShadowFissure NPC + SPELL_SHADOW_CLEAVE = 30495, + H_SPELL_SHADOW_SLAM = 35953, + SPELL_HEMORRHAGE = 30478, + SPELL_CONSUMPTION = 30497, + SPELL_TEMPORARY_VISUAL = 39312, // this is wrong, a temporary solution. spell consumption already has the purple visual, but doesn't display as it should +}; + +class boss_grand_warlock_nethekurse : public CreatureScript { - mob_fel_orc_convertAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } + public: - ScriptedInstance* pInstance; - uint32 Hemorrhage_Timer; - - void Reset() - { - me->SetNoCallAssistance(true); //we don't want any assistance (WE R HEROZ!) - Hemorrhage_Timer = 3000; - } - - void MoveInLineOfSight(Unit * /*who*/) - { - } - - void EnterCombat(Unit* /*who*/) - { - if (pInstance) + boss_grand_warlock_nethekurse() + : CreatureScript("boss_grand_warlock_nethekurse") { - if (pInstance->GetData64(DATA_NETHEKURSE)) - { - Creature *pKurse = Unit::GetCreature(*me,pInstance->GetData64(DATA_NETHEKURSE)); - if (pKurse && me->IsWithinDist(pKurse, 45.0f)) - { - CAST_AI(boss_grand_warlock_nethekurseAI, pKurse->AI())->DoYellForPeonAggro(); + } - if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS) - return; - else - pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS); + struct boss_grand_warlock_nethekurseAI : public ScriptedAI + { + boss_grand_warlock_nethekurseAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceData(); + } + + ScriptedInstance* pInstance; + + bool IntroOnce; + bool IsIntroEvent; + bool IsMainEvent; + bool SpinOnce; + //bool HasTaunted; + bool Phase; + + uint32 PeonEngagedCount; + uint32 PeonKilledCount; + + uint32 IntroEvent_Timer; + uint32 DeathCoil_Timer; + uint32 ShadowFissure_Timer; + uint32 Cleave_Timer; + + void Reset() + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + IsIntroEvent = false; + IntroOnce = false; + IsMainEvent = false; + //HasTaunted = false; + SpinOnce = false; + Phase = false; + + PeonEngagedCount = 0; + PeonKilledCount = 0; + + IntroEvent_Timer = 90000; //how long before getting bored and kills his minions? + DeathCoil_Timer = 20000; + ShadowFissure_Timer = 8000; + Cleave_Timer = 5000; + } + + void DoYellForPeonAggro() + { + if (PeonEngagedCount >= 4) + return; + + DoScriptText(PeonAttacked[PeonEngagedCount].id, me); + ++PeonEngagedCount; + } + + void DoYellForPeonDeath() + { + if (PeonKilledCount >= 4) + return; + + DoScriptText(PeonDies[PeonKilledCount].id, me); + ++PeonKilledCount; + + if (PeonKilledCount == 4) + { + IsIntroEvent = false; + IsMainEvent = true; + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } } - } - } - void JustDied(Unit* /*Killer*/) - { - if (pInstance) + void DoTauntPeons() + { + DoScriptText(RAND(SAY_TAUNT_1,SAY_TAUNT_2,SAY_TAUNT_3), me); + + //TODO: kill the peons first + IsIntroEvent = false; + PeonEngagedCount = 4; + PeonKilledCount = 4; + IsMainEvent = true; + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void AttackStart(Unit* who) + { + if (IsIntroEvent || !IsMainEvent) + return; + + if (me->Attack(who, true)) + { + if (Phase) + DoStartNoMovement(who); + else + DoStartMovement(who); + } + } + + void MoveInLineOfSight(Unit *who) + { + if (!IntroOnce && me->IsWithinDistInMap(who, 50.0f)) + { + if (who->GetTypeId() != TYPEID_PLAYER) + return; + + DoScriptText(SAY_INTRO, me); + IntroOnce = true; + IsIntroEvent = true; + + if (pInstance) + pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS); + } + + if (IsIntroEvent || !IsMainEvent) + return; + + ScriptedAI::MoveInLineOfSight(who); + } + + void EnterCombat(Unit * /*who*/) + { + DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me); + } + + void JustSummoned(Creature *summoned) + { + summoned->setFaction(16); + summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + //triggered spell of consumption does not properly show it's SpellVisual, wrong spellid? + summoned->CastSpell(summoned,SPELL_TEMPORARY_VISUAL,true); + summoned->CastSpell(summoned,SPELL_CONSUMPTION,false,0,0,me->GetGUID()); + } + + void KilledUnit(Unit* /*victim*/) + { + DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me); + } + + void JustDied(Unit* /*Killer*/) + { + DoScriptText(SAY_DIE, me); + + if (!pInstance) + return; + + pInstance->SetData(TYPE_NETHEKURSE,DONE); + pInstance->HandleGameObject(pInstance->GetData64(DATA_NETHEKURSE_DOOR), true); + } + + void UpdateAI(const uint32 diff) + { + if (IsIntroEvent) + { + if (!pInstance) + return; + + if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS) + { + if (IntroEvent_Timer <= diff) + DoTauntPeons(); + else + IntroEvent_Timer -= diff; + } + } + + if (!UpdateVictim()) + return; + + if (!IsMainEvent) + return; + + if (Phase) + { + if (!SpinOnce) + { + DoCast(me->getVictim(), SPELL_DARK_SPIN); + SpinOnce = true; + } + + if (Cleave_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_SHADOW_CLEAVE); + Cleave_Timer = 6000+rand()%2500; + } + else + Cleave_Timer -= diff; + } + else + { + if (ShadowFissure_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) + DoCast(pTarget, SPELL_SHADOW_FISSURE); + ShadowFissure_Timer = urand(7500,15000); + } + else + ShadowFissure_Timer -= diff; + + if (DeathCoil_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) + DoCast(pTarget, SPELL_DEATH_COIL); + DeathCoil_Timer = urand(15000,20000); + } + else + DeathCoil_Timer -= diff; + + if ((me->GetHealth()*100) / me->GetMaxHealth() <= 20) + Phase = true; + + DoMeleeAttackIfReady(); + } + } + }; + + CreatureAI* GetAI(Creature* Creature) const { - if (pInstance->GetData(TYPE_NETHEKURSE) != IN_PROGRESS) - return; - if (pInstance->GetData64(DATA_NETHEKURSE)) - if (Creature *pKurse = Unit::GetCreature(*me,pInstance->GetData64(DATA_NETHEKURSE))) - CAST_AI(boss_grand_warlock_nethekurseAI, pKurse->AI())->DoYellForPeonDeath(); + return new boss_grand_warlock_nethekurseAI (Creature); } - } +}; - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - if (Hemorrhage_Timer <= diff) +class mob_fel_orc_convert : public CreatureScript +{ + public: + + mob_fel_orc_convert() + : CreatureScript("mob_fel_orc_convert") { - DoCast(me->getVictim(), SPELL_HEMORRHAGE); - Hemorrhage_Timer = 15000; - } else Hemorrhage_Timer -= diff; + } - DoMeleeAttackIfReady(); - } + struct mob_fel_orc_convertAI : public ScriptedAI + { + mob_fel_orc_convertAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceData(); + } + + ScriptedInstance* pInstance; + uint32 Hemorrhage_Timer; + + void Reset() + { + me->SetNoCallAssistance(true); //we don't want any assistance (WE R HEROZ!) + Hemorrhage_Timer = 3000; + } + + void MoveInLineOfSight(Unit * /*who*/) + { + } + + void EnterCombat(Unit* /*who*/) + { + if (pInstance) + { + if (pInstance->GetData64(DATA_NETHEKURSE)) + { + Creature *pKurse = Unit::GetCreature(*me,pInstance->GetData64(DATA_NETHEKURSE)); + if (pKurse && me->IsWithinDist(pKurse, 45.0f)) + { + CAST_AI(boss_grand_warlock_nethekurse::boss_grand_warlock_nethekurseAI, pKurse->AI())->DoYellForPeonAggro(); + + if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS) + return; + else + pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS); + } + } + } + } + + void JustDied(Unit* /*Killer*/) + { + if (pInstance) + { + if (pInstance->GetData(TYPE_NETHEKURSE) != IN_PROGRESS) + return; + if (pInstance->GetData64(DATA_NETHEKURSE)) + if (Creature *pKurse = Unit::GetCreature(*me,pInstance->GetData64(DATA_NETHEKURSE))) + CAST_AI(boss_grand_warlock_nethekurse::boss_grand_warlock_nethekurseAI, pKurse->AI())->DoYellForPeonDeath(); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (Hemorrhage_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_HEMORRHAGE); + Hemorrhage_Timer = 15000; + } else Hemorrhage_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new mob_fel_orc_convertAI (Creature); + } }; //NOTE: this Creature are also summoned by other spells, for different creatures -struct mob_lesser_shadow_fissureAI : public ScriptedAI +class mob_lesser_shadow_fissure : public CreatureScript { - mob_lesser_shadow_fissureAI(Creature *c) : ScriptedAI(c) {} + public: - void Reset() { } - void MoveInLineOfSight(Unit * /*who*/) {} - void AttackStart(Unit* /*who*/) {} - void EnterCombat(Unit* /*who*/) {} + mob_lesser_shadow_fissure() + : CreatureScript("mob_lesser_shadow_fissure") + { + } + + struct mob_lesser_shadow_fissureAI : public ScriptedAI + { + mob_lesser_shadow_fissureAI(Creature* pCreature) : ScriptedAI(pCreature) {} + + void Reset() { } + void MoveInLineOfSight(Unit * /*who*/) {} + void AttackStart(Unit* /*who*/) {} + void EnterCombat(Unit* /*who*/) {} + }; + + CreatureAI* GetAI_mob_lesser_shadow_fissure(Creature* pCreature) + { + return new mob_lesser_shadow_fissureAI (pCreature); + } }; -CreatureAI* GetAI_boss_grand_warlock_nethekurse(Creature* pCreature) -{ - return new boss_grand_warlock_nethekurseAI (pCreature); -} - -CreatureAI* GetAI_mob_fel_orc_convert(Creature* pCreature) -{ - return new mob_fel_orc_convertAI (pCreature); -} - -CreatureAI* GetAI_mob_lesser_shadow_fissure(Creature* pCreature) -{ - return new mob_lesser_shadow_fissureAI (pCreature); -} - void AddSC_boss_grand_warlock_nethekurse() { - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_grand_warlock_nethekurse"; - newscript->GetAI = &GetAI_boss_grand_warlock_nethekurse; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_fel_orc_convert"; - newscript->GetAI = &GetAI_mob_fel_orc_convert; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_lesser_shadow_fissure"; - newscript->GetAI = &GetAI_mob_lesser_shadow_fissure; - newscript->RegisterSelf(); + new boss_grand_warlock_nethekurse(); + new mob_fel_orc_convert(); + new mob_lesser_shadow_fissure(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp index 29119eb4015..9b2d8af3e6a 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp @@ -94,313 +94,334 @@ static Yell Killing[]= {-1540036, NPC_LEFT_HEAD}, {-1540037, NPC_RIGHT_HEAD}, }; + static Yell KillingDelay[]= { {-1540038, NPC_RIGHT_HEAD}, {-1000000, NPC_LEFT_HEAD}, }; -struct mob_omrogg_headsAI : public ScriptedAI +class mob_omrogg_heads : public CreatureScript { - mob_omrogg_headsAI(Creature *c) : ScriptedAI(c) {} + public: - bool DeathYell; - uint32 Death_Timer; - - void Reset() - { - Death_Timer = 4000; - DeathYell = false; - } - void EnterCombat(Unit* /*who*/) {} - - void DoDeathYell() - { - DeathYell = true; - } - - void UpdateAI(const uint32 diff) - { - if (!DeathYell) - return; - - if (Death_Timer <= diff) + mob_omrogg_heads() + : CreatureScript("mob_omrogg_heads") { - DoScriptText(YELL_DIE_R, me); - Death_Timer = false; - me->setDeathState(JUST_DIED); - } else Death_Timer -= diff; - } + } + + struct mob_omrogg_headsAI : public ScriptedAI + { + mob_omrogg_headsAI(Creature* pCreature) : ScriptedAI(pCreature) {} + + bool DeathYell; + uint32 Death_Timer; + + void Reset() + { + Death_Timer = 4000; + DeathYell = false; + } + void EnterCombat(Unit* /*who*/) {} + + void DoDeathYell() + { + DeathYell = true; + } + + void UpdateAI(const uint32 diff) + { + if (!DeathYell) + return; + + if (Death_Timer <= diff) + { + DoScriptText(YELL_DIE_R, me); + Death_Timer = false; + me->setDeathState(JUST_DIED); + } else Death_Timer -= diff; + } + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new mob_omrogg_headsAI (Creature); + } }; -struct boss_warbringer_omroggAI : public ScriptedAI +class boss_warbringer_omrogg : public CreatureScript { - boss_warbringer_omroggAI(Creature *c) : ScriptedAI(c) - { - LeftHeadGUID = 0; - RightHeadGUID = 0; - pInstance = c->GetInstanceData(); - } + public: - ScriptedInstance* pInstance; - - uint64 LeftHeadGUID; - uint64 RightHeadGUID; - int iaggro; - int ithreat; - int ikilling; - - bool AggroYell; - bool ThreatYell; - bool ThreatYell2; - bool KillingYell; - - uint32 Delay_Timer; - uint32 BlastWave_Timer; - uint32 BlastCount; - uint32 Fear_Timer; - uint32 BurningMaul_Timer; - uint32 ThunderClap_Timer; - uint32 ResetThreat_Timer; - - void Reset() - { - if (Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID)) + boss_warbringer_omrogg() + : CreatureScript("boss_warbringer_omrogg") { - pLeftHead->setDeathState(JUST_DIED); - LeftHeadGUID = 0; } - if (Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID)) + struct boss_warbringer_omroggAI : public ScriptedAI { - pRightHead->setDeathState(JUST_DIED); - RightHeadGUID = 0; - } - - AggroYell = false; - ThreatYell = false; - ThreatYell2 = false; - KillingYell = false; - - Delay_Timer = 4000; - BlastWave_Timer = 0; - BlastCount = 0; - Fear_Timer = 8000; - BurningMaul_Timer = 25000; - ThunderClap_Timer = 15000; - ResetThreat_Timer = 30000; - - if (pInstance) - pInstance->SetData(TYPE_OMROGG, NOT_STARTED); //End boss can use this later. O'mrogg must be defeated(DONE) or he will come to aid. - } - - void DoYellForThreat() - { - Unit *pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); - Unit *pRightHead = Unit::GetUnit(*me,RightHeadGUID); - - if (!pLeftHead || !pRightHead) - return; - - ithreat = rand()%4; - - Unit *source = (pLeftHead->GetEntry() == Threat[ithreat].creature ? pLeftHead : pRightHead); - - DoScriptText(Threat[ithreat].id, source); - - Delay_Timer = 3500; - ThreatYell = true; - } - - void EnterCombat(Unit * /*who*/) - { - me->SummonCreature(NPC_LEFT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0); - me->SummonCreature(NPC_RIGHT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0); - - if (Unit *pLeftHead = Unit::GetUnit(*me,LeftHeadGUID)) - { - iaggro = rand()%3; - - DoScriptText(GoCombat[iaggro].id, pLeftHead); - - Delay_Timer = 3500; - AggroYell = true; - } - - if (pInstance) - pInstance->SetData(TYPE_OMROGG, IN_PROGRESS); - } - - void JustSummoned(Creature *summoned) - { - if (summoned->GetEntry() == NPC_LEFT_HEAD) - LeftHeadGUID = summoned->GetGUID(); - - if (summoned->GetEntry() == NPC_RIGHT_HEAD) - RightHeadGUID = summoned->GetGUID(); - - //summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - //summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - summoned->SetVisibility(VISIBILITY_OFF); - } - - void KilledUnit(Unit* /*victim*/) - { - Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); - Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); - - if (!pLeftHead || !pRightHead) - return; - - ikilling = rand()%2; - - Unit *source = (pLeftHead->GetEntry() == Killing[ikilling].creature ? pLeftHead : pRightHead); - - switch(ikilling) - { - case 0: - DoScriptText(Killing[ikilling].id, source); - Delay_Timer = 3500; - KillingYell = true; - break; - case 1: - DoScriptText(Killing[ikilling].id, source); - KillingYell = false; - break; - } - } - - void JustDied(Unit* /*Killer*/) - { - Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); - Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); - - if (!pLeftHead || !pRightHead) - return; - - DoScriptText(YELL_DIE_L, pLeftHead); - - CAST_AI(mob_omrogg_headsAI, CAST_CRE(pRightHead)->AI())->DoDeathYell(); - - if (pInstance) - pInstance->SetData(TYPE_OMROGG, DONE); - } - - void UpdateAI(const uint32 diff) - { - if (Delay_Timer <= diff) - { - Delay_Timer = 3500; - - Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); - Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); - - if (!pLeftHead || !pRightHead) - return; - - if (AggroYell) + boss_warbringer_omroggAI(Creature* pCreature) : ScriptedAI(pCreature) { - DoScriptText(GoCombatDelay[iaggro].id, pRightHead); + LeftHeadGUID = 0; + RightHeadGUID = 0; + pInstance = pCreature->GetInstanceData(); + } + + ScriptedInstance* pInstance; + + uint64 LeftHeadGUID; + uint64 RightHeadGUID; + int iaggro; + int ithreat; + int ikilling; + + bool AggroYell; + bool ThreatYell; + bool ThreatYell2; + bool KillingYell; + + uint32 Delay_Timer; + uint32 BlastWave_Timer; + uint32 BlastCount; + uint32 Fear_Timer; + uint32 BurningMaul_Timer; + uint32 ThunderClap_Timer; + uint32 ResetThreat_Timer; + + void Reset() + { + if (Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID)) + { + pLeftHead->setDeathState(JUST_DIED); + LeftHeadGUID = 0; + } + + if (Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID)) + { + pRightHead->setDeathState(JUST_DIED); + RightHeadGUID = 0; + } + AggroYell = false; - } - - if (ThreatYell2) - { - Unit *source = (pLeftHead->GetEntry() == ThreatDelay2[ithreat].creature ? pLeftHead : pRightHead); - - DoScriptText(ThreatDelay2[ithreat].id, source); - ThreatYell2 = false; - } - - if (ThreatYell) - { - Unit *source = (pLeftHead->GetEntry() == ThreatDelay1[ithreat].creature ? pLeftHead : pRightHead); - - DoScriptText(ThreatDelay1[ithreat].id, source); ThreatYell = false; - ThreatYell2 = true; - } - - if (KillingYell) - { - Unit *source = (pLeftHead->GetEntry() == KillingDelay[ikilling].creature ? pLeftHead : pRightHead); - - DoScriptText(KillingDelay[ikilling].id, source); + ThreatYell2 = false; KillingYell = false; - } - } else Delay_Timer -= diff; - if (!UpdateVictim()) - return; - - if (BlastCount && BlastWave_Timer <= diff) - { - DoCast(me, SPELL_BLAST_WAVE); - BlastWave_Timer = 5000; - ++BlastCount; - - if (BlastCount == 3) + Delay_Timer = 4000; + BlastWave_Timer = 0; BlastCount = 0; - } else BlastWave_Timer -= diff; + Fear_Timer = 8000; + BurningMaul_Timer = 25000; + ThunderClap_Timer = 15000; + ResetThreat_Timer = 30000; - if (BurningMaul_Timer <= diff) - { - DoScriptText(EMOTE_ENRAGE, me); - DoCast(me, SPELL_BURNING_MAUL); - BurningMaul_Timer = 40000; - BlastWave_Timer = 16000; - BlastCount = 1; - } else BurningMaul_Timer -= diff; - - if (ResetThreat_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - { - DoYellForThreat(); - DoResetThreat(); - me->AddThreat(pTarget, 0.0f); + if (pInstance) + pInstance->SetData(TYPE_OMROGG, NOT_STARTED); //End boss can use this later. O'mrogg must be defeated(DONE) or he will come to aid. } - ResetThreat_Timer = 25000+rand()%15000; - } else ResetThreat_Timer -= diff; - if (Fear_Timer <= diff) + void DoYellForThreat() + { + Unit *pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); + Unit *pRightHead = Unit::GetUnit(*me,RightHeadGUID); + + if (!pLeftHead || !pRightHead) + return; + + ithreat = rand()%4; + + Unit *source = (pLeftHead->GetEntry() == Threat[ithreat].creature ? pLeftHead : pRightHead); + + DoScriptText(Threat[ithreat].id, source); + + Delay_Timer = 3500; + ThreatYell = true; + } + + void EnterCombat(Unit * /*who*/) + { + me->SummonCreature(NPC_LEFT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0); + me->SummonCreature(NPC_RIGHT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0); + + if (Unit *pLeftHead = Unit::GetUnit(*me,LeftHeadGUID)) + { + iaggro = rand()%3; + + DoScriptText(GoCombat[iaggro].id, pLeftHead); + + Delay_Timer = 3500; + AggroYell = true; + } + + if (pInstance) + pInstance->SetData(TYPE_OMROGG, IN_PROGRESS); + } + + void JustSummoned(Creature *summoned) + { + if (summoned->GetEntry() == NPC_LEFT_HEAD) + LeftHeadGUID = summoned->GetGUID(); + + if (summoned->GetEntry() == NPC_RIGHT_HEAD) + RightHeadGUID = summoned->GetGUID(); + + //summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + //summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + summoned->SetVisibility(VISIBILITY_OFF); + } + + void KilledUnit(Unit* /*victim*/) + { + Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); + Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); + + if (!pLeftHead || !pRightHead) + return; + + ikilling = rand()%2; + + Unit *source = (pLeftHead->GetEntry() == Killing[ikilling].creature ? pLeftHead : pRightHead); + + switch(ikilling) + { + case 0: + DoScriptText(Killing[ikilling].id, source); + Delay_Timer = 3500; + KillingYell = true; + break; + case 1: + DoScriptText(Killing[ikilling].id, source); + KillingYell = false; + break; + } + } + + void JustDied(Unit* /*Killer*/) + { + Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); + Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); + + if (!pLeftHead || !pRightHead) + return; + + DoScriptText(YELL_DIE_L, pLeftHead); + + CAST_AI(mob_omrogg_heads::mob_omrogg_headsAI, CAST_CRE(pRightHead)->AI())->DoDeathYell(); + + if (pInstance) + pInstance->SetData(TYPE_OMROGG, DONE); + } + + void UpdateAI(const uint32 diff) + { + if (Delay_Timer <= diff) + { + Delay_Timer = 3500; + + Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); + Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); + + if (!pLeftHead || !pRightHead) + return; + + if (AggroYell) + { + DoScriptText(GoCombatDelay[iaggro].id, pRightHead); + AggroYell = false; + } + + if (ThreatYell2) + { + Unit *source = (pLeftHead->GetEntry() == ThreatDelay2[ithreat].creature ? pLeftHead : pRightHead); + + DoScriptText(ThreatDelay2[ithreat].id, source); + ThreatYell2 = false; + } + + if (ThreatYell) + { + Unit *source = (pLeftHead->GetEntry() == ThreatDelay1[ithreat].creature ? pLeftHead : pRightHead); + + DoScriptText(ThreatDelay1[ithreat].id, source); + ThreatYell = false; + ThreatYell2 = true; + } + + if (KillingYell) + { + Unit *source = (pLeftHead->GetEntry() == KillingDelay[ikilling].creature ? pLeftHead : pRightHead); + + DoScriptText(KillingDelay[ikilling].id, source); + KillingYell = false; + } + } else Delay_Timer -= diff; + + if (!UpdateVictim()) + return; + + if (BlastCount && BlastWave_Timer <= diff) + { + DoCast(me, SPELL_BLAST_WAVE); + BlastWave_Timer = 5000; + ++BlastCount; + + if (BlastCount == 3) + BlastCount = 0; + } + else + BlastWave_Timer -= diff; + + if (BurningMaul_Timer <= diff) + { + DoScriptText(EMOTE_ENRAGE, me); + DoCast(me, SPELL_BURNING_MAUL); + BurningMaul_Timer = 40000; + BlastWave_Timer = 16000; + BlastCount = 1; + } + else + BurningMaul_Timer -= diff; + + if (ResetThreat_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) + { + DoYellForThreat(); + DoResetThreat(); + me->AddThreat(pTarget, 0.0f); + } + ResetThreat_Timer = 25000+rand()%15000; + } + else + ResetThreat_Timer -= diff; + + if (Fear_Timer <= diff) + { + DoCast(me, SPELL_FEAR); + Fear_Timer = 15000+rand()%20000; + } + else + Fear_Timer -= diff; + + if (ThunderClap_Timer <= diff) + { + DoCast(me, SPELL_THUNDERCLAP); + ThunderClap_Timer = 15000+rand()%15000; + } + else + ThunderClap_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI_boss_warbringer_omrogg(Creature* pCreature) { - DoCast(me, SPELL_FEAR); - Fear_Timer = 15000+rand()%20000; - } else Fear_Timer -= diff; - - if (ThunderClap_Timer <= diff) - { - DoCast(me, SPELL_THUNDERCLAP); - ThunderClap_Timer = 15000+rand()%15000; - } else ThunderClap_Timer -= diff; - - DoMeleeAttackIfReady(); - } + return new boss_warbringer_omroggAI (pCreature); + } }; - -CreatureAI* GetAI_boss_warbringer_omrogg(Creature* pCreature) -{ - return new boss_warbringer_omroggAI (pCreature); -} - -CreatureAI* GetAI_mob_omrogg_heads(Creature* pCreature) -{ - return new mob_omrogg_headsAI (pCreature); -} - void AddSC_boss_warbringer_omrogg() { - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_warbringer_omrogg"; - newscript->GetAI = &GetAI_boss_warbringer_omrogg; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_omrogg_heads"; - newscript->GetAI = &GetAI_mob_omrogg_heads; - newscript->RegisterSelf(); + new boss_warbringer_omrogg(); + new mob_omrogg_heads(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp index 46138e48c0c..c2d9c95e7f4 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp @@ -29,262 +29,295 @@ EndContentData */ #include "ScriptPCH.h" -#define SAY_AGGRO1 -1540042 -#define SAY_AGGRO2 -1540043 -#define SAY_AGGRO3 -1540044 -#define SAY_SLAY1 -1540045 -#define SAY_SLAY2 -1540046 -#define SAY_DEATH -1540047 +enum eSays +{ + SAY_AGGRO1 = -1540042, + SAY_AGGRO2 = -1540043, + SAY_AGGRO3 = -1540044, + SAY_SLAY1 = -1540045, + SAY_SLAY2 = -1540046, + SAY_DEATH = -1540047, +}; -#define SPELL_BLADE_DANCE 30739 -#define H_SPELL_CHARGE 25821 +enum eSpells +{ + SPELL_BLADE_DANCE = 30739, + H_SPELL_CHARGE = 25821, +}; + +enum eCreatures +{ + MOB_SHATTERED_ASSASSIN = 17695, + MOB_HEARTHEN_GUARD = 17621, + MOB_SHARPSHOOTER_GUARD = 17622, + MOB_REAVER_GUARD = 17623, +}; #define TARGET_NUM 5 -#define MOB_SHATTERED_ASSASSIN 17695 -#define MOB_HEARTHEN_GUARD 17621 -#define MOB_SHARPSHOOTER_GUARD 17622 -#define MOB_REAVER_GUARD 17623 - float AssassEntrance[3] = {275.136,-84.29,2.3}; // y -8 float AssassExit[3] = {184.233,-84.29,2.3}; // y -8 float AddsEntrance[3] = {306.036,-84.29,1.93}; -struct boss_warchief_kargath_bladefistAI : public ScriptedAI +class boss_warchief_kargath_bladefist : public CreatureScript { - boss_warchief_kargath_bladefistAI(Creature *c) : ScriptedAI(c) - { - } + public: - std::vector adds; - std::vector assassins; - - uint32 Charge_timer; - uint32 Blade_Dance_Timer; - uint32 Summon_Assistant_Timer; - uint32 resetcheck_timer; - uint32 Wait_Timer; - - uint32 Assassins_Timer; - - uint32 summoned; - bool InBlade; - - uint32 target_num; - - void Reset() - { - removeAdds(); - - me->SetSpeed(MOVE_RUN,2); - me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); - - summoned = 2; - InBlade = false; - Wait_Timer = 0; - - Charge_timer = 0; - Blade_Dance_Timer = 45000; - Summon_Assistant_Timer = 30000; - Assassins_Timer = 5000; - resetcheck_timer = 5000; - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(RAND(SAY_AGGRO1,SAY_AGGRO2,SAY_AGGRO3), me); - } - - void JustSummoned(Creature *summoned) - { - switch(summoned->GetEntry()) + boss_warchief_kargath_bladefist() + : CreatureScript("boss_warchief_kargath_bladefist") { - case MOB_HEARTHEN_GUARD: - case MOB_SHARPSHOOTER_GUARD: - case MOB_REAVER_GUARD: - summoned->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM,0)); - adds.push_back(summoned->GetGUID()); - break; - case MOB_SHATTERED_ASSASSIN: - assassins.push_back(summoned->GetGUID()); - break; } - } - void KilledUnit(Unit* victim) - { - if (victim->GetTypeId() == TYPEID_PLAYER) + struct boss_warchief_kargath_bladefistAI : public ScriptedAI { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); - } - } - - void JustDied(Unit* /*Killer*/) - { - DoScriptText(SAY_DEATH, me); - removeAdds(); - } - - void MovementInform(uint32 type, uint32 id) - { - if (InBlade) - { - if (type != POINT_MOTION_TYPE) - return; - - if (id != 1) - return; - - if (target_num > 0) // to prevent loops + boss_warchief_kargath_bladefistAI(Creature* pCreature) : ScriptedAI(pCreature) { - Wait_Timer = 1; - DoCast(me, SPELL_BLADE_DANCE, true); - target_num--; } - } - } - void removeAdds() - { - for (std::vector::const_iterator itr = adds.begin(); itr!= adds.end(); ++itr) - { - Unit* temp = Unit::GetUnit((*me),*itr); - if (temp && temp->isAlive()) + std::vector adds; + std::vector assassins; + + uint32 Charge_timer; + uint32 Blade_Dance_Timer; + uint32 Summon_Assistant_Timer; + uint32 resetcheck_timer; + uint32 Wait_Timer; + + uint32 Assassins_Timer; + + uint32 summoned; + bool InBlade; + + uint32 target_num; + + void Reset() { - (*temp).GetMotionMaster()->Clear(true); - me->DealDamage(temp,temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - CAST_CRE(temp)->RemoveCorpse(); + removeAdds(); + + me->SetSpeed(MOVE_RUN,2); + me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); + + summoned = 2; + InBlade = false; + Wait_Timer = 0; + + Charge_timer = 0; + Blade_Dance_Timer = 45000; + Summon_Assistant_Timer = 30000; + Assassins_Timer = 5000; + resetcheck_timer = 5000; } - } - adds.clear(); - for (std::vector::const_iterator itr = assassins.begin(); itr!= assassins.end(); ++itr) - { - Unit* temp = Unit::GetUnit((*me),*itr); - if (temp && temp->isAlive()) + void EnterCombat(Unit * /*who*/) { - (*temp).GetMotionMaster()->Clear(true); - me->DealDamage(temp,temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - CAST_CRE(temp)->RemoveCorpse(); + DoScriptText(RAND(SAY_AGGRO1,SAY_AGGRO2,SAY_AGGRO3), me); } - } - assassins.clear(); - } - void SpawnAssassin() - { - me->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassEntrance[0],AssassEntrance[1]+8, AssassEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); - me->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassEntrance[0],AssassEntrance[1]-8, AssassEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); - me->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassExit[0],AssassExit[1]+8, AssassExit[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); - me->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassExit[0],AssassExit[1]-8, AssassExit[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); - } - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (Assassins_Timer) - if (Assassins_Timer <= diff) + void JustSummoned(Creature *summoned) { - SpawnAssassin(); - Assassins_Timer = 0; - } else Assassins_Timer -= diff; - - if (InBlade) - { - if (Wait_Timer) - if (Wait_Timer <= diff) + switch(summoned->GetEntry()) { - if (target_num <= 0) - { - // stop bladedance - InBlade = false; - me->SetSpeed(MOVE_RUN,2); - me->GetMotionMaster()->MoveChase(me->getVictim()); - Blade_Dance_Timer = 30000; - Wait_Timer = 0; - if (IsHeroic()) - Charge_timer = 5000; - } - else - { - //move in bladedance - float x,y,randx,randy; - randx = (rand()%40); - randy = (rand()%40); - x = 210+ randx ; - y = -60- randy ; - me->GetMotionMaster()->MovePoint(1,x,y,me->GetPositionZ()); - Wait_Timer = 0; - } - } else Wait_Timer -= diff; - } - else - { - if (Blade_Dance_Timer) - if (Blade_Dance_Timer <= diff) - { - target_num = TARGET_NUM; - Wait_Timer = 1; - InBlade = true; - Blade_Dance_Timer = 0; - me->SetSpeed(MOVE_RUN,4); - return; - } else Blade_Dance_Timer -= diff; + case MOB_HEARTHEN_GUARD: + case MOB_SHARPSHOOTER_GUARD: + case MOB_REAVER_GUARD: + summoned->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM,0)); + adds.push_back(summoned->GetGUID()); + break; + case MOB_SHATTERED_ASSASSIN: + assassins.push_back(summoned->GetGUID()); + break; + } + } - if (Charge_timer) - if (Charge_timer <= diff) - { - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), H_SPELL_CHARGE); - Charge_timer = 0; - } else Charge_timer -= diff; - - if (Summon_Assistant_Timer <= diff) + void KilledUnit(Unit* victim) { - for (uint8 i = 0; i < summoned; ++i) + if (victim->GetTypeId() == TYPEID_PLAYER) { - switch (urand(0,2)) + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); + } + } + + void JustDied(Unit* /*Killer*/) + { + DoScriptText(SAY_DEATH, me); + removeAdds(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (InBlade) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id != 1) + return; + + if (target_num > 0) // to prevent loops { - case 0: me->SummonCreature(MOB_HEARTHEN_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); break; - case 1: me->SummonCreature(MOB_SHARPSHOOTER_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); break; - case 2: me->SummonCreature(MOB_REAVER_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); break; + Wait_Timer = 1; + DoCast(me, SPELL_BLADE_DANCE, true); + target_num--; } } - if (urand(0,9) < 2) - ++summoned; - Summon_Assistant_Timer = urand(25000,35000); - } else Summon_Assistant_Timer -= diff; - - DoMeleeAttackIfReady(); - } - - if (resetcheck_timer <= diff) - { - uint32 tempx,tempy; - tempx = uint32(me->GetPositionX()); - tempy = uint32(me->GetPositionY()); - if (tempx > 255 || tempx < 205) - { - EnterEvadeMode(); - return; } - resetcheck_timer = 5000; - } else resetcheck_timer -= diff; - } -}; -CreatureAI* GetAI_boss_warchief_kargath_bladefist(Creature* pCreature) -{ - return new boss_warchief_kargath_bladefistAI (pCreature); -} + void removeAdds() + { + for (std::vector::const_iterator itr = adds.begin(); itr!= adds.end(); ++itr) + { + Unit* temp = Unit::GetUnit((*me),*itr); + if (temp && temp->isAlive()) + { + (*temp).GetMotionMaster()->Clear(true); + me->DealDamage(temp,temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + CAST_CRE(temp)->RemoveCorpse(); + } + } + adds.clear(); + + for (std::vector::const_iterator itr = assassins.begin(); itr!= assassins.end(); ++itr) + { + Unit* temp = Unit::GetUnit((*me),*itr); + if (temp && temp->isAlive()) + { + (*temp).GetMotionMaster()->Clear(true); + me->DealDamage(temp,temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + CAST_CRE(temp)->RemoveCorpse(); + } + } + assassins.clear(); + } + void SpawnAssassin() + { + me->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassEntrance[0],AssassEntrance[1]+8, AssassEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); + me->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassEntrance[0],AssassEntrance[1]-8, AssassEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); + me->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassExit[0],AssassExit[1]+8, AssassExit[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); + me->SummonCreature(MOB_SHATTERED_ASSASSIN,AssassExit[0],AssassExit[1]-8, AssassExit[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + if (Assassins_Timer) + if (Assassins_Timer <= diff) + { + SpawnAssassin(); + Assassins_Timer = 0; + } + else + Assassins_Timer -= diff; + + if (InBlade) + { + if (Wait_Timer) + if (Wait_Timer <= diff) + { + if (target_num <= 0) + { + // stop bladedance + InBlade = false; + me->SetSpeed(MOVE_RUN,2); + me->GetMotionMaster()->MoveChase(me->getVictim()); + Blade_Dance_Timer = 30000; + Wait_Timer = 0; + if (IsHeroic()) + Charge_timer = 5000; + } + else + { + //move in bladedance + float x,y,randx,randy; + randx = (rand()%40); + randy = (rand()%40); + x = 210+ randx ; + y = -60- randy ; + me->GetMotionMaster()->MovePoint(1,x,y,me->GetPositionZ()); + Wait_Timer = 0; + } + } + else + Wait_Timer -= diff; + } + else + { + if (Blade_Dance_Timer) + if (Blade_Dance_Timer <= diff) + { + target_num = TARGET_NUM; + Wait_Timer = 1; + InBlade = true; + Blade_Dance_Timer = 0; + me->SetSpeed(MOVE_RUN,4); + return; + } + else + Blade_Dance_Timer -= diff; + + if (Charge_timer) + if (Charge_timer <= diff) + { + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), H_SPELL_CHARGE); + Charge_timer = 0; + } + else + Charge_timer -= diff; + + if (Summon_Assistant_Timer <= diff) + { + for (uint8 i = 0; i < summoned; ++i) + { + switch (urand(0,2)) + { + case 0: + me->SummonCreature(MOB_HEARTHEN_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); + break; + case 1: + me->SummonCreature(MOB_SHARPSHOOTER_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); + break; + case 2: + me->SummonCreature(MOB_REAVER_GUARD,AddsEntrance[0],AddsEntrance[1], AddsEntrance[2], 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); + break; + } + } + if (urand(0,9) < 2) + ++summoned; + Summon_Assistant_Timer = urand(25000,35000); + } + else + Summon_Assistant_Timer -= diff; + + DoMeleeAttackIfReady(); + } + + if (resetcheck_timer <= diff) + { + uint32 tempx,tempy; + tempx = uint32(me->GetPositionX()); + tempy = uint32(me->GetPositionY()); + if (tempx > 255 || tempx < 205) + { + EnterEvadeMode(); + return; + } + resetcheck_timer = 5000; + } + else + resetcheck_timer -= diff; + } + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new boss_warchief_kargath_bladefistAI (Creature); + } +}; void AddSC_boss_warchief_kargath_bladefist() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_warchief_kargath_bladefist"; - newscript->GetAI = &GetAI_boss_warchief_kargath_bladefist; - newscript->RegisterSelf(); + new boss_warchief_kargath_bladefist(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp index c7107cdb244..8f052f592e1 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp @@ -30,87 +30,95 @@ EndScriptData */ #define DOOR_NETHEKURSE 1 -struct instance_shattered_halls : public ScriptedInstance +class instance_shattered_halls : public InstanceMapScript { - instance_shattered_halls(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - uint64 nethekurseGUID; - uint64 nethekurseDoorGUID; - - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - nethekurseGUID = 0; - nethekurseDoorGUID = 0; - } - - void OnGameObjectCreate(GameObject* pGo, bool /*add*/) - { - switch(pGo->GetEntry()) + public: + instance_shattered_halls() + : InstanceMapScript("instance_shattered_halls") { - case DOOR_NETHEKURSE: nethekurseDoorGUID = pGo->GetGUID(); break; } - } - - void OnCreatureCreate(Creature* pCreature, bool /*add*/) - { - switch(pCreature->GetEntry()) + struct instance_shattered_halls_InstanceMapScript : public ScriptedInstance { - case 16807: nethekurseGUID = pCreature->GetGUID(); break; - } - } + instance_shattered_halls_InstanceMapScript(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - void SetData(uint32 type, uint32 data) - { - switch(type) - { - case TYPE_NETHEKURSE: - m_auiEncounter[0] = data; - break; - case TYPE_OMROGG: - m_auiEncounter[1] = data; - break; - } - } + uint32 m_auiEncounter[MAX_ENCOUNTER]; + uint64 nethekurseGUID; + uint64 nethekurseDoorGUID; - uint32 GetData(uint32 type) - { - switch(type) - { - case TYPE_NETHEKURSE: - return m_auiEncounter[0]; - case TYPE_OMROGG: - return m_auiEncounter[1]; - } - return 0; - } + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - uint64 GetData64(uint32 data) - { - switch(data) + nethekurseGUID = 0; + nethekurseDoorGUID = 0; + } + + void OnGameObjectCreate(GameObject* pGo, bool /*add*/) + { + switch(pGo->GetEntry()) + { + case DOOR_NETHEKURSE: + nethekurseDoorGUID = pGo->GetGUID(); + break; + } + } + + void OnCreatureCreate(Creature* pCreature, bool /*add*/) + { + switch(pCreature->GetEntry()) + { + case 16807: + nethekurseGUID = pCreature->GetGUID(); + break; + } + } + + void SetData(uint32 type, uint32 data) + { + switch(type) + { + case TYPE_NETHEKURSE: + m_auiEncounter[0] = data; + break; + case TYPE_OMROGG: + m_auiEncounter[1] = data; + break; + } + } + + uint32 GetData(uint32 type) + { + switch(type) + { + case TYPE_NETHEKURSE: + return m_auiEncounter[0]; + case TYPE_OMROGG: + return m_auiEncounter[1]; + } + return 0; + } + + uint64 GetData64(uint32 data) + { + switch(data) + { + case DATA_NETHEKURSE: + return nethekurseGUID; + case DATA_NETHEKURSE_DOOR: + return nethekurseDoorGUID; + } + return 0; + } + }; + + InstanceData* GetInstanceData(Map* pMap) const { - case DATA_NETHEKURSE: - return nethekurseGUID; - case DATA_NETHEKURSE_DOOR: - return nethekurseDoorGUID; + return new instance_shattered_halls_InstanceMapScript(pMap); } - return 0; - } }; -InstanceData* GetInstanceData_instance_shattered_halls(Map* pMap) -{ - return new instance_shattered_halls(pMap); -} - void AddSC_instance_shattered_halls() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_shattered_halls"; - newscript->GetInstanceData = &GetInstanceData_instance_shattered_halls; - newscript->RegisterSelf(); + new instance_shattered_halls(); }