Scripts/Icecrown Citadel: Added Lady Deathwhisper script, huge thanks to wowgargamel for script parts, timers and sniffs
Core/Scripts: Added GetPhaseMask() method to EventMap --HG-- branch : trunk
This commit is contained in:
@@ -14749,6 +14749,8 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
|
||||
( 70834, 'spell_marrowgar_bone_storm'),
|
||||
( 70835, 'spell_marrowgar_bone_storm'),
|
||||
( 70836, 'spell_marrowgar_bone_storm'),
|
||||
( 70903, 'spell_cultist_dark_martyrdrom'),
|
||||
( 71236, 'spell_cultist_dark_martyrdrom'),
|
||||
-- quest
|
||||
( 45449, 'spell_q11587_arcane_prisoner_rescue'),
|
||||
( 46023, 'spell_q11730_ultrasonic_screwdriver'),
|
||||
|
||||
@@ -2652,6 +2652,26 @@ INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1`
|
||||
(36612,-1631009,'THE MASTER''S RAGE COURSES THROUGH ME!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16945,1,0,0,'SAY_BERSERK'),
|
||||
(36612,-1631010,'Lord Marrowgar creates a whirling storm of bone!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'SAY_BONE_STORM_EMOTE'),
|
||||
|
||||
-- Lady Deathwhisper
|
||||
(36855,-1631011,'You have found your way here, because you are among the few gifted with true vision in a world cursed with blindness.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17272,1,0,0,'SAY_INTRO_1'),
|
||||
(36855,-1631012,'You can see through the fog that hangs over this world like a shroud, and grasp where true power lies.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17273,1,0,0,'SAY_INTRO_2'),
|
||||
(36855,-1631013,'Fix your eyes upon your crude hands: the sinew, the soft meat, the dark blood coursing within.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16878,1,0,0,'SAY_INTRO_3'),
|
||||
(36855,-1631014,'It is a weakness; a crippling flaw.... A joke played by the Creators upon their own creations.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17268,1,0,0,'SAY_INTRO_4'),
|
||||
(36855,-1631015,'The sooner you come to accept your condition as a defect, the sooner you will find yourselves in a position to transcend it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17269,1,0,0,'SAY_INTRO_5'),
|
||||
(36855,-1631016,'Through our Master, all things are possible. His power is without limit, and his will unbending.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17270,1,0,0,'SAY_INTRO_6'),
|
||||
(36855,-1631017,'Those who oppose him will be destroyed utterly, and those who serve -- who serve wholly, unquestioningly, with utter devotion of mind and soul -- elevated to heights beyond your ken.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17271,1,0,0,'SAY_INTRO_7'),
|
||||
(36855,-1631018,'What is this disturbance?! You dare trespass upon this hallowed ground? This shall be your final resting place.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16868,1,0,0,'SAY_AGGRO'),
|
||||
(36855,-1631019,'Enough! I see I must take matters into my own hands!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16877,1,0,0,'SAY_PHASE_2'),
|
||||
(36855,-1631020,'Lady Deathwhisper''s Mana Barrier shimmers and fades away!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'SAY_PHASE_2_EMOTE'),
|
||||
(36855,-1631021,'You are weak, powerless to resist my will!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16876,1,0,0,'SAY_DOMINATE_MIND'),
|
||||
(36855,-1631022,'Take this blessing and show these intruders a taste of our master''s power.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16873,1,0,0,'SAY_DARK_EMPOWERMENT'),
|
||||
(36855,-1631023,'I release you from the curse of flesh!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16874,1,0,0,'SAY_DARK_TRANSFORMATION'),
|
||||
(36855,-1631024,'Arise and exult in your pure form!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16875,1,0,0,'SAY_ANIMATE_DEAD'),
|
||||
(36855,-1631025,'Do you yet grasp of the futility of your actions?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16869,1,0,0,'SAY_KILL_1'),
|
||||
(36855,-1631026,'Embrace the darkness... Darkness eternal!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16870,1,0,0,'SAY_KILL_2'),
|
||||
(36855,-1631027,'This charade has gone on long enough.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16872,1,0,0,'SAY_BERSERK'),
|
||||
(36855,-1631028,'All part of the masters plan! Your end is... inevitable!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16871,1,0,0,'SAY_DEATH');
|
||||
|
||||
-- -1 632 000 ICECROWN CITADEL: FROZEN HALLS: FORGE OF SOULS
|
||||
-- Bronjham
|
||||
(36497,-1632001,'Finally...a captive audience!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16595,1,0,0,'Bronjham SAY_AGGRO'),
|
||||
|
||||
@@ -831,6 +831,10 @@ UPDATE `instance_template` SET `script`='instance_icecrown_citadel' WHERE `map`=
|
||||
UPDATE `creature_template` SET `ScriptName`='boss_lord_marrowgar' WHERE `entry`=36612;
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_coldflame' WHERE `entry`=36672;
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_bone_spike' WHERE `entry`=36619;
|
||||
UPDATE `creature_template` SET `ScriptName`='boss_lady_deathwhisper' WHERE `entry`=36855;
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_cult_fanatic' WHERE `entry` IN (37890,38009,38135);
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_cult_adherent' WHERE `entry` IN(37949,38010,38136);
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_vengeful_shade' WHERE `entry`=38222;
|
||||
|
||||
/* IRONFORGE */
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_royal_historian_archesonus' WHERE `entry`=8879;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
DELETE FROM `script_texts` WHERE `entry` BETWEEN -1631028 AND -1631011;
|
||||
INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`,`sound`,`type`,`language`,`emote`,`comment`) VALUES
|
||||
(36855,-1631011, 'You have found your way here, because you are among the few gifted with true vision in a world cursed with blindness.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17272,1,0,0, 'SAY_INTRO_1'),
|
||||
(36855,-1631012, 'You can see through the fog that hangs over this world like a shroud, and grasp where true power lies.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17273,1,0,0, 'SAY_INTRO_2'),
|
||||
(36855,-1631013, 'Fix your eyes upon your crude hands: the sinew, the soft meat, the dark blood coursing within.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16878,1,0,0, 'SAY_INTRO_3'),
|
||||
(36855,-1631014, 'It is a weakness; a crippling flaw.... A joke played by the Creators upon their own creations.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17268,1,0,0, 'SAY_INTRO_4'),
|
||||
(36855,-1631015, 'The sooner you come to accept your condition as a defect, the sooner you will find yourselves in a position to transcend it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17269,1,0,0, 'SAY_INTRO_5'),
|
||||
(36855,-1631016, 'Through our Master, all things are possible. His power is without limit, and his will unbending.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17270,1,0,0, 'SAY_INTRO_6'),
|
||||
(36855,-1631017, 'Those who oppose him will be destroyed utterly, and those who serve -- who serve wholly, unquestioningly, with utter devotion of mind and soul -- elevated to heights beyond your ken.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17271,1,0,0, 'SAY_INTRO_7'),
|
||||
(36855,-1631018, 'What is this disturbance?! You dare trespass upon this hallowed ground? This shall be your final resting place.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16868,1,0,0, 'SAY_AGGRO'),
|
||||
(36855,-1631019, 'Enough! I see I must take matters into my own hands!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16877,1,0,0, 'SAY_PHASE_2'),
|
||||
(36855,-1631020, 'Lady Deathwhisper''s Mana Barrier shimmers and fades away!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0, 'SAY_PHASE_2_EMOTE'),
|
||||
(36855,-1631021, 'You are weak, powerless to resist my will!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16876,1,0,0, 'SAY_DOMINATE_MIND'),
|
||||
(36855,-1631022, 'Take this blessing and show these intruders a taste of our master''s power.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16873,1,0,0, 'SAY_DARK_EMPOWERMENT'),
|
||||
(36855,-1631023, 'I release you from the curse of flesh!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16874,1,0,0, 'SAY_DARK_TRANSFORMATION'),
|
||||
(36855,-1631024, 'Arise and exult in your pure form!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16875,1,0,0, 'SAY_ANIMATE_DEAD'),
|
||||
(36855,-1631025, 'Do you yet grasp of the futility of your actions?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16869,1,0,0, 'SAY_KILL_1'),
|
||||
(36855,-1631026, 'Embrace the darkness... Darkness eternal!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16870,1,0,0, 'SAY_KILL_2'),
|
||||
(36855,-1631027, 'This charade has gone on long enough.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16872,1,0,0, 'SAY_BERSERK'),
|
||||
(36855,-1631028, 'All part of the masters plan! Your end is... inevitable!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16871,1,0,0, 'SAY_DEATH');
|
||||
@@ -0,0 +1,4 @@
|
||||
UPDATE `creature_template` SET `ScriptName`='boss_lady_deathwhisper' WHERE `entry`=36855;
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_cult_fanatic' WHERE `entry` IN (37890,38009,38135);
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_cult_adherent' WHERE `entry` IN(37949,38010,38136);
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_vengeful_shade' WHERE `entry`=38222;
|
||||
@@ -0,0 +1,4 @@
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id` IN (70903,71236) AND `ScriptName`='spell_cultist_dark_martyrdom';
|
||||
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
|
||||
(70903,'spell_cultist_dark_martyrdom'),
|
||||
(71236,'spell_cultist_dark_martyrdom');
|
||||
@@ -325,6 +325,8 @@ class EventMap : private std::map<uint32, uint32>
|
||||
|
||||
void Update(uint32 time) { m_time += time; }
|
||||
|
||||
uint32 GetPhaseMask() const { return (m_phase >> 24) & 0xFF; }
|
||||
|
||||
void SetPhase(uint32 phase)
|
||||
{
|
||||
if (phase && phase < 9)
|
||||
|
||||
@@ -418,6 +418,7 @@ void AddSC_halls_of_reflection();
|
||||
void AddSC_boss_falric();
|
||||
void AddSC_boss_marwyn();
|
||||
void AddSC_boss_lord_marrowgar(); // Icecrown Citadel
|
||||
void AddSC_boss_lady_deathwhisper();
|
||||
void AddSC_instance_icecrown_citadel();
|
||||
|
||||
void AddSC_dalaran();
|
||||
@@ -1082,6 +1083,7 @@ void AddNorthrendScripts()
|
||||
AddSC_boss_falric();
|
||||
AddSC_boss_marwyn();
|
||||
AddSC_boss_lord_marrowgar(); // Icecrown Citadel
|
||||
AddSC_boss_lady_deathwhisper();
|
||||
AddSC_instance_icecrown_citadel();
|
||||
|
||||
AddSC_dalaran();
|
||||
|
||||
@@ -2224,6 +2224,14 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
|
||||
case 39857: triggerSpellId = 39856; break;
|
||||
// Personalized Weather
|
||||
case 46736: triggerSpellId = 46737; break;
|
||||
// Mana Barrier - Lady Deathwhisper
|
||||
case 70842:
|
||||
{
|
||||
int32 missingHealth = caster->GetMaxHealth() - caster->GetHealth();
|
||||
caster->ModifyHealth(missingHealth);
|
||||
caster->ModifyPower(POWER_MANA, -missingHealth);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,798 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptPCH.h"
|
||||
#include "icecrown_citadel.h"
|
||||
|
||||
enum eScriptTexts
|
||||
{
|
||||
SAY_INTRO_1 = -1631011,
|
||||
SAY_INTRO_2 = -1631012,
|
||||
SAY_INTRO_3 = -1631013,
|
||||
SAY_INTRO_4 = -1631014,
|
||||
SAY_INTRO_5 = -1631015,
|
||||
SAY_INTRO_6 = -1631016,
|
||||
SAY_INTRO_7 = -1631017,
|
||||
SAY_AGGRO = -1631018,
|
||||
SAY_PHASE_2 = -1631019,
|
||||
SAY_PHASE_2_EMOTE = -1631020,
|
||||
SAY_DOMINATE_MIND = -1631021,
|
||||
SAY_DARK_EMPOWERMENT = -1631022,
|
||||
SAY_DARK_TRANSFORMATION = -1631023,
|
||||
SAY_ANIMATE_DEAD = -1631024,
|
||||
SAY_KILL_1 = -1631025,
|
||||
SAY_KILL_2 = -1631026,
|
||||
SAY_BERSERK = -1631027,
|
||||
SAY_DEATH = -1631028
|
||||
};
|
||||
|
||||
enum eSpells
|
||||
{
|
||||
// Lady Deathwhisper
|
||||
SPELL_MANA_BARRIER = 70842,
|
||||
SPELL_SHADOW_BOLT = 71254,
|
||||
SPELL_DEATH_AND_DECAY = 71001,
|
||||
SPELL_DOMINATE_MIND_H = 71289,
|
||||
SPELL_FROSTBOLT = 71420,
|
||||
SPELL_FROSTBOLT_VOLLEY = 72905,
|
||||
SPELL_TOUCH_OF_INSIGNIFICANCE = 71204,
|
||||
SPELL_SUMMON_SHADE = 71363,
|
||||
SPELL_SHADOW_CHANNELING = 43897, // Prefight, during intro
|
||||
SPELL_DARK_TRANSFORMATION_T = 70895,
|
||||
SPELL_DARK_EMPOWERMENT_T = 70896,
|
||||
SPELL_DARK_MARTYRDOM_T = 70897,
|
||||
|
||||
// Achievement
|
||||
SPELL_FULL_HOUSE = 72827, // does not exist in dbc but still can be used for criteria check
|
||||
|
||||
// Both Adds
|
||||
SPELL_TELEPORT_VISUAL = 41236,
|
||||
|
||||
// Fanatics
|
||||
SPELL_DARK_TRANSFORMATION = 70900,
|
||||
SPELL_NECROTIC_STRIKE = 70659,
|
||||
SPELL_SHADOW_CLEAVE = 70670,
|
||||
SPELL_VAMPIRIC_MIGHT = 70674,
|
||||
SPELL_FANATIC_S_DETERMINATION = 71235,
|
||||
SPELL_DARK_MARTYRDOM_FANATIC = 71236,
|
||||
|
||||
// Adherents
|
||||
SPELL_DARK_EMPOWERMENT = 70901,
|
||||
SPELL_FROST_FEVER = 67767,
|
||||
SPELL_DEATHCHILL_BOLT = 70594,
|
||||
SPELL_DEATHCHILL_BLAST = 70906,
|
||||
SPELL_CURSE_OF_TORPOR = 71237,
|
||||
SPELL_SHORUD_OF_THE_OCCULT = 70768,
|
||||
SPELL_ADHERENT_S_DETERMINATION = 71234,
|
||||
SPELL_DARK_MARTYRDOM_ADHERENT = 70903,
|
||||
|
||||
// Vengeful Shade
|
||||
SPELL_VENGEFUL_BLAST = 71544,
|
||||
SPELL_VENGEFUL_BLAST_PASSIVE = 71494
|
||||
};
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
// 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_INTRO_FINISH = 7,
|
||||
EVENT_BERSERK = 8,
|
||||
EVENT_DEATH_AND_DECAY = 9,
|
||||
EVENT_DOMINATE_MIND_H = 10,
|
||||
|
||||
// Phase 1 only
|
||||
EVENT_P1_SUMMON_WAVE = 11,
|
||||
EVENT_P1_SHADOW_BOLT = 12,
|
||||
EVENT_P1_EMPOWER_CULTIST = 13,
|
||||
EVENT_P1_REANIMATE_CULTIST = 14,
|
||||
|
||||
// Phase 2 only
|
||||
EVENT_P2_SUMMON_WAVE = 15,
|
||||
EVENT_P2_FROSTBOLT = 16,
|
||||
EVENT_P2_FROSTBOLT_VOLLEY = 17,
|
||||
EVENT_P2_TOUCH_OF_INSIGNIFICANCE = 18,
|
||||
EVENT_P2_SUMMON_SHADE = 19,
|
||||
|
||||
// Shared adds events
|
||||
EVENT_CULTIST_DARK_MARTYRDOM = 20,
|
||||
|
||||
// Cult Fanatic
|
||||
EVENT_FANATIC_NECROTIC_STRIKE = 21,
|
||||
EVENT_FANATIC_SHADOW_CLEAVE = 22,
|
||||
EVENT_FANATIC_VAMPIRIC_MIGHT = 23,
|
||||
|
||||
// Cult Adherent
|
||||
EVENT_ADHERENT_FROST_FEVER = 24,
|
||||
EVENT_ADHERENT_DEATHCHILL = 25,
|
||||
EVENT_ADHERENT_CURSE_OF_TORPOR = 26,
|
||||
EVENT_ADHERENT_SHORUD_OF_THE_OCCULT = 27
|
||||
};
|
||||
|
||||
enum ePhases
|
||||
{
|
||||
PHASE_ALL = 0,
|
||||
PHASE_INTRO = 1,
|
||||
PHASE_ONE = 2,
|
||||
PHASE_TWO = 3,
|
||||
|
||||
PHASE_INTRO_MASK = 1 << PHASE_INTRO,
|
||||
PHASE_ONE_MASK = 1 << PHASE_ONE,
|
||||
};
|
||||
|
||||
static const uint32 uiAddEntries[2] = {NPC_CULT_FANATIC, NPC_CULT_ADHERENT};
|
||||
|
||||
static const Position addSpawnPos[7] =
|
||||
{
|
||||
{-578.7066f, 2154.167f, 51.01529f, 1.692969f}, // 1 Left Door 1 (Cult Fanatic)
|
||||
{-598.9028f, 2155.005f, 51.01530f, 1.692969f}, // 2 Left Door 2 (Cult Adherent)
|
||||
{-619.2864f, 2154.460f, 51.01530f, 1.692969f}, // 3 Left Door 3 (Cult Fanatic)
|
||||
{-578.6996f, 2269.856f, 51.01529f, 4.590216f}, // 4 Right Door 1 (Cult Adherent)
|
||||
{-598.9688f, 2269.264f, 51.01529f, 4.590216f}, // 5 Right Door 2 (Cult Fanatic)
|
||||
{-619.4323f, 2268.523f, 51.01530f, 4.590216f}, // 6 Right Door 3 (Cult Adherent)
|
||||
{-524.2480f, 2211.920f, 62.90960f, 3.141592f} // 7 Upper (Random Cultist)
|
||||
};
|
||||
|
||||
class boss_lady_deathwhisper : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_lady_deathwhisper() : CreatureScript("boss_lady_deathwhisper") { }
|
||||
|
||||
struct boss_lady_deathwhisperAI : public ScriptedAI
|
||||
{
|
||||
boss_lady_deathwhisperAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
bIntroDone = false;
|
||||
uiDominateMindCount = RAID_MODE(0,1,1,3);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA));
|
||||
me->SetLastManaUse(0xFFFFFFFF); // hacky, but no other way atm to prevent mana regen
|
||||
events.Reset();
|
||||
events.SetPhase(PHASE_ONE);
|
||||
uiAddWaveCounter = 0;
|
||||
uiNextVengefulShadeTarget = 0;
|
||||
DoCast(me, SPELL_SHADOW_CHANNELING);
|
||||
me->RemoveAurasDueToSpell(SPELL_BERSERK);
|
||||
me->RemoveAurasDueToSpell(SPELL_MANA_BARRIER);
|
||||
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_LADY_DEATHWHISPER, NOT_STARTED);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!bIntroDone && me->IsWithinDistInMap(who, 100.0f))
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
bIntroDone = true;
|
||||
DoScriptText(SAY_INTRO_1, me);
|
||||
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);
|
||||
events.ScheduleEvent(EVENT_INTRO_FINISH, 76000, 0, PHASE_INTRO);
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit* victim)
|
||||
{
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
|
||||
return;
|
||||
|
||||
if (victim && me->Attack(victim, true) && !(events.GetPhaseMask() & PHASE_ONE_MASK))
|
||||
me->GetMotionMaster()->MoveChase(victim);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
events.Reset();
|
||||
events.SetPhase(PHASE_ONE);
|
||||
// phase-independent events
|
||||
events.ScheduleEvent(EVENT_BERSERK, 600000);
|
||||
events.ScheduleEvent(EVENT_DEATH_AND_DECAY, 10000);
|
||||
// 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);
|
||||
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
DoStartNoMovement(who);
|
||||
me->RemoveAurasDueToSpell(SPELL_SHADOW_CHANNELING);
|
||||
DoCast(me, SPELL_MANA_BARRIER, true);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_LADY_DEATHWHISPER, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_LADY_DEATHWHISPER, DONE);
|
||||
|
||||
std::set<uint32> livingAddEntries;
|
||||
// Full House achievement
|
||||
for (SummonList::iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Unit* unit = ObjectAccessor::GetUnit(*me, *itr))
|
||||
if (unit->isAlive() && unit->GetEntry() != NPC_VENGEFUL_SHADE)
|
||||
livingAddEntries.insert(unit->GetEntry());
|
||||
|
||||
if (livingAddEntries.size() >= 5)
|
||||
{
|
||||
if (Player *player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
{
|
||||
if (Group* group = player->GetGroup())
|
||||
{
|
||||
for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player* member = itr->getSource();
|
||||
if (!member || !member->IsAtGroupRewardDistance(me))
|
||||
continue;
|
||||
|
||||
if (member->isAlive()|| !member->GetCorpse())
|
||||
member->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_FULL_HOUSE, 0, me);
|
||||
}
|
||||
}
|
||||
else
|
||||
player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_FULL_HOUSE, 0, me);
|
||||
}
|
||||
}
|
||||
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
if(pInstance)
|
||||
pInstance->SetData(DATA_LADY_DEATHWHISPER, FAIL);
|
||||
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
DoScriptText(RAND(SAY_KILL_1, SAY_KILL_2), me);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*damageDealer*/, uint32& uiDamage)
|
||||
{
|
||||
// phase transition
|
||||
if (events.GetPhaseMask() & PHASE_ONE_MASK && uiDamage > me->GetPower(POWER_MANA))
|
||||
{
|
||||
DoScriptText(SAY_PHASE_2, me);
|
||||
DoScriptText(SAY_PHASE_2_EMOTE, me);
|
||||
DoStartMovement(me->getVictim());
|
||||
me->SetPower(POWER_MANA, 0);
|
||||
uiDamage -= me->GetPower(POWER_MANA);
|
||||
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);
|
||||
// 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, urand(30000, 60000), 0, PHASE_TWO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.push_back(summon->GetGUID());
|
||||
Unit* target = NULL;
|
||||
if (summon->GetEntry() == NPC_VENGEFUL_SHADE)
|
||||
{
|
||||
target = ObjectAccessor::GetUnit(*me, uiNextVengefulShadeTarget); // Vengeful Shade
|
||||
uiNextVengefulShadeTarget = 0;
|
||||
}
|
||||
else
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM); // Wave adds
|
||||
|
||||
summon->AI()->AttackStart(target); // CAN be NULL
|
||||
if (summon->GetEntry() == NPC_REANIMATED_FANATIC)
|
||||
summon->AI()->DoCast(summon, SPELL_FANATIC_S_DETERMINATION);
|
||||
else if (summon->GetEntry() == NPC_REANIMATED_ADHERENT)
|
||||
summon->AI()->DoCast(summon, SPELL_ADHERENT_S_DETERMINATION);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon)
|
||||
{
|
||||
summons.remove(summon->GetGUID());
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->hasUnitState(UNIT_STAT_CASTING) && !(events.GetPhaseMask() & PHASE_INTRO_MASK))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_INTRO_2:
|
||||
DoScriptText(SAY_INTRO_2, me);
|
||||
break;
|
||||
case EVENT_INTRO_3:
|
||||
DoScriptText(SAY_INTRO_3, me);
|
||||
break;
|
||||
case EVENT_INTRO_4:
|
||||
DoScriptText(SAY_INTRO_4, me);
|
||||
break;
|
||||
case EVENT_INTRO_5:
|
||||
DoScriptText(SAY_INTRO_5, me);
|
||||
break;
|
||||
case EVENT_INTRO_6:
|
||||
DoScriptText(SAY_INTRO_6, me);
|
||||
break;
|
||||
case EVENT_INTRO_7:
|
||||
DoScriptText(SAY_INTRO_7, me);
|
||||
break;
|
||||
case EVENT_INTRO_FINISH:
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
break;
|
||||
case EVENT_DEATH_AND_DECAY:
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(pTarget, SPELL_DEATH_AND_DECAY);
|
||||
events.ScheduleEvent(EVENT_DEATH_AND_DECAY, urand(10000, 12000));
|
||||
break;
|
||||
case EVENT_DOMINATE_MIND_H:
|
||||
DoScriptText(SAY_DOMINATE_MIND, me);
|
||||
for (uint8 i = 0; i < uiDominateMindCount; 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(18000, 22000));
|
||||
break;
|
||||
case EVENT_P1_SUMMON_WAVE:
|
||||
SummonWaveP1();
|
||||
events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, 60000, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_P1_SHADOW_BOLT:
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(pTarget, 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* pShadeTarget = SelectUnit(SELECT_TARGET_RANDOM, 1))
|
||||
{
|
||||
uiNextVengefulShadeTarget = pShadeTarget->GetGUID();
|
||||
DoCast(pShadeTarget, 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, 60000, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
DoScriptText(SAY_BERSERK, me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We should not melee attack when barrier is up
|
||||
if (me->HasAura(SPELL_MANA_BARRIER))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
// summoning function for first phase
|
||||
void SummonWaveP1()
|
||||
{
|
||||
uint8 addIndex = uiAddWaveCounter & 1;
|
||||
uint8 addIndexOther = addIndex ^ 1;
|
||||
_SummonAdd(uiAddEntries[addIndex], addSpawnPos[addIndex*3]);
|
||||
_SummonAdd(uiAddEntries[addIndexOther], addSpawnPos[addIndex*3+1]);
|
||||
_SummonAdd(uiAddEntries[addIndex], addSpawnPos[addIndex*3+2]);
|
||||
if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL || getDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC)
|
||||
{
|
||||
_SummonAdd(uiAddEntries[addIndexOther], addSpawnPos[addIndexOther*3]);
|
||||
_SummonAdd(uiAddEntries[addIndex], addSpawnPos[addIndexOther*3+1]);
|
||||
_SummonAdd(uiAddEntries[addIndexOther], addSpawnPos[addIndexOther*3+2]);
|
||||
_SummonAdd(uiAddEntries[urand(0,1)], addSpawnPos[6]);
|
||||
}
|
||||
++uiAddWaveCounter;
|
||||
}
|
||||
|
||||
// summoning function for second phase
|
||||
void SummonWaveP2()
|
||||
{
|
||||
if (getDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC)
|
||||
{
|
||||
uint8 addIndex = uiAddWaveCounter & 1;
|
||||
_SummonAdd(uiAddEntries[addIndex], addSpawnPos[addIndex*3]);
|
||||
_SummonAdd(uiAddEntries[addIndex ^ 1], addSpawnPos[addIndex*3+1]);
|
||||
_SummonAdd(uiAddEntries[addIndex], addSpawnPos[addIndex*3+2]);
|
||||
}
|
||||
else
|
||||
_SummonAdd(uiAddEntries[urand(0,1)], addSpawnPos[6]);
|
||||
++uiAddWaveCounter;
|
||||
}
|
||||
|
||||
// helper for summoning wave mobs
|
||||
void _SummonAdd(uint32 entry, const Position& pos)
|
||||
{
|
||||
if (TempSummon* summon = me->SummonCreature(entry, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
|
||||
summon->AI()->DoCast(summon, SPELL_TELEPORT_VISUAL);
|
||||
}
|
||||
|
||||
void AddToReanimationQueue(Unit* summon)
|
||||
{
|
||||
reanimationQueue.push_back(summon->GetGUID());
|
||||
events.ScheduleEvent(EVENT_P1_REANIMATE_CULTIST, 3000, 0, PHASE_ONE);
|
||||
}
|
||||
|
||||
void ReanimateCultist()
|
||||
{
|
||||
if (reanimationQueue.empty())
|
||||
return;
|
||||
|
||||
uint64 cultistGUID = reanimationQueue.front();
|
||||
Creature* cultist = ObjectAccessor::GetCreature(*me, cultistGUID);
|
||||
reanimationQueue.pop_front();
|
||||
if (!cultist)
|
||||
return;
|
||||
|
||||
DoScriptText(SAY_ANIMATE_DEAD, me);
|
||||
DoCast(cultist, SPELL_DARK_MARTYRDOM_T);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit * target, const SpellEntry * spell)
|
||||
{
|
||||
if (spell->Id == SPELL_DARK_MARTYRDOM_T)
|
||||
{
|
||||
Position pos;
|
||||
target->GetPosition(&pos);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void EmpowerCultist()
|
||||
{
|
||||
if (summons.empty())
|
||||
return;
|
||||
|
||||
std::list<Creature*> tmpList;
|
||||
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))
|
||||
tmpList.push_back(cre);
|
||||
|
||||
// noone to empower
|
||||
if (tmpList.empty())
|
||||
return;
|
||||
|
||||
// select random cultist
|
||||
std::list<Creature*>::iterator cultistItr = tmpList.begin();
|
||||
std::advance(cultistItr, urand(0, tmpList.size()-1));
|
||||
|
||||
Creature* cultist = *cultistItr;
|
||||
DoCast(cultist, cultist->GetEntry() == NPC_CULT_FANATIC ? SPELL_DARK_TRANSFORMATION_T : SPELL_DARK_EMPOWERMENT_T, true);
|
||||
DoScriptText(cultist->GetEntry() == NPC_CULT_FANATIC ? SAY_DARK_TRANSFORMATION : SAY_DARK_EMPOWERMENT, me);
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
InstanceScript* pInstance;
|
||||
bool bIntroDone;
|
||||
uint32 uiAddWaveCounter;
|
||||
uint64 uiNextVengefulShadeTarget;
|
||||
SummonList summons;
|
||||
std::deque<uint64> reanimationQueue;
|
||||
uint8 uiDominateMindCount;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_lady_deathwhisperAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_cult_fanatic : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_cult_fanatic() : CreatureScript("npc_cult_fanatic") { }
|
||||
|
||||
struct npc_cult_fanaticAI : public ScriptedAI
|
||||
{
|
||||
npc_cult_fanaticAI(Creature* pCreature) : ScriptedAI(pCreature) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, const SpellEntry * spell)
|
||||
{
|
||||
if (spell->Id == SPELL_DARK_TRANSFORMATION)
|
||||
me->UpdateEntry(NPC_DEFORMED_FANATIC);
|
||||
else if (spell->Id == SPELL_DARK_TRANSFORMATION_T)
|
||||
{
|
||||
events.CancelEvent(EVENT_CULTIST_DARK_MARTYRDOM);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
DoCast(me, SPELL_DARK_TRANSFORMATION);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->hasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_FANATIC_NECROTIC_STRIKE:
|
||||
DoCastVictim(SPELL_NECROTIC_STRIKE);
|
||||
events.ScheduleEvent(SPELL_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;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_cult_fanaticAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_cult_adherent : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_cult_adherent() : CreatureScript("npc_cult_adherent") { }
|
||||
|
||||
struct npc_cult_adherentAI : public ScriptedAI
|
||||
{
|
||||
npc_cult_adherentAI(Creature* pCreature) : ScriptedAI(pCreature) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, const SpellEntry * spell)
|
||||
{
|
||||
if (spell->Id == SPELL_DARK_EMPOWERMENT)
|
||||
me->UpdateEntry(NPC_EMPOWERED_ADHERENT);
|
||||
else if (spell->Id == SPELL_DARK_EMPOWERMENT_T)
|
||||
{
|
||||
events.CancelEvent(EVENT_CULTIST_DARK_MARTYRDOM);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
DoCast(me, SPELL_DARK_EMPOWERMENT);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->hasUnitState(UNIT_STAT_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* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1))
|
||||
DoCast(pTarget, 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;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_cult_adherentAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_vengeful_shade : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_vengeful_shade() : CreatureScript("npc_vengeful_shade") { }
|
||||
|
||||
struct npc_vengeful_shadeAI : public ScriptedAI
|
||||
{
|
||||
npc_vengeful_shadeAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->AddAura(SPELL_VENGEFUL_BLAST_PASSIVE, me);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit * /*pTarget*/, const SpellEntry * spell)
|
||||
{
|
||||
if (spell->Id == SPELL_VENGEFUL_BLAST)
|
||||
me->Kill(me);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_vengeful_shadeAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_cultist_dark_martyrdom : public SpellHandlerScript
|
||||
{
|
||||
public:
|
||||
spell_cultist_dark_martyrdom() : SpellHandlerScript("spell_cultist_dark_martyrdom") { }
|
||||
|
||||
class spell_cultist_dark_martyrdom_SpellScript : public SpellScript
|
||||
{
|
||||
bool Validate(SpellEntry const* spellEntry)
|
||||
{
|
||||
if (uint32 scriptId = sObjectMgr.GetScriptId("boss_lady_deathwhisper"))
|
||||
if (CreatureInfo const* creInfo = ObjectMgr::GetCreatureTemplate(NPC_LADY_DEATHWHISPER))
|
||||
if (creInfo->ScriptID == scriptId)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleEffect(SpellEffIndex effIndex)
|
||||
{
|
||||
if (GetCaster()->isSummon())
|
||||
if (Unit* owner = GetCaster()->ToTempSummon()->GetSummoner())
|
||||
if (owner->GetEntry() == NPC_LADY_DEATHWHISPER)
|
||||
CAST_AI(boss_lady_deathwhisper::boss_lady_deathwhisperAI, owner->ToCreature()->AI())->AddToReanimationQueue(GetCaster());
|
||||
|
||||
GetCaster()->Kill(GetCaster());
|
||||
GetCaster()->SetDisplayId(GetCaster()->GetEntry() == NPC_CULT_FANATIC ? 38009 : 38010);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
EffectHandlers += EffectHandlerFn(spell_cultist_dark_martyrdom_SpellScript::HandleEffect, EFFECT_2, SPELL_EFFECT_FORCE_DESELECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_cultist_dark_martyrdom_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_lady_deathwhisper()
|
||||
{
|
||||
new boss_lady_deathwhisper();
|
||||
new npc_cult_fanatic();
|
||||
new npc_cult_adherent();
|
||||
new npc_vengeful_shade();
|
||||
new spell_cultist_dark_martyrdom();
|
||||
}
|
||||
@@ -91,6 +91,7 @@ class boss_lord_marrowgar : public CreatureScript
|
||||
{
|
||||
me->SetSpeed(MOVE_RUN, fBaseSpeed, true);
|
||||
me->RemoveAurasDueToSpell(SPELL_BONE_STORM);
|
||||
me->RemoveAurasDueToSpell(SPELL_BERSERK);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000);
|
||||
events.ScheduleEvent(EVENT_BONE_SPIKE_GRAVEYARD, urand(20000, 30000));
|
||||
|
||||
@@ -48,14 +48,25 @@ enum eCreatures
|
||||
{
|
||||
NPC_LORD_MARROWGAR = 36612,
|
||||
NPC_COLDFLAME = 36672,
|
||||
NPC_BONE_SPIKE = 36619
|
||||
NPC_BONE_SPIKE = 36619,
|
||||
|
||||
NPC_LADY_DEATHWHISPER = 36855,
|
||||
NPC_CULT_FANATIC = 37890,
|
||||
NPC_DEFORMED_FANATIC = 38135,
|
||||
NPC_REANIMATED_FANATIC = 38009,
|
||||
NPC_CULT_ADHERENT = 37949,
|
||||
NPC_EMPOWERED_ADHERENT = 38136,
|
||||
NPC_REANIMATED_ADHERENT = 38010,
|
||||
NPC_VENGEFUL_SHADE = 38222,
|
||||
};
|
||||
|
||||
enum eGameobjects
|
||||
{
|
||||
DOODAD_ICECROWN_ICEWALL02 = 201910,
|
||||
ICEWALL = 201911,
|
||||
LORD_MARROWGAR_S_ENTRANCE = 201857
|
||||
DOODAD_ICECROWN_ICEWALL02 = 201910,
|
||||
ICEWALL = 201911,
|
||||
LORD_MARROWGAR_S_ENTRANCE = 201857,
|
||||
ORATORY_OF_THE_DAMNED_ENTRANCE = 201563,
|
||||
LADY_DEATHWHISPER_ELEVATOR = 202220,
|
||||
};
|
||||
|
||||
enum eAchievementCriteria
|
||||
|
||||
@@ -26,11 +26,13 @@ class instance_icecrown_citadel : public InstanceMapScript
|
||||
|
||||
struct instance_icecrown_citadel_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_icecrown_citadel_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
|
||||
instance_icecrown_citadel_InstanceMapScript(InstanceMap* pMap) : InstanceScript(pMap)
|
||||
{
|
||||
memset(uiEncounterState, 0, MAX_ENCOUNTER*sizeof(uint32));
|
||||
memset(uiIcewall, 0, 2*sizeof(uint32));
|
||||
uiMarrowgarEntrance = 0;
|
||||
uiLadyDeathwisperElevator = 0;
|
||||
uiOratoryDoor = 0;
|
||||
isBonedEligible = true;
|
||||
}
|
||||
|
||||
@@ -49,19 +51,32 @@ class instance_icecrown_citadel : public InstanceMapScript
|
||||
{
|
||||
case DOODAD_ICECROWN_ICEWALL02:
|
||||
uiIcewall[0] = pGo->GetGUID();
|
||||
if (GetData(DATA_LORD_MARROWGAR) == NOT_STARTED)
|
||||
HandleGameObject(uiIcewall[0], false, pGo);
|
||||
if (GetData(DATA_LORD_MARROWGAR) == DONE)
|
||||
HandleGameObject(uiIcewall[0], true, pGo);
|
||||
break;
|
||||
case ICEWALL:
|
||||
uiIcewall[1] = pGo->GetGUID();
|
||||
if (GetData(DATA_LORD_MARROWGAR) == NOT_STARTED)
|
||||
HandleGameObject(uiIcewall[1], false, pGo);
|
||||
if (GetData(DATA_LORD_MARROWGAR) == DONE)
|
||||
HandleGameObject(uiIcewall[1], true, pGo);
|
||||
break;
|
||||
case LORD_MARROWGAR_S_ENTRANCE:
|
||||
uiMarrowgarEntrance = pGo->GetGUID();
|
||||
if (GetData(DATA_LORD_MARROWGAR) == DONE)
|
||||
HandleGameObject(uiMarrowgarEntrance, true, pGo);
|
||||
break;
|
||||
case ORATORY_OF_THE_DAMNED_ENTRANCE:
|
||||
uiOratoryDoor = pGo->GetGUID();
|
||||
if (GetData(DATA_LADY_DEATHWHISPER) == DONE)
|
||||
HandleGameObject(uiOratoryDoor, true, pGo);
|
||||
break;
|
||||
case LADY_DEATHWHISPER_ELEVATOR:
|
||||
uiLadyDeathwisperElevator = pGo->GetGUID();
|
||||
if (GetData(DATA_LADY_DEATHWHISPER) == DONE)
|
||||
{
|
||||
pGo->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
|
||||
pGo->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +126,25 @@ class instance_icecrown_citadel : public InstanceMapScript
|
||||
}
|
||||
break;
|
||||
case DATA_LADY_DEATHWHISPER:
|
||||
uiEncounterState[type] = data;
|
||||
switch(data)
|
||||
{
|
||||
case DONE:
|
||||
HandleGameObject(uiOratoryDoor, true);
|
||||
if (GameObject* elevator = instance->GetGameObject(uiLadyDeathwisperElevator))
|
||||
{
|
||||
elevator->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
|
||||
elevator->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
HandleGameObject(uiOratoryDoor, false);
|
||||
break;
|
||||
case NOT_STARTED:
|
||||
HandleGameObject(uiOratoryDoor, true);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DATA_GUNSHIP_EVENT:
|
||||
case DATA_DEATHBRINGER_SAURFANG:
|
||||
case DATA_FESTERGUT:
|
||||
@@ -126,7 +160,11 @@ class instance_icecrown_citadel : public InstanceMapScript
|
||||
|
||||
case COMMAND_FAIL_BONED:
|
||||
isBonedEligible = data ? true : false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE && type < MAX_ENCOUNTER)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/)
|
||||
@@ -152,8 +190,6 @@ class instance_icecrown_citadel : public InstanceMapScript
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
saveStream << uiEncounterState[i] << " ";
|
||||
|
||||
saveStream << isBonedEligible;
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
@@ -183,8 +219,6 @@ class instance_icecrown_citadel : public InstanceMapScript
|
||||
tmpState = NOT_STARTED;
|
||||
uiEncounterState[i] = tmpState;
|
||||
}
|
||||
|
||||
loadStream >> isBonedEligible;
|
||||
} else OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
@@ -194,6 +228,8 @@ class instance_icecrown_citadel : public InstanceMapScript
|
||||
uint32 uiEncounterState[MAX_ENCOUNTER];
|
||||
uint64 uiIcewall[2];
|
||||
uint64 uiMarrowgarEntrance;
|
||||
uint64 uiLadyDeathwisperElevator;
|
||||
uint64 uiOratoryDoor;
|
||||
bool isBonedEligible;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user