aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo <sirikfoll@hotmail.com>2016-10-14 16:44:49 -0300
committerSnapperRy <snapperryen@gmail.com>2016-10-14 21:44:49 +0200
commit8e82d8a9e79ba95fbd780fa093416ebe7431a1c0 (patch)
treef84d58a69ae53937ea6260714aa989f5c1c6d9a1
parent1824347594f3a53fd50c9e7da0d546becd69db0d (diff)
Core/Scripts Boss Lady DeathWhisper improvements (#17389)
-rw-r--r--sql/updates/world/3.3.5/2016_99_99_99_world.sql15
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp818
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp8
3 files changed, 445 insertions, 396 deletions
diff --git a/sql/updates/world/3.3.5/2016_99_99_99_world.sql b/sql/updates/world/3.3.5/2016_99_99_99_world.sql
new file mode 100644
index 00000000000..e42d5e46ce7
--- /dev/null
+++ b/sql/updates/world/3.3.5/2016_99_99_99_world.sql
@@ -0,0 +1,15 @@
+UPDATE `creature_template` SET `unit_flags`=33554432 WHERE `entry`=38222;
+UPDATE `creature_template` SET `speed_run`=0.571429 WHERE `entry`=38222;
+UPDATE `spell_dbc` SET `DurationIndex`=29, `Effect1`=6, `EffectImplicitTargetA1`=1, `EffectApplyAuraName1`=61, `EffectBasePoints1`=100 WHERE `Id`=71290;
+
+DELETE FROM `linked_respawn`WHERE `guid`=201129 AND `linkedGuid`=201129;
+DELETE FROM `creature_template_addon` WHERE `entry` IN (38009,38010,38136);
+INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES
+(38009,0,0,0,0,0,71235),
+(38010,0,0,0,0,0,'71234 70768'),
+(38136,0,0,0,0,0,70901);
+
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN('spell_deathwhisper_dominated_mind', 'spell_deathwhisper_summon_spirits','spell_cultist_dark_martyrdom');
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(71289,'spell_deathwhisper_dominated_mind'),
+(72478,'spell_deathwhisper_summon_spirits');
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index 5f884ccee9e..85126b35cdb 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -56,21 +56,26 @@ enum Spells
SPELL_MANA_BARRIER = 70842,
SPELL_SHADOW_BOLT = 71254,
SPELL_DEATH_AND_DECAY = 71001,
- SPELL_DOMINATE_MIND_H = 71289,
+ SPELL_DOMINATE_MIND = 71289,
+ SPELL_DOMINATE_MIND_SCALE = 71290,
SPELL_FROSTBOLT = 71420,
SPELL_FROSTBOLT_VOLLEY = 72905,
SPELL_TOUCH_OF_INSIGNIFICANCE = 71204,
SPELL_SUMMON_SHADE = 71363,
- SPELL_SHADOW_CHANNELING = 43897, // Prefight, during intro
+ SPELL_SHADOW_CHANNELING = 43897,
SPELL_DARK_TRANSFORMATION_T = 70895,
SPELL_DARK_EMPOWERMENT_T = 70896,
SPELL_DARK_MARTYRDOM_T = 70897,
+ SPELL_SUMMON_SPIRITS = 72478,
// Achievement
SPELL_FULL_HOUSE = 72827, // does not exist in dbc but still can be used for criteria check
// Both Adds
SPELL_TELEPORT_VISUAL = 41236,
+ SPELL_CLEAR_ALL_DEBUFFS = 34098,
+ SPELL_FULL_HEAL = 17683,
+ SPELL_PERMANENT_FEIGN_DEATH = 70628,
// Fanatics
SPELL_DARK_TRANSFORMATION = 70900,
@@ -86,7 +91,7 @@ enum Spells
SPELL_DEATHCHILL_BOLT = 70594,
SPELL_DEATHCHILL_BLAST = 70906,
SPELL_CURSE_OF_TORPOR = 71237,
- SPELL_SHORUD_OF_THE_OCCULT = 70768,
+ SPELL_SHROUD_OF_THE_OCCULT = 70768,
SPELL_ADHERENT_S_DETERMINATION = 71234,
SPELL_DARK_MARTYRDOM_ADHERENT = 70903,
@@ -108,44 +113,6 @@ enum Spells
enum EventTypes
{
- // Lady Deathwhisper
- EVENT_INTRO_2 = 1,
- EVENT_INTRO_3 = 2,
- EVENT_INTRO_4 = 3,
- EVENT_INTRO_5 = 4,
- EVENT_INTRO_6 = 5,
- EVENT_INTRO_7 = 6,
- EVENT_BERSERK = 7,
- EVENT_DEATH_AND_DECAY = 8,
- EVENT_DOMINATE_MIND_H = 9,
-
- // Phase 1 only
- EVENT_P1_SUMMON_WAVE = 10,
- EVENT_P1_SHADOW_BOLT = 11,
- EVENT_P1_EMPOWER_CULTIST = 12,
- EVENT_P1_REANIMATE_CULTIST = 13,
-
- // Phase 2 only
- EVENT_P2_SUMMON_WAVE = 14,
- EVENT_P2_FROSTBOLT = 15,
- EVENT_P2_FROSTBOLT_VOLLEY = 16,
- EVENT_P2_TOUCH_OF_INSIGNIFICANCE = 17,
- EVENT_P2_SUMMON_SHADE = 18,
-
- // Shared adds events
- EVENT_CULTIST_DARK_MARTYRDOM = 19,
-
- // Cult Fanatic
- EVENT_FANATIC_NECROTIC_STRIKE = 20,
- EVENT_FANATIC_SHADOW_CLEAVE = 21,
- EVENT_FANATIC_VAMPIRIC_MIGHT = 22,
-
- // Cult Adherent
- EVENT_ADHERENT_FROST_FEVER = 23,
- EVENT_ADHERENT_DEATHCHILL = 24,
- EVENT_ADHERENT_CURSE_OF_TORPOR = 25,
- EVENT_ADHERENT_SHORUD_OF_THE_OCCULT = 26,
-
// Darnavan
EVENT_DARNAVAN_BLADESTORM = 27,
EVENT_DARNAVAN_CHARGE = 28,
@@ -163,6 +130,13 @@ enum Phases
PHASE_TWO = 3
};
+enum Groups
+{
+ GROUP_INTRO = 0,
+ GROUP_ONE = 1,
+ GROUP_TWO = 2
+};
+
enum DeprogrammingData
{
NPC_DARNAVAN_10 = 38472,
@@ -185,8 +159,6 @@ enum Actions
uint32 const SummonEntries[2] = {NPC_CULT_FANATIC, NPC_CULT_ADHERENT};
-#define GUID_CULTIST 1
-
Position const SummonPositions[7] =
{
{-578.7066f, 2154.167f, 51.01529f, 1.692969f}, // 1 Left Door 1 (Cult Fanatic)
@@ -229,43 +201,67 @@ class boss_lady_deathwhisper : public CreatureScript
void Initialize()
{
_waveCounter = 0;
- _nextVengefulShadeTargetGUID.Clear();
+ _nextVengefulShadeTargetGUID.clear();
+ _cultistQueue.clear();
_darnavanGUID.Clear();
+ _phase = PHASE_ALL;
+ scheduler.SetValidator([this]
+ {
+ return !(me->HasUnitState(UNIT_STATE_CASTING) && _phase != PHASE_INTRO);
+ });
}
void Reset() override
{
- _Reset();
- me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA));
- events.SetPhase(PHASE_ONE);
Initialize();
- DoCast(me, SPELL_SHADOW_CHANNELING);
- me->RemoveAurasDueToSpell(SPELL_BERSERK);
- me->RemoveAurasDueToSpell(SPELL_MANA_BARRIER);
+ _phase = PHASE_ONE;
+ DoCastSelf(SPELL_SHADOW_CHANNELING);
+ me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA));
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false);
}
void DoAction(int32 action) override
{
- switch (action)
+ if (action != ACTION_START_INTRO)
+ return;
+
+ if (!_introDone)
{
- case ACTION_START_INTRO:
- if (!_introDone)
+ _introDone = true;
+ Talk(SAY_INTRO_1);
+ _phase = PHASE_INTRO;
+ scheduler.Schedule(Seconds(10), GROUP_INTRO, [this](TaskContext context)
+ {
+ switch (context.GetRepeatCounter())
{
- _introDone = true;
- Talk(SAY_INTRO_1);
- events.SetPhase(PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_2, 11000, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_3, 21000, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_4, 31500, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_5, 39500, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_6, 48500, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_7, 58000, 0, PHASE_INTRO);
+ case 0:
+ Talk(SAY_INTRO_2);
+ context.Repeat(Seconds(21));
+ break;
+ case 1:
+ Talk(SAY_INTRO_3);
+ context.Repeat(Seconds(11));
+ break;
+ case 2:
+ Talk(SAY_INTRO_4);
+ context.Repeat(Seconds(9));
+ break;
+ case 3:
+ Talk(SAY_INTRO_5);
+ context.Repeat(Seconds(21));
+ break;
+ case 4:
+ Talk(SAY_INTRO_6);
+ context.Repeat(Seconds(10));
+ break;
+ case 5:
+ Talk(SAY_INTRO_7);
+ return;
+ default:
+ break;
}
- break;
- default:
- break;
+ });
}
}
@@ -274,7 +270,7 @@ class boss_lady_deathwhisper : public CreatureScript
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
- if (victim && me->Attack(victim, true) && !events.IsInPhase(PHASE_ONE))
+ if (victim && me->Attack(victim, true) && _phase != PHASE_ONE)
me->GetMotionMaster()->MoveChase(victim);
}
@@ -282,31 +278,61 @@ class boss_lady_deathwhisper : public CreatureScript
{
if (!instance->CheckRequiredBosses(DATA_LADY_DEATHWHISPER, who->ToPlayer()))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_SEQUENCE_BREAK);
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
+ me->SetCombatPulseDelay(5);
me->setActive(true);
DoZoneInCombat();
-
- events.Reset();
- events.SetPhase(PHASE_ONE);
+ _phase = PHASE_ONE;
+ scheduler.CancelGroup(GROUP_INTRO);
// phase-independent events
- events.ScheduleEvent(EVENT_BERSERK, 600000);
- events.ScheduleEvent(EVENT_DEATH_AND_DECAY, 10000);
+ scheduler
+ .Schedule(Minutes(10), [this](TaskContext /*context*/)
+ {
+ DoCastSelf(SPELL_BERSERK);
+ Talk(SAY_BERSERK);
+ })
+ .Schedule(Seconds(17), [this](TaskContext death_and_decay)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_DEATH_AND_DECAY);
+ death_and_decay.Repeat(Seconds(22), Seconds(30));
+ });
+ if (GetDifficulty() != RAID_DIFFICULTY_10MAN_NORMAL)
+ scheduler.Schedule(Seconds(27), [this](TaskContext dominate_mind)
+ {
+ Talk(SAY_DOMINATE_MIND);
+ for (uint8 i = 0; i < _dominateMindCount; i++)
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_DOMINATE_MIND))
+ DoCast(target, SPELL_DOMINATE_MIND);
+ dominate_mind.Repeat(Seconds(40), Seconds(45));
+ });
// phase one only
- events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, 5000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_P1_SHADOW_BOLT, urand(5500, 6000), 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_P1_EMPOWER_CULTIST, urand(20000, 30000), 0, PHASE_ONE);
- if (GetDifficulty() != RAID_DIFFICULTY_10MAN_NORMAL)
- events.ScheduleEvent(EVENT_DOMINATE_MIND_H, 27000);
+ scheduler
+ .Schedule(Seconds(5), GROUP_ONE, [this](TaskContext wave)
+ {
+ SummonWaveP1();
+ wave.Repeat(Seconds(IsHeroic() ? 45 : 60));
+ })
+ .Schedule(Seconds(2), GROUP_ONE, [this](TaskContext shadow_bolt)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_SHADOW_BOLT);
+ shadow_bolt.Repeat(Milliseconds(2450), Milliseconds(3600));
+ })
+ .Schedule(Seconds(15), GROUP_ONE, [this](TaskContext context)
+ {
+ DoImproveCultist();
+ context.Repeat(Seconds(25));
+ });
Talk(SAY_AGGRO);
DoStartNoMovement(who);
me->RemoveAurasDueToSpell(SPELL_SHADOW_CHANNELING);
- DoCast(me, SPELL_MANA_BARRIER, true);
-
+ DoCastSelf(SPELL_MANA_BARRIER, true);
instance->SetBossState(DATA_LADY_DEATHWHISPER, IN_PROGRESS);
}
@@ -338,7 +364,7 @@ class boss_lady_deathwhisper : public CreatureScript
{
if (Group* group = owner->GetGroup())
{
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* member = itr->GetSource())
member->KilledMonsterCredit(NPC_DARNAVAN_CREDIT);
}
@@ -351,17 +377,14 @@ class boss_lady_deathwhisper : public CreatureScript
_JustDied();
}
- void JustReachedHome() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
- _JustReachedHome();
- instance->SetBossState(DATA_LADY_DEATHWHISPER, FAIL);
-
+ scheduler.CancelAll();
summons.DespawnAll();
if (Creature* darnavan = ObjectAccessor::GetCreature(*me, _darnavanGUID))
- {
darnavan->DespawnOrUnsummon();
- _darnavanGUID.Clear();
- }
+
+ _DespawnAtEvade();
}
void KilledUnit(Unit* victim) override
@@ -373,151 +396,98 @@ class boss_lady_deathwhisper : public CreatureScript
void DamageTaken(Unit* /*damageDealer*/, uint32& damage) override
{
// phase transition
- if (events.IsInPhase(PHASE_ONE) && damage > me->GetPower(POWER_MANA))
+ if (_phase == PHASE_ONE && damage > me->GetPower(POWER_MANA))
{
+ _phase = PHASE_TWO;
Talk(SAY_PHASE_2);
Talk(EMOTE_PHASE_2);
DoStartMovement(me->GetVictim());
+ DoResetThreat();
damage -= me->GetPower(POWER_MANA);
me->SetPower(POWER_MANA, 0);
me->RemoveAurasDueToSpell(SPELL_MANA_BARRIER);
- events.SetPhase(PHASE_TWO);
- events.ScheduleEvent(EVENT_P2_FROSTBOLT, urand(10000, 12000), 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_P2_FROSTBOLT_VOLLEY, urand(19000, 21000), 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_P2_TOUCH_OF_INSIGNIFICANCE, urand(6000, 9000), 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_P2_SUMMON_SHADE, urand(12000, 15000), 0, PHASE_TWO);
+ scheduler.CancelGroup(GROUP_ONE);
+
+ scheduler
+ .Schedule(Seconds(12), GROUP_TWO, [this](TaskContext frostbolt)
+ {
+ DoCastVictim(SPELL_FROSTBOLT);
+ frostbolt.Repeat();
+ })
+ .Schedule(Seconds(20), GROUP_TWO, [this](TaskContext frostboldVolley)
+ {
+ DoCastAOE(SPELL_FROSTBOLT_VOLLEY);
+ frostboldVolley.Repeat();
+ })
+ .Schedule(Seconds(6), Seconds(9), GROUP_TWO, [this](TaskContext touch)
+ {
+ if (me->GetVictim())
+ me->AddAura(SPELL_TOUCH_OF_INSIGNIFICANCE, me->EnsureVictim());
+ touch.Repeat();
+ })
+ .Schedule(Seconds(12), GROUP_TWO, [this](TaskContext summonShade)
+ {
+ me->CastCustomSpell(SPELL_SUMMON_SPIRITS, SPELLVALUE_MAX_TARGETS, Is25ManRaid() ? 2 : 1);
+ summonShade.Repeat();
+ });
+
// on heroic mode Lady Deathwhisper is immune to taunt effects in phase 2 and continues summoning adds
if (IsHeroic())
{
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
- events.ScheduleEvent(EVENT_P2_SUMMON_WAVE, 45000, 0, PHASE_TWO);
+ scheduler.Schedule(Seconds(), GROUP_TWO, [this](TaskContext context)
+ {
+ SummonWaveP2();
+ context.Repeat(Seconds(45));
+ });
}
}
}
- void JustSummoned(Creature* summon) override
+ void SpellHitTarget(Unit* target, const SpellInfo* spell) override
{
- if (summon->GetEntry() == NPC_DARNAVAN)
- _darnavanGUID = summon->GetGUID();
- else
- summons.Summon(summon);
+ if (spell->Id == SPELL_SUMMON_SPIRITS)
+ _nextVengefulShadeTargetGUID.push_back(target->GetGUID());
+ }
- Unit* target = NULL;
- if (summon->GetEntry() == NPC_VENGEFUL_SHADE)
+ void JustSummoned(Creature* summon) override
+ {
+ switch (summon->GetEntry())
{
- target = ObjectAccessor::GetUnit(*me, _nextVengefulShadeTargetGUID); // Vengeful Shade
- _nextVengefulShadeTargetGUID.Clear();
+ case NPC_DARNAVAN_10:
+ case NPC_DARNAVAN_25:
+ _darnavanGUID = summon->GetGUID();
+ summon->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM));
+ return;
+ case NPC_VENGEFUL_SHADE:
+ if (_nextVengefulShadeTargetGUID.empty())
+ break;
+ summon->AI()->SetGUID(_nextVengefulShadeTargetGUID.front());
+ _nextVengefulShadeTargetGUID.pop_front();
+ break;
+ case NPC_CULT_ADHERENT:
+ case NPC_CULT_FANATIC:
+ _cultistQueue.push_back(summon->GetGUID());
+ summon->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM));
+ break;
+ default:
+ break;
}
- else
- target = SelectTarget(SELECT_TARGET_RANDOM); // Wave adds
-
- summon->AI()->AttackStart(target); // CAN be NULL
- if (summon->GetEntry() == NPC_REANIMATED_FANATIC)
- summon->CastSpell(summon, SPELL_FANATIC_S_DETERMINATION, true);
- else if (summon->GetEntry() == NPC_REANIMATED_ADHERENT)
- summon->CastSpell(summon, SPELL_ADHERENT_S_DETERMINATION, true);
+ summons.Summon(summon);
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO))
+ if (!UpdateVictim() && _phase != PHASE_INTRO)
return;
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_INTRO))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ scheduler.Update(diff, [this]
{
- switch (eventId)
- {
- case EVENT_INTRO_2:
- Talk(SAY_INTRO_2);
- break;
- case EVENT_INTRO_3:
- Talk(SAY_INTRO_3);
- break;
- case EVENT_INTRO_4:
- Talk(SAY_INTRO_4);
- break;
- case EVENT_INTRO_5:
- Talk(SAY_INTRO_5);
- break;
- case EVENT_INTRO_6:
- Talk(SAY_INTRO_6);
- break;
- case EVENT_INTRO_7:
- Talk(SAY_INTRO_7);
- break;
- case EVENT_DEATH_AND_DECAY:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_DEATH_AND_DECAY);
- events.ScheduleEvent(EVENT_DEATH_AND_DECAY, urand(22000, 30000));
- break;
- case EVENT_DOMINATE_MIND_H:
- Talk(SAY_DOMINATE_MIND);
- for (uint8 i = 0; i < _dominateMindCount; i++)
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_DOMINATE_MIND_H))
- DoCast(target, SPELL_DOMINATE_MIND_H);
- events.ScheduleEvent(EVENT_DOMINATE_MIND_H, urand(40000, 45000));
- break;
- case EVENT_P1_SUMMON_WAVE:
- SummonWaveP1();
- events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, IsHeroic() ? 45000 : 60000, 0, PHASE_ONE);
- break;
- case EVENT_P1_SHADOW_BOLT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_SHADOW_BOLT);
- events.ScheduleEvent(EVENT_P1_SHADOW_BOLT, urand(5000, 8000), 0, PHASE_ONE);
- break;
- case EVENT_P1_REANIMATE_CULTIST:
- ReanimateCultist();
- break;
- case EVENT_P1_EMPOWER_CULTIST:
- EmpowerCultist();
- events.ScheduleEvent(EVENT_P1_EMPOWER_CULTIST, urand(18000, 25000));
- break;
- case EVENT_P2_FROSTBOLT:
- DoCastVictim(SPELL_FROSTBOLT);
- events.ScheduleEvent(EVENT_P2_FROSTBOLT, urand(10000, 11000), 0, PHASE_TWO);
- break;
- case EVENT_P2_FROSTBOLT_VOLLEY:
- DoCastAOE(SPELL_FROSTBOLT_VOLLEY);
- events.ScheduleEvent(EVENT_P2_FROSTBOLT_VOLLEY, urand(13000, 15000), 0, PHASE_TWO);
- break;
- case EVENT_P2_TOUCH_OF_INSIGNIFICANCE:
- DoCastVictim(SPELL_TOUCH_OF_INSIGNIFICANCE);
- events.ScheduleEvent(EVENT_P2_TOUCH_OF_INSIGNIFICANCE, urand(9000, 13000), 0, PHASE_TWO);
- break;
- case EVENT_P2_SUMMON_SHADE:
- if (Unit* shadeTarget = SelectTarget(SELECT_TARGET_RANDOM, 1))
- {
- _nextVengefulShadeTargetGUID = shadeTarget->GetGUID();
- DoCast(shadeTarget, SPELL_SUMMON_SHADE);
- }
- events.ScheduleEvent(EVENT_P2_SUMMON_SHADE, urand(18000, 23000), 0, PHASE_TWO);
- break;
- case EVENT_P2_SUMMON_WAVE:
- SummonWaveP2();
- events.ScheduleEvent(EVENT_P2_SUMMON_WAVE, 45000, 0, PHASE_TWO);
- break;
- case EVENT_BERSERK:
- DoCast(me, SPELL_BERSERK);
- Talk(SAY_BERSERK);
- break;
- }
-
- if (me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_INTRO))
- return;
- }
-
- // We should not melee attack when barrier is up
- if (me->HasAura(SPELL_MANA_BARRIER))
- return;
-
- DoMeleeAttackIfReady();
+ // We should not melee attack when barrier is up
+ if (!me->HasAura(SPELL_MANA_BARRIER))
+ DoMeleeAttackIfReady();
+ });
}
// summoning function for first phase
@@ -568,72 +538,40 @@ class boss_lady_deathwhisper : public CreatureScript
summon->CastSpell(summon, SPELL_TELEPORT_VISUAL);
}
- void SetGUID(ObjectGuid guid, int32 id/* = 0*/) override
+ void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
- if (id != GUID_CULTIST)
- return;
-
- _reanimationQueue.push_back(guid);
- events.ScheduleEvent(EVENT_P1_REANIMATE_CULTIST, 3000, 0, PHASE_ONE);
+ if (summon->GetEntry() == NPC_CULT_ADHERENT || summon->GetEntry() == NPC_CULT_FANATIC)
+ _cultistQueue.remove(summon->GetGUID());
}
- void ReanimateCultist()
+ void DoImproveCultist()
{
- if (_reanimationQueue.empty())
+ if (_cultistQueue.empty())
return;
- ObjectGuid cultistGUID = _reanimationQueue.front();
- Creature* cultist = ObjectAccessor::GetCreature(*me, cultistGUID);
- _reanimationQueue.pop_front();
+ _cultistGUID = Trinity::Containers::SelectRandomContainerElement(_cultistQueue);
+ _cultistQueue.remove(_cultistGUID);
+ Creature* cultist = ObjectAccessor::GetCreature(*me, _cultistGUID);
if (!cultist)
return;
- Talk(SAY_ANIMATE_DEAD);
- DoCast(cultist, SPELL_DARK_MARTYRDOM_T);
- }
-
- void SpellHitTarget(Unit* target, SpellInfo const* spell) override
- {
- if (spell->Id == SPELL_DARK_MARTYRDOM_T)
+ if (RAND(0,1))
+ me->CastSpell(cultist, SPELL_DARK_MARTYRDOM_T);
+ else
{
- Position pos = target->GetPosition();
- if (target->GetEntry() == NPC_CULT_FANATIC)
- me->SummonCreature(NPC_REANIMATED_FANATIC, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- else
- me->SummonCreature(NPC_REANIMATED_ADHERENT, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
-
- if (TempSummon* summon = target->ToTempSummon())
- summon->UnSummon();
+ me->CastSpell(cultist, cultist->GetEntry() == NPC_CULT_FANATIC ? SPELL_DARK_TRANSFORMATION_T : SPELL_DARK_EMPOWERMENT_T, true);
+ Talk(uint8(cultist->GetEntry() == NPC_CULT_FANATIC ? SAY_DARK_TRANSFORMATION : SAY_DARK_EMPOWERMENT));
}
}
- void EmpowerCultist()
- {
- if (summons.empty())
- return;
-
- std::list<Creature*> temp;
- for (SummonList::iterator itr = summons.begin(); itr != summons.end(); ++itr)
- if (Creature* cre = ObjectAccessor::GetCreature(*me, *itr))
- if (cre->IsAlive() && (cre->GetEntry() == NPC_CULT_FANATIC || cre->GetEntry() == NPC_CULT_ADHERENT))
- temp.push_back(cre);
-
- // noone to empower
- if (temp.empty())
- return;
-
- // select random cultist
- Creature* cultist = Trinity::Containers::SelectRandomContainerElement(temp);
- DoCast(cultist, cultist->GetEntry() == NPC_CULT_FANATIC ? SPELL_DARK_TRANSFORMATION_T : SPELL_DARK_EMPOWERMENT_T, true);
- Talk(uint8(cultist->GetEntry() == NPC_CULT_FANATIC ? SAY_DARK_TRANSFORMATION : SAY_DARK_EMPOWERMENT));
- }
-
private:
- ObjectGuid _nextVengefulShadeTargetGUID;
ObjectGuid _darnavanGUID;
- GuidDeque _reanimationQueue;
+ ObjectGuid _cultistGUID;
+ GuidList _cultistQueue;
+ GuidList _nextVengefulShadeTargetGUID;
uint32 _waveCounter;
uint8 const _dominateMindCount;
+ uint8 _phase;
bool _introDone;
};
@@ -643,8 +581,6 @@ class boss_lady_deathwhisper : public CreatureScript
}
};
-typedef boss_lady_deathwhisper::boss_lady_deathwhisperAI DeathwisperAI;
-
class npc_cult_fanatic : public CreatureScript
{
public:
@@ -652,71 +588,91 @@ class npc_cult_fanatic : public CreatureScript
struct npc_cult_fanaticAI : public ScriptedAI
{
- npc_cult_fanaticAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_cult_fanaticAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
void Reset() override
{
- Events.Reset();
- Events.ScheduleEvent(EVENT_FANATIC_NECROTIC_STRIKE, urand(10000, 12000));
- Events.ScheduleEvent(EVENT_FANATIC_SHADOW_CLEAVE, urand(14000, 16000));
- Events.ScheduleEvent(EVENT_FANATIC_VAMPIRIC_MIGHT, urand(20000, 27000));
- if (me->GetEntry() == NPC_CULT_FANATIC)
- Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, urand(18000, 32000));
+ _scheduler.CancelAll();
+ _scheduler
+ .SetValidator([this]
+ {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ })
+ .Schedule(Seconds(17), [this](TaskContext vampiric_might)
+ {
+ DoCastSelf(SPELL_VAMPIRIC_MIGHT);
+ vampiric_might.Repeat(Seconds(25));
+ })
+ .Schedule(Seconds(12), [this](TaskContext shadow_cleave)
+ {
+ DoCastVictim(SPELL_SHADOW_CLEAVE);
+ shadow_cleave.Repeat(Seconds(14));
+ })
+ .Schedule(Seconds(10), [this](TaskContext necrotic_strike)
+ {
+ DoCastVictim(SPELL_NECROTIC_STRIKE);
+ necrotic_strike.Repeat(Seconds(17));
+ });
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
- if (spell->Id == SPELL_DARK_TRANSFORMATION)
- me->UpdateEntry(NPC_DEFORMED_FANATIC);
- else if (spell->Id == SPELL_DARK_TRANSFORMATION_T)
+ switch (spell->Id)
{
- Events.CancelEvent(EVENT_CULTIST_DARK_MARTYRDOM);
- me->InterruptNonMeleeSpells(true);
- DoCast(me, SPELL_DARK_TRANSFORMATION);
+ case SPELL_DARK_TRANSFORMATION_T:
+ me->InterruptNonMeleeSpells(true);
+ DoCastSelf(SPELL_DARK_TRANSFORMATION);
+ break;
+ case SPELL_DARK_TRANSFORMATION:
+ DoCastSelf(SPELL_FULL_HEAL);
+ me->UpdateEntry(NPC_DEFORMED_FANATIC);
+ break;
+ case SPELL_DARK_MARTYRDOM_T:
+ me->SetReactState(REACT_PASSIVE);
+ me->InterruptNonMeleeSpells(true);
+ me->AttackStop();
+ DoCastSelf(SPELL_DARK_MARTYRDOM_FANATIC);
+ break;
+ case SPELL_DARK_MARTYRDOM_FANATIC:
+ _scheduler
+ .Schedule(Seconds(2), [this](TaskContext /*context*/)
+ {
+ me->UpdateEntry(NPC_REANIMATED_FANATIC);
+ DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH);
+ DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS);
+ DoCastSelf(SPELL_FULL_HEAL, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_UNK_29 | UNIT_FLAG_NOT_SELECTABLE);
+ })
+ .Schedule(Seconds(6), [this](TaskContext /*context*/)
+ {
+ me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_UNK_29 | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoZoneInCombat(me);
+
+ if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
+ ladyDeathwhisper->AI()->Talk(SAY_ANIMATE_DEAD);
+ });
+ break;
+ default:
+ break;
}
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
- return;
-
- Events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
+ if (!UpdateVictim() && !me->HasAura(SPELL_PERMANENT_FEIGN_DEATH))
return;
- while (uint32 eventId = Events.ExecuteEvent())
+ _scheduler.Update(diff, [this]
{
- switch (eventId)
- {
- case EVENT_FANATIC_NECROTIC_STRIKE:
- DoCastVictim(SPELL_NECROTIC_STRIKE);
- Events.ScheduleEvent(EVENT_FANATIC_NECROTIC_STRIKE, urand(11000, 13000));
- break;
- case EVENT_FANATIC_SHADOW_CLEAVE:
- DoCastVictim(SPELL_SHADOW_CLEAVE);
- Events.ScheduleEvent(EVENT_FANATIC_SHADOW_CLEAVE, urand(9500, 11000));
- break;
- case EVENT_FANATIC_VAMPIRIC_MIGHT:
- DoCast(me, SPELL_VAMPIRIC_MIGHT);
- Events.ScheduleEvent(EVENT_FANATIC_VAMPIRIC_MIGHT, urand(20000, 27000));
- break;
- case EVENT_CULTIST_DARK_MARTYRDOM:
- DoCast(me, SPELL_DARK_MARTYRDOM_FANATIC);
- Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, urand(16000, 21000));
- break;
- }
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- }
-
- DoMeleeAttackIfReady();
+ DoMeleeAttackIfReady();
+ });
}
protected:
- EventMap Events;
+ TaskScheduler _scheduler;
+ InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -732,80 +688,88 @@ class npc_cult_adherent : public CreatureScript
struct npc_cult_adherentAI : public ScriptedAI
{
- npc_cult_adherentAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_cult_adherentAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
void Reset() override
{
- Events.Reset();
- Events.ScheduleEvent(EVENT_ADHERENT_FROST_FEVER, urand(10000, 12000));
- Events.ScheduleEvent(EVENT_ADHERENT_DEATHCHILL, urand(14000, 16000));
- Events.ScheduleEvent(EVENT_ADHERENT_CURSE_OF_TORPOR, urand(14000, 16000));
- Events.ScheduleEvent(EVENT_ADHERENT_SHORUD_OF_THE_OCCULT, urand(32000, 39000));
- if (me->GetEntry() == NPC_CULT_ADHERENT)
- Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, urand(18000, 32000));
+ _scheduler.CancelAll();
+ _scheduler
+ .SetValidator([this]
+ {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ })
+ .Schedule(Seconds(5), [this](TaskContext deathchill)
+ {
+ if (me->GetEntry() == NPC_EMPOWERED_ADHERENT)
+ DoCastVictim(SPELL_DEATHCHILL_BLAST);
+ else
+ DoCastVictim(SPELL_DEATHCHILL_BOLT);
+ deathchill.Repeat(Milliseconds(2500));
+ })
+ .Schedule(Seconds(15), [this](TaskContext shroud_of_the_occult)
+ {
+ DoCastSelf(SPELL_SHROUD_OF_THE_OCCULT);
+ shroud_of_the_occult.Repeat(Seconds(10));
+ })
+ .Schedule(Seconds(15), [this](TaskContext curse_of_torpor)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ DoCast(target, SPELL_CURSE_OF_TORPOR);
+ curse_of_torpor.Repeat(Seconds(18));
+ });
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
- if (spell->Id == SPELL_DARK_EMPOWERMENT)
- me->UpdateEntry(NPC_EMPOWERED_ADHERENT);
- else if (spell->Id == SPELL_DARK_EMPOWERMENT_T)
+ switch (spell->Id)
{
- Events.CancelEvent(EVENT_CULTIST_DARK_MARTYRDOM);
- me->InterruptNonMeleeSpells(true);
- DoCast(me, SPELL_DARK_EMPOWERMENT);
+ case SPELL_DARK_EMPOWERMENT_T:
+ me->UpdateEntry(NPC_EMPOWERED_ADHERENT);
+ break;
+ case SPELL_DARK_MARTYRDOM_T:
+ me->SetReactState(REACT_PASSIVE);
+ me->InterruptNonMeleeSpells(true);
+ me->AttackStop();
+ DoCastSelf(SPELL_DARK_MARTYRDOM_ADHERENT);
+ break;
+ case SPELL_DARK_MARTYRDOM_ADHERENT:
+ _scheduler
+ .Schedule(Seconds(2), [this](TaskContext /*context*/)
+ {
+ me->UpdateEntry(NPC_REANIMATED_ADHERENT);
+ DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH);
+ DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS);
+ DoCastSelf(SPELL_FULL_HEAL, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_UNK_29 | UNIT_FLAG_NOT_SELECTABLE);
+ })
+ .Schedule(Seconds(6), [this](TaskContext /*context*/)
+ {
+ me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_UNK_29 | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoCastSelf(SPELL_SHROUD_OF_THE_OCCULT);
+ DoZoneInCombat(me);
+
+ if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
+ ladyDeathwhisper->AI()->Talk(SAY_ANIMATE_DEAD);
+ });
+ break;
+ default:
+ break;
}
}
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
+ if (!UpdateVictim() && !me->HasAura(SPELL_PERMANENT_FEIGN_DEATH))
return;
- Events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = Events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_ADHERENT_FROST_FEVER:
- DoCastVictim(SPELL_FROST_FEVER);
- Events.ScheduleEvent(EVENT_ADHERENT_FROST_FEVER, urand(9000, 13000));
- break;
- case EVENT_ADHERENT_DEATHCHILL:
- if (me->GetEntry() == NPC_EMPOWERED_ADHERENT)
- DoCastVictim(SPELL_DEATHCHILL_BLAST);
- else
- DoCastVictim(SPELL_DEATHCHILL_BOLT);
- Events.ScheduleEvent(EVENT_ADHERENT_DEATHCHILL, urand(9000, 13000));
- break;
- case EVENT_ADHERENT_CURSE_OF_TORPOR:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
- DoCast(target, SPELL_CURSE_OF_TORPOR);
- Events.ScheduleEvent(EVENT_ADHERENT_CURSE_OF_TORPOR, urand(9000, 13000));
- break;
- case EVENT_ADHERENT_SHORUD_OF_THE_OCCULT:
- DoCast(me, SPELL_SHORUD_OF_THE_OCCULT);
- Events.ScheduleEvent(EVENT_ADHERENT_SHORUD_OF_THE_OCCULT, urand(27000, 32000));
- break;
- case EVENT_CULTIST_DARK_MARTYRDOM:
- DoCast(me, SPELL_DARK_MARTYRDOM_ADHERENT);
- Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, urand(16000, 21000));
- break;
- }
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- }
-
- DoMeleeAttackIfReady();
+ _scheduler.Update(diff);
}
protected:
- EventMap Events;
+ TaskScheduler _scheduler;
+ InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -821,15 +785,28 @@ class npc_vengeful_shade : public CreatureScript
struct npc_vengeful_shadeAI : public ScriptedAI
{
- npc_vengeful_shadeAI(Creature* creature) : ScriptedAI(creature)
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
+ npc_vengeful_shadeAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
+ me->SetReactState(REACT_PASSIVE);
me->AddAura(SPELL_VENGEFUL_BLAST_PASSIVE, me);
+
+ _scheduler
+ .Schedule(Seconds(2), [this](TaskContext /*context*/)
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->AI()->AttackStart(ObjectAccessor::GetUnit(*me, _targetGUID));
+ })
+ .Schedule(Seconds(7), [this](TaskContext /*context*/)
+ {
+ me->KillSelf();
+ });
+ }
+
+ void SetGUID(ObjectGuid guid, int32 /*type*/) override
+ {
+ _targetGUID = guid;
}
void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) override
@@ -846,6 +823,18 @@ class npc_vengeful_shade : public CreatureScript
break;
}
}
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff, [this]
+ {
+ DoMeleeAttackIfReady();
+ });
+ }
+
+ private:
+ TaskScheduler _scheduler;
+ ObjectGuid _targetGUID;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -875,10 +864,10 @@ class npc_darnavan : public CreatureScript
void Reset() override
{
_events.Reset();
- _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, 10000);
- _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, urand(20000, 25000));
- _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, urand(25000, 30000));
- _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, urand(5000, 8000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, Seconds(10));
+ _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, Seconds(20), Seconds(25));
+ _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, Seconds(25), Seconds(30));
+ _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, Seconds(5), Seconds(8));
Initialize();
}
@@ -889,7 +878,7 @@ class npc_darnavan : public CreatureScript
{
if (Group* group = owner->GetGroup())
{
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* member = itr->GetSource())
member->FailQuest(QUEST_DEPROGRAMMING);
}
@@ -925,7 +914,7 @@ class npc_darnavan : public CreatureScript
{
DoCastVictim(SPELL_SHATTERING_THROW);
_canShatter = false;
- _events.ScheduleEvent(EVENT_DARNAVAN_SHATTERING_THROW, 30000);
+ _events.ScheduleEvent(EVENT_DARNAVAN_SHATTERING_THROW, Seconds(30));
return;
}
@@ -933,7 +922,7 @@ class npc_darnavan : public CreatureScript
{
DoCastVictim(SPELL_CHARGE);
_canCharge = false;
- _events.ScheduleEvent(EVENT_DARNAVAN_CHARGE, 20000);
+ _events.ScheduleEvent(EVENT_DARNAVAN_CHARGE, Seconds(20));
return;
}
@@ -943,25 +932,25 @@ class npc_darnavan : public CreatureScript
{
case EVENT_DARNAVAN_BLADESTORM:
DoCast(SPELL_BLADESTORM);
- _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, urand(90000, 100000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, Seconds(90), Seconds(100));
break;
case EVENT_DARNAVAN_CHARGE:
_canCharge = true;
break;
case EVENT_DARNAVAN_INTIMIDATING_SHOUT:
DoCast(SPELL_INTIMIDATING_SHOUT);
- _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, urand(90000, 120000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, Seconds(90), Minutes(2));
break;
case EVENT_DARNAVAN_MORTAL_STRIKE:
DoCastVictim(SPELL_MORTAL_STRIKE);
- _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, urand(15000, 30000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, Seconds(15), Seconds(30));
break;
case EVENT_DARNAVAN_SHATTERING_THROW:
_canShatter = true;
break;
case EVENT_DARNAVAN_SUNDER_ARMOR:
DoCastVictim(SPELL_SUNDER_ARMOR);
- _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, urand(3000, 7000));
+ _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, Seconds(3), Seconds(7));
break;
}
}
@@ -1013,50 +1002,86 @@ class spell_deathwhisper_mana_barrier : public SpellScriptLoader
}
};
-class spell_cultist_dark_martyrdom : public SpellScriptLoader
+class at_lady_deathwhisper_entrance : public AreaTriggerScript
{
public:
- spell_cultist_dark_martyrdom() : SpellScriptLoader("spell_cultist_dark_martyrdom") { }
+ at_lady_deathwhisper_entrance() : AreaTriggerScript("at_lady_deathwhisper_entrance") { }
- class spell_cultist_dark_martyrdom_SpellScript : public SpellScript
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
{
- PrepareSpellScript(spell_cultist_dark_martyrdom_SpellScript);
+ if (InstanceScript* instance = player->GetInstanceScript())
+ if (instance->GetBossState(DATA_LADY_DEATHWHISPER) != DONE)
+ if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
+ ladyDeathwhisper->AI()->DoAction(ACTION_START_INTRO);
+
+ return true;
+ }
+};
+
+class spell_deathwhisper_dominated_mind : public SpellScriptLoader
+{
+ public:
+ spell_deathwhisper_dominated_mind() : SpellScriptLoader("spell_deathwhisper_dominated_mind") { }
- void HandleEffect(SpellEffIndex /*effIndex*/)
+ class spell_deathwhisper_dominated_mind_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_deathwhisper_dominated_mind_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
{
- if (GetCaster()->IsSummon())
- if (Unit* owner = GetCaster()->ToTempSummon()->GetSummoner())
- owner->GetAI()->SetGUID(GetCaster()->GetGUID(), GUID_CULTIST);
+ if (!sSpellMgr->GetSpellInfo(SPELL_DOMINATE_MIND_SCALE))
+ return false;
+ return true;
+ }
- GetCaster()->KillSelf();
- GetCaster()->SetDisplayId(uint32(GetCaster()->GetEntry() == NPC_CULT_FANATIC ? 38009 : 38010));
+ void HandleApply(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ target->CastSpell(target, SPELL_DOMINATE_MIND_SCALE, true);
}
void Register() override
{
- OnEffectHitTarget += SpellEffectFn(spell_cultist_dark_martyrdom_SpellScript::HandleEffect, EFFECT_2, SPELL_EFFECT_FORCE_DESELECT);
+ AfterEffectApply += AuraEffectApplyFn(spell_deathwhisper_dominated_mind_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_AOE_CHARM, AURA_EFFECT_HANDLE_REAL);
}
};
- SpellScript* GetSpellScript() const override
+ AuraScript* GetAuraScript() const override
{
- return new spell_cultist_dark_martyrdom_SpellScript();
+ return new spell_deathwhisper_dominated_mind_AuraScript();
}
};
-class at_lady_deathwhisper_entrance : public AreaTriggerScript
+class spell_deathwhisper_summon_spirits : public SpellScriptLoader
{
public:
- at_lady_deathwhisper_entrance() : AreaTriggerScript("at_lady_deathwhisper_entrance") { }
+ spell_deathwhisper_summon_spirits() : SpellScriptLoader("spell_deathwhisper_summon_spirits") { }
- bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
+ class spell_deathwhisper_summon_spirits_SpellScript : public SpellScript
{
- if (InstanceScript* instance = player->GetInstanceScript())
- if (instance->GetBossState(DATA_LADY_DEATHWHISPER) != DONE)
- if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
- ladyDeathwhisper->AI()->DoAction(ACTION_START_INTRO);
+ PrepareSpellScript(spell_deathwhisper_summon_spirits_SpellScript);
- return true;
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_SHADE))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_SHADE, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_deathwhisper_summon_spirits_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_deathwhisper_summon_spirits_SpellScript();
}
};
@@ -1068,6 +1093,7 @@ void AddSC_boss_lady_deathwhisper()
new npc_vengeful_shade();
new npc_darnavan();
new spell_deathwhisper_mana_barrier();
- new spell_cultist_dark_martyrdom();
+ new spell_deathwhisper_dominated_mind();
+ new spell_deathwhisper_summon_spirits();
new at_lady_deathwhisper_entrance();
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 794ef470d40..f1eaf45770e 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -1100,9 +1100,17 @@ class spell_gen_creature_permanent_feign_death : public SpellScriptLoader
target->ToCreature()->SetReactState(REACT_PASSIVE);
}
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+ target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ }
+
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_gen_creature_permanent_feign_death_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_creature_permanent_feign_death_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};