diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp index 3057d70f7..029abe651 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp @@ -18,6 +18,216 @@ #include "boss_heigan.h" +enum Says +{ + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_TAUNT = 2, + EMOTE_DEATH = 3, + EMOTE_DANCE = 4, + EMOTE_DANCE_END = 5, + SAY_DANCE = 6 +}; + +enum Spells +{ + SPELL_SPELL_DISRUPTION = 29310, + SPELL_DECREPIT_FEVER_10 = 29998, + SPELL_DECREPIT_FEVER_25 = 55011, + SPELL_PLAGUE_CLOUD = 29350, + SPELL_TELEPORT_SELF = 30211 +}; + +enum Events +{ + EVENT_DISRUPTION = 1, + EVENT_DECEPIT_FEVER = 2, + EVENT_ERUPT_SECTION = 3, + EVENT_SWITCH_PHASE = 4, + EVENT_SAFETY_DANCE = 5, + EVENT_PLAGUE_CLOUD = 6 +}; + +enum Misc +{ + PHASE_SLOW_DANCE = 0, + PHASE_FAST_DANCE = 1 +}; + +CreatureAI* boss_heigan::GetAI(Creature* pCreature) const +{ + return GetNaxxramasAI(pCreature); +} + +boss_heigan::boss_heiganAI::boss_heiganAI(Creature* c) : BossAI(c, BOSS_HEIGAN) +{ + pInstance = me->GetInstanceScript(); +} + +void boss_heigan::boss_heiganAI::Reset() +{ + BossAI::Reset(); + events.Reset(); + currentPhase = 0; + currentSection = 3; + moveRight = true; + if (pInstance) + { + if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HEIGAN_ENTER_GATE))) + { + go->SetGoState(GO_STATE_ACTIVE); + } + } +} + +void boss_heigan::boss_heiganAI::KilledUnit(Unit* who) +{ + if (who->GetTypeId() != TYPEID_PLAYER) + return; + + Talk(SAY_SLAY); + if (pInstance) + { + pInstance->SetData(DATA_IMMORTAL_FAIL, 0); + } +} + +void boss_heigan::boss_heiganAI::JustDied(Unit* killer) +{ + BossAI::JustDied(killer); + Talk(EMOTE_DEATH); +} + +void boss_heigan::boss_heiganAI::JustEngagedWith(Unit* who) +{ + BossAI::JustEngagedWith(who); + me->SetInCombatWithZone(); + Talk(SAY_AGGRO); + if (pInstance) + { + if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HEIGAN_ENTER_GATE))) + { + go->SetGoState(GO_STATE_READY); + } + } + StartFightPhase(PHASE_SLOW_DANCE); +} + +void boss_heigan::boss_heiganAI::StartFightPhase(uint8 phase) +{ + currentSection = 3; + currentPhase = phase; + events.Reset(); + if (phase == PHASE_SLOW_DANCE) + { + me->CastStop(); + me->SetReactState(REACT_AGGRESSIVE); + DoZoneInCombat(); + events.ScheduleEvent(EVENT_DISRUPTION, 12s, 15s); + events.ScheduleEvent(EVENT_DECEPIT_FEVER, 17s); + events.ScheduleEvent(EVENT_ERUPT_SECTION, 15s); + events.ScheduleEvent(EVENT_SWITCH_PHASE, 90s); + } + else // if (phase == PHASE_FAST_DANCE) + { + Talk(EMOTE_DANCE); + Talk(SAY_DANCE); + me->AttackStop(); + me->StopMoving(); + me->SetReactState(REACT_PASSIVE); + me->CastSpell(me, SPELL_TELEPORT_SELF, false); + me->SetFacingTo(2.40f); + events.ScheduleEvent(EVENT_PLAGUE_CLOUD, 1s); + events.ScheduleEvent(EVENT_ERUPT_SECTION, 7s); + events.ScheduleEvent(EVENT_SWITCH_PHASE, 45s); + } + events.ScheduleEvent(EVENT_SAFETY_DANCE, 5s); +} + +bool boss_heigan::boss_heiganAI::IsInRoom(Unit* who) +{ + if (who->GetPositionX() > 2826 || who->GetPositionX() < 2723 || who->GetPositionY() > -3641 || who->GetPositionY() < -3736) + { + if (who->GetGUID() == me->GetGUID()) + EnterEvadeMode(); + + return false; + } + return true; +} + +void boss_heigan::boss_heiganAI::UpdateAI(uint32 diff) +{ + if (!IsInRoom(me)) + return; + + if (!UpdateVictim()) + return; + + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case EVENT_DISRUPTION: + me->CastSpell(me, SPELL_SPELL_DISRUPTION, false); + events.Repeat(10s); + break; + case EVENT_DECEPIT_FEVER: + me->CastSpell(me, RAID_MODE(SPELL_DECREPIT_FEVER_10, SPELL_DECREPIT_FEVER_25), false); + events.Repeat(22s, 25s); + break; + case EVENT_PLAGUE_CLOUD: + me->CastSpell(me, SPELL_PLAGUE_CLOUD, false); + break; + case EVENT_SWITCH_PHASE: + if (currentPhase == PHASE_SLOW_DANCE) + { + StartFightPhase(PHASE_FAST_DANCE); + } + else + { + StartFightPhase(PHASE_SLOW_DANCE); + Talk(EMOTE_DANCE_END); // avoid play the emote on aggro + } + break; + case EVENT_ERUPT_SECTION: + if (pInstance) + { + pInstance->SetData(DATA_HEIGAN_ERUPTION, currentSection); + if (currentSection == 3) + { + moveRight = false; + } + else if (currentSection == 0) + { + moveRight = true; + } + moveRight ? currentSection++ : currentSection--; + } + if (currentPhase == PHASE_SLOW_DANCE) + { + Talk(SAY_TAUNT); + } + events.Repeat(currentPhase == PHASE_SLOW_DANCE ? 10s : 4s); + break; + case EVENT_SAFETY_DANCE: + { + Map::PlayerList const& pList = me->GetMap()->GetPlayers(); + for (const auto& itr : pList) + { + if (IsInRoom(itr.GetSource()) && !itr.GetSource()->IsAlive()) + { + pInstance->SetData(DATA_DANCE_FAIL, 0); + pInstance->SetData(DATA_IMMORTAL_FAIL, 0); + return; + } + } + events.Repeat(5s); + return; + } + } + DoMeleeAttackIfReady(); +} void AddSC_boss_heigan() { new boss_heigan(); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.h b/src/server/scripts/Northrend/Naxxramas/boss_heigan.h index 273dc766e..4758f4e6b 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.h +++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.h @@ -6,58 +6,18 @@ #include "ScriptedCreature.h" #include "naxxramas.h" -enum Says -{ - SAY_AGGRO = 0, - SAY_SLAY = 1, - SAY_TAUNT = 2, - EMOTE_DEATH = 3, - EMOTE_DANCE = 4, - EMOTE_DANCE_END = 5, - SAY_DANCE = 6 -}; -enum Spells -{ - SPELL_SPELL_DISRUPTION = 29310, - SPELL_DECREPIT_FEVER_10 = 29998, - SPELL_DECREPIT_FEVER_25 = 55011, - SPELL_PLAGUE_CLOUD = 29350, - SPELL_TELEPORT_SELF = 30211 -}; - -enum Events -{ - EVENT_DISRUPTION = 1, - EVENT_DECEPIT_FEVER = 2, - EVENT_ERUPT_SECTION = 3, - EVENT_SWITCH_PHASE = 4, - EVENT_SAFETY_DANCE = 5, - EVENT_PLAGUE_CLOUD = 6 -}; - -enum Misc -{ - PHASE_SLOW_DANCE = 0, - PHASE_FAST_DANCE = 1 -}; class boss_heigan : public CreatureScript { public: boss_heigan() : CreatureScript("boss_heigan") { } - CreatureAI* GetAI(Creature* pCreature) const override - { - return GetNaxxramasAI(pCreature); - } + CreatureAI* GetAI(Creature* pCreature) const override; struct boss_heiganAI : public BossAI { - explicit boss_heiganAI(Creature* c) : BossAI(c, BOSS_HEIGAN) - { - pInstance = me->GetInstanceScript(); - } + explicit boss_heiganAI(Creature* c); InstanceScript* pInstance; EventMap events; @@ -65,170 +25,19 @@ public: uint8 currentSection{}; bool moveRight{}; - void Reset() override - { - BossAI::Reset(); - events.Reset(); - currentPhase = 0; - currentSection = 3; - moveRight = true; - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HEIGAN_ENTER_GATE))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } - } + void Reset() override; - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() != TYPEID_PLAYER) - return; + void KilledUnit(Unit* who) override; - Talk(SAY_SLAY); - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } - } + void JustDied(Unit* killer) override; - void JustDied(Unit* killer) override - { - BossAI::JustDied(killer); - Talk(EMOTE_DEATH); - } + void JustEngagedWith(Unit* who) override; - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - me->SetInCombatWithZone(); - Talk(SAY_AGGRO); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_HEIGAN_ENTER_GATE))) - { - go->SetGoState(GO_STATE_READY); - } - } - StartFightPhase(PHASE_SLOW_DANCE); - } + void StartFightPhase(uint8 phase); - void StartFightPhase(uint8 phase) - { - currentSection = 3; - currentPhase = phase; - events.Reset(); - if (phase == PHASE_SLOW_DANCE) - { - me->CastStop(); - me->SetReactState(REACT_AGGRESSIVE); - DoZoneInCombat(); - events.ScheduleEvent(EVENT_DISRUPTION, 12s, 15s); - events.ScheduleEvent(EVENT_DECEPIT_FEVER, 17s); - events.ScheduleEvent(EVENT_ERUPT_SECTION, 15s); - events.ScheduleEvent(EVENT_SWITCH_PHASE, 90s); - } - else // if (phase == PHASE_FAST_DANCE) - { - Talk(EMOTE_DANCE); - Talk(SAY_DANCE); - me->AttackStop(); - me->StopMoving(); - me->SetReactState(REACT_PASSIVE); - me->CastSpell(me, SPELL_TELEPORT_SELF, false); - me->SetFacingTo(2.40f); - events.ScheduleEvent(EVENT_PLAGUE_CLOUD, 1s); - events.ScheduleEvent(EVENT_ERUPT_SECTION, 7s); - events.ScheduleEvent(EVENT_SWITCH_PHASE, 45s); - } - events.ScheduleEvent(EVENT_SAFETY_DANCE, 5s); - } + bool IsInRoom(Unit* who); - bool IsInRoom(Unit* who) - { - if (who->GetPositionX() > 2826 || who->GetPositionX() < 2723 || who->GetPositionY() > -3641 || who->GetPositionY() < -3736) - { - if (who->GetGUID() == me->GetGUID()) - EnterEvadeMode(); - - return false; - } - return true; - } - - void UpdateAI(uint32 diff) override - { - if (!IsInRoom(me)) - return; - - if (!UpdateVictim()) - return; - - events.Update(diff); - - switch (events.ExecuteEvent()) - { - case EVENT_DISRUPTION: - me->CastSpell(me, SPELL_SPELL_DISRUPTION, false); - events.Repeat(10s); - break; - case EVENT_DECEPIT_FEVER: - me->CastSpell(me, RAID_MODE(SPELL_DECREPIT_FEVER_10, SPELL_DECREPIT_FEVER_25), false); - events.Repeat(22s, 25s); - break; - case EVENT_PLAGUE_CLOUD: - me->CastSpell(me, SPELL_PLAGUE_CLOUD, false); - break; - case EVENT_SWITCH_PHASE: - if (currentPhase == PHASE_SLOW_DANCE) - { - StartFightPhase(PHASE_FAST_DANCE); - } - else - { - StartFightPhase(PHASE_SLOW_DANCE); - Talk(EMOTE_DANCE_END); // avoid play the emote on aggro - } - break; - case EVENT_ERUPT_SECTION: - if (pInstance) - { - pInstance->SetData(DATA_HEIGAN_ERUPTION, currentSection); - if (currentSection == 3) - { - moveRight = false; - } - else if (currentSection == 0) - { - moveRight = true; - } - moveRight ? currentSection++ : currentSection--; - } - if (currentPhase == PHASE_SLOW_DANCE) - { - Talk(SAY_TAUNT); - } - events.Repeat(currentPhase == PHASE_SLOW_DANCE ? 10s : 4s); - break; - case EVENT_SAFETY_DANCE: - { - Map::PlayerList const& pList = me->GetMap()->GetPlayers(); - for (const auto& itr : pList) - { - if (IsInRoom(itr.GetSource()) && !itr.GetSource()->IsAlive()) - { - pInstance->SetData(DATA_DANCE_FAIL, 0); - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - return; - } - } - events.Repeat(5s); - return; - } - } - DoMeleeAttackIfReady(); - } + void UpdateAI(uint32 diff) override; }; };