summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/sql/updates/pending_db_world/rev_1763435406973665500.sql2
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp158
2 files changed, 77 insertions, 83 deletions
diff --git a/data/sql/updates/pending_db_world/rev_1763435406973665500.sql b/data/sql/updates/pending_db_world/rev_1763435406973665500.sql
new file mode 100644
index 0000000000..9d20b40d25
--- /dev/null
+++ b/data/sql/updates/pending_db_world/rev_1763435406973665500.sql
@@ -0,0 +1,2 @@
+-- despawn on evade
+UPDATE `creature_template` SET `flags_extra` = `flags_extra`|0x80000000 WHERE `entry` IN (26631, 31350);
diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
index 277e951045..36f8b555c4 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
@@ -47,7 +47,7 @@ enum Spells
SPELL_COPY_OF_SUMMON_MINIONS = 59933,
SPELL_BLIZZARD = 49034,
SPELL_FROSTBOLT = 49037,
- SPELL_TOUCH_OF_MISERY = 50090
+ SPELL_WRATH_OF_MISERY = 50089
};
enum Misc
@@ -56,14 +56,7 @@ enum Misc
NPC_CRYSTAL_HANDLER = 26627,
NPC_SUMMON_CRYSTAL_HANDLER_TARGET = 27583,
- EVENT_SUMMON_FETID_TROLL = 1,
- EVENT_SUMMON_SHADOWCASTER = 2,
- EVENT_SUMMON_HULKING_CORPSE = 3,
- EVENT_SUMMON_CRYSTAL_HANDLER = 4,
- EVENT_CAST_OFFENSIVE_SPELL = 5,
- EVENT_KILL_TALK = 6,
- EVENT_CHECK_PHASE = 7,
- EVENT_SPELL_SUMMON_MINIONS = 8,
+ EVENT_KILL_TALK = 1,
ROOM_RIGHT = 0,
ROOM_LEFT = 1,
@@ -80,9 +73,7 @@ std::unordered_map<uint32, std::tuple <uint32, Position>> const npcSummon =
// 26631
struct boss_novos : public BossAI
{
- boss_novos(Creature* creature) : BossAI(creature, DATA_NOVOS)
- {
- }
+ boss_novos(Creature* creature) : BossAI(creature, DATA_NOVOS) { }
void Reset() override
{
@@ -120,16 +111,73 @@ struct boss_novos : public BossAI
{
Talk(SAY_AGGRO);
BossAI::JustEngagedWith(who);
+ scheduler.ClearValidator();
+
+ ScheduleTimedEvent(3s, [&] {
+ if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
+ trigger->CastSpell(trigger, SPELL_SUMMON_FETID_TROLL_CORPSE, true, nullptr, nullptr, me->GetGUID());
+ }, 3s);
+
+ ScheduleTimedEvent(9s, [&] {
+ if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
+ trigger->CastSpell(trigger, SPELL_SUMMON_RISEN_SHADOWCASTER, true, nullptr, nullptr, me->GetGUID());
+ }, 10s);
+
+ ScheduleTimedEvent(30s, [&] {
+ if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
+ trigger->CastSpell(trigger, SPELL_SUMMON_HULKING_CORPSE, true, nullptr, nullptr, me->GetGUID());
+ }, 30s);
+
+ scheduler.Schedule(70s, [this](TaskContext context) {
+ if (me->HasAura(SPELL_BEAM_CHANNEL))
+ {
+ context.Repeat(2s);
+ return;
+ }
+
+ scheduler.CancelAll();
+
+ me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->InterruptNonMeleeSpells(false);
+
+ scheduler.SetValidator([this] {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ });
+
+ ScheduleTimedEvent(5s, 10s, [&] {
+ DoCastRandomTarget(SPELL_BLIZZARD);
+ }, 12s, 25s);
+
+ ScheduleTimedEvent(5s, 10s, [&] {
+ DoCastRandomTarget(SPELL_WRATH_OF_MISERY);
+ }, 8s, 16s);
+
+ if (IsHeroic())
+ {
+ ScheduleTimedEvent(10s, [&] {
+ DoCastAOE(SPELL_SUMMON_MINIONS);
+ }, 37s, 55s);
+ }
+ });
+
+ for (Seconds timer : { 16s, 32s, 48s, 64s })
+ {
+ me->m_Events.AddEventAtOffset([&] {
+ Talk(SAY_SUMMONING_ADDS);
+ Talk(EMOTE_SUMMONING_ADDS);
+ if (Creature* target = ObjectAccessor::GetCreature(*me, _stage ? _summonTargetLeftGUID : _summonTargetRightGUID))
+ target->CastSpell(target, SPELL_SUMMON_CRYSTAL_HANDLER, true, nullptr, nullptr, me->GetGUID());
+ _stage = _stage ? 0 : 1;
+ }, timer);
+ }
- events.ScheduleEvent(EVENT_SUMMON_FETID_TROLL, 3s);
- events.ScheduleEvent(EVENT_SUMMON_SHADOWCASTER, 9s);
- events.ScheduleEvent(EVENT_SUMMON_HULKING_CORPSE, 30s);
- events.ScheduleEvent(EVENT_SUMMON_CRYSTAL_HANDLER, 20s);
- events.ScheduleEvent(EVENT_CHECK_PHASE, 80s);
+ me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty);
+ me->RemoveAllAuras();
+ me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->CastSpell(me, SPELL_ARCANE_BLAST, true);
- me->CastSpell(me, SPELL_ARCANE_FIELD, true);
- me->CastSpell(me, SPELL_DESPAWN_CRYSTAL_HANDLER, true);
+ DoCastSelf(SPELL_ARCANE_BLAST, true);
+ DoCastSelf(SPELL_ARCANE_FIELD, true);
+ DoCastSelf(SPELL_DESPAWN_CRYSTAL_HANDLER, true);
for (auto& itr : npcSummon)
{
@@ -147,11 +195,6 @@ struct boss_novos : public BossAI
break;
}
}
-
- me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty);
- me->RemoveAllAuras();
- me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
void JustDied(Unit* killer) override
@@ -182,6 +225,9 @@ struct boss_novos : public BossAI
if (summon->GetEntry() == NPC_FETID_TROLL_CORPSE)
summon->GetMotionMaster()->MovePoint(1, -373.56f, -770.86f, 28.59f);
+
+ if (summon->EntryEquals(NPC_CRYSTAL_HANDLER))
+ summon->SetInCombatWithZone();
}
// Phase 2
else if (summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET)
@@ -211,65 +257,11 @@ struct boss_novos : public BossAI
if (!UpdateVictim())
return;
+ scheduler.Update(diff);
events.Update(diff);
- switch (events.ExecuteEvent())
- {
- case EVENT_SUMMON_FETID_TROLL:
- if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
- trigger->CastSpell(trigger, SPELL_SUMMON_FETID_TROLL_CORPSE, true, nullptr, nullptr, me->GetGUID());
- events.ScheduleEvent(EVENT_SUMMON_FETID_TROLL, 3s);
- break;
- case EVENT_SUMMON_HULKING_CORPSE:
- if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
- trigger->CastSpell(trigger, SPELL_SUMMON_HULKING_CORPSE, true, nullptr, nullptr, me->GetGUID());
- events.ScheduleEvent(EVENT_SUMMON_HULKING_CORPSE, 30s);
- break;
- case EVENT_SUMMON_SHADOWCASTER:
- if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
- trigger->CastSpell(trigger, SPELL_SUMMON_RISEN_SHADOWCASTER, true, nullptr, nullptr, me->GetGUID());
- events.ScheduleEvent(EVENT_SUMMON_SHADOWCASTER, 10s);
- break;
- case EVENT_SUMMON_CRYSTAL_HANDLER:
- if (_crystalCounter++ < 4)
- {
- Talk(SAY_SUMMONING_ADDS);
- Talk(EMOTE_SUMMONING_ADDS);
- if (Creature* target = ObjectAccessor::GetCreature(*me, _stage ? _summonTargetLeftGUID : _summonTargetRightGUID))
- target->CastSpell(target, SPELL_SUMMON_CRYSTAL_HANDLER, true, nullptr, nullptr, me->GetGUID());
- _stage = _stage ? 0 : 1;
- events.ScheduleEvent(EVENT_SUMMON_CRYSTAL_HANDLER, 20s);
- }
- break;
- case EVENT_CHECK_PHASE:
- if (me->HasAura(SPELL_BEAM_CHANNEL))
- {
- events.ScheduleEvent(EVENT_CHECK_PHASE, 2s);
- break;
- }
- events.Reset();
- events.ScheduleEvent(EVENT_CAST_OFFENSIVE_SPELL, 3s);
- events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 10s);
- me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->InterruptNonMeleeSpells(false);
- break;
- case EVENT_CAST_OFFENSIVE_SPELL:
- if (!me->HasUnitState(UNIT_STATE_CASTING))
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
- me->CastSpell(target, RAND(SPELL_BLIZZARD, SPELL_FROSTBOLT, SPELL_TOUCH_OF_MISERY), false);
-
- events.ScheduleEvent(EVENT_CAST_OFFENSIVE_SPELL, 500ms);
- break;
- case EVENT_SPELL_SUMMON_MINIONS:
- if (me->HasUnitState(UNIT_STATE_CASTING))
- {
- me->CastSpell(me, SPELL_SUMMON_MINIONS, false);
- events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 15s);
- break;
- }
- events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 500ms);
- break;
- }
+
+ if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
+ DoSpellAttackIfReady(SPELL_FROSTBOLT);
}
bool CheckEvadeIfOutOfCombatArea() const override