diff options
author | Supabad <none@none> | 2010-08-08 00:49:40 +0200 |
---|---|---|
committer | Supabad <none@none> | 2010-08-08 00:49:40 +0200 |
commit | c260b3f77848dc02518712a319f1daa94ef94ebe (patch) | |
tree | f18ab97269ce4e9b5f4cbde5cb5e062b9927902c /src | |
parent | d3712984c1fd070aaaf4543b00a3939bc4e4bc77 (diff) |
convert Magtheridons Lair and Shattered Halls to new format
--HG--
branch : trunk
Diffstat (limited to 'src')
6 files changed, 1594 insertions, 1422 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 - -#define EMOTE_BERSERK -1544012 -#define EMOTE_BLASTNOVA -1544013 -#define EMOTE_BEGIN -1544014 - -#define MOB_MAGTHERIDON 17257 -#define MOB_ROOM 17516 -#define MOB_CHANNELLER 17256 -#define 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 - -#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 -#define CLICKERS_COUNT 5 +enum eSays +{ + SAY_FREED = -1544006, + SAY_AGGRO = -1544007, + SAY_BANISH = -1544008, + SAY_CHAMBER_DESTROY = -1544009, + SAY_PLAYER_KILLED = -1544010, + SAY_DEATH = -1544011, +}; -typedef std::map<uint64, uint64> CubeMap; +enum eEmotes +{ + EMOTE_BERSERK = -1544012, + EMOTE_BLASTNOVA = -1544013, + EMOTE_BEGIN = -1544014, +}; -struct mob_abyssalAI : public ScriptedAI +enum eCreatures { - mob_abyssalAI(Creature *c) : ScriptedAI(c) - { - trigger = 0; - Despawn_Timer = 60000; - } + MOB_MAGTHERIDON = 17257, + MOB_ROOM = 17516, + MOB_CHANNELLER = 17256, + MOB_ABYSSAL = 17454, +}; - uint32 FireBlast_Timer; - uint32 Despawn_Timer; - uint32 trigger; +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, +}; - void Reset() - { - FireBlast_Timer = 6000; - } +//count of clickers needed to interrupt blast nova +#define CLICKERS_COUNT 5 - 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; - } - } +typedef std::map<uint64, uint64> CubeMap; - void SetTrigger(uint32 _trigger) - { - trigger = _trigger; - me->SetDisplayId(11686); - if (trigger == 1) //debris +class mob_abyssal : public CreatureScript +{ + public: + + mob_abyssal() + : CreatureScript("mob_abyssal") { - 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) + struct mob_abyssalAI : public ScriptedAI { - if (trigger == 1) + mob_abyssalAI(Creature* pCreature) : ScriptedAI(pCreature) { - if (FireBlast_Timer <= diff) - { - DoCast(me, SPELL_DEBRIS_DAMAGE, true); - trigger = 3; - } else FireBlast_Timer -= diff; + trigger = 0; + Despawn_Timer = 60000; } - return; - } - if (Despawn_Timer <= diff) - { - me->ForcedDespawn(); - } else Despawn_Timer -= diff; + uint32 FireBlast_Timer; + uint32 Despawn_Timer; + uint32 trigger; - if (!UpdateVictim()) - return; + void Reset() + { + FireBlast_Timer = 6000; + } - if (FireBlast_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_FIRE_BLAST); - FireBlast_Timer = 5000+rand()%10000; - } else FireBlast_Timer -= diff; + 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; + } + } - DoMeleeAttackIfReady(); - } -}; + 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; + } + } -struct boss_magtheridonAI : public ScriptedAI -{ - boss_magtheridonAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); - me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); - - // 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) - { - 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; - } - } + void EnterCombat(Unit* /*who*/) + { + DoZoneInCombat(); + } + void AttackStart(Unit *who) + { + if (!trigger) + ScriptedAI::AttackStart(who); + } + void MoveInLineOfSight(Unit *who) + { + if (!trigger) + ScriptedAI::MoveInLineOfSight(who); + } - CubeMap Cube; + 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; + } - ScriptedInstance* pInstance; + if (Despawn_Timer <= diff) + { + me->ForcedDespawn(); + } + else Despawn_Timer -= diff; - uint32 Berserk_Timer; - uint32 Quake_Timer; - uint32 Cleave_Timer; - uint32 BlastNova_Timer; - uint32 Blaze_Timer; - uint32 Debris_Timer; - uint32 RandChat_Timer; + if (!UpdateVictim()) + return; - bool Phase3; - bool NeedCheckCube; + if (FireBlast_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_FIRE_BLAST); + FireBlast_Timer = 5000+rand()%10000; + } + else FireBlast_Timer -= diff; - 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); - } + DoMeleeAttackIfReady(); + } + }; - void JustReachedHome() - { - if (pInstance) + CreatureAI* GetAI(Creature* Creature) const { - pInstance->SetData(DATA_MAGTHERIDON_EVENT, NOT_STARTED); - pInstance->SetData(DATA_COLLAPSE, false); + return new mob_abyssalAI(Creature); } - } - - 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); - } +class boss_magtheridon : public CreatureScript +{ + public: - 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) + boss_magtheridon() + : CreatureScript("boss_magtheridon") { - 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)) + struct boss_magtheridonAI : public ScriptedAI { - 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); + boss_magtheridonAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceData(); + me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); + me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); + + // 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) + { + 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; + } + } - if (!ClickerNum) NeedCheckCube = false; - } + CubeMap Cube; - void KilledUnit(Unit* /*victim*/) - { - DoScriptText(SAY_PLAYER_KILLED, me); - } + ScriptedInstance* pInstance; - void JustDied(Unit* /*Killer*/) - { - if (pInstance) - pInstance->SetData(DATA_MAGTHERIDON_EVENT, DONE); + uint32 Berserk_Timer; + uint32 Quake_Timer; + uint32 Cleave_Timer; + uint32 BlastNova_Timer; + uint32 Blaze_Timer; + uint32 Debris_Timer; + uint32 RandChat_Timer; - DoScriptText(SAY_DEATH, me); - } + bool Phase3; + bool NeedCheckCube; - void MoveInLineOfSight(Unit* /*who*/) {} + 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; - void AttackStart(Unit *who) - { - if (!me->hasUnitState(UNIT_STAT_STUNNED)) - ScriptedAI::AttackStart(who); - } + Phase3 = false; + NeedCheckCube = false; - void EnterCombat(Unit * /*who*/) - { - if (pInstance) - pInstance->SetData(DATA_MAGTHERIDON_EVENT, IN_PROGRESS); - DoZoneInCombat(); + 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); + } - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE_C); + void JustReachedHome() + { + if (pInstance) + { + pInstance->SetData(DATA_MAGTHERIDON_EVENT, NOT_STARTED); + pInstance->SetData(DATA_COLLAPSE, false); + } + } - DoScriptText(SAY_FREED, me); - } + 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; + } - void UpdateAI(const uint32 diff) - { - if (!me->isInCombat()) - { - if (RandChat_Timer <= diff) + //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) { - DoScriptText(RandomTaunt[rand()%6].id, me); - RandChat_Timer = 90000; - } else RandChat_Timer -= diff; - } + if (!clicker || !clicker->isAlive()) + return; - if (!UpdateVictim()) - return; + clicker->RemoveAurasDueToSpell(SPELL_SHADOW_GRASP); // cannot interrupt triggered spells + clicker->InterruptNonMeleeSpells(false); + clicker->CastSpell(clicker, SPELL_MIND_EXHAUSTION, true); + } - if (NeedCheckCube) NeedCheckCubeStatus(); + 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 (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - DoScriptText(EMOTE_BERSERK, me); - Berserk_Timer = 60000; - } else Berserk_Timer -= diff; + // 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 (Cleave_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_CLEAVE); - Cleave_Timer = 10000; - } else Cleave_Timer -= diff; + if (!ClickerNum) + NeedCheckCube = false; + } - if (BlastNova_Timer <= diff) - { - // to avoid earthquake interruption - if (!me->hasUnitState(UNIT_STAT_STUNNED)) + void KilledUnit(Unit* /*victim*/) { - DoScriptText(EMOTE_BLASTNOVA, me); - DoCast(me, SPELL_BLASTNOVA); - BlastNova_Timer = 60000; + DoScriptText(SAY_PLAYER_KILLED, me); } - } else BlastNova_Timer -= diff; - if (Quake_Timer <= diff) - { - // to avoid blastnova interruption - if (!me->IsNonMeleeSpellCasted(false)) + void JustDied(Unit* /*Killer*/) { - DoCast(me, SPELL_QUAKE_TRIGGER, true); - Quake_Timer = 50000; + if (pInstance) + pInstance->SetData(DATA_MAGTHERIDON_EVENT, DONE); + + DoScriptText(SAY_DEATH, me); } - } else Quake_Timer -= diff; - if (Blaze_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + void MoveInLineOfSight(Unit* /*who*/) {} + + void AttackStart(Unit *who) { - 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(2); - DoCast(summon, SPELL_BLAZE_TARGET, true); - summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } + if (!me->hasUnitState(UNIT_STAT_STUNNED)) + ScriptedAI::AttackStart(who); } - 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); + void EnterCombat(Unit * /*who*/) + { + if (pInstance) + pInstance->SetData(DATA_MAGTHERIDON_EVENT, IN_PROGRESS); + DoZoneInCombat(); - if (pInstance) - pInstance->SetData(DATA_COLLAPSE, true); - } + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE_C); - if (Phase3) - { - if (Debris_Timer <= diff) + DoScriptText(SAY_FREED, me); + } + + void UpdateAI(const uint32 diff) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + if (!me->isInCombat()) { - 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); + if (RandChat_Timer <= diff) + { + DoScriptText(RandomTaunt[rand()%6].id, me); + RandChat_Timer = 90000; + } + else + RandChat_Timer -= diff; } - Debris_Timer = 10000; - } else Debris_Timer -= diff; - } - DoMeleeAttackIfReady(); - } + 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; + mob_hellfire_channeler() + : CreatureScript("mob_hellfire_channeler") + { + } - uint32 ShadowBoltVolley_Timer; - uint32 DarkMending_Timer; - uint32 Fear_Timer; - uint32 Infernal_Timer; + struct mob_hellfire_channelerAI : public ScriptedAI + { + mob_hellfire_channelerAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceData(); + } - uint32 Check_Timer; + ScriptedInstance* pInstance; - void Reset() - { - ShadowBoltVolley_Timer = 8000 + rand()%2000; - DarkMending_Timer = 10000; - Fear_Timer = 15000 + rand()%5000; - Infernal_Timer = 10000 + rand()%40000; + uint32 ShadowBoltVolley_Timer; + uint32 DarkMending_Timer; + uint32 Fear_Timer; + uint32 Infernal_Timer; - Check_Timer = 5000; - } + uint32 Check_Timer; - void EnterCombat(Unit * /*who*/) - { - if (pInstance) - pInstance->SetData(DATA_CHANNELER_EVENT, IN_PROGRESS); + void Reset() + { + ShadowBoltVolley_Timer = 8000 + rand()%2000; + DarkMending_Timer = 10000; + Fear_Timer = 15000 + rand()%5000; + Infernal_Timer = 10000 + rand()%40000; - me->InterruptNonMeleeSpells(false); - DoZoneInCombat(); - } + Check_Timer = 5000; + } - void JustReachedHome() - { - if (pInstance) - pInstance->SetData(DATA_CHANNELER_EVENT, NOT_STARTED); + void EnterCombat(Unit * /*who*/) + { + if (pInstance) + pInstance->SetData(DATA_CHANNELER_EVENT, IN_PROGRESS); - DoCast(me, SPELL_SHADOW_GRASP_C, false); - } + me->InterruptNonMeleeSpells(false); + DoZoneInCombat(); + } - void JustSummoned(Creature *summon) - { - summon->AI()->AttackStart(me->getVictim()); - } + void JustReachedHome() + { + if (pInstance) + pInstance->SetData(DATA_CHANNELER_EVENT, NOT_STARTED); - void DamageTaken(Unit*, uint32 &damage) - { - if (damage >= me->GetHealth()) - DoCast(me, SPELL_SOUL_TRANSFER, true); - } + DoCast(me, SPELL_SHADOW_GRASP_C, false); + } - void JustDied(Unit* /*who*/) - { - if (pInstance) - pInstance->SetData(DATA_CHANNELER_EVENT, DONE); - } + void JustSummoned(Creature *summon) + { + summon->AI()->AttackStart(me->getVictim()); + } - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + void DamageTaken(Unit*, uint32 &damage) + { + if (damage >= me->GetHealth()) + DoCast(me, SPELL_SOUL_TRANSFER, true); + } - if (ShadowBoltVolley_Timer <= diff) - { - DoCast(me, SPELL_SHADOW_BOLT_VOLLEY); - ShadowBoltVolley_Timer = 10000 + rand()%10000; - } else ShadowBoltVolley_Timer -= diff; + void JustDied(Unit* /*who*/) + { + if (pInstance) + pInstance->SetData(DATA_CHANNELER_EVENT, DONE); + } - 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; + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; - 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 (ShadowBoltVolley_Timer <= diff) + { + DoCast(me, SPELL_SHADOW_BOLT_VOLLEY); + ShadowBoltVolley_Timer = 10000 + rand()%10000; + } + else + ShadowBoltVolley_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; + 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; - DoMeleeAttackIfReady(); - } + 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 + { + 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) - 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; +public: + go_manticron_cube() : GameObjectScript("go_manticron_cube") + { + } - // if exhausted or already channeling return - if (pPlayer->HasAura(SPELL_MIND_EXHAUSTION) || pPlayer->HasAura(SPELL_SHADOW_GRASP)) + 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; - - 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]; + public: + instance_magtheridons_lair() + : InstanceMapScript("instance_magtheridons_lair") + { + } - uint64 MagtheridonGUID; - std::set<uint64> ChannelerGUID; - uint64 DoorGUID; - std::set<uint64> ColumnGUID; + struct instance_magtheridons_lair_InstanceMapScript : public ScriptedInstance + { + instance_magtheridons_lair_InstanceMapScript(Map* pMap) : ScriptedInstance(pMap) + { + Initialize(); + } - uint32 CageTimer; - uint32 RespawnTimer; + uint32 m_auiEncounter[MAX_ENCOUNTER]; - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + uint64 MagtheridonGUID; + std::set<uint64> ChannelerGUID; + uint64 DoorGUID; + std::set<uint64> ColumnGUID; - MagtheridonGUID = 0; - ChannelerGUID.clear(); - DoorGUID = 0; - ColumnGUID.clear(); + uint32 CageTimer; + uint32 RespawnTimer; - CageTimer = 0; - RespawnTimer = 0; - } + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - bool IsEncounterInProgress() const - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) return true; - return false; - } + MagtheridonGUID = 0; + ChannelerGUID.clear(); + DoorGUID = 0; + ColumnGUID.clear(); - void OnCreatureCreate(Creature* pCreature, bool /*add*/) - { - switch(pCreature->GetEntry()) - { - case 17257: - MagtheridonGUID = pCreature->GetGUID(); - break; - case 17256: - ChannelerGUID.insert(pCreature->GetGUID()); - break; - } - } + CageTimer = 0; + RespawnTimer = 0; + } - 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; - } - } + bool IsEncounterInProgress() const + { + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) return true; + return false; + } - uint64 GetData64(uint32 type) - { - switch(type) - { - case DATA_MAGTHERIDON: - return MagtheridonGUID; - } - return 0; - } + void OnCreatureCreate(Creature* pCreature, bool /*add*/) + { + switch(pCreature->GetEntry()) + { + case 17257: + MagtheridonGUID = pCreature->GetGUID(); + break; + case 17256: + ChannelerGUID.insert(pCreature->GetGUID()); + break; + } + } - 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) + void OnGameObjectCreate(GameObject* pGo, bool /*add*/) { - case NOT_STARTED: // Reset all channelers once one is reset. - if (m_auiEncounter[1] != NOT_STARTED) + switch(pGo->GetEntry()) { - m_auiEncounter[1] = NOT_STARTED; - for (std::set<uint64>::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); + 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; } - break; - case IN_PROGRESS: // Event start. - if (m_auiEncounter[1] != IN_PROGRESS) + } + + uint64 GetData64(uint32 type) + { + switch(type) { - m_auiEncounter[1] = IN_PROGRESS; - // Let all five channelers aggro. - for (std::set<uint64>::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); + case DATA_MAGTHERIDON: + return MagtheridonGUID; } - break; - case DONE: // Add buff and check if all channelers are dead. - for (std::set<uint64>::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) + return 0; + } + + void SetData(uint32 type, uint32 data) + { + switch(type) { - Creature *Channeler = instance->GetCreature(*i); - if (Channeler && Channeler->isAlive()) + 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) { - //Channeler->CastSpell(Channeler, SPELL_SOUL_TRANSFER, true); - data = IN_PROGRESS; + case NOT_STARTED: // Reset all channelers once one is reset. + if (m_auiEncounter[1] != NOT_STARTED) + { + m_auiEncounter[1] = NOT_STARTED; + for (std::set<uint64>::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<uint64>::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<uint64>::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; + } + } break; } + m_auiEncounter[1] = data; + break; + case DATA_COLLAPSE: + // true - collapse / false - reset + for (std::set<uint64>::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<uint64>::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; - } + uint32 GetData(uint32 type) + { + if (type == DATA_MAGTHERIDON_EVENT) + return m_auiEncounter[0]; + return 0; + } - void Update(uint32 diff) - { - if (CageTimer) - { - if (CageTimer <= diff) + void Update(uint32 diff) { - Creature *Magtheridon = instance->GetCreature(MagtheridonGUID); - if (Magtheridon && Magtheridon->isAlive()) + if (CageTimer) { - Magtheridon->clearUnitState(UNIT_STAT_STUNNED); - Magtheridon->AI()->AttackStart(Magtheridon->SelectNearestTarget(999)); + if (CageTimer <= diff) + { + 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; } - CageTimer = 0; - } else CageTimer -= diff; - } - if (RespawnTimer) - { - if (RespawnTimer <= diff) - { - for (std::set<uint64>::const_iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i) + if (RespawnTimer) { - if (Creature *Channeler = instance->GetCreature(*i)) + if (RespawnTimer <= diff) { - if (Channeler->isAlive()) - Channeler->AI()->EnterEvadeMode(); - else - Channeler->Respawn(); - } + for (std::set<uint64>::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; } - 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 +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, +}; + +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 { - 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) + public: + + boss_grand_warlock_nethekurse() + : CreatureScript("boss_grand_warlock_nethekurse") { - 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)) + + struct boss_grand_warlock_nethekurseAI : public ScriptedAI { - if (Phase) - DoStartNoMovement(who); - else - DoStartMovement(who); - } - } + 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 MoveInLineOfSight(Unit *who) - { - if (!IntroOnce && me->IsWithinDistInMap(who, 50.0f)) + void Reset() { - if (who->GetTypeId() != TYPEID_PLAYER) - return; + 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; + } - DoScriptText(SAY_INTRO, me); - IntroOnce = true; - IsIntroEvent = true; + void DoYellForPeonAggro() + { + if (PeonEngagedCount >= 4) + return; - if (pInstance) - pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS); + DoScriptText(PeonAttacked[PeonEngagedCount].id, me); + ++PeonEngagedCount; } - if (IsIntroEvent || !IsMainEvent) - return; + void DoYellForPeonDeath() + { + if (PeonKilledCount >= 4) + return; - ScriptedAI::MoveInLineOfSight(who); - } + DoScriptText(PeonDies[PeonKilledCount].id, me); + ++PeonKilledCount; - void EnterCombat(Unit * /*who*/) - { - DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me); - } + if (PeonKilledCount == 4) + { + IsIntroEvent = false; + IsMainEvent = true; + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } - 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); + 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; - //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()); - } + if (me->Attack(who, true)) + { + if (Phase) + DoStartNoMovement(who); + else + DoStartMovement(who); + } + } - void KilledUnit(Unit* /*victim*/) - { - DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me); - } + void MoveInLineOfSight(Unit *who) + { + if (!IntroOnce && me->IsWithinDistInMap(who, 50.0f)) + { + if (who->GetTypeId() != TYPEID_PLAYER) + return; - void JustDied(Unit* /*Killer*/) - { - DoScriptText(SAY_DIE, me); + DoScriptText(SAY_INTRO, me); + IntroOnce = true; + IsIntroEvent = true; - if (!pInstance) - return; + if (pInstance) + pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS); + } - pInstance->SetData(TYPE_NETHEKURSE,DONE); - pInstance->HandleGameObject(pInstance->GetData64(DATA_NETHEKURSE_DOOR), true); - } + if (IsIntroEvent || !IsMainEvent) + return; - void UpdateAI(const uint32 diff) - { - if (IsIntroEvent) - { - if (!pInstance) - return; + ScriptedAI::MoveInLineOfSight(who); + } - if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS) + void EnterCombat(Unit * /*who*/) { - if (IntroEvent_Timer <= diff) - DoTauntPeons(); - else - IntroEvent_Timer -= diff; + DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me); } - } - if (!UpdateVictim()) - return; + 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); - if (!IsMainEvent) - return; + //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()); + } - if (Phase) - { - if (!SpinOnce) + void KilledUnit(Unit* /*victim*/) { - DoCast(me->getVictim(), SPELL_DARK_SPIN); - SpinOnce = true; + DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me); } - if (Cleave_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_SHADOW_CLEAVE); - Cleave_Timer = 6000+rand()%2500; - } else Cleave_Timer -= diff; - } - else - { - if (ShadowFissure_Timer <= diff) + void JustDied(Unit* /*Killer*/) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_SHADOW_FISSURE); - ShadowFissure_Timer = urand(7500,15000); - } else ShadowFissure_Timer -= diff; + DoScriptText(SAY_DIE, me); - if (DeathCoil_Timer <= diff) + if (!pInstance) + return; + + pInstance->SetData(TYPE_NETHEKURSE,DONE); + pInstance->HandleGameObject(pInstance->GetData64(DATA_NETHEKURSE_DOOR), true); + } + + void UpdateAI(const uint32 diff) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_DEATH_COIL); - DeathCoil_Timer = urand(15000,20000); - } else DeathCoil_Timer -= diff; + if (IsIntroEvent) + { + if (!pInstance) + return; - if ((me->GetHealth()*100) / me->GetMaxHealth() <= 20) - Phase = true; + if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS) + { + if (IntroEvent_Timer <= diff) + DoTauntPeons(); + else + IntroEvent_Timer -= diff; + } + } + + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); + 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 + { + return new boss_grand_warlock_nethekurseAI (Creature); } - } }; -struct mob_fel_orc_convertAI : public ScriptedAI + +class mob_fel_orc_convert : public CreatureScript { - mob_fel_orc_convertAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->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) + public: + + mob_fel_orc_convert() + : CreatureScript("mob_fel_orc_convert") + { + } + + struct mob_fel_orc_convertAI : public ScriptedAI { - if (pInstance->GetData64(DATA_NETHEKURSE)) + mob_fel_orc_convertAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceData(); + } + + ScriptedInstance* pInstance; + uint32 Hemorrhage_Timer; + + void Reset() { - Creature *pKurse = Unit::GetCreature(*me,pInstance->GetData64(DATA_NETHEKURSE)); - if (pKurse && me->IsWithinDist(pKurse, 45.0f)) + 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) { - CAST_AI(boss_grand_warlock_nethekurseAI, pKurse->AI())->DoYellForPeonAggro(); + 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); + } + } + } + } - if (pInstance->GetData(TYPE_NETHEKURSE) == IN_PROGRESS) + void JustDied(Unit* /*Killer*/) + { + if (pInstance) + { + if (pInstance->GetData(TYPE_NETHEKURSE) != IN_PROGRESS) return; - else - pInstance->SetData(TYPE_NETHEKURSE,IN_PROGRESS); + 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 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_nethekurseAI, pKurse->AI())->DoYellForPeonDeath(); - } - } + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + if (Hemorrhage_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_HEMORRHAGE); + Hemorrhage_Timer = 15000; + } else Hemorrhage_Timer -= diff; - if (Hemorrhage_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_HEMORRHAGE); - Hemorrhage_Timer = 15000; - } else Hemorrhage_Timer -= diff; + DoMeleeAttackIfReady(); + } + }; - 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") + { + } -CreatureAI* GetAI_boss_grand_warlock_nethekurse(Creature* pCreature) -{ - return new boss_grand_warlock_nethekurseAI (pCreature); -} + struct mob_lesser_shadow_fissureAI : public ScriptedAI + { + mob_lesser_shadow_fissureAI(Creature* pCreature) : ScriptedAI(pCreature) {} -CreatureAI* GetAI_mob_fel_orc_convert(Creature* pCreature) -{ - return new mob_fel_orc_convertAI (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_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) {} - - 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; + public: - if (Death_Timer <= diff) - { - DoScriptText(YELL_DIE_R, me); - Death_Timer = false; - me->setDeathState(JUST_DIED); - } else Death_Timer -= diff; - } -}; - -struct boss_warbringer_omroggAI : public ScriptedAI -{ - boss_warbringer_omroggAI(Creature *c) : ScriptedAI(c) - { - LeftHeadGUID = 0; - RightHeadGUID = 0; - pInstance = c->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)) + mob_omrogg_heads() + : CreatureScript("mob_omrogg_heads") { - pLeftHead->setDeathState(JUST_DIED); - LeftHeadGUID = 0; } - if (Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID)) + struct mob_omrogg_headsAI : 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); + mob_omrogg_headsAI(Creature* pCreature) : ScriptedAI(pCreature) {} - if (!pLeftHead || !pRightHead) - return; + bool DeathYell; + uint32 Death_Timer; - ithreat = rand()%4; + void Reset() + { + Death_Timer = 4000; + DeathYell = false; + } + void EnterCombat(Unit* /*who*/) {} - Unit *source = (pLeftHead->GetEntry() == Threat[ithreat].creature ? pLeftHead : pRightHead); + void DoDeathYell() + { + DeathYell = true; + } - DoScriptText(Threat[ithreat].id, source); + 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; + } + }; - Delay_Timer = 3500; - ThreatYell = true; - } + CreatureAI* GetAI(Creature* Creature) const + { + return new mob_omrogg_headsAI (Creature); + } +}; - 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); +class boss_warbringer_omrogg : public CreatureScript +{ + public: - if (Unit *pLeftHead = Unit::GetUnit(*me,LeftHeadGUID)) + boss_warbringer_omrogg() + : CreatureScript("boss_warbringer_omrogg") { - iaggro = rand()%3; + } - DoScriptText(GoCombat[iaggro].id, pLeftHead); + struct boss_warbringer_omroggAI : public ScriptedAI + { + boss_warbringer_omroggAI(Creature* pCreature) : ScriptedAI(pCreature) + { + LeftHeadGUID = 0; + RightHeadGUID = 0; + pInstance = pCreature->GetInstanceData(); + } - Delay_Timer = 3500; - AggroYell = true; - } + ScriptedInstance* pInstance; - if (pInstance) - pInstance->SetData(TYPE_OMROGG, IN_PROGRESS); - } + uint64 LeftHeadGUID; + uint64 RightHeadGUID; + int iaggro; + int ithreat; + int ikilling; - void JustSummoned(Creature *summoned) - { - if (summoned->GetEntry() == NPC_LEFT_HEAD) - LeftHeadGUID = summoned->GetGUID(); + bool AggroYell; + bool ThreatYell; + bool ThreatYell2; + bool KillingYell; - if (summoned->GetEntry() == NPC_RIGHT_HEAD) - RightHeadGUID = summoned->GetGUID(); + uint32 Delay_Timer; + uint32 BlastWave_Timer; + uint32 BlastCount; + uint32 Fear_Timer; + uint32 BurningMaul_Timer; + uint32 ThunderClap_Timer; + uint32 ResetThreat_Timer; - //summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - //summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - summoned->SetVisibility(VISIBILITY_OFF); - } + 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; + } - void KilledUnit(Unit* /*victim*/) - { - Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); - Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); + AggroYell = false; + ThreatYell = false; + ThreatYell2 = false; + KillingYell = false; - if (!pLeftHead || !pRightHead) - return; + Delay_Timer = 4000; + BlastWave_Timer = 0; + BlastCount = 0; + Fear_Timer = 8000; + BurningMaul_Timer = 25000; + ThunderClap_Timer = 15000; + ResetThreat_Timer = 30000; - ikilling = rand()%2; + 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. + } - Unit *source = (pLeftHead->GetEntry() == Killing[ikilling].creature ? pLeftHead : pRightHead); + void DoYellForThreat() + { + Unit *pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); + Unit *pRightHead = Unit::GetUnit(*me,RightHeadGUID); - 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; - } - } + if (!pLeftHead || !pRightHead) + return; - void JustDied(Unit* /*Killer*/) - { - Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); - Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); + ithreat = rand()%4; - if (!pLeftHead || !pRightHead) - return; + Unit *source = (pLeftHead->GetEntry() == Threat[ithreat].creature ? pLeftHead : pRightHead); - DoScriptText(YELL_DIE_L, pLeftHead); + DoScriptText(Threat[ithreat].id, source); - CAST_AI(mob_omrogg_headsAI, CAST_CRE(pRightHead)->AI())->DoDeathYell(); + Delay_Timer = 3500; + ThreatYell = true; + } - if (pInstance) - pInstance->SetData(TYPE_OMROGG, DONE); - } + 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); - void UpdateAI(const uint32 diff) - { - if (Delay_Timer <= diff) - { - Delay_Timer = 3500; + if (Unit *pLeftHead = Unit::GetUnit(*me,LeftHeadGUID)) + { + iaggro = rand()%3; - Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); - Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); + DoScriptText(GoCombat[iaggro].id, pLeftHead); - if (!pLeftHead || !pRightHead) - return; + Delay_Timer = 3500; + AggroYell = true; + } - if (AggroYell) - { - DoScriptText(GoCombatDelay[iaggro].id, pRightHead); - AggroYell = false; + if (pInstance) + pInstance->SetData(TYPE_OMROGG, IN_PROGRESS); } - if (ThreatYell2) + void JustSummoned(Creature *summoned) { - Unit *source = (pLeftHead->GetEntry() == ThreatDelay2[ithreat].creature ? pLeftHead : pRightHead); + if (summoned->GetEntry() == NPC_LEFT_HEAD) + LeftHeadGUID = summoned->GetGUID(); - DoScriptText(ThreatDelay2[ithreat].id, source); - ThreatYell2 = false; + 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); } - if (ThreatYell) + void KilledUnit(Unit* /*victim*/) { - Unit *source = (pLeftHead->GetEntry() == ThreatDelay1[ithreat].creature ? pLeftHead : pRightHead); - - DoScriptText(ThreatDelay1[ithreat].id, source); - ThreatYell = false; - ThreatYell2 = true; + 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; + } } - if (KillingYell) + void JustDied(Unit* /*Killer*/) { - Unit *source = (pLeftHead->GetEntry() == KillingDelay[ikilling].creature ? pLeftHead : pRightHead); + Unit* pLeftHead = Unit::GetUnit(*me,LeftHeadGUID); + Unit* pRightHead = Unit::GetUnit(*me,RightHeadGUID); - DoScriptText(KillingDelay[ikilling].id, source); - KillingYell = false; - } - } else Delay_Timer -= diff; + if (!pLeftHead || !pRightHead) + return; - if (!UpdateVictim()) - return; + DoScriptText(YELL_DIE_L, pLeftHead); - if (BlastCount && BlastWave_Timer <= diff) - { - DoCast(me, SPELL_BLAST_WAVE); - BlastWave_Timer = 5000; - ++BlastCount; + CAST_AI(mob_omrogg_heads::mob_omrogg_headsAI, CAST_CRE(pRightHead)->AI())->DoDeathYell(); - if (BlastCount == 3) - BlastCount = 0; - } else BlastWave_Timer -= diff; + if (pInstance) + pInstance->SetData(TYPE_OMROGG, DONE); + } - 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)) + void UpdateAI(const uint32 diff) { - DoYellForThreat(); - DoResetThreat(); - me->AddThreat(pTarget, 0.0f); + 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(); } - ResetThreat_Timer = 25000+rand()%15000; - } else ResetThreat_Timer -= diff; + }; - if (Fear_Timer <= diff) + 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, +}; -#define TARGET_NUM 5 +enum eCreatures +{ + MOB_SHATTERED_ASSASSIN = 17695, + MOB_HEARTHEN_GUARD = 17621, + MOB_SHARPSHOOTER_GUARD = 17622, + MOB_REAVER_GUARD = 17623, +}; -#define MOB_SHATTERED_ASSASSIN 17695 -#define MOB_HEARTHEN_GUARD 17621 -#define MOB_SHARPSHOOTER_GUARD 17622 -#define MOB_REAVER_GUARD 17623 +#define TARGET_NUM 5 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) - { - } - - std::vector<uint64> adds; - std::vector<uint64> assassins; - - uint32 Charge_timer; - uint32 Blade_Dance_Timer; - uint32 Summon_Assistant_Timer; - uint32 resetcheck_timer; - uint32 Wait_Timer; - - uint32 Assassins_Timer; + public: - uint32 summoned; - bool InBlade; - - uint32 target_num; + boss_warchief_kargath_bladefist() + : CreatureScript("boss_warchief_kargath_bladefist") + { + } - void Reset() - { - removeAdds(); + struct boss_warchief_kargath_bladefistAI : public ScriptedAI + { + boss_warchief_kargath_bladefistAI(Creature* pCreature) : ScriptedAI(pCreature) + { + } - me->SetSpeed(MOVE_RUN,2); - me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); + std::vector<uint64> adds; + std::vector<uint64> assassins; - summoned = 2; - InBlade = false; - Wait_Timer = 0; + uint32 Charge_timer; + uint32 Blade_Dance_Timer; + uint32 Summon_Assistant_Timer; + uint32 resetcheck_timer; + uint32 Wait_Timer; - Charge_timer = 0; - Blade_Dance_Timer = 45000; - Summon_Assistant_Timer = 30000; - Assassins_Timer = 5000; - resetcheck_timer = 5000; - } + uint32 Assassins_Timer; - void EnterCombat(Unit * /*who*/) - { - DoScriptText(RAND(SAY_AGGRO1,SAY_AGGRO2,SAY_AGGRO3), me); - } + uint32 summoned; + bool InBlade; - void JustSummoned(Creature *summoned) - { - switch(summoned->GetEntry()) - { - 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; - } - } + uint32 target_num; - void KilledUnit(Unit* victim) - { - if (victim->GetTypeId() == TYPEID_PLAYER) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); - } - } + void Reset() + { + removeAdds(); - void JustDied(Unit* /*Killer*/) - { - DoScriptText(SAY_DEATH, me); - removeAdds(); - } + me->SetSpeed(MOVE_RUN,2); + me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); - void MovementInform(uint32 type, uint32 id) - { - if (InBlade) - { - if (type != POINT_MOTION_TYPE) - return; + summoned = 2; + InBlade = false; + Wait_Timer = 0; - if (id != 1) - return; + Charge_timer = 0; + Blade_Dance_Timer = 45000; + Summon_Assistant_Timer = 30000; + Assassins_Timer = 5000; + resetcheck_timer = 5000; + } - if (target_num > 0) // to prevent loops + void EnterCombat(Unit * /*who*/) { - Wait_Timer = 1; - DoCast(me, SPELL_BLADE_DANCE, true); - target_num--; + DoScriptText(RAND(SAY_AGGRO1,SAY_AGGRO2,SAY_AGGRO3), me); } - } - } - void removeAdds() - { - for (std::vector<uint64>::const_iterator itr = adds.begin(); itr!= adds.end(); ++itr) - { - Unit* temp = Unit::GetUnit((*me),*itr); - if (temp && temp->isAlive()) + void JustSummoned(Creature *summoned) { - (*temp).GetMotionMaster()->Clear(true); - me->DealDamage(temp,temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - CAST_CRE(temp)->RemoveCorpse(); + switch(summoned->GetEntry()) + { + 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; + } } - } - adds.clear(); - for (std::vector<uint64>::const_iterator itr = assassins.begin(); itr!= assassins.end(); ++itr) - { - Unit* temp = Unit::GetUnit((*me),*itr); - if (temp && temp->isAlive()) + void KilledUnit(Unit* victim) { - (*temp).GetMotionMaster()->Clear(true); - me->DealDamage(temp,temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - CAST_CRE(temp)->RemoveCorpse(); + if (victim->GetTypeId() == TYPEID_PLAYER) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), 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 JustDied(Unit* /*Killer*/) { - SpawnAssassin(); - Assassins_Timer = 0; - } else Assassins_Timer -= diff; + DoScriptText(SAY_DEATH, me); + removeAdds(); + } - if (InBlade) - { - if (Wait_Timer) - if (Wait_Timer <= diff) + void MovementInform(uint32 type, uint32 id) + { + if (InBlade) { - if (target_num <= 0) + if (type != POINT_MOTION_TYPE) + return; + + if (id != 1) + return; + + if (target_num > 0) // to prevent loops { - // 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; + Wait_Timer = 1; + DoCast(me, SPELL_BLADE_DANCE, true); + target_num--; } - else + } + } + + void removeAdds() + { + for (std::vector<uint64>::const_iterator itr = adds.begin(); itr!= adds.end(); ++itr) + { + Unit* temp = Unit::GetUnit((*me),*itr); + if (temp && temp->isAlive()) { - //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; + (*temp).GetMotionMaster()->Clear(true); + me->DealDamage(temp,temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + CAST_CRE(temp)->RemoveCorpse(); } - } 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; + } + adds.clear(); - if (Charge_timer) - if (Charge_timer <= diff) + for (std::vector<uint64>::const_iterator itr = assassins.begin(); itr!= assassins.end(); ++itr) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), H_SPELL_CHARGE); - Charge_timer = 0; - } else Charge_timer -= diff; + 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); + } - if (Summon_Assistant_Timer <= diff) + void UpdateAI(const uint32 diff) { - for (uint8 i = 0; i < summoned; ++i) - { - switch (urand(0,2)) + //Return since we have no target + if (!UpdateVictim()) + return; + + if (Assassins_Timer) + if (Assassins_Timer <= diff) { - 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; + 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; } - if (urand(0,9) < 2) - ++summoned; - Summon_Assistant_Timer = urand(25000,35000); - } else Summon_Assistant_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(); - } + DoMeleeAttackIfReady(); + } - if (resetcheck_timer <= diff) - { - uint32 tempx,tempy; - tempx = uint32(me->GetPositionX()); - tempy = uint32(me->GetPositionY()); - if (tempx > 255 || tempx < 205) - { - EnterEvadeMode(); - return; + 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; } - resetcheck_timer = 5000; - } else resetcheck_timer -= diff; - } -}; + }; -CreatureAI* GetAI_boss_warchief_kargath_bladefist(Creature* pCreature) -{ - return new boss_warchief_kargath_bladefistAI (pCreature); -} + 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()) - { - 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) + public: + instance_shattered_halls() + : InstanceMapScript("instance_shattered_halls") { - case TYPE_NETHEKURSE: - m_auiEncounter[0] = data; - break; - case TYPE_OMROGG: - m_auiEncounter[1] = data; - break; } - } - - uint32 GetData(uint32 type) - { - switch(type) + struct instance_shattered_halls_InstanceMapScript : public ScriptedInstance { - case TYPE_NETHEKURSE: - return m_auiEncounter[0]; - case TYPE_OMROGG: - return m_auiEncounter[1]; - } - return 0; - } - - uint64 GetData64(uint32 data) - { - switch(data) + instance_shattered_halls_InstanceMapScript(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()) + { + 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(); } |