aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoroffl <11556157+offl@users.noreply.github.com>2021-04-13 10:30:56 +0300
committerGitHub <noreply@github.com>2021-04-13 09:30:56 +0200
commit7dc1d5c5a1fad174e35dabb261431969f3db686a (patch)
treeb9ac3f8fe01c0ca3770ff1f2a7aea1ed897c21dd /src
parentcb82cded17f49c7736012f226c542c2240bbf7a4 (diff)
Scripts/Naxxramas: Update Noth to new model (#26387)
Co-authored-by: offl <offl@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_noth.cpp435
1 files changed, 212 insertions, 223 deletions
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
index 0a8d6473e72..dd72982a514 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
@@ -73,268 +73,257 @@ const uint32 SummonGuardianSpells[N_GUARDIAN_SPELLS] = { 29239, 29256, 29268 };
#define SPELL_BLINK RAND(29208, 29209, 29210, 29211)
-class boss_noth : public CreatureScript
+struct boss_noth : public BossAI
{
-public:
- boss_noth() : CreatureScript("boss_noth") { }
-
- struct boss_nothAI : public BossAI
+ boss_noth(Creature* creature) : BossAI(creature, BOSS_NOTH), balconyCount(0), justBlinked(false)
{
- boss_nothAI(Creature* creature) : BossAI(creature, BOSS_NOTH), balconyCount(0), justBlinked(false)
- {
- std::copy(SummonWarriorSpells, SummonWarriorSpells + N_WARRIOR_SPELLS, _SummonWarriorSpells);
- std::copy(SummonChampionSpells, SummonChampionSpells + N_CHAMPION_SPELLS, _SummonChampionSpells);
- std::copy(SummonGuardianSpells, SummonGuardianSpells + N_GUARDIAN_SPELLS, _SummonGuardianSpells);
+ std::copy(SummonWarriorSpells, SummonWarriorSpells + N_WARRIOR_SPELLS, _SummonWarriorSpells);
+ std::copy(SummonChampionSpells, SummonChampionSpells + N_CHAMPION_SPELLS, _SummonChampionSpells);
+ std::copy(SummonGuardianSpells, SummonGuardianSpells + N_GUARDIAN_SPELLS, _SummonGuardianSpells);
- events.SetPhase(PHASE_NONE);
- }
+ events.SetPhase(PHASE_NONE);
+ }
- void EnterEvadeMode(EvadeReason why) override
- {
- // in case we reset during balcony phase
- if (events.IsInPhase(PHASE_BALCONY))
- DoCastAOE(SPELL_TELEPORT_BACK);
- BossAI::EnterEvadeMode(why);
- }
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ // in case we reset during balcony phase
+ if (events.IsInPhase(PHASE_BALCONY))
+ DoCastAOE(SPELL_TELEPORT_BACK);
+ BossAI::EnterEvadeMode(why);
+ }
- void Reset() override
- {
- _Reset();
+ void Reset() override
+ {
+ _Reset();
- me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- balconyCount = 0;
- events.SetPhase(PHASE_NONE);
- justBlinked = false;
- }
+ balconyCount = 0;
+ events.SetPhase(PHASE_NONE);
+ justBlinked = false;
+ }
- void JustEngagedWith(Unit* who) override
- {
- BossAI::JustEngagedWith(who);
- Talk(SAY_AGGRO);
- EnterPhaseGround();
- }
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+ Talk(SAY_AGGRO);
+ EnterPhaseGround();
+ }
- void EnterPhaseGround()
- {
- events.SetPhase(PHASE_GROUND);
+ void EnterPhaseGround()
+ {
+ events.SetPhase(PHASE_GROUND);
- DoZoneInCombat();
+ DoZoneInCombat();
- if (!me->IsThreatened())
- EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
- else
+ if (!me->IsThreatened())
+ EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
+ else
+ {
+ uint8 timeGround;
+ switch (balconyCount)
{
- uint8 timeGround;
- switch (balconyCount)
- {
- case 0:
- timeGround = 90;
- break;
- case 1:
- timeGround = 110;
- break;
- case 2:
- default:
- timeGround = 180;
- }
- events.ScheduleEvent(EVENT_GROUND_ATTACKABLE, Seconds(2), 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_BALCONY, Seconds(timeGround), 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_CURSE, randtime(Seconds(10), Seconds(25)), 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_WARRIOR, randtime(Seconds(20), Seconds(30)), 0, PHASE_GROUND);
- if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
- events.ScheduleEvent(EVENT_BLINK, randtime(Seconds(20), Seconds(30)), 0, PHASE_GROUND);
+ case 0:
+ timeGround = 90;
+ break;
+ case 1:
+ timeGround = 110;
+ break;
+ case 2:
+ default:
+ timeGround = 180;
}
+ events.ScheduleEvent(EVENT_GROUND_ATTACKABLE, Seconds(2), 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_BALCONY, Seconds(timeGround), 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_CURSE, randtime(Seconds(10), Seconds(25)), 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_WARRIOR, randtime(Seconds(20), Seconds(30)), 0, PHASE_GROUND);
+ if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ events.ScheduleEvent(EVENT_BLINK, randtime(Seconds(20), Seconds(30)), 0, PHASE_GROUND);
}
+ }
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_SLAY);
- }
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
- void JustSummoned(Creature* summon) override
- {
- summons.Summon(summon);
- summon->setActive(true);
- summon->SetFarVisible(true);
- summon->AI()->DoZoneInCombat();
- }
+ void JustSummoned(Creature* summon) override
+ {
+ summons.Summon(summon);
+ summon->setActive(true);
+ summon->SetFarVisible(true);
+ summon->AI()->DoZoneInCombat();
+ }
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
- Talk(SAY_DEATH);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+ }
- void DamageTaken(Unit* /*who*/, uint32& damage) override // prevent noth from somehow dying in the balcony phase
- {
- if (!events.IsInPhase(PHASE_BALCONY))
- return;
- if (damage < me->GetHealth())
- return;
+ void DamageTaken(Unit* /*who*/, uint32& damage) override // prevent noth from somehow dying in the balcony phase
+ {
+ if (!events.IsInPhase(PHASE_BALCONY))
+ return;
+ if (damage < me->GetHealth())
+ return;
- me->SetHealth(1u);
- damage = 0u;
- }
+ me->SetHealth(1u);
+ damage = 0u;
+ }
- void HandleSummon(uint32* spellsList, const uint8 nSpells, uint8 num)
- { // this ensures we do not spawn two mobs using the same spell (<=> in the same position) if we can help it
- while (num)
- for (uint8 it = 0; it < nSpells && num; ++it)
- {
- num--;
- uint8 selected = urand(it, nSpells - 1);
- DoCastAOE(spellsList[selected]);
- if (selected != it) // shuffle the selected into the part of the array that is no longer being searched
- std::swap(spellsList[selected], spellsList[it]);
- }
- }
+ void HandleSummon(uint32* spellsList, const uint8 nSpells, uint8 num)
+ { // this ensures we do not spawn two mobs using the same spell (<=> in the same position) if we can help it
+ while (num)
+ for (uint8 it = 0; it < nSpells && num; ++it)
+ {
+ num--;
+ uint8 selected = urand(it, nSpells - 1);
+ DoCastAOE(spellsList[selected]);
+ if (selected != it) // shuffle the selected into the part of the array that is no longer being searched
+ std::swap(spellsList[selected], spellsList[it]);
+ }
+ }
- void CastSummon(uint8 nWarrior, uint8 nChampion, uint8 nGuardian)
- {
- HandleSummon(_SummonWarriorSpells, N_WARRIOR_SPELLS, nWarrior);
- HandleSummon(_SummonChampionSpells, N_CHAMPION_SPELLS, nChampion);
- HandleSummon(_SummonGuardianSpells, N_GUARDIAN_SPELLS, nGuardian);
- }
+ void CastSummon(uint8 nWarrior, uint8 nChampion, uint8 nGuardian)
+ {
+ HandleSummon(_SummonWarriorSpells, N_WARRIOR_SPELLS, nWarrior);
+ HandleSummon(_SummonChampionSpells, N_CHAMPION_SPELLS, nChampion);
+ HandleSummon(_SummonGuardianSpells, N_GUARDIAN_SPELLS, nGuardian);
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- events.Update(diff);
+ events.Update(diff);
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- while (uint32 eventId = events.ExecuteEvent())
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- switch (eventId)
+ case EVENT_CURSE:
{
- case EVENT_CURSE:
+ DoCastAOE(SPELL_CURSE);
+ events.Repeat(randtime(Seconds(50), Seconds(70)));
+ break;
+ }
+ case EVENT_WARRIOR:
+ Talk(SAY_SUMMON);
+ Talk(EMOTE_SUMMON);
+
+ CastSummon(RAID_MODE(2, 3), 0, 0);
+
+ events.Repeat(Seconds(40));
+ break;
+ case EVENT_BLINK:
+ DoCastAOE(SPELL_CRIPPLE, true);
+ DoCastAOE(SPELL_BLINK);
+ ResetThreatList();
+ justBlinked = true;
+
+ events.Repeat(Seconds(40));
+ break;
+ case EVENT_BALCONY:
+ events.SetPhase(PHASE_BALCONY);
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->AttackStop();
+ me->StopMoving();
+ me->RemoveAllAuras();
+
+ events.ScheduleEvent(EVENT_BALCONY_TELEPORT, Seconds(3), 0, PHASE_BALCONY);
+ events.ScheduleEvent(EVENT_WAVE, randtime(Seconds(5), Seconds(8)), 0, PHASE_BALCONY);
+
+ uint8 timeBalcony;
+ switch (balconyCount)
{
- DoCastAOE(SPELL_CURSE);
- events.Repeat(randtime(Seconds(50), Seconds(70)));
- break;
+ case 0:
+ timeBalcony = 70;
+ break;
+ case 1:
+ timeBalcony = 97;
+ break;
+ case 2:
+ default:
+ timeBalcony = 120;
+ break;
}
- case EVENT_WARRIOR:
- Talk(SAY_SUMMON);
- Talk(EMOTE_SUMMON);
-
- CastSummon(RAID_MODE(2, 3), 0, 0);
-
- events.Repeat(Seconds(40));
- break;
- case EVENT_BLINK:
- DoCastAOE(SPELL_CRIPPLE, true);
- DoCastAOE(SPELL_BLINK);
- ResetThreatList();
- justBlinked = true;
-
- events.Repeat(Seconds(40));
- break;
- case EVENT_BALCONY:
- events.SetPhase(PHASE_BALCONY);
- me->SetReactState(REACT_PASSIVE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->AttackStop();
- me->StopMoving();
- me->RemoveAllAuras();
-
- events.ScheduleEvent(EVENT_BALCONY_TELEPORT, Seconds(3), 0, PHASE_BALCONY);
- events.ScheduleEvent(EVENT_WAVE, randtime(Seconds(5), Seconds(8)), 0, PHASE_BALCONY);
-
- uint8 timeBalcony;
- switch (balconyCount)
- {
- case 0:
- timeBalcony = 70;
- break;
- case 1:
- timeBalcony = 97;
- break;
- case 2:
- default:
- timeBalcony = 120;
- break;
- }
- events.ScheduleEvent(EVENT_GROUND, Seconds(timeBalcony), 0, PHASE_BALCONY);
- break;
- case EVENT_BALCONY_TELEPORT:
- Talk(EMOTE_TELEPORT_1);
- DoCastAOE(SPELL_TELEPORT);
- break;
- case EVENT_WAVE:
- Talk(EMOTE_SUMMON_WAVE);
- switch (balconyCount)
- {
- case 0:
- CastSummon(0, RAID_MODE(2, 4), 0);
- break;
- case 1:
- CastSummon(0, RAID_MODE(1, 2), RAID_MODE(1, 2));
- break;
- case 2:
- CastSummon(0, 0, RAID_MODE(2, 4));
- break;
- default:
- CastSummon(0, RAID_MODE(5, 10), RAID_MODE(5, 10));
- break;
- }
- events.Repeat(randtime(Seconds(30), Seconds(45)));
- break;
- case EVENT_GROUND:
- ++balconyCount;
-
- DoCastAOE(SPELL_TELEPORT_BACK);
- Talk(EMOTE_TELEPORT_2);
-
- EnterPhaseGround();
- break;
- case EVENT_GROUND_ATTACKABLE:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- break;
- }
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ events.ScheduleEvent(EVENT_GROUND, Seconds(timeBalcony), 0, PHASE_BALCONY);
+ break;
+ case EVENT_BALCONY_TELEPORT:
+ Talk(EMOTE_TELEPORT_1);
+ DoCastAOE(SPELL_TELEPORT);
+ break;
+ case EVENT_WAVE:
+ Talk(EMOTE_SUMMON_WAVE);
+ switch (balconyCount)
+ {
+ case 0:
+ CastSummon(0, RAID_MODE(2, 4), 0);
+ break;
+ case 1:
+ CastSummon(0, RAID_MODE(1, 2), RAID_MODE(1, 2));
+ break;
+ case 2:
+ CastSummon(0, 0, RAID_MODE(2, 4));
+ break;
+ default:
+ CastSummon(0, RAID_MODE(5, 10), RAID_MODE(5, 10));
+ break;
+ }
+ events.Repeat(randtime(Seconds(30), Seconds(45)));
+ break;
+ case EVENT_GROUND:
+ ++balconyCount;
+
+ DoCastAOE(SPELL_TELEPORT_BACK);
+ Talk(EMOTE_TELEPORT_2);
+
+ EnterPhaseGround();
+ break;
+ case EVENT_GROUND_ATTACKABLE:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
}
- if (events.IsInPhase(PHASE_GROUND))
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
+
+ if (events.IsInPhase(PHASE_GROUND))
+ {
+ /* workaround for movechase breaking after blinking
+ without this noth would just stand there unless his current target moves */
+ if (justBlinked && me->GetVictim() && !me->IsWithinMeleeRange(me->EnsureVictim()))
{
- /* workaround for movechase breaking after blinking
- without this noth would just stand there unless his current target moves */
- if (justBlinked && me->GetVictim() && !me->IsWithinMeleeRange(me->EnsureVictim()))
- {
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveChase(me->EnsureVictim());
- justBlinked = false;
- }
- else
- DoMeleeAttackIfReady();
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveChase(me->EnsureVictim());
+ justBlinked = false;
}
+ else
+ DoMeleeAttackIfReady();
}
+ }
- private:
- uint32 balconyCount;
-
- bool justBlinked;
+ private:
+ uint32 balconyCount;
- uint32 _SummonWarriorSpells[N_WARRIOR_SPELLS];
- uint32 _SummonChampionSpells[N_CHAMPION_SPELLS];
- uint32 _SummonGuardianSpells[N_GUARDIAN_SPELLS];
- };
+ bool justBlinked;
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetNaxxramasAI<boss_nothAI>(creature);
- }
+ uint32 _SummonWarriorSpells[N_WARRIOR_SPELLS];
+ uint32 _SummonChampionSpells[N_CHAMPION_SPELLS];
+ uint32 _SummonGuardianSpells[N_GUARDIAN_SPELLS];
};
void AddSC_boss_noth()
{
- new boss_noth();
+ RegisterNaxxramasCreatureAI(boss_noth);
}