aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Scripting/ScriptLoader.cpp2
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp18
-rw-r--r--src/server/scripts/Northrend/CMakeLists.txt1
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp29
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp1324
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h58
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp107
7 files changed, 1484 insertions, 55 deletions
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 482b8f51c73..969294733d5 100755
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -476,6 +476,7 @@ void AddSC_boss_rotface();
void AddSC_boss_professor_putricide();
void AddSC_boss_blood_prince_council();
void AddSC_boss_blood_queen_lana_thel();
+void AddSC_boss_valithria_dreamwalker();
void AddSC_boss_sindragosa();
void AddSC_icecrown_citadel_teleport();
void AddSC_instance_icecrown_citadel();
@@ -1171,6 +1172,7 @@ void AddNorthrendScripts()
AddSC_boss_professor_putricide();
AddSC_boss_blood_prince_council();
AddSC_boss_blood_queen_lana_thel();
+ AddSC_boss_valithria_dreamwalker();
AddSC_boss_sindragosa();
AddSC_icecrown_citadel_teleport();
AddSC_instance_icecrown_citadel();
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 8d98ae1a5a9..5791d311281 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -4099,6 +4099,24 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->AreaGroupId = 0;
++count;
break;
+ case 70588: // Suppression
+ case 70602: // Corruption
+ spellInfo->AttributesEx |= SPELL_ATTR1_STACK_FOR_DIFF_CASTERS;
+ ++count;
+ break;
+ case 70715: // Column of Frost (visual marker)
+ spellInfo->DurationIndex = 32; // 6 seconds (missing)
+ ++count;
+ break;
+ case 71085: // Mana Void (periodic aura)
+ spellInfo->DurationIndex = 9; // 30 seconds (missing)
+ ++count;
+ break;
+ case 70936: // Summon Suppressor
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ANY;
+ spellInfo->EffectImplicitTargetB[0] = 0;
+ ++count;
+ break;
case 71357: // Order Whelp
spellInfo->EffectRadiusIndex[0] = 22;
++count;
diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt
index 79f36fe3763..88e551cd6b6 100644
--- a/src/server/scripts/Northrend/CMakeLists.txt
+++ b/src/server/scripts/Northrend/CMakeLists.txt
@@ -165,6 +165,7 @@ set(scripts_STAT_SRCS
Northrend/IcecrownCitadel/boss_professor_putricide.cpp
Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+ Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
Northrend/IcecrownCitadel/boss_sindragosa.cpp
Northrend/zuldrak.cpp
Northrend/icecrown.cpp
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 2844376fe21..af5d50fc11c 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -932,6 +932,34 @@ class spell_putricide_slime_puddle : public SpellScriptLoader
}
};
+// this is here only because on retail you dont actually enter HEROIC mode for ICC
+class spell_putricide_slime_puddle_aura : public SpellScriptLoader
+{
+ public:
+ spell_putricide_slime_puddle_aura() : SpellScriptLoader("spell_putricide_slime_puddle_aura") { }
+
+ class spell_putricide_slime_puddle_aura_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_slime_puddle_aura_SpellScript);
+
+ void ReplaceAura()
+ {
+ if (Unit* target = GetHitUnit())
+ GetCaster()->AddAura((GetCaster()->GetMap()->GetSpawnMode() & 1) ? 72456 : 70346, target);
+ }
+
+ void Register()
+ {
+ OnHit += SpellHitFn(spell_putricide_slime_puddle_aura_SpellScript::ReplaceAura);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_slime_puddle_aura_SpellScript();
+ }
+};
+
class spell_putricide_unstable_experiment : public SpellScriptLoader
{
public:
@@ -1516,6 +1544,7 @@ void AddSC_boss_professor_putricide()
new spell_putricide_ooze_channel();
new spell_putricide_expunged_gas();
new spell_putricide_slime_puddle();
+ new spell_putricide_slime_puddle_aura();
new spell_putricide_unstable_experiment();
new spell_putricide_ooze_summon();
new spell_putricide_ooze_eruption_searcher();
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
new file mode 100644
index 00000000000..d99b5395a74
--- /dev/null
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -0,0 +1,1324 @@
+/*
+ * Copyright (C) 2008-2011 TrinityCore <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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellAuraEffects.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "icecrown_citadel.h"
+
+enum Texts
+{
+ // The Lich King
+ SAY_LICH_KING_INTRO = 0,
+
+ // Valithria Dreamwalker
+ SAY_VALITHRIA_ENTER_COMBAT = 0,
+ SAY_VALITHRIA_DREAM_PORTAL = 1,
+ SAY_VALITHRIA_75_PERCENT = 2,
+ SAY_VALITHRIA_25_PERCENT = 3,
+ SAY_VALITHRIA_DEATH = 4,
+ SAY_VALITHRIA_PLAYER_DEATH = 5,
+ SAY_VALITHRIA_BERSERK = 6,
+ SAY_VALITHRIA_SUCCESS = 7,
+};
+
+enum Spells
+{
+ // Valithria Dreamwalker
+ SPELL_COPY_DAMAGE = 71948,
+ SPELL_DREAM_PORTAL_VISUAL_PRE = 71304,
+ SPELL_NIGHTMARE_PORTAL_VISUAL_PRE = 71986,
+ SPELL_NIGHTMARE_CLOUD = 71970,
+ SPELL_NIGHTMARE_CLOUD_VISUAL = 71939,
+ SPELL_PRE_SUMMON_DREAM_PORTAL = 72224,
+ SPELL_PRE_SUMMON_NIGHTMARE_PORTAL = 72480,
+ SPELL_SUMMON_DREAM_PORTAL = 71305,
+ SPELL_SUMMON_NIGHTMARE_PORTAL = 71987,
+ SPELL_DREAMWALKERS_RAGE = 71189,
+ SPELL_DREAM_SLIP = 71196,
+ SPELL_ACHIEVEMENT_CHECK = 72706,
+ SPELL_CLEAR_ALL = 71721,
+ SPELL_AWARD_REPUTATION_BOSS_KILL = 73843,
+ SPELL_CORRUPTION_VALITHRIA = 70904,
+
+ // The Lich King
+ SPELL_TIMER_GLUTTONOUS_ABOMINATION = 70915,
+ SPELL_TIMER_SUPPRESSER = 70912,
+ SPELL_TIMER_BLISTERING_ZOMBIE = 70914,
+ SPELL_TIMER_RISEN_ARCHMAGE = 70916,
+ SPELL_TIMER_BLAZING_SKELETON = 70913,
+ SPELL_SUMMON_SUPPRESSER = 70936,
+ SPELL_RECENTLY_SPAWNED = 72954,
+ SPELL_SPAWN_CHEST = 71207,
+
+ // Risen Archmage
+ SPELL_CORRUPTION = 70602,
+ SPELL_FROSTBOLT_VOLLEY = 70759,
+ SPELL_MANA_VOID = 71179,
+ SPELL_COLUMN_OF_FROST = 70704,
+ SPELL_COLUMN_OF_FROST_DAMAGE = 70702,
+
+ // Blazing Skeleton
+ SPELL_FIREBALL = 70754,
+ SPELL_LEY_WASTE = 69325,
+
+ // Suppresser
+ SPELL_SUPPRESSION = 70588,
+
+ // Blistering Zombie
+ SPELL_ACID_BURST = 70744,
+
+ // Gluttonous Abomination
+ SPELL_GUT_SPRAY = 70633,
+ SPELL_ROT_WORM_SPAWNER = 70675,
+
+ // Dream Cloud
+ SPELL_EMERALD_VIGOR = 70873,
+
+ // Nightmare Cloud
+ SPELL_TWISTED_NIGHTMARE = 71941,
+};
+
+#define SUMMON_PORTAL RAID_MODE<uint32>(SPELL_PRE_SUMMON_DREAM_PORTAL, SPELL_PRE_SUMMON_DREAM_PORTAL, \
+ SPELL_PRE_SUMMON_NIGHTMARE_PORTAL, SPELL_PRE_SUMMON_NIGHTMARE_PORTAL)
+
+#define EMERALD_VIGOR RAID_MODE<uint32>(SPELL_EMERALD_VIGOR, SPELL_EMERALD_VIGOR, \
+ SPELL_TWISTED_NIGHTMARE, SPELL_TWISTED_NIGHTMARE)
+
+enum Events
+{
+ // Valithria Dreamwalker
+ EVENT_INTRO_TALK = 1,
+ EVENT_BERSERK,
+ EVENT_DREAM_PORTAL,
+ EVENT_DREAM_SLIP,
+
+ // The Lich King
+ EVENT_GLUTTONOUS_ABOMINATION_SUMMONER,
+ EVENT_SUPPRESSER_SUMMONER,
+ EVENT_BLISTERING_ZOMBIE_SUMMONER,
+ EVENT_RISEN_ARCHMAGE_SUMMONER,
+ EVENT_BLAZING_SKELETON_SUMMONER,
+
+ // Risen Archmage
+ EVENT_FROSTBOLT_VOLLEY,
+ EVENT_MANA_VOID,
+ EVENT_COLUMN_OF_FROST,
+
+ // Blazing Skeleton
+ EVENT_FIREBALL,
+ EVENT_LEY_WASTE,
+
+ // Suppresser
+ EVENT_SUPPRESSION,
+
+ // Gluttonous Abomination
+ EVENT_GUT_SPRAY,
+
+ // Dream Cloud
+ // Nightmare Cloud
+ EVENT_CHECK_PLAYER,
+ EVENT_EXPLODE,
+};
+
+enum Actions
+{
+ ACTION_ENTER_COMBAT = 1,
+ MISSED_PORTALS = 2,
+ ACTION_DEATH = 3,
+};
+
+Position const ValithriaSpawnPos = {4210.813f, 2484.443f, 364.9558f, 0.01745329f};
+
+class RisenArchmageCheck
+{
+ public:
+ // look for all permanently spawned Risen Archmages that are not yet in combat
+ bool operator()(Creature* creature)
+ {
+ return creature->isAlive() && creature->GetEntry() == NPC_RISEN_ARCHMAGE &&
+ creature->GetDBTableGUIDLow() && !creature->isInCombat();
+ }
+};
+
+struct ManaVoidSelector : public std::unary_function<Unit*, bool>
+{
+ explicit ManaVoidSelector(WorldObject const* source) : _source(source) { }
+
+ bool operator()(Unit* unit) const
+ {
+ return unit->getPowerType() == POWER_MANA && _source->GetDistance(unit) > 15.0f;
+ }
+
+ WorldObject const* _source;
+};
+
+class DelayedCastEvent : public BasicEvent
+{
+ public:
+ DelayedCastEvent(Creature* trigger, uint32 spellId, uint64 originalCaster, uint32 despawnTime) : _trigger(trigger), _spellId(spellId), _originalCaster(originalCaster), _despawnTime(despawnTime)
+ {
+ }
+
+ bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ {
+ _trigger->CastSpell(_trigger, _spellId, false, NULL, NULL, _originalCaster);
+ if (_despawnTime)
+ _trigger->DespawnOrUnsummon(_despawnTime);
+ return true;
+ }
+
+ private:
+ Creature* _trigger;
+ uint64 _originalCaster;
+ uint32 _spellId;
+ uint32 _despawnTime;
+};
+
+class AuraRemoveEvent : public BasicEvent
+{
+ public:
+ AuraRemoveEvent(Creature* trigger, uint32 spellId) : _trigger(trigger), _spellId(spellId)
+ {
+ }
+
+ bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ {
+ _trigger->RemoveAurasDueToSpell(_spellId);
+ return true;
+ }
+
+ private:
+ Creature* _trigger;
+ uint32 _spellId;
+};
+
+class SummonTargetSelector
+{
+ public:
+ bool operator()(Unit* unit) const
+ {
+ return unit->HasAura(SPELL_RECENTLY_SPAWNED);
+ }
+};
+
+class ValithriaDespawner : public BasicEvent
+{
+ public:
+ explicit ValithriaDespawner(Creature* creature) : _creature(creature)
+ {
+ }
+
+ bool Execute(uint64 /*currTime*/, uint32 /*diff*/)
+ {
+ Trinity::CreatureWorker<ValithriaDespawner> worker(_creature, *this);
+ _creature->VisitNearbyGridObject(333.0f, worker);
+ return true;
+ }
+
+ void operator()(Creature* creature) const
+ {
+ switch (creature->GetEntry())
+ {
+ case NPC_VALITHRIA_DREAMWALKER:
+ if (InstanceScript* instance = creature->GetInstanceScript())
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, creature);
+ break;
+ case NPC_BLAZING_SKELETON:
+ case NPC_SUPPRESSER:
+ case NPC_BLISTERING_ZOMBIE:
+ case NPC_GLUTTONOUS_ABOMINATION:
+ case NPC_MANA_VOID:
+ case NPC_COLUMN_OF_FROST:
+ creature->DespawnOrUnsummon();
+ return;
+ case NPC_RISEN_ARCHMAGE:
+ if (!creature->GetDBTableGUIDLow())
+ {
+ creature->DespawnOrUnsummon();
+ return;
+ }
+ creature->Respawn(true);
+ break;
+ default:
+ return;
+ }
+
+ uint32 corpseDelay = creature->GetCorpseDelay();
+ uint32 respawnDelay = creature->GetRespawnDelay();
+ creature->SetCorpseDelay(1);
+ creature->SetRespawnDelay(10);
+
+ if (CreatureData const* data = creature->GetCreatureData())
+ creature->SetPosition(data->posX, data->posY, data->posZ, data->orientation);
+ creature->ForcedDespawn();
+
+ creature->SetCorpseDelay(corpseDelay);
+ creature->SetRespawnDelay(respawnDelay);
+ }
+
+ private:
+ Creature* _creature;
+};
+
+class boss_valithria_dreamwalker : public CreatureScript
+{
+ public:
+ boss_valithria_dreamwalker() : CreatureScript("boss_valithria_dreamwalker") { }
+
+ struct boss_valithria_dreamwalkerAI : public ScriptedAI
+ {
+ boss_valithria_dreamwalkerAI(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript()), _portalCount(RAID_MODE<uint32>(3, 8, 3, 8))
+ {
+ }
+
+ void InitializeAI()
+ {
+ if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow()))
+ if (data->curhealth)
+ _spawnHealth = data->curhealth;
+ }
+
+ void Reset()
+ {
+ me->SetHealth(_spawnHealth);
+ me->SetReactState(REACT_PASSIVE);
+ me->LoadCreaturesAddon(true);
+ _instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me);
+ _missedPortals = 0;
+ _under25PercentTalkDone = false;
+ _over75PercentTalkDone = false;
+ _justDied = false;
+ }
+
+ void AttackStart(Unit* /*target*/)
+ {
+ }
+
+ void DoAction(int32 const action)
+ {
+ if (action != ACTION_ENTER_COMBAT)
+ return;
+
+ DoCast(me, SPELL_COPY_DAMAGE);
+ _instance->SendEncounterUnit(ENCOUNTER_FRAME_ADD, me);
+ _events.ScheduleEvent(EVENT_INTRO_TALK, 15000);
+ _events.ScheduleEvent(EVENT_DREAM_PORTAL, urand(45000, 48000));
+ if (IsHeroic())
+ _events.ScheduleEvent(EVENT_BERSERK, 420000);
+ }
+
+ void HealReceived(Unit* /*healer*/, uint32& heal)
+ {
+ // encounter complete
+ if (me->HealthAbovePctHealed(100, heal))
+ {
+ Talk(SAY_VALITHRIA_SUCCESS);
+ me->RemoveAurasDueToSpell(SPELL_CORRUPTION_VALITHRIA);
+ DoCast(me, SPELL_ACHIEVEMENT_CHECK);
+ DoCast(me, SPELL_DREAMWALKERS_RAGE);
+ _events.ScheduleEvent(EVENT_DREAM_SLIP, 3500);
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_LICH_KING)))
+ lichKing->AI()->EnterEvadeMode();
+ }
+ else if (!_over75PercentTalkDone && me->HealthAbovePctHealed(75, heal))
+ {
+ _over75PercentTalkDone = true;
+ Talk(SAY_VALITHRIA_75_PERCENT);
+ }
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage)
+ {
+ if (me->HealthBelowPctDamaged(25, damage))
+ {
+ if (!_under25PercentTalkDone)
+ {
+ _under25PercentTalkDone = true;
+ Talk(SAY_VALITHRIA_25_PERCENT);
+ }
+
+ if (damage > me->GetHealth() && !_justDied)
+ {
+ _justDied = true;
+ Talk(SAY_VALITHRIA_DEATH);
+ _instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me);
+ if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_TRIGGER)))
+ trigger->AI()->DoAction(ACTION_DEATH);
+ }
+ }
+ }
+
+ void SpellHit(Unit* /*caster*/, SpellEntry const* spell)
+ {
+ if (spell->Id == SPELL_DREAM_SLIP)
+ {
+ DoCast(me, SPELL_CLEAR_ALL);
+ DoCast(me, SPELL_AWARD_REPUTATION_BOSS_KILL);
+ // this display id was found in sniff instead of the one on aura
+ me->SetDisplayId(11686);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->DespawnOrUnsummon(4000);
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_LICH_KING)))
+ lichKing->CastSpell(lichKing, SPELL_SPAWN_CHEST, false);
+
+ if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_TRIGGER)))
+ me->Kill(trigger);
+ }
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ if (summon->GetEntry() == NPC_DREAM_PORTAL_PRE_EFFECT)
+ {
+ summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_DREAM_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000));
+ summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_DREAM_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000));
+ }
+ else if (summon->GetEntry() == NPC_NIGHTMARE_PORTAL_PRE_EFFECT)
+ {
+ summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_NIGHTMARE_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000));
+ summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_NIGHTMARE_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000));
+ }
+ }
+
+ void SummonedCreatureDespawn(Creature* summon)
+ {
+ if (summon->GetEntry() == NPC_DREAM_PORTAL || summon->GetEntry() == NPC_NIGHTMARE_PORTAL)
+ if (summon->AI()->GetData(MISSED_PORTALS))
+ ++_missedPortals;
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ // does not enter combat
+ if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) != IN_PROGRESS)
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_INTRO_TALK:
+ Talk(SAY_VALITHRIA_ENTER_COMBAT);
+ break;
+ case EVENT_BERSERK:
+ Talk(SAY_VALITHRIA_BERSERK);
+ break;
+ case EVENT_DREAM_PORTAL:
+ if (!IsHeroic())
+ Talk(SAY_VALITHRIA_DREAM_PORTAL);
+ for (uint32 i = 0; i < _portalCount; ++i)
+ DoCast(me, SUMMON_PORTAL);
+ _events.ScheduleEvent(EVENT_DREAM_PORTAL, urand(45000, 48000));
+ break;
+ case EVENT_DREAM_SLIP:
+ DoCast(me, SPELL_DREAM_SLIP);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ if (type == MISSED_PORTALS)
+ return _missedPortals;
+
+ return 0;
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ uint32 _spawnHealth;
+ uint32 const _portalCount;
+ uint32 _missedPortals;
+ bool _under25PercentTalkDone;
+ bool _over75PercentTalkDone;
+ bool _justDied;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<boss_valithria_dreamwalkerAI>(creature);
+ }
+};
+
+class npc_green_dragon_combat_trigger : public CreatureScript
+{
+ public:
+ npc_green_dragon_combat_trigger() : CreatureScript("npc_green_dragon_combat_trigger") { }
+
+ struct npc_green_dragon_combat_triggerAI : public BossAI
+ {
+ npc_green_dragon_combat_triggerAI(Creature* creature) : BossAI(creature, DATA_VALITHRIA_DREAMWALKER)
+ {
+ }
+
+ void Reset()
+ {
+ _Reset();
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void EnterCombat(Unit* /*target*/)
+ {
+ me->setActive(true);
+ DoZoneInCombat();
+ instance->SetBossState(DATA_VALITHRIA_DREAMWALKER, IN_PROGRESS);
+ if (Creature* valithria = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VALITHRIA_DREAMWALKER)))
+ valithria->AI()->DoAction(ACTION_ENTER_COMBAT);
+ }
+
+ void AttackStart(Unit* target)
+ {
+ if (target->GetEntry() != NPC_VALITHRIA_DREAMWALKER)
+ BossAI::AttackStart(target);
+ }
+
+ void JustReachedHome()
+ {
+ BossAI::JustReachedHome();
+ DoAction(ACTION_DEATH);
+ }
+
+ void DoAction(int32 const action)
+ {
+ if (action == ACTION_DEATH)
+ {
+ instance->SetBossState(DATA_VALITHRIA_DREAMWALKER, FAIL);
+ me->m_Events.AddEvent(new ValithriaDespawner(me), me->m_Events.CalculateTime(5000));
+ }
+ }
+
+ void UpdateAI(uint32 const /*diff*/)
+ {
+ UpdateVictim();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_green_dragon_combat_triggerAI>(creature);
+ }
+};
+
+class npc_the_lich_king_controller : public CreatureScript
+{
+ public:
+ npc_the_lich_king_controller() : CreatureScript("npc_the_lich_king_controller") { }
+
+ struct npc_the_lich_king_controllerAI : public ScriptedAI
+ {
+ npc_the_lich_king_controllerAI(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_GLUTTONOUS_ABOMINATION_SUMMONER, 5000);
+ _events.ScheduleEvent(EVENT_SUPPRESSER_SUMMONER, 10000);
+ _events.ScheduleEvent(EVENT_BLISTERING_ZOMBIE_SUMMONER, 15000);
+ _events.ScheduleEvent(EVENT_RISEN_ARCHMAGE_SUMMONER, 20000);
+ _events.ScheduleEvent(EVENT_BLAZING_SKELETON_SUMMONER, 30000);
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void JustReachedHome()
+ {
+ me->setActive(false);
+ }
+
+ void EnterCombat(Unit* /*target*/)
+ {
+ Talk(SAY_LICH_KING_INTRO);
+ me->setActive(true);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ // must not be in dream phase
+ summon->SetPhaseMask((summon->GetPhaseMask() & ~0x10), true);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_GLUTTONOUS_ABOMINATION_SUMMONER:
+ DoCast(me, SPELL_TIMER_GLUTTONOUS_ABOMINATION);
+ break;
+ case EVENT_SUPPRESSER_SUMMONER:
+ DoCast(me, SPELL_TIMER_SUPPRESSER);
+ break;
+ case EVENT_BLISTERING_ZOMBIE_SUMMONER:
+ DoCast(me, SPELL_TIMER_BLISTERING_ZOMBIE);
+ break;
+ case EVENT_RISEN_ARCHMAGE_SUMMONER:
+ DoCast(me, SPELL_TIMER_RISEN_ARCHMAGE);
+ break;
+ case EVENT_BLAZING_SKELETON_SUMMONER:
+ DoCast(me, SPELL_TIMER_BLAZING_SKELETON);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_the_lich_king_controllerAI(creature);
+ }
+};
+
+class npc_risen_archmage : public CreatureScript
+{
+ public:
+ npc_risen_archmage() : CreatureScript("npc_risen_archmage") { }
+
+ struct npc_risen_archmageAI : public ScriptedAI
+ {
+ npc_risen_archmageAI(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ }
+
+ bool CanAIAttack(Unit const* target) const
+ {
+ return target->GetEntry() != NPC_VALITHRIA_DREAMWALKER;
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, urand(5000, 15000));
+ _events.ScheduleEvent(EVENT_MANA_VOID, urand(20000, 25000));
+ _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, urand(10000, 20000));
+ _canCallEnterCombat = true;
+ }
+
+ void EnterCombat(Unit* /*target*/)
+ {
+ me->FinishSpell(CURRENT_CHANNELED_SPELL, false);
+ if (me->GetDBTableGUIDLow() && _canCallEnterCombat)
+ {
+ std::list<Creature*> archmages;
+ RisenArchmageCheck check;
+ Trinity::CreatureListSearcher<RisenArchmageCheck> searcher(me, archmages, check);
+ me->VisitNearbyGridObject(100.0f, searcher);
+ for (std::list<Creature*>::iterator itr = archmages.begin(); itr != archmages.end(); ++itr)
+ (*itr)->AI()->DoAction(ACTION_ENTER_COMBAT);
+
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_LICH_KING)))
+ lichKing->AI()->DoZoneInCombat();
+
+ if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_TRIGGER)))
+ trigger->AI()->DoZoneInCombat();
+ }
+ }
+
+ void DoAction(int32 const action)
+ {
+ if (action != ACTION_ENTER_COMBAT)
+ return;
+
+ _canCallEnterCombat = false;
+ DoZoneInCombat();
+ _canCallEnterCombat = true;
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ if (summon->GetEntry() == NPC_COLUMN_OF_FROST)
+ summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_COLUMN_OF_FROST_DAMAGE, 0, 8000), summon->m_Events.CalculateTime(2000));
+ else if (summon->GetEntry() == NPC_MANA_VOID)
+ summon->DespawnOrUnsummon(36000);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!me->isInCombat())
+ if (me->GetDBTableGUIDLow())
+ if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
+ DoCast(me, SPELL_CORRUPTION);
+
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FROSTBOLT_VOLLEY:
+ DoCast(me, SPELL_FROSTBOLT_VOLLEY);
+ _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, urand(8000, 15000));
+ break;
+ case EVENT_MANA_VOID:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, ManaVoidSelector(me)))
+ DoCast(target, SPELL_MANA_VOID);
+ _events.ScheduleEvent(EVENT_MANA_VOID, urand(20000, 25000));
+ break;
+ case EVENT_COLUMN_OF_FROST:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -10.0f, true))
+ DoCast(target, SPELL_COLUMN_OF_FROST);
+ _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, urand(15000, 25000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ bool _canCallEnterCombat;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_risen_archmageAI>(creature);
+ }
+};
+
+class npc_blazing_skeleton : public CreatureScript
+{
+ public:
+ npc_blazing_skeleton() : CreatureScript("npc_blazing_skeleton") { }
+
+ struct npc_blazing_skeletonAI : public ScriptedAI
+ {
+ npc_blazing_skeletonAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_FIREBALL, urand(2000, 4000));
+ _events.ScheduleEvent(EVENT_LEY_WASTE, urand(15000, 20000));
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FIREBALL:
+ if (!me->IsWithinMeleeRange(me->getVictim()))
+ DoCastVictim(SPELL_FIREBALL);
+ _events.ScheduleEvent(EVENT_FIREBALL, urand(2000, 4000));
+ break;
+ case EVENT_LEY_WASTE:
+ DoCast(me, SPELL_LEY_WASTE);
+ _events.ScheduleEvent(EVENT_LEY_WASTE, urand(15000, 20000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_blazing_skeletonAI>(creature);
+ }
+};
+
+class npc_suppresser : public CreatureScript
+{
+ public:
+ npc_suppresser() : CreatureScript("npc_suppresser") { }
+
+ struct npc_suppresserAI : public ScriptedAI
+ {
+ npc_suppresserAI(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_SUPPRESSION, urand(10000, 15000));
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void IsSummonedBy(Unit* /*summoner*/)
+ {
+ if (Creature* valithria = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_DREAMWALKER)))
+ AttackStart(valithria);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ // this code will never be reached while channeling
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SUPPRESSION:
+ DoCast(me, SPELL_SUPPRESSION);
+ _events.ScheduleEvent(EVENT_SUPPRESSION, 5000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* const _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_suppresserAI>(creature);
+ }
+};
+
+class npc_blistering_zombie : public CreatureScript
+{
+ public:
+ npc_blistering_zombie() : CreatureScript("npc_blistering_zombie") { }
+
+ struct npc_blistering_zombieAI : public ScriptedAI
+ {
+ npc_blistering_zombieAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoCast(me, SPELL_ACID_BURST, true);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_blistering_zombieAI>(creature);
+ }
+};
+
+class npc_gluttonous_abomination : public CreatureScript
+{
+ public:
+ npc_gluttonous_abomination() : CreatureScript("npc_gluttonous_abomination") { }
+
+ struct npc_gluttonous_abominationAI : public ScriptedAI
+ {
+ npc_gluttonous_abominationAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_GUT_SPRAY, urand(10000, 13000));
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoCast(me, SPELL_ROT_WORM_SPAWNER, true);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_GUT_SPRAY:
+ DoCast(me, SPELL_GUT_SPRAY);
+ _events.ScheduleEvent(EVENT_GUT_SPRAY, urand(10000, 13000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_gluttonous_abominationAI>(creature);
+ }
+};
+
+class npc_dream_portal : public CreatureScript
+{
+ public:
+ npc_dream_portal() : CreatureScript("npc_dream_portal") { }
+
+ struct npc_dream_portalAI : public CreatureAI
+ {
+ npc_dream_portalAI(Creature* creature) : CreatureAI(creature),
+ _used(false)
+ {
+ }
+
+ void DoAction(int32 const action)
+ {
+ if (action != EVENT_SPELLCLICK)
+ return;
+
+ _used = true;
+ me->DespawnOrUnsummon();
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ return (type == MISSED_PORTALS && _used) ? 0 : 1;
+ }
+
+ void UpdateAI(uint32 const /*diff*/)
+ {
+ UpdateVictim();
+ }
+
+ private:
+ bool _used;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_dream_portalAI>(creature);
+ }
+};
+
+class npc_dream_cloud : public CreatureScript
+{
+ public:
+ npc_dream_cloud() : CreatureScript("npc_dream_cloud") { }
+
+ struct npc_dream_cloudAI : public ScriptedAI
+ {
+ npc_dream_cloudAI(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_CHECK_PLAYER, 1000);
+ me->SetCorpseDelay(0); // remove corpse immediately
+ me->LoadCreaturesAddon(true);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ // trigger
+ if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) != IN_PROGRESS)
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CHECK_PLAYER:
+ {
+ Player* player = NULL;
+ Trinity::AnyPlayerInObjectRangeCheck check(me, 5.0f);
+ Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(me, player, check);
+ me->VisitNearbyWorldObject(7.5f, searcher);
+ _events.ScheduleEvent(player ? EVENT_EXPLODE : EVENT_CHECK_PLAYER, 1000);
+ break;
+ }
+ case EVENT_EXPLODE:
+ me->GetMotionMaster()->MoveIdle();
+ // must use originalCaster the same for all clouds to allow stacking
+ me->CastSpell(me, EMERALD_VIGOR, false, NULL, NULL, _instance->GetData64(DATA_VALITHRIA_DREAMWALKER));
+ me->ForcedDespawn(100);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_dream_cloudAI>(creature);
+ }
+};
+
+class spell_dreamwalker_mana_void : public SpellScriptLoader
+{
+ public:
+ spell_dreamwalker_mana_void() : SpellScriptLoader("spell_dreamwalker_mana_void") { }
+
+ class spell_dreamwalker_mana_void_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dreamwalker_mana_void_AuraScript);
+
+ void PeriodicTick(AuraEffect const* aurEff)
+ {
+ // first 3 ticks have amplitude 1 second
+ // remaining tick every 500ms
+ if (aurEff->GetTickNumber() <= 5)
+ if (!(aurEff->GetTickNumber() & 1))
+ PreventDefaultAction();
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_dreamwalker_mana_void_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dreamwalker_mana_void_AuraScript();
+ }
+};
+
+class spell_dreamwalker_decay_periodic_timer : public SpellScriptLoader
+{
+ public:
+ spell_dreamwalker_decay_periodic_timer() : SpellScriptLoader("spell_dreamwalker_decay_periodic_timer") { }
+
+ class spell_dreamwalker_decay_periodic_timer_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dreamwalker_decay_periodic_timer_AuraScript);
+
+ bool Load()
+ {
+ _decayRate = GetId() != SPELL_TIMER_BLAZING_SKELETON ? 1000 : 5000;
+ return true;
+ }
+
+ void DecayPeriodicTimer(AuraEffect* aurEff)
+ {
+ int32 timer = aurEff->GetPeriodicTimer();
+ if (timer <= 5)
+ return;
+
+ aurEff->SetPeriodicTimer(timer - _decayRate);
+ }
+
+ void Register()
+ {
+ OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_dreamwalker_decay_periodic_timer_AuraScript::DecayPeriodicTimer, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+
+ int32 _decayRate;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dreamwalker_decay_periodic_timer_AuraScript();
+ }
+};
+
+class spell_dreamwalker_summoner : public SpellScriptLoader
+{
+ public:
+ spell_dreamwalker_summoner() : SpellScriptLoader("spell_dreamwalker_summoner") { }
+
+ class spell_dreamwalker_summoner_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dreamwalker_summoner_SpellScript);
+
+ void FilterTargets(std::list<Unit*>& targets)
+ {
+ targets.remove_if(SummonTargetSelector());
+ if (targets.empty())
+ return;
+
+ std::list<Unit*>::iterator itr = targets.begin();
+ std::advance(itr, urand(0, targets.size() - 1));
+ Unit* target = *itr;
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void Register()
+ {
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENTRY_SRC);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_dreamwalker_summoner_SpellScript();
+ }
+};
+
+class spell_dreamwalker_summon_suppresser : public SpellScriptLoader
+{
+ public:
+ spell_dreamwalker_summon_suppresser() : SpellScriptLoader("spell_dreamwalker_summon_suppresser") { }
+
+ class spell_dreamwalker_summon_suppresser_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dreamwalker_summon_suppresser_AuraScript);
+
+ void PeriodicTick(AuraEffect const* aurEff)
+ {
+ PreventDefaultAction();
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ std::list<Creature*> summoners;
+ GetCreatureListWithEntryInGrid(summoners, caster, 22515, 100.0f);
+ summoners.remove_if(SummonTargetSelector());
+ Trinity::RandomResizeList(summoners, 2);
+ if (summoners.empty())
+ return;
+
+ for (uint32 i = 0; i < 3; ++i)
+ caster->CastSpell(summoners.front(), SPELL_SUMMON_SUPPRESSER, true);
+ for (uint32 i = 0; i < 3; ++i)
+ caster->CastSpell(summoners.back(), SPELL_SUMMON_SUPPRESSER, true);
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_dreamwalker_summon_suppresser_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+
+ int32 _decayRate;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dreamwalker_summon_suppresser_AuraScript();
+ }
+};
+
+class spell_dreamwalker_summon_dream_portal : public SpellScriptLoader
+{
+ public:
+ spell_dreamwalker_summon_dream_portal() : SpellScriptLoader("spell_dreamwalker_summon_dream_portal") { }
+
+ class spell_dreamwalker_summon_dream_portal_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dreamwalker_summon_dream_portal_SpellScript);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ if (!GetHitUnit())
+ return;
+
+ uint32 spellId = RAND<uint32>(71301, 72220, 72223, 72225);
+ GetHitUnit()->CastSpell(GetHitUnit(), spellId, true);
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_dreamwalker_summon_dream_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_dreamwalker_summon_dream_portal_SpellScript();
+ }
+};
+
+class spell_dreamwalker_summon_nightmare_portal : public SpellScriptLoader
+{
+ public:
+ spell_dreamwalker_summon_nightmare_portal() : SpellScriptLoader("spell_dreamwalker_summon_nightmare_portal") { }
+
+ class spell_dreamwalker_summon_nightmare_portal_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dreamwalker_summon_nightmare_portal_SpellScript);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ if (!GetHitUnit())
+ return;
+
+ uint32 spellId = RAND<uint32>(71977, 72481, 72482, 72483);
+ GetHitUnit()->CastSpell(GetHitUnit(), spellId, true);
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_dreamwalker_summon_nightmare_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_dreamwalker_summon_nightmare_portal_SpellScript();
+ }
+};
+
+class spell_dreamwalker_nightmare_cloud : public SpellScriptLoader
+{
+ public:
+ spell_dreamwalker_nightmare_cloud() : SpellScriptLoader("spell_dreamwalker_nightmare_cloud") { }
+
+ class spell_dreamwalker_nightmare_cloud_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dreamwalker_nightmare_cloud_AuraScript);
+
+ bool Load()
+ {
+ _instance = GetOwner()->GetInstanceScript();
+ return _instance != NULL;
+ }
+
+ void PeriodicTick(AuraEffect const* /*aurEff*/)
+ {
+ if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) != IN_PROGRESS)
+ PreventDefaultAction();
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_dreamwalker_nightmare_cloud_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+
+ InstanceScript* _instance;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dreamwalker_nightmare_cloud_AuraScript();
+ }
+};
+
+class achievement_portal_jockey : public AchievementCriteriaScript
+{
+ public:
+ achievement_portal_jockey() : AchievementCriteriaScript("achievement_portal_jockey") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ return target && !target->GetAI()->GetData(MISSED_PORTALS);
+ }
+};
+
+void AddSC_boss_valithria_dreamwalker()
+{
+ new boss_valithria_dreamwalker();
+ new npc_green_dragon_combat_trigger();
+ new npc_the_lich_king_controller();
+ new npc_risen_archmage();
+ new npc_blazing_skeleton();
+ new npc_suppresser();
+ new npc_blistering_zombie();
+ new npc_gluttonous_abomination();
+ new npc_dream_portal();
+ new npc_dream_cloud();
+ new spell_dreamwalker_mana_void();
+ new spell_dreamwalker_decay_periodic_timer();
+ new spell_dreamwalker_summoner();
+ new spell_dreamwalker_summon_suppresser();
+ new spell_dreamwalker_summon_dream_portal();
+ new spell_dreamwalker_summon_nightmare_portal();
+ new spell_dreamwalker_nightmare_cloud();
+ new achievement_portal_jockey();
+}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index 137ac32df24..9453610a034 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -27,6 +27,8 @@
uint32 const EncounterCount = 13;
uint32 const WeeklyNPCs = 9;
uint32 const MaxHeroicAttempts = 50;
+
+extern Position const ValithriaSpawnPos;
// Defined in boss_sindragosa.cpp
extern Position const SindragosaSpawnPos;
@@ -70,28 +72,30 @@ enum DataTypes
DATA_THE_LICH_KING = 12,
// Additional data
- DATA_SAURFANG_EVENT_NPC = 34,
- DATA_BONED_ACHIEVEMENT = 13,
- DATA_OOZE_DANCE_ACHIEVEMENT = 14,
- DATA_PUTRICIDE_TABLE = 15,
- DATA_NAUSEA_ACHIEVEMENT = 16,
- DATA_ORB_WHISPERER_ACHIEVEMENT = 17,
- DATA_PRINCE_KELESETH_GUID = 18,
- DATA_PRINCE_TALDARAM_GUID = 19,
- DATA_PRINCE_VALANAR_GUID = 20,
- DATA_BLOOD_PRINCES_CONTROL = 21,
- DATA_SINDRAGOSA_FROSTWYRMS = 22,
- DATA_SPINESTALKER = 23,
- DATA_RIMEFANG = 24,
- DATA_COLDFLAME_JETS = 25,
- DATA_TEAM_IN_INSTANCE = 26,
- DATA_BLOOD_QUICKENING_STATE = 27,
- DATA_HEROIC_ATTEMPTS = 28,
- DATA_CROK_SCOURGEBANE = 29,
- DATA_CAPTAIN_ARNATH = 30,
- DATA_CAPTAIN_BRANDON = 31,
- DATA_CAPTAIN_GRONDEL = 32,
- DATA_CAPTAIN_RUPERT = 33,
+ DATA_SAURFANG_EVENT_NPC = 13,
+ DATA_BONED_ACHIEVEMENT = 14,
+ DATA_OOZE_DANCE_ACHIEVEMENT = 15,
+ DATA_PUTRICIDE_TABLE = 16,
+ DATA_NAUSEA_ACHIEVEMENT = 17,
+ DATA_ORB_WHISPERER_ACHIEVEMENT = 18,
+ DATA_PRINCE_KELESETH_GUID = 19,
+ DATA_PRINCE_TALDARAM_GUID = 20,
+ DATA_PRINCE_VALANAR_GUID = 21,
+ DATA_BLOOD_PRINCES_CONTROL = 22,
+ DATA_SINDRAGOSA_FROSTWYRMS = 23,
+ DATA_SPINESTALKER = 24,
+ DATA_RIMEFANG = 25,
+ DATA_COLDFLAME_JETS = 26,
+ DATA_TEAM_IN_INSTANCE = 27,
+ DATA_BLOOD_QUICKENING_STATE = 28,
+ DATA_HEROIC_ATTEMPTS = 29,
+ DATA_CROK_SCOURGEBANE = 30,
+ DATA_CAPTAIN_ARNATH = 31,
+ DATA_CAPTAIN_BRANDON = 32,
+ DATA_CAPTAIN_GRONDEL = 33,
+ DATA_CAPTAIN_RUPERT = 34,
+ DATA_VALITHRIA_TRIGGER = 35,
+ DATA_VALITHRIA_LICH_KING = 36,
};
enum CreaturesIds
@@ -218,7 +222,13 @@ enum CreaturesIds
NPC_SUPPRESSER = 37863,
NPC_BLISTERING_ZOMBIE = 37934,
NPC_GLUTTONOUS_ABOMINATION = 37886,
+ NPC_MANA_VOID = 38068,
+ NPC_COLUMN_OF_FROST = 37918,
NPC_THE_LICH_KING_VALITHRIA = 16980,
+ NPC_DREAM_PORTAL_PRE_EFFECT = 38186,
+ NPC_NIGHTMARE_PORTAL_PRE_EFFECT = 38429,
+ NPC_DREAM_PORTAL = 37945,
+ NPC_NIGHTMARE_PORTAL = 38430,
// Sindragosa
NPC_SINDRAGOSA = 36853,
@@ -275,6 +285,10 @@ enum GameObjectsIds
// Valithria Dreamwalker
GO_GREEN_DRAGON_BOSS_ENTRANCE = 201375,
GO_GREEN_DRAGON_BOSS_EXIT = 201374,
+ GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01 = 201380,
+ GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02 = 201381,
+ GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03 = 201382,
+ GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04 = 201383,
// Sindragosa
GO_SINDRAGOSA_ENTRANCE_DOOR = 201373,
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index f537a70d61e..048def7a120 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -25,28 +25,32 @@
DoorData const doorData[] =
{
- {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM, BOUNDARY_N },
- {GO_ICEWALL, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_DOODAD_ICECROWN_ICEWALL02, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_ORATORY_OF_THE_DAMNED_ENTRANCE, DATA_LADY_DEATHWHISPER, DOOR_TYPE_ROOM, BOUNDARY_N },
- {GO_SAURFANG_S_DOOR, DATA_DEATHBRINGER_SAURFANG, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_ORANGE_PLAGUE_MONSTER_ENTRANCE, DATA_FESTERGUT, DOOR_TYPE_ROOM, BOUNDARY_E },
- {GO_GREEN_PLAGUE_MONSTER_ENTRANCE, DATA_ROTFACE, DOOR_TYPE_ROOM, BOUNDARY_E },
- {GO_SCIENTIST_ENTRANCE, DATA_PROFESSOR_PUTRICIDE, DOOR_TYPE_ROOM, BOUNDARY_E },
- {GO_CRIMSON_HALL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_ROOM, BOUNDARY_S },
- {GO_BLOOD_ELF_COUNCIL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_W },
- {GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_E },
- {GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_ROOM, BOUNDARY_S },
- {GO_DOODAD_ICECROWN_GRATE_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_SISTER_SVALNA, DOOR_TYPE_PASSAGE, BOUNDARY_S },
- {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_ROOM, BOUNDARY_N },
- {GO_GREEN_DRAGON_BOSS_EXIT, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_PASSAGE, BOUNDARY_S },
- {GO_SINDRAGOSA_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_S },
- {GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_E },
- {GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SE },
- {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SW },
- {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END
+ {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM, BOUNDARY_N },
+ {GO_ICEWALL, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
+ {GO_DOODAD_ICECROWN_ICEWALL02, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
+ {GO_ORATORY_OF_THE_DAMNED_ENTRANCE, DATA_LADY_DEATHWHISPER, DOOR_TYPE_ROOM, BOUNDARY_N },
+ {GO_SAURFANG_S_DOOR, DATA_DEATHBRINGER_SAURFANG, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
+ {GO_ORANGE_PLAGUE_MONSTER_ENTRANCE, DATA_FESTERGUT, DOOR_TYPE_ROOM, BOUNDARY_E },
+ {GO_GREEN_PLAGUE_MONSTER_ENTRANCE, DATA_ROTFACE, DOOR_TYPE_ROOM, BOUNDARY_E },
+ {GO_SCIENTIST_ENTRANCE, DATA_PROFESSOR_PUTRICIDE, DOOR_TYPE_ROOM, BOUNDARY_E },
+ {GO_CRIMSON_HALL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_ROOM, BOUNDARY_S },
+ {GO_BLOOD_ELF_COUNCIL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_W },
+ {GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_E },
+ {GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_ROOM, BOUNDARY_S },
+ {GO_DOODAD_ICECROWN_GRATE_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
+ {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_SISTER_SVALNA, DOOR_TYPE_PASSAGE, BOUNDARY_S },
+ {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_ROOM, BOUNDARY_N },
+ {GO_GREEN_DRAGON_BOSS_EXIT, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_PASSAGE, BOUNDARY_S },
+ {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_N },
+ {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_S },
+ {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_N },
+ {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_S },
+ {GO_SINDRAGOSA_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_S },
+ {GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_E },
+ {GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
+ {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SE },
+ {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SW },
+ {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE},// END
};
// this doesnt have to only store questgivers, also can be used for related quest spawns
@@ -105,6 +109,9 @@ class instance_icecrown_citadel : public InstanceMapScript
CrokScourgebaneGUID = 0;
memset(CrokCaptainGUIDs, 0, 4 * sizeof(uint64));
SisterSvalnaGUID = 0;
+ ValithriaDreamwalkerGUID = 0;
+ ValithriaLichKingGUID = 0;
+ ValithriaTriggerGUID = 0;
SindragosaGUID = 0;
SpinestalkerGUID = 0;
RimefangGUID = 0;
@@ -238,6 +245,15 @@ class instance_icecrown_citadel : public InstanceMapScript
case NPC_SISTER_SVALNA:
SisterSvalnaGUID = creature->GetGUID();
break;
+ case NPC_VALITHRIA_DREAMWALKER:
+ ValithriaDreamwalkerGUID = creature->GetGUID();
+ break;
+ case NPC_THE_LICH_KING_VALITHRIA:
+ ValithriaLichKingGUID = creature->GetGUID();
+ break;
+ case NPC_GREEN_DRAGON_COMBAT_TRIGGER:
+ ValithriaTriggerGUID = creature->GetGUID();
+ break;
case NPC_SINDRAGOSA:
SindragosaGUID = creature->GetGUID();
break;
@@ -330,12 +346,20 @@ class instance_icecrown_citadel : public InstanceMapScript
case GO_DOODAD_ICECROWN_GRATE_01:
case GO_GREEN_DRAGON_BOSS_ENTRANCE:
case GO_GREEN_DRAGON_BOSS_EXIT:
+ case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02:
+ case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03:
case GO_SINDRAGOSA_ENTRANCE_DOOR:
case GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR:
case GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR:
case GO_ICE_WALL:
AddDoor(go, true);
break;
+ // these 2 gates are functional only on 25man modes
+ case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01:
+ case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04:
+ if (instance->GetSpawnMode() & 1)
+ AddDoor(go, true);
+ break;
case GO_LADY_DEATHWHISPER_ELEVATOR:
LadyDeathwisperElevatorGUID = go->GetGUID();
if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE)
@@ -428,6 +452,10 @@ class instance_icecrown_citadel : public InstanceMapScript
case GO_DOODAD_ICECROWN_GRATE_01:
case GO_GREEN_DRAGON_BOSS_ENTRANCE:
case GO_GREEN_DRAGON_BOSS_EXIT:
+ case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01:
+ case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02:
+ case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03:
+ case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04:
case GO_SINDRAGOSA_ENTRANCE_DOOR:
case GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR:
case GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR:
@@ -494,21 +522,27 @@ class instance_icecrown_citadel : public InstanceMapScript
return BloodCouncilControllerGUID;
case DATA_BLOOD_QUEEN_LANA_THEL:
return BloodQueenLanaThelGUID;
- case DATA_SINDRAGOSA:
- return SindragosaGUID;
- case DATA_SPINESTALKER:
- return SpinestalkerGUID;
- case DATA_RIMEFANG:
- return RimefangGUID;
case DATA_CROK_SCOURGEBANE:
return CrokScourgebaneGUID;
case DATA_CAPTAIN_ARNATH:
case DATA_CAPTAIN_BRANDON:
case DATA_CAPTAIN_GRONDEL:
case DATA_CAPTAIN_RUPERT:
- return CrokCaptainGUIDs[type-DATA_CAPTAIN_ARNATH];
+ return CrokCaptainGUIDs[type - DATA_CAPTAIN_ARNATH];
case DATA_SISTER_SVALNA:
return SisterSvalnaGUID;
+ case DATA_VALITHRIA_DREAMWALKER:
+ return ValithriaDreamwalkerGUID;
+ case DATA_VALITHRIA_LICH_KING:
+ return ValithriaLichKingGUID;
+ case DATA_VALITHRIA_TRIGGER:
+ return ValithriaTriggerGUID;
+ case DATA_SINDRAGOSA:
+ return SindragosaGUID;
+ case DATA_SPINESTALKER:
+ return SpinestalkerGUID;
+ case DATA_RIMEFANG:
+ return RimefangGUID;
default:
break;
}
@@ -611,6 +645,8 @@ class instance_icecrown_citadel : public InstanceMapScript
}
break;
case DATA_VALITHRIA_DREAMWALKER:
+ if (state == DONE && sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->GetSpawnMode() & 1]))
+ instance->SummonCreature(NPC_VALITHRIA_DREAMWALKER_QUEST, ValithriaSpawnPos);
break;
case DATA_SINDRAGOSA:
HandleGameObject(FrostwingSigilGUID, state != DONE);
@@ -959,8 +995,8 @@ class instance_icecrown_citadel : public InstanceMapScript
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
- saveStream << "I C " << GetBossSaveData() << ColdflameJetsState
- << " " << BloodQuickeningState << " " << BloodQuickeningMinutes;
+ saveStream << "I C " << GetBossSaveData() << HeroicAttempts << " "
+ << ColdflameJetsState << " " << BloodQuickeningState << " " << BloodQuickeningMinutes;
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
@@ -992,10 +1028,12 @@ class instance_icecrown_citadel : public InstanceMapScript
SetBossState(i, EncounterState(tmpState));
}
+ loadStream >> HeroicAttempts;
+
uint32 temp = 0;
loadStream >> temp;
ColdflameJetsState = temp ? DONE : NOT_STARTED;
- temp = 0;
+
loadStream >> temp;
BloodQuickeningState = temp ? DONE : NOT_STARTED; // DONE means finished (not success/fail)
loadStream >> BloodQuickeningMinutes;
@@ -1057,6 +1095,9 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 CrokScourgebaneGUID;
uint64 CrokCaptainGUIDs[4];
uint64 SisterSvalnaGUID;
+ uint64 ValithriaDreamwalkerGUID;
+ uint64 ValithriaLichKingGUID;
+ uint64 ValithriaTriggerGUID;
uint64 SindragosaGUID;
uint64 SpinestalkerGUID;
uint64 RimefangGUID;
@@ -1067,7 +1108,7 @@ class instance_icecrown_citadel : public InstanceMapScript
uint32 SpinestalkerTrashCount;
uint32 RimefangTrashCount;
uint32 BloodQuickeningState;
- uint16 HeroicAttempts;
+ uint32 HeroicAttempts;
uint16 BloodQuickeningMinutes;
bool IsBonedEligible;
bool IsOozeDanceEligible;