aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoroffl <11556157+offl@users.noreply.github.com>2025-11-08 17:20:20 +0200
committerGitHub <noreply@github.com>2025-11-08 16:20:20 +0100
commit806a44526d3787ec5c9bb9931f46947d29c0cd6f (patch)
treea3ef30657fda744f9f85e5408df17dd97156616a /src
parentd1a2f20b56aebc220b48560dfcd0e6bb72e90f7e (diff)
Scripts/Sunwell Plateau: Rewrite M'uru (#31323)
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp1007
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h11
3 files changed, 710 insertions, 309 deletions
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
index 44c339f8310..0d0c98871ed 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
@@ -15,166 +15,327 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/*
+ * Combat timers requires to be revisited
+ * Singularity may be much trickier:
+ 1. Check if singularity should change targets
+ 2. Check if despawn timer depends on how much targets singularity hits by passive spells
+ * Check if Dark Fiend should change target
+ * Berserk for Entropius should be triggered from Entropius' AI since M'uru originally despawns after summoning Entropius,
+ NYI, currently triggered from M'uru's AI
+ */
+
#include "ScriptMgr.h"
#include "InstanceScript.h"
-#include "ObjectAccessor.h"
+#include "MotionMaster.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
+#include "SpellInfo.h"
#include "SpellScript.h"
#include "sunwell_plateau.h"
-enum Spells
+enum MuruSpells
{
- // Muru's spells
+ // M'uru - Initial
SPELL_OPEN_PORTAL_PERIODIC = 45994,
SPELL_DARKNESS_PERIODIC = 45998,
SPELL_NEGATIVE_ENERGY_PERIODIC = 46009,
- SPELL_SUMMON_VOID_SPAWN = 46071,
- SPELL_SUMMON_BLOOD_ELVES_SCRIPT = 46050,
SPELL_SUMMON_BLOOD_ELVES_PERIODIC = 46041,
+
+ // M'uru - Combat
+ SPELL_BERSERK = 26662,
+
+ // M'uru - Transition
SPELL_OPEN_ALL_PORTALS = 46177,
SPELL_SUMMON_ENTROPIUS = 46217,
- SPELL_ENRAGE = 26662,
- SPELL_SUMMON_DARK_FIEND_0 = 46000,
- SPELL_SUMMON_DARK_FIEND_1 = 46001,
- SPELL_SUMMON_DARK_FIEND_2 = 46002,
- SPELL_SUMMON_DARK_FIEND_3 = 46003,
- SPELL_SUMMON_DARK_FIEND_4 = 46004,
- SPELL_SUMMON_DARK_FIEND_5 = 46005,
- SPELL_SUMMON_DARK_FIEND_6 = 46006,
- SPELL_SUMMON_DARK_FIEND_7 = 46007,
- SPELL_SUMMON_BERSERKER = 46037,
- SPELL_SUMMON_BERSERKER_2 = 46040,
- SPELL_SUMMON_FURY_MAGE = 46038,
- SPELL_SUMMON_FURY_MAGE_2 = 46039,
- // Entropius's spells
+ // Entropius - Initial
SPELL_ENTROPIUS_COSMETIC_SPAWN = 46223,
- SPELL_DARKNESS_E = 46269,
SPELL_NEGATIVE_ENERGY_PERIODIC_E = 46284,
- SPELL_NEGATIVE_ENERGY_DAMAGE = 46285,
- SPELL_BLACKHOLE = 46282,
- SPELL_SUMMON_DARKFIEND_E = 46263,
- // Myruu's Portal Target
+ // Entropius - Combat
+ SPELL_DARKNESS = 46269,
+ SPELL_BLACK_HOLE = 46282,
+
+ // M'uru Portal Target
+ SPELL_OPEN_PORTAL = 45976,
+ SPELL_OPEN_PORTAL_VISUAL = 45977,
SPELL_SUMMON_VOID_SENTINEL_SUMMONER = 45978,
SPELL_SUMMON_VOID_SENTINEL_SUMMONER_VISUAL = 45989,
- SPELL_SUMMON_VOID_SENTINEL = 45988,
SPELL_TRANSFORM_VISUAL_MISSILE = 46205,
- TRANSFORM_VISUAL_MISSILE_1 = 46208,
- TRANSFORM_VISUAL_MISSILE_2 = 46178,
- SPELL_OPEN_PORTAL = 45977,
- SPELL_OPEN_PORTAL_2 = 45976,
- //Dark Fiend Spells
- SPELL_DARKFIEND_DAMAGE = 45944,
- SPELL_DARKFIEND_VISUAL = 45936,
- SPELL_DARKFIEND_SKIN = 45934,
+ // Void Sentinel Summoner
+ SPELL_SUMMON_VOID_SENTINEL = 45988,
- // Void Sentinel's spells
+ // Void Sentinel
SPELL_SHADOW_PULSE_PERIODIC = 46086,
SPELL_VOID_BLAST = 46161,
+ SPELL_SUMMON_VOID_SPAWN = 46071,
+
+ // Void Spawn
+ SPELL_SHADOW_BOLT_VOLLEY = 46082,
+
+ // Dark Fiend
+ SPELL_DARK_FIEND_MAGIC = 45934,
+ SPELL_DARK_FIEND_VISUAL = 45936,
+ SPELL_DARK_FIEND_TRAP = 45943,
+ SPELL_DARK_FIEND_DAMAGE = 45944,
+
+ // Darkness
+ SPELL_VOID_ZONE_PRE_EFFECT_VISUAL = 46265,
+ SPELL_VOID_ZONE_PERIODIC = 46262,
+ SPELL_SUMMON_DARK_FIEND = 46263,
+
+ // Singularity
+ SPELL_BLACK_HOLE_SUMMON_VISUAL = 46242,
+ SPELL_BLACK_HOLE_SUMMON_VISUAL_2 = 46247,
+ SPELL_BLACK_HOLE_PASSIVE = 46228,
+ SPELL_BLACK_HOLE_VISUAL_2 = 46235,
+
+ // Shadowsword Berserker
+ SPELL_DUAL_WIELD_PASSIVE = 42459,
+ SPELL_FLURRY = 46160,
+
+ // Shadowsword Fury Mage
+ SPELL_FEL_FIREBALL = 46101,
+ SPELL_SPELL_FURY = 46102,
+
+ // Scripts
+ SPELL_SUMMON_BLOOD_ELVES_SCRIPT = 46050,
+
+ SPELL_SUMMON_BERSERKER_1 = 46037,
+ SPELL_SUMMON_BERSERKER_2 = 46040,
+ SPELL_SUMMON_FURY_MAGE_1 = 46038,
+ SPELL_SUMMON_FURY_MAGE_2 = 46039,
- //Black Hole Spells
- SPELL_BLACKHOLE_SUMMON_VISUAL = 46242,
- SPELL_BLACKHOLE_SUMMON_VISUAL_2 = 46247,
- SPELL_BLACKHOLE_PASSIVE = 46228,
- SPELL_BLACK_HOLE_VISUAL_2 = 46235
+ SPELL_SUMMON_DARK_FIEND_1 = 46000,
+ SPELL_SUMMON_DARK_FIEND_2 = 46001,
+ SPELL_SUMMON_DARK_FIEND_3 = 46002,
+ SPELL_SUMMON_DARK_FIEND_4 = 46003,
+ SPELL_SUMMON_DARK_FIEND_5 = 46004,
+ SPELL_SUMMON_DARK_FIEND_6 = 46005,
+ SPELL_SUMMON_DARK_FIEND_7 = 46006,
+ SPELL_SUMMON_DARK_FIEND_8 = 46007,
+
+ SPELL_TRANSFORM_VISUAL_MISSILE_1 = 46178,
+ SPELL_TRANSFORM_VISUAL_MISSILE_2 = 46208,
+
+ SPELL_NEGATIVE_ENERGY_DAMAGE = 46285
};
-enum Phases
+enum MuruEvents
{
- PHASE_ONE = 1,
- PHASE_TWO = 2
+ // M'uru
+ EVENT_SUMMON_BLOOD_ELVES = 1,
+ EVENT_SUMMON_ENTROPIUS,
+ EVENT_SET_INVISIBLE,
+ EVENT_BERSERK,
+
+ // Entropius
+ EVENT_SPAWN_1,
+ EVENT_SPAWN_2,
+ EVENT_DARKNESS,
+ EVENT_BLACK_HOLE
};
-enum Misc
+enum MuruMisc
{
+ ACTION_BERSERK = 0,
+ ACTION_DISPELLED_MAGIC = 1,
+ ACTION_CANCEL_SUMMON = 2,
MAX_VOID_SPAWNS = 6,
- MAX_SUMMON_BLOOD_ELVES = 4,
- MAX_SUMMON_DARK_FIEND = 8
+ NPC_WORLD_TRIGGER_MOVE_TO = 22515,
+ POINT_ROOM = 0
};
-uint32 const SummonDarkFiendSpells[MAX_SUMMON_DARK_FIEND] =
+static constexpr std::array<uint32, 8> SummonDarkFiendSpells =
{
- SPELL_SUMMON_DARK_FIEND_0,
SPELL_SUMMON_DARK_FIEND_1,
SPELL_SUMMON_DARK_FIEND_2,
SPELL_SUMMON_DARK_FIEND_3,
SPELL_SUMMON_DARK_FIEND_4,
SPELL_SUMMON_DARK_FIEND_5,
SPELL_SUMMON_DARK_FIEND_6,
- SPELL_SUMMON_DARK_FIEND_7
+ SPELL_SUMMON_DARK_FIEND_7,
+ SPELL_SUMMON_DARK_FIEND_8
};
-uint32 const SummonBloodElvesSpells[MAX_SUMMON_BLOOD_ELVES] =
+void DoResetPortals(Creature* creature)
{
- SPELL_SUMMON_BERSERKER,
- SPELL_SUMMON_BERSERKER_2,
- SPELL_SUMMON_FURY_MAGE,
- SPELL_SUMMON_FURY_MAGE_2
-};
+ std::vector<Creature*> portals;
+ GetCreatureListWithEntryInGrid(portals, creature, NPC_MURU_PORTAL_TARGET, 100.0f);
+ for (Creature* portal : portals)
+ portal->RemoveAllAuras();
+}
+
+void DoDespawnSummons(Creature* creature)
+{
+ std::vector<Creature*> spawns;
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_ENTROPIUS, 250.0f);
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_VOID_SENTINEL_SUMMONER, 250.0f);
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_VOID_SENTINEL, 250.0f);
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_VOID_SPAWN, 250.0f);
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_DARK_FIEND, 250.0f);
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_DARKNESS, 250.0f);
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_SINGULARITY, 250.0f);
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_BERSERKER, 250.0f);
+ GetCreatureListWithEntryInGrid(spawns, creature, NPC_FURY_MAGE, 250.0f);
+ for (Creature* spawn : spawns)
+ spawn->DespawnOrUnsummon();
+
+ std::vector<Creature*> portals;
+ GetCreatureListWithEntryInGrid(portals, creature, NPC_MURU_PORTAL_TARGET, 100.0f);
+ for (Creature* portal : portals)
+ portal->AI()->DoAction(ACTION_CANCEL_SUMMON);
+}
-class VoidSpawnSummon : public BasicEvent
+// 25741 - M'uru
+struct boss_muru : public BossAI
{
- public:
- explicit VoidSpawnSummon(Creature* owner)
- : _owner(owner)
+ boss_muru(Creature* creature) : BossAI(creature, DATA_MURU), _isBerserkTriggered(false), _isInTransition(false) { }
+
+ void Reset() override
+ {
+ _Reset();
+
+ _isBerserkTriggered = false;
+ _isInTransition = false;
+ }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+
+ DoCastSelf(SPELL_OPEN_PORTAL_PERIODIC);
+ DoCastSelf(SPELL_DARKNESS_PERIODIC);
+ DoCastSelf(SPELL_NEGATIVE_ENERGY_PERIODIC);
+
+ me->SetReactState(REACT_PASSIVE);
+
+ events.ScheduleEvent(EVENT_SUMMON_BLOOD_ELVES, 5s);
+ events.ScheduleEvent(EVENT_BERSERK, 10min);
+ }
+
+ void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (damage >= me->GetHealth())
{
+ damage = me->GetHealth() - 1;
+
+ if (_isInTransition)
+ return;
+
+ _isInTransition = true;
+ me->RemoveAurasDueToSpell(SPELL_SUMMON_BLOOD_ELVES_PERIODIC);
+ me->RemoveAurasDueToSpell(SPELL_NEGATIVE_ENERGY_PERIODIC);
+ me->RemoveAurasDueToSpell(SPELL_DARKNESS_PERIODIC);
+ me->RemoveAurasDueToSpell(SPELL_OPEN_PORTAL_PERIODIC);
+ DoCastSelf(SPELL_OPEN_ALL_PORTALS);
+ me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ events.CancelEvent(EVENT_SUMMON_BLOOD_ELVES);
+ events.ScheduleEvent(EVENT_SUMMON_ENTROPIUS, 6s);
}
+ }
+
+ void OnSpellCast(SpellInfo const* spell) override
+ {
+ if (spell->Id == SPELL_SUMMON_ENTROPIUS)
+ /// @todo: Temporarily replaced with SetVisible. Otherwise we will be not able to respawn M'uru in case of wipe
+ /// me->DespawnOrUnsummon(1500ms);
+ events.ScheduleEvent(EVENT_SET_INVISIBLE, 1500ms);
+ }
+
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ DoResetPortals(me);
+ DoDespawnSummons(me);
+ _DespawnAtEvade();
+ }
+
+ // Do not store anything, despawn is handled in DoDespawnSummons
+ void JustSummoned(Creature* summon) override
+ {
+ if (summon->GetEntry() == NPC_ENTROPIUS)
+ if (_isBerserkTriggered)
+ summon->AI()->DoAction(ACTION_BERSERK);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- _owner->CastSpell(nullptr, SPELL_SUMMON_VOID_SENTINEL, true);
- return true;
+ switch (eventId)
+ {
+ case EVENT_SUMMON_BLOOD_ELVES:
+ DoCastSelf(SPELL_SUMMON_BLOOD_ELVES_PERIODIC);
+ break;
+ case EVENT_SUMMON_ENTROPIUS:
+ DoCastSelf(SPELL_SUMMON_ENTROPIUS);
+ break;
+ case EVENT_SET_INVISIBLE:
+ me->SetVisible(false);
+ break;
+ case EVENT_BERSERK:
+ {
+ _isBerserkTriggered = true;
+ DoCastSelf(SPELL_BERSERK);
+
+ if (Creature* entropius = instance->GetCreature(DATA_ENTROPIUS))
+ entropius->AI()->DoAction(ACTION_BERSERK);
+ break;
+ }
+ default:
+ break;
+ }
}
+ }
- private:
- Creature* _owner;
+private:
+ bool _isBerserkTriggered;
+ bool _isInTransition;
};
+// 25840 - Entropius
struct boss_entropius : public BossAI
{
boss_entropius(Creature* creature) : BossAI(creature, DATA_MURU) { }
- void Reset() override
+ void InitializeAI() override
{
- _Reset();
- DoCast(me, SPELL_ENTROPIUS_COSMETIC_SPAWN, true);
+ me->SetReactState(REACT_PASSIVE);
}
- void ScheduleTasks() override
+ void JustAppeared() override
{
- scheduler.Schedule(Milliseconds(2000), [this](TaskContext /*context*/)
- {
- DoResetPortals();
- DoCastAOE(SPELL_NEGATIVE_ENERGY_PERIODIC_E, true);
- });
+ DoCastSelf(SPELL_ENTROPIUS_COSMETIC_SPAWN);
- scheduler.Schedule(Seconds(15), [this](TaskContext context)
- {
- DoCastAOE(SPELL_DARKNESS_E, true);
- DoCastAOE(SPELL_BLACKHOLE, true);
+ events.ScheduleEvent(EVENT_SPAWN_1, 1500ms);
+ }
- context.Repeat();
- });
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+
+ events.ScheduleEvent(EVENT_DARKNESS, 10s, 15s);
+ events.ScheduleEvent(EVENT_BLACK_HOLE, 10s, 15s);
}
- void JustSummoned(Creature* summon) override
+ // Do not store anything, despawn is handled in DoDespawnSummons
+ void JustSummoned(Creature* /*summon*/) override { }
+
+ void DoAction(int32 action) override
{
- switch (summon->GetEntry())
- {
- case NPC_DARK_FIENDS:
- summon->CastSpell(summon, SPELL_DARKFIEND_VISUAL);
- break;
- case NPC_DARKNESS:
- summon->SetReactState(REACT_PASSIVE);
- summon->CastSpell(summon, SPELL_BLACKHOLE);
- summon->CastSpell(summon, SPELL_SUMMON_DARKFIEND_E, true);
- break;
- }
- summons.Summon(summon);
+ if (action == ACTION_BERSERK)
+ DoCastSelf(SPELL_BERSERK);
}
void EnterEvadeMode(EvadeReason /*why*/) override
@@ -182,8 +343,8 @@ struct boss_entropius : public BossAI
if (Creature* muru = instance->GetCreature(DATA_MURU))
muru->AI()->EnterEvadeMode();
- DoResetPortals();
- summons.DespawnAll();
+ DoResetPortals(me);
+ DoDespawnSummons(me);
me->DespawnOrUnsummon();
}
@@ -191,307 +352,394 @@ struct boss_entropius : public BossAI
{
_JustDied();
+ DoDespawnSummons(me);
+
if (Creature* muru = instance->GetCreature(DATA_MURU))
muru->DisappearAndDie();
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- scheduler.Update(diff, [this]
+ while (uint32 eventId = events.ExecuteEvent())
{
- DoMeleeAttackIfReady();
- });
- }
+ switch (eventId)
+ {
+ case EVENT_SPAWN_1:
+ DoResetPortals(me);
+ events.ScheduleEvent(EVENT_SPAWN_2, 1500ms);
+ break;
+ case EVENT_SPAWN_2:
+ DoCastSelf(SPELL_NEGATIVE_ENERGY_PERIODIC_E);
+ DoZoneInCombat();
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ case EVENT_DARKNESS:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
+ DoCast(target, SPELL_DARKNESS);
+ events.Repeat(10s, 15s);
+ break;
+ case EVENT_BLACK_HOLE:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
+ DoCast(target, SPELL_BLACK_HOLE);
+ events.Repeat(20s, 25s);
+ break;
+ default:
+ break;
+ }
- void DoResetPortals()
- {
- std::list<Creature*> portals;
- me->GetCreatureListWithEntryInGrid(portals, NPC_MURU_PORTAL_TARGET, 100.0f);
- for (Creature* portal : portals)
- portal->RemoveAllAuras();
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
+
+ if (UpdateVictim())
+ DoMeleeAttackIfReady();
}
};
-struct boss_muru : public BossAI
+// 25770 - M'uru Portal Target
+struct npc_muru_portal : public ScriptedAI
{
- boss_muru(Creature* creature) : BossAI(creature, DATA_MURU)
+ npc_muru_portal(Creature* creature) : ScriptedAI(creature) { }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
{
- Initialize();
- SetCombatMovement(false);
+ switch (spellInfo->Id)
+ {
+ case SPELL_OPEN_PORTAL:
+ DoCastSelf(SPELL_OPEN_PORTAL_VISUAL);
+ _scheduler.Schedule(5s, [this](TaskContext /*task*/)
+ {
+ DoCastSelf(SPELL_SUMMON_VOID_SENTINEL_SUMMONER);
+ });
+ break;
+ case SPELL_OPEN_ALL_PORTALS:
+ DoCastSelf(SPELL_OPEN_PORTAL_VISUAL);
+ _scheduler.Schedule(2s, [this](TaskContext /*task*/)
+ {
+ DoCastSelf(SPELL_TRANSFORM_VISUAL_MISSILE);
+ });
+ break;
+ default:
+ break;
+ }
}
- void Initialize()
+ void JustSummoned(Creature* summon) override
{
- _hasEnraged = false;
- _phase = PHASE_ONE;
- _entropiusGUID.Clear();
+ DoCast(summon, SPELL_SUMMON_VOID_SENTINEL_SUMMONER_VISUAL);
}
- void Reset() override
+ void DoAction(int32 action) override
{
- _Reset();
- Initialize();
- me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
- me->SetVisible(true);
+ if (action == ACTION_CANCEL_SUMMON)
+ _scheduler.CancelAll();
}
- void EnterEvadeMode(EvadeReason /*why*/) override
+ void UpdateAI(uint32 diff) override
{
- BossAI::EnterEvadeMode();
- if (Creature* entropius = ObjectAccessor::GetCreature(*me, _entropiusGUID))
- entropius->AI()->EnterEvadeMode();
+ _scheduler.Update(diff);
}
- void ScheduleTasks() override
- {
- scheduler.Schedule(Minutes(10), [this](TaskContext /*context*/)
- {
- if (Creature* entropius = ObjectAccessor::GetCreature(*me, _entropiusGUID))
- entropius->CastSpell(entropius, SPELL_ENRAGE);
- DoCast(me, SPELL_ENRAGE);
- _hasEnraged = true;
- });
+private:
+ TaskScheduler _scheduler;
+};
- scheduler.Schedule(Seconds(10), [this](TaskContext /*context*/)
+// 25782 - Void Sentinel Summoner
+struct npc_void_sentinel_summoner : public ScriptedAI
+{
+ npc_void_sentinel_summoner(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustAppeared() override
+ {
+ _scheduler.Schedule(1500ms, [this](TaskContext /*task*/)
{
- DoCast(me, SPELL_SUMMON_BLOOD_ELVES_SCRIPT, true);
- DoCast(me, SPELL_SUMMON_BLOOD_ELVES_PERIODIC, true);
+ DoCastSelf(SPELL_SUMMON_VOID_SENTINEL);
+ me->DespawnOrUnsummon(3500ms);
});
}
- void JustEngagedWith(Unit* who) override
+ void UpdateAI(uint32 diff) override
{
- BossAI::JustEngagedWith(who);
- DoCast(me, SPELL_OPEN_PORTAL_PERIODIC, true);
- DoCast(me, SPELL_DARKNESS_PERIODIC, true);
- DoCast(me, SPELL_NEGATIVE_ENERGY_PERIODIC, true);
+ _scheduler.Update(diff);
}
- void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+private:
+ TaskScheduler _scheduler;
+};
+
+// 25772 - Void Sentinel
+struct npc_void_sentinel : public ScriptedAI
+{
+ npc_void_sentinel(Creature* creature) : ScriptedAI(creature) { }
+
+ void InitializeAI() override
{
- if (damage >= me->GetHealth())
- {
- damage = me->GetHealth() - 1;
- if (_phase != PHASE_ONE)
- return;
+ me->SetCorpseDelay(5, true);
+ me->SetReactState(REACT_PASSIVE);
+ }
- _phase = PHASE_TWO;
- me->RemoveAllAuras();
- DoCast(me, SPELL_OPEN_ALL_PORTALS, true);
- me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ void JustAppeared() override
+ {
+ DoCastSelf(SPELL_SHADOW_PULSE_PERIODIC);
- scheduler.Schedule(Seconds(6), [this](TaskContext /*context*/)
- {
- DoCast(me, SPELL_SUMMON_ENTROPIUS, true);
- });
- }
+ _scheduler.Schedule(2500ms, [this](TaskContext /*task*/)
+ {
+ DoZoneInCombat();
+ me->SetReactState(REACT_AGGRESSIVE);
+ });
}
- void JustSummoned(Creature* summon) override
+ void JustEngagedWith(Unit* /*who*/) override
{
- if (summon->GetEntry() == NPC_ENTROPIUS)
+ _scheduler.Schedule(10s, 15s, [this](TaskContext task)
{
- me->SetVisible(false);
- _entropiusGUID = summon->GetGUID();
- DoZoneInCombat(summon);
- if (_hasEnraged)
- summon->CastSpell(summon, SPELL_ENRAGE, true);
- return;
- }
- BossAI::JustSummoned(summon);
+ DoCastVictim(SPELL_VOID_BLAST);
+ task.Repeat(20s, 30s);
+ });
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ for (uint8 i = 0; i < MAX_VOID_SPAWNS; ++i)
+ DoCastSelf(SPELL_SUMMON_VOID_SPAWN);
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
- return;
+ _scheduler.Update(diff);
- scheduler.Update(diff);
+ if (UpdateVictim())
+ DoMeleeAttackIfReady();
}
private:
- ObjectGuid _entropiusGUID;
- bool _hasEnraged;
- uint8 _phase;
+ TaskScheduler _scheduler;
};
-struct npc_muru_portal : public ScriptedAI
+// 25824 - Void Spawn
+struct npc_void_spawn : public ScriptedAI
{
- npc_muru_portal(Creature* creature) : ScriptedAI(creature) { }
+ npc_void_spawn(Creature* creature) : ScriptedAI(creature) { }
- void JustSummoned(Creature* summon) override
+ void InitializeAI() override
{
- DoCast(summon, SPELL_SUMMON_VOID_SENTINEL_SUMMONER_VISUAL, true);
+ me->SetCorpseDelay(5, true);
+ me->SetReactState(REACT_PASSIVE);
+ }
- summon->m_Events.AddEvent(new VoidSpawnSummon(summon), summon->m_Events.CalculateTime(1500ms));
+ void JustAppeared() override
+ {
+ _scheduler.Schedule(2s, [this](TaskContext /*task*/)
+ {
+ DoZoneInCombat();
+ me->SetReactState(REACT_AGGRESSIVE);
+ });
}
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ void JustEngagedWith(Unit* /*who*/) override
{
- switch (spellInfo->Id)
+ _scheduler.Schedule(10s, 20s, [this](TaskContext task)
{
- case SPELL_OPEN_ALL_PORTALS:
- DoCastAOE(SPELL_OPEN_PORTAL, true);
- DoCastAOE(SPELL_TRANSFORM_VISUAL_MISSILE, true);
- break;
- case SPELL_OPEN_PORTAL_2:
- DoCastAOE(SPELL_OPEN_PORTAL, true);
- _scheduler.Schedule(Seconds(6), [this](TaskContext /*context*/)
- {
- DoCastAOE(SPELL_SUMMON_VOID_SENTINEL_SUMMONER, true);
- });
- break;
- default:
- break;
- }
+ DoCastSelf(SPELL_SHADOW_BOLT_VOLLEY);
+ task.Repeat(20s, 30s);
+ });
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
+
+ if (UpdateVictim())
+ DoMeleeAttackIfReady();
}
private:
TaskScheduler _scheduler;
};
+// 25744 - Dark Fiend
struct npc_dark_fiend : public ScriptedAI
{
- npc_dark_fiend(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- }
+ npc_dark_fiend(Creature* creature) : ScriptedAI(creature), _isKilled(false) { }
- void Initialize()
+ void InitializeAI() override
{
me->SetDisplayId(me->GetCreatureTemplate()->Modelid2);
me->SetReactState(REACT_PASSIVE);
- DoCast(me, SPELL_DARKFIEND_SKIN, true);
+ }
- _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/)
+ void JustAppeared() override
+ {
+ DoCastSelf(SPELL_DARK_FIEND_MAGIC);
+
+ _scheduler.Schedule(2s, [this](TaskContext /*task*/)
{
+ DoZoneInCombat();
me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ });
- if (Creature* _summoner = ObjectAccessor::GetCreature(*me, _summonerGUID))
- if (Unit* target = _summoner->AI()->SelectTarget(SelectTargetMethod::Random, 0))
- AttackStart(target);
+ _scheduler.Schedule(2s, [this](TaskContext task)
+ {
+ if (me->IsWithinDist(me->GetVictim(), 2.0f))
+ DoCastVictim(SPELL_DARK_FIEND_TRAP);
+ else
+ task.Repeat(100ms);
});
+ }
- _scheduler.Schedule(Seconds(3), [this](TaskContext context)
+ void SpellHitTarget(WorldObject* /*target*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_DARK_FIEND_TRAP)
{
- if (me->IsWithinDist(me->GetVictim(), 5.0f) && me->HasAura(SPELL_DARKFIEND_SKIN))
+ _scheduler.Schedule(0s, [this](TaskContext task)
{
- DoCastAOE(SPELL_DARKFIEND_DAMAGE, false);
- me->DisappearAndDie();
- }
-
- context.Repeat(Milliseconds(500));
- });
+ switch (task.GetRepeatCounter())
+ {
+ case 0:
+ me->RemoveAurasDueToSpell(SPELL_DARK_FIEND_MAGIC);
+ DoCastSelf(SPELL_DARK_FIEND_DAMAGE);
+ me->SetReactState(REACT_PASSIVE);
+ me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ task.Repeat(2500ms);
+ break;
+ case 1:
+ DoCastSelf(SPELL_DARK_FIEND_VISUAL);
+ me->DespawnOrUnsummon(3500ms);
+ break;
+ default:
+ break;
+ }
+ });
+ }
}
- void IsSummonedBy(WorldObject* summoner) override
+ void DoAction(int32 action) override
{
- _summonerGUID = summoner->GetGUID();
+ /// @todo: This part requires sniff verification
+ if (action == ACTION_DISPELLED_MAGIC)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ DoCastSelf(SPELL_DARK_FIEND_VISUAL);
+ me->DespawnOrUnsummon(3s);
+ }
}
- bool CanAIAttack(Unit const* /*target*/) const override
+ void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
{
- return me->HasAura(SPELL_DARKFIEND_SKIN);
+ if (damage >= me->GetHealth())
+ {
+ damage = me->GetHealth() -1;
+
+ if (!_isKilled)
+ {
+ _isKilled = true;
+ me->RemoveAurasDueToSpell(SPELL_DARK_FIEND_MAGIC);
+ DoCastSelf(SPELL_DARK_FIEND_VISUAL);
+ me->SetReactState(REACT_PASSIVE);
+ me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ me->DespawnOrUnsummon(4500ms);
+ }
+ }
}
void UpdateAI(uint32 diff) override
{
+ UpdateVictim();
+
_scheduler.Update(diff);
}
private:
+ bool _isKilled;
TaskScheduler _scheduler;
- ObjectGuid _summonerGUID;
};
-struct npc_void_sentinel : public ScriptedAI
+// 25879 - Darkness
+struct npc_darkness : public ScriptedAI
{
- npc_void_sentinel(Creature* creature) : ScriptedAI(creature)
- {
- _instance = me->GetInstanceScript();
- }
+ npc_darkness(Creature* creature) : ScriptedAI(creature) { }
- void IsSummonedBy(WorldObject* /*summoner*/) override
+ void InitializeAI() override
{
- if (Creature* muru = _instance->GetCreature(DATA_MURU))
- muru->AI()->JustSummoned(me);
+ me->SetReactState(REACT_PASSIVE);
}
- void JustEngagedWith(Unit* /*who*/) override
+ void JustAppeared() override
{
- DoCast(me, SPELL_SHADOW_PULSE_PERIODIC, true);
-
- _scheduler.Schedule(Seconds(45), [this](TaskContext context)
+ _scheduler.Schedule(1s, [this](TaskContext task)
{
- DoCastVictim(SPELL_VOID_BLAST, false);
-
- context.Repeat();
+ switch (task.GetRepeatCounter())
+ {
+ case 0:
+ DoCastSelf(SPELL_VOID_ZONE_PRE_EFFECT_VISUAL);
+ task.Repeat(3s);
+ break;
+ case 1:
+ me->RemoveAurasDueToSpell(SPELL_VOID_ZONE_PRE_EFFECT_VISUAL);
+ DoCastSelf(SPELL_VOID_ZONE_PERIODIC);
+ task.Repeat(2500ms);
+ break;
+ case 2:
+ DoCastSelf(SPELL_SUMMON_DARK_FIEND);
+ break;
+ default:
+ break;
+ }
});
}
- void JustDied(Unit* /*killer*/) override
- {
- for (uint8 i = 0; i < MAX_VOID_SPAWNS; ++i)
- DoCastAOE(SPELL_SUMMON_VOID_SPAWN, true);
- }
-
void UpdateAI(uint32 diff) override
{
- _scheduler.Update(diff, [this]
- {
- DoMeleeAttackIfReady();
- });
+ _scheduler.Update(diff);
}
private:
TaskScheduler _scheduler;
- InstanceScript* _instance;
};
-struct npc_blackhole : public ScriptedAI
+// 25855 - Singularity
+struct npc_singularity : public ScriptedAI
{
- npc_blackhole(Creature* creature) : ScriptedAI(creature)
- {
- _instance = creature->GetInstanceScript();
- }
+ npc_singularity(Creature* creature) : ScriptedAI(creature) { }
- void Reset() override
+ void InitializeAI() override
{
me->SetReactState(REACT_PASSIVE);
- DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL);
-
- _scheduler.Schedule(Seconds(15), [this](TaskContext /*context*/)
- {
- me->DisappearAndDie();
- });
+ }
- _scheduler.Schedule(Seconds(1), [this](TaskContext context)
+ void JustAppeared() override
+ {
+ _scheduler.Schedule(1s, [this](TaskContext task)
{
- switch (context.GetRepeatCounter())
+ switch (task.GetRepeatCounter())
{
case 0:
- me->SetReactState(REACT_AGGRESSIVE);
- DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL_2);
- if (Unit* victim = ObjectAccessor::GetUnit(*me, _instance->GetGuidData(DATA_PLAYER_GUID)))
- AttackStart(victim);
- context.Repeat(Milliseconds(1200));
+ DoCastSelf(SPELL_BLACK_HOLE_SUMMON_VISUAL);
+ task.Repeat(1s);
break;
case 1:
- DoCast(SPELL_BLACKHOLE_SUMMON_VISUAL);
- context.Repeat(Seconds(2));
+ DoCastSelf(SPELL_BLACK_HOLE_SUMMON_VISUAL_2);
+ task.Repeat(1s);
break;
case 2:
- DoCast(SPELL_BLACKHOLE_PASSIVE);
- DoCast(SPELL_BLACK_HOLE_VISUAL_2);
+ DoCastSelf(SPELL_BLACK_HOLE_SUMMON_VISUAL);
+ task.Repeat(2s);
+ break;
+ case 3:
+ me->RemoveAurasDueToSpell(SPELL_BLACK_HOLE_SUMMON_VISUAL_2);
+ DoCastSelf(SPELL_BLACK_HOLE_PASSIVE);
+ DoCastSelf(SPELL_BLACK_HOLE_VISUAL_2);
+ task.Repeat(1s);
+ break;
+ case 4:
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoZoneInCombat();
+ me->DespawnOrUnsummon(15s);
break;
default:
break;
@@ -501,113 +749,256 @@ struct npc_blackhole : public ScriptedAI
void UpdateAI(uint32 diff) override
{
+ UpdateVictim();
+
_scheduler.Update(diff);
}
private:
TaskScheduler _scheduler;
- InstanceScript* _instance;
+};
+
+struct ShadowswordBaseAI : public ScriptedAI
+{
+ ShadowswordBaseAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void InitializeAI() override
+ {
+ me->SetReactState(REACT_PASSIVE);
+ me->SetCorpseDelay(3, true);
+ }
+
+ void JustAppeared() override
+ {
+ scheduler.SetValidator([this]
+ {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ });
+
+ if (Creature* trigger = me->FindNearestCreature(NPC_WORLD_TRIGGER_MOVE_TO, 120.0f))
+ {
+ float x, y, z;
+ trigger->GetClosePoint(x, y, z, 0.0f, 3.0f, float(M_PI));
+ me->GetMotionMaster()->MovePoint(POINT_ROOM, x, y, z);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 pointId) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (pointId == POINT_ROOM)
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoZoneInCombat();
+ }
+ }
+
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ ScheduleEvents();
+ }
+
+ virtual void ScheduleEvents() = 0;
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ scheduler.Update(diff);
+
+ DoMeleeAttackIfReady();
+ }
+
+protected:
+ TaskScheduler scheduler;
+};
+
+// 25798 - Shadowsword Berserker
+struct npc_shadowsword_berserker : public ShadowswordBaseAI
+{
+ npc_shadowsword_berserker(Creature* creature) : ShadowswordBaseAI(creature) { }
+
+ void JustAppeared() override
+ {
+ DoCastSelf(SPELL_DUAL_WIELD_PASSIVE);
+ ShadowswordBaseAI::JustAppeared();
+ }
+
+ void ScheduleEvents() override
+ {
+ scheduler.Schedule(10s, 20s, [this](TaskContext task)
+ {
+ DoCastSelf(SPELL_FLURRY);
+ task.Repeat(15s, 25s);
+ });
+ }
+};
+
+// 25799 - Shadowsword Fury Mage
+struct npc_shadowsword_fury_mage : public ShadowswordBaseAI
+{
+ npc_shadowsword_fury_mage(Creature* creature) : ShadowswordBaseAI(creature) { }
+
+ void ScheduleEvents() override
+ {
+ scheduler.Schedule(5s, 10s, [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_FEL_FIREBALL);
+ task.Repeat(5s, 10s);
+ });
+
+ scheduler.Schedule(20s, 40s, [this](TaskContext task)
+ {
+ DoCastSelf(SPELL_SPELL_FURY);
+ task.Repeat(40s, 60s);
+ });
+ }
+};
+
+// 46041 - Summon Blood Elves Periodic
+class spell_muru_summon_blood_elves_periodic : public AuraScript
+{
+ PrepareAuraScript(spell_muru_summon_blood_elves_periodic);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_SUMMON_BLOOD_ELVES_SCRIPT });
+ }
+
+ void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_BLOOD_ELVES_SCRIPT);
+ }
+
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_BLOOD_ELVES_SCRIPT);
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_muru_summon_blood_elves_periodic::AfterApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_muru_summon_blood_elves_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
};
// 46050 - Summon Blood Elves Script
-class spell_summon_blood_elves_script : public SpellScript
+class spell_muru_summon_blood_elves_script : public SpellScript
{
- PrepareSpellScript(spell_summon_blood_elves_script);
+ PrepareSpellScript(spell_muru_summon_blood_elves_script);
- bool Validate(SpellInfo const* /*spell*/) override
+ bool Validate(SpellInfo const* /*spellInfo*/) override
{
- return ValidateSpellInfo(SummonBloodElvesSpells);
+ return ValidateSpellInfo(
+ {
+ SPELL_SUMMON_BERSERKER_1,
+ SPELL_SUMMON_BERSERKER_2,
+ SPELL_SUMMON_FURY_MAGE_1,
+ SPELL_SUMMON_FURY_MAGE_2
+ });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
- for (uint8 i = 0; i < MAX_SUMMON_BLOOD_ELVES; ++i)
- GetCaster()->CastSpell(nullptr, SummonBloodElvesSpells[urand(0,3)], true);
+ Unit* caster = GetCaster();
+ caster->CastSpell(caster, SPELL_SUMMON_BERSERKER_1);
+ caster->CastSpell(caster, SPELL_SUMMON_BERSERKER_1);
+ caster->CastSpell(caster, SPELL_SUMMON_FURY_MAGE_1);
+ caster->CastSpell(caster, SPELL_SUMMON_FURY_MAGE_2);
+ caster->CastSpell(caster, SPELL_SUMMON_BERSERKER_2);
+ caster->CastSpell(caster, SPELL_SUMMON_BERSERKER_2);
}
void Register() override
{
- OnEffectHitTarget += SpellEffectFn(spell_summon_blood_elves_script::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnEffectHit += SpellEffectFn(spell_muru_summon_blood_elves_script::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 45996 - Darkness
-class spell_muru_darkness : public SpellScript
+class spell_muru_darkness : public AuraScript
{
- PrepareSpellScript(spell_muru_darkness);
+ PrepareAuraScript(spell_muru_darkness);
- bool Validate(SpellInfo const* /*spell*/) override
+ bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(SummonDarkFiendSpells);
}
- void HandleAfterCast()
+ void HandleEffectPeriodic(AuraEffect const* aurEff)
{
- for (uint8 i = 0; i < MAX_SUMMON_DARK_FIEND; ++i)
- GetCaster()->CastSpell(nullptr, SummonDarkFiendSpells[i], true);
+ if (aurEff->GetTickNumber() == 2)
+ {
+ Unit* target = GetTarget();
+ for (uint32 SummonSpell : SummonDarkFiendSpells)
+ target->CastSpell(target, SummonSpell);
+ }
}
void Register() override
{
- AfterCast += SpellCastFn(spell_muru_darkness::HandleAfterCast);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_muru_darkness::HandleEffectPeriodic, EFFECT_2, SPELL_AURA_PERIODIC_DUMMY);
}
};
// 45934 - Dark Fiend
-class spell_dark_fiend_skin : public AuraScript
+class spell_muru_dark_fiend_magic : public AuraScript
{
- PrepareAuraScript(spell_dark_fiend_skin);
+ PrepareAuraScript(spell_muru_dark_fiend_magic);
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
return;
if (Creature* target = GetTarget()->ToCreature())
- {
- target->SetReactState(REACT_PASSIVE);
- target->AttackStop();
- target->StopMoving();
- target->CastSpell(target, SPELL_DARKFIEND_VISUAL, true);
- target->DespawnOrUnsummon(3s);
- }
+ target->AI()->DoAction(ACTION_DISPELLED_MAGIC);
}
void Register() override
{
- AfterEffectRemove += AuraEffectRemoveFn(spell_dark_fiend_skin::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_muru_dark_fiend_magic::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
// 46205 - Transform Visual Missile Periodic
-class spell_transform_visual_missile_periodic : public AuraScript
+class spell_muru_transform_visual_missile_periodic : public AuraScript
{
- PrepareAuraScript(spell_transform_visual_missile_periodic);
+ PrepareAuraScript(spell_muru_transform_visual_missile_periodic);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_TRANSFORM_VISUAL_MISSILE_1, SPELL_TRANSFORM_VISUAL_MISSILE_2 });
+ }
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
- GetTarget()->CastSpell(nullptr, RAND(TRANSFORM_VISUAL_MISSILE_1, TRANSFORM_VISUAL_MISSILE_2), true);
+ GetTarget()->CastSpell(nullptr, RAND(SPELL_TRANSFORM_VISUAL_MISSILE_1, SPELL_TRANSFORM_VISUAL_MISSILE_2));
}
void Register() override
{
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_transform_visual_missile_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_muru_transform_visual_missile_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
-// 46041 - Summon Blood Elves Periodic
-class spell_summon_blood_elves_periodic : public AuraScript
+// 45978 - Summon Void Sentinel Summoner
+class spell_muru_summon_void_sentinel_summoner : public SpellScript
{
- PrepareAuraScript(spell_summon_blood_elves_periodic);
+ PrepareSpellScript(spell_muru_summon_void_sentinel_summoner);
- void OnPeriodic(AuraEffect const* /*aurEff*/)
+ void SetDest(SpellDestination& dest)
{
- GetTarget()->CastSpell(nullptr, SPELL_SUMMON_BLOOD_ELVES_SCRIPT, true);
+ Unit* caster = GetCaster();
+ dest._position.m_positionZ = caster->GetMapHeight(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
}
void Register() override
{
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_summon_blood_elves_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_muru_summon_void_sentinel_summoner::SetDest, EFFECT_0, TARGET_DEST_CASTER_FRONT);
}
};
@@ -662,14 +1053,20 @@ void AddSC_boss_muru()
RegisterSunwellPlateauCreatureAI(boss_muru);
RegisterSunwellPlateauCreatureAI(boss_entropius);
RegisterSunwellPlateauCreatureAI(npc_muru_portal);
- RegisterSunwellPlateauCreatureAI(npc_dark_fiend);
+ RegisterSunwellPlateauCreatureAI(npc_void_sentinel_summoner);
RegisterSunwellPlateauCreatureAI(npc_void_sentinel);
- RegisterSunwellPlateauCreatureAI(npc_blackhole);
- RegisterSpellScript(spell_summon_blood_elves_script);
+ RegisterSunwellPlateauCreatureAI(npc_void_spawn);
+ RegisterSunwellPlateauCreatureAI(npc_dark_fiend);
+ RegisterSunwellPlateauCreatureAI(npc_darkness);
+ RegisterSunwellPlateauCreatureAI(npc_singularity);
+ RegisterSunwellPlateauCreatureAI(npc_shadowsword_berserker);
+ RegisterSunwellPlateauCreatureAI(npc_shadowsword_fury_mage);
+ RegisterSpellScript(spell_muru_summon_blood_elves_periodic);
+ RegisterSpellScript(spell_muru_summon_blood_elves_script);
RegisterSpellScript(spell_muru_darkness);
- RegisterSpellScript(spell_dark_fiend_skin);
- RegisterSpellScript(spell_transform_visual_missile_periodic);
- RegisterSpellScript(spell_summon_blood_elves_periodic);
+ RegisterSpellScript(spell_muru_dark_fiend_magic);
+ RegisterSpellScript(spell_muru_transform_visual_missile_periodic);
+ RegisterSpellScript(spell_muru_summon_void_sentinel_summoner);
RegisterSpellScript(spell_muru_negative_energy_periodic);
RegisterSpellScript(spell_muru_negative_energy);
}
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp
index 248480c65ff..ac4c33e8f7e 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp
@@ -56,6 +56,7 @@ ObjectData const creatureData[] =
{ NPC_GRAND_WARLOCK_ALYTHESS, DATA_ALYTHESS },
{ NPC_LADY_SACROLASH, DATA_SACROLASH },
{ NPC_MURU, DATA_MURU },
+ { NPC_ENTROPIUS, DATA_ENTROPIUS },
{ NPC_KILJAEDEN, DATA_KILJAEDEN },
{ NPC_KILJAEDEN_CONTROLLER, DATA_KILJAEDEN_CONTROLLER },
{ NPC_ANVEENA, DATA_ANVEENA },
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h
index 7dfc6e55329..28946c17e98 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h
@@ -45,6 +45,7 @@ enum SWPDataTypes
DATA_KILJAEDEN_CONTROLLER,
DATA_ANVEENA,
DATA_KALECGOS_KJ,
+ DATA_ENTROPIUS,
// GameObject GUIDs
DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1,
@@ -99,13 +100,15 @@ enum SWPCreatureIds
NPC_SPIKE_TARGET2 = 30614,
NPC_SINISTER_REFLECTION = 25708, // Sinister Relection spawnd on Phase swichtes
+ // M'uru
+ NPC_VOID_SENTINEL_SUMMONER = 25782,
+ NPC_VOID_SENTINEL = 25772,
+ NPC_VOID_SPAWN = 25824,
+ NPC_DARK_FIEND = 25744,
NPC_DARKNESS = 25879,
- NPC_DARK_FIENDS = 25744,
+ NPC_SINGULARITY = 25855,
NPC_BERSERKER = 25798,
NPC_FURY_MAGE = 25799,
- NPC_VOID_SENTINEL = 25772,
- NPC_VOID_SPAWN = 25824,
- NPC_BLACK_HOLE = 25855,
NPC_MURU_PORTAL_TARGET = 25770
};