aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/scripts/northrend/naxxramas/boss_kelthuzad.cpp450
-rw-r--r--src/scripts/northrend/naxxramas/instance_naxxramas.cpp46
-rw-r--r--src/scripts/northrend/naxxramas/naxxramas.h8
3 files changed, 453 insertions, 51 deletions
diff --git a/src/scripts/northrend/naxxramas/boss_kelthuzad.cpp b/src/scripts/northrend/naxxramas/boss_kelthuzad.cpp
index 1e1a6073d2b..559205d9a38 100644
--- a/src/scripts/northrend/naxxramas/boss_kelthuzad.cpp
+++ b/src/scripts/northrend/naxxramas/boss_kelthuzad.cpp
@@ -38,7 +38,7 @@ enum Yells
SAY_TAUNT2 = -1533091, //not used
SAY_TAUNT3 = -1533092, //not used
SAY_TAUNT4 = -1533093, //not used
- SAY_SUMMON_MINIONS = -1533105, //start of phase 1 not used
+ SAY_SUMMON_MINIONS = -1533105, //start of phase 1
SAY_AGGRO_1 = -1533094, //start of phase 2
SAY_AGGRO_2 = -1533095,
SAY_AGGRO_3 = -1533096,
@@ -60,6 +60,7 @@ enum Event
EVENT_BOLT,
EVENT_NOVA,
EVENT_CHAIN,
+ EVENT_CHAINED_SPELL,
EVENT_DETONATE,
EVENT_FISSURE,
EVENT_BLAST,
@@ -68,6 +69,7 @@ enum Event
EVENT_ABOMIN,
EVENT_WEAVER,
EVENT_ICECROWN,
+ EVENT_TRIGGER,
EVENT_PHASE,
};
@@ -83,7 +85,40 @@ enum Spells
SPELL_MANA_DETONATION = 27819,
SPELL_FROST_BLAST = 27808,
SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect
- SPELL_KELTHUZAD_CHANNEL = 29423
+ SPELL_KELTHUZAD_CHANNEL = 29423,
+ SPELL_BERSERK = 28498,
+
+ //spells for chained
+ //warlock
+ SPELL_CURSE_OF_AGONY = 47864,
+ SPELL_SHADOW_BOLT = 47809,
+ //shaman
+ SPELL_EARTH_SHOCK = 49231,
+ SPELL_HEALING_WAVE = 49273,
+ //mage
+ SPELL_FROST_FIREBOLT = 47610,
+ SPELL_ARCANE_MISSILES = 42846,
+ //rogue
+ SPELL_HEMORRHAGE = 48660,
+ SPELL_MUTILATE = 48666,
+ //paladin
+ SPELL_HOLY_SHOCK = 48825,
+ SPELL_HAMMER_OF_JUSTICE = 10308,
+ //priest
+ SPELL_VAMPIRIC_TOUCH = 48160,
+ SPELL_RENEW = 48068,
+ //hunter
+ SPELL_MULTI_SHOT = 49048,
+ SPELL_VOLLEY = 58434,
+ //warrior
+ SPELL_BLADESTORM = 46924,
+ SPELL_CLEAVE = 47520,
+ //druid
+ SPELL_MOONFIRE = 48463,
+ SPELL_LIFEBLOOM = 48451,
+ //death knight
+ SPELL_PLAGUE_STRIKE = 49921,
+ SPELL_HOWLING_BLAST = 51411,
};
enum Creatures
@@ -98,41 +133,183 @@ const Position Pos[12] =
{
{3783.272705, -5062.697266, 143.711203, 3.617599}, //LEFT_FAR
{3730.291260, -5027.239258, 143.956909, 4.461900}, //LEFT_MIDDLE
- {3683.868652, -5057.281250, 143.183884, 5.237086}, //LEFT_NEAR
+ {3757.6, -5172.0, 143.7, 1.97}, //WINDOW_PORTAL05
{3759.355225, -5174.128418, 143.802383, 2.170104}, //RIGHT_FAR
{3700.724365, -5185.123047, 143.928024, 1.309310}, //RIGHT_MIDDLE
- {3665.121094, -5138.679199, 143.183212, 0.604023}, //RIGHT_NEAR
+ {3700.86, -5181.29, 143.928024, 1.42}, //WINDOW_PORTAL04
{3754.431396, -5080.727734, 142.036316, 3.736189}, //LEFT_FAR
{3724.396484, -5061.330566, 142.032700, 4.564785}, //LEFT_MIDDLE
- {3687.158424, -5076.834473, 142.017319, 5.237086}, //LEFT_NEAR
+ {3732.02, -5028.53, 143.92, 4.49}, //WINDOW_PORTAL02
{3687.571777, -5126.831055, 142.017807, 0.604023}, //RIGHT_FAR
{3707.990733, -5151.450195, 142.032562, 1.376855}, //RIGHT_MIDDLE
- {3739.500000, -5141.883989, 142.014113, 2.121412} //RIGHT_NEAR
+ {3782.76, -5062.97, 143.79, 3.82}, //WINDOW_PORTAL03
};
-struct boss_kelthuzadAI : public BossAI
+//creatures in corners
+//Unstoppable Abominations
+#define MAX_ABOMINATIONS 21
+const Position PosAbominations[MAX_ABOMINATIONS] =
+{
+ {3755.52, -5155.22, 143.480, 2.0},
+ {3744.35, -5164.03, 143.590, 2.00},
+ {3749.28, -5159.04, 143.190, 2.0},
+ {3774.47, -5076.28, 143.528, 2.15912},
+ {3765.94, -5074.15, 143.186, 3.77233},
+ {3763.15, -5063.36, 143.694, 3.77233},
+ {3737.81, -5045.69, 143.709, 4.9033},
+ {3728.13, -5045.01, 143.355, 1.45069},
+ {3721.56, -5048.35, 143.542, 1.45069},
+ {3689.55, -5049.66, 143.637, 5.2104},
+ {3681.71, -5053.03, 143.242, 2.47957},
+ {3677.64, -5061.44, 143.358, 2.47957},
+ {3654.2, -5090.87, 143.469, 1.0313},
+ {3650.39, -5097.45, 143.496, 2.5047},
+ {3658.7, -5103.59, 143.607, 3.3278},
+ {3659.02, -5133.97, 143.624, 3.84538},
+ {3666.33, -5139.34, 143.183, 3.84538},
+ {3669.74, -5149.63, 143.678, 0.528643},
+ {3695.53, -5169.53, 143.671, 2.11908},
+ {3701.98, -5166.51, 143.395, 1.24257},
+ {3709.62, -5169.15, 143.576, 5.97695},
+};
+
+//Soldiers of the Frozen Wastes
+#define MAX_WASTES 49
+const Position PosWastes[MAX_WASTES] =
+{
+ {3754.41, -5147.24, 143.204, 2.0},
+ {3754.68, -5156.17, 143.418, 2.0},
+ {3757.91, -5160.12, 143.503, 2.0},
+ {3752.67, -5164.6, 143.395, 2.0},
+ {3745.42, -5164.47, 143.565, 2.74587},
+ {3741.2, -5155.92, 143.17, 5.29134},
+ {3746.57, -5148.82, 143.176, 5.07772},
+ {3778.14, -5070.1, 143.568, 3.16208},
+ {3775.09, -5078.97, 143.65, 2.81022},
+ {3773.54, -5083.47, 143.758, 3.21549},
+ {3765, -5078.29, 143.176, 4.36688},
+ {3766.94, -5072.63, 143.184, 5.27951},
+ {3762.68, -5064.94, 143.635, 3.95297},
+ {3769.9, -5059.94, 143.74, 3.36549},
+ {3736.33, -5042.18, 143.643, 5.9471},
+ {3727.51, -5040.58, 143.502, 0.871859},
+ {3719.89, -5049.64, 143.58, 4.75172},
+ {3720.69, -5044.43, 143.662, 1.87245},
+ {3725.69, -5048.99, 143.363, 2.48271},
+ {3732.33, -5054.01, 143.44, 3.59405},
+ {3738.09, -5051.06, 143.718, 4.70931},
+ {3682.76, -5063.5, 143.175, 0.636238},
+ {3686.7, -5060.58, 143.18, 0.636238},
+ {3682.45, -5057.21, 143.184, 5.61252},
+ {3677.57, -5053.34, 143.369, 1.52531},
+ {3677.3, -5062.26, 143.369, 2.73482},
+ {3691.21, -5053.02, 143.421, 5.93218},
+ {3685.22, -5053.34, 143.314, 4.70303},
+ {3652.11, -5088.47, 143.555, 0.793317},
+ {3648.23, -5093.21, 143.311, 1.18837},
+ {3648.14, -5100.11, 143.632, 2.12221},
+ {3653.88, -5099.7, 143.558, 3.04348},
+ {3661.23, -5100.33, 143.42, 4.08335},
+ {3663.49, -5092.77, 143.346, 4.47134},
+ {3661.85, -5087.99, 143.571, 1.0148},
+ {3664.56, -5149.01, 143.532, 0.0762528},
+ {3665.01, -5142.04, 143.201, 1.72009},
+ {3671.15, -5142.92, 143.174, 4.81535},
+ {3670.18, -5134.38, 143.177, 5.37534},
+ {3664.33, -5131.69, 143.262, 5.39576},
+ {3658.21, -5133.63, 143.662, 1.3863},
+ {3659.7, -5144.49, 143.363, 2.32328},
+ {3705.71, -5179.63, 143.746, 1.06743},
+ {3696.77, -5177.45, 143.759, 5.36748},
+ {3700.97, -5173.13, 143.52, 3.26575},
+ {3708.53, -5172.19, 143.573, 3.26575},
+ {3712.49, -5167.62, 143.657, 5.63295},
+ {3704.89, -5161.84, 143.239, 5.63295},
+ {3695.66, -5164.63, 143.674, 1.54416},
+};
+
+//Soul Weavers
+#define MAX_WEAVERS 7
+const Position PosWeavers[MAX_WEAVERS] =
{
- boss_kelthuzadAI(Creature* c) : BossAI(c, BOSS_KELTHUZAD) {}
+ {3752.45, -5168.35, 143.562, 1.6094},
+ {3772.2, -5070.04, 143.329, 1.93686},
+ {3732.28, -5032.88, 143.771, 3.08355},
+ {3689.05, -5055.7, 143.172, 6.09554},
+ {3649.45, -5093.17, 143.299, 2.51805},
+ {3659.7, -5144.49, 143.363, 4.08806},
+ {3704.71, -5175.96, 143.597, 3.36549},
+};
- uint32 GuardiansOfIcecrown_Count;
+// predicate function to select not charmed target
+struct NotCharmedTargetSelector : public std::unary_function<Unit *, bool> {
+ NotCharmedTargetSelector() {}
+
+ bool operator() (const Unit *pTarget) {
+ return (!pTarget->isCharmed());
+ }
+};
+
+struct boss_kelthuzadAI : public BossAI
+{
+ boss_kelthuzadAI(Creature* c) : BossAI(c, BOSS_KELTHUZAD), spawns(c)
+ {
+ uiFaction = m_creature->getFaction();
+ }
uint32 Phase;
- uint32 GuardiansOfIcecrown_Timer;
+ uint32 uiGuardiansOfIcecrownTimer;
+ uint32 uiFaction;
+
+ uint8 nGuardiansOfIcecrownCount;
uint8 nAbomination;
uint8 nWeaver;
+ std::map<uint64, float> chained;
+
+ GameObject* pPortals[4];
+ GameObject* pKTTrigger;
+ SummonList spawns; // adds spawn by the trigger. kept in separated list (i.e. not in summons)
+
void Reset()
{
_Reset();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- GuardiansOfIcecrown_Count = 0;
- GuardiansOfIcecrown_Timer = 5000; //5 seconds for summoning each Guardian of Icecrown in phase 3
+ me->setFaction(35);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
+ std::map<uint64, float>::iterator itr;
+ for (itr = chained.begin(); itr != chained.end(); ++itr)
+ {
+ if (Player* charmed = Unit::GetPlayer((*itr).first))
+ charmed->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ }
+
+ chained.clear();
+ spawns.DespawnAll();
+
+ FindGameObjects();
- Phase=0;
- nAbomination=0;
- nWeaver=0;
+ if (pKTTrigger)
+ {
+ pKTTrigger->ResetDoorOrButton();
+ pKTTrigger->SetPhaseMask(1, true);
+ }
+
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (pPortals[i])
+ {
+ if (!((pPortals[i]->getLootState() == GO_READY) || (pPortals[i]->getLootState() == GO_NOT_READY)))
+ pPortals[i]->ResetDoorOrButton();
+ }
+ }
+
+ nGuardiansOfIcecrownCount = 0;
+ uiGuardiansOfIcecrownTimer = 5000; //5 seconds for summoning each Guardian of Icecrown in phase 3
+
+ Phase = 0;
+ nAbomination = 0;
+ nWeaver = 0;
}
void KilledUnit()
@@ -144,22 +321,49 @@ struct boss_kelthuzadAI : public BossAI
{
_JustDied();
DoScriptText(SAY_DEATH, m_creature);
+
+ std::map<uint64, float>::iterator itr;
+ for (itr = chained.begin(); itr != chained.end(); ++itr)
+ {
+ if (Player* pPlayer = Unit::GetPlayer((*itr).first))
+ pPlayer->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ }
+ chained.clear();
}
void EnterCombat(Unit* who)
{
+ me->setFaction(uiFaction);
+
_EnterCombat();
- DoCast(me, SPELL_KELTHUZAD_CHANNEL);
- DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
- Phase=1;
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetReactState(REACT_PASSIVE);
- events.ScheduleEvent(EVENT_WASTE, 30000);
- events.ScheduleEvent(EVENT_ABOMIN, 60000);
- events.ScheduleEvent(EVENT_WEAVER, 80000);
+ FindGameObjects();
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (pPortals[i])
+ pPortals[i]->ResetDoorOrButton();
+ }
+ DoCast(me, SPELL_KELTHUZAD_CHANNEL, false);
+ DoScriptText(SAY_SUMMON_MINIONS, me);
+ Phase = 1;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFloatValue(UNIT_FIELD_COMBATREACH, 4);
+ me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 4);
+ events.ScheduleEvent(EVENT_TRIGGER, 5000);
+ events.ScheduleEvent(EVENT_WASTE, 15000);
+ events.ScheduleEvent(EVENT_ABOMIN, 30000);
+ events.ScheduleEvent(EVENT_WEAVER, 50000);
events.ScheduleEvent(EVENT_PHASE, 228000);
}
+ void FindGameObjects()
+ {
+ pPortals[0] = instance ? instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_PORTAL01)) : NULL;
+ pPortals[1] = instance ? instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_PORTAL02)) : NULL;
+ pPortals[2] = instance ? instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_PORTAL03)) : NULL;
+ pPortals[3] = instance ? instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_PORTAL04)) : NULL;
+ pKTTrigger = instance ? instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_TRIGGER)) : NULL;
+ }
+
void UpdateAI(const uint32 diff)
{
if (!UpdateCombatState())
@@ -185,9 +389,7 @@ struct boss_kelthuzadAI : public BossAI
events.RepeatEvent(20000);
}
else
- {
events.PopEvent();
- }
break;
case EVENT_WEAVER:
if (nWeaver < 8)
@@ -197,16 +399,21 @@ struct boss_kelthuzadAI : public BossAI
events.RepeatEvent(25000);
}
else
- {
events.PopEvent();
- }
+ break;
+ case EVENT_TRIGGER:
+ if (pKTTrigger)
+ pKTTrigger->SetPhaseMask(2, true);
+ events.PopEvent();
break;
case EVENT_PHASE:
- // TODO : Add missing text
events.Reset();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- me->InterruptNonMeleeSpells(false);
+ DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
+ spawns.DespawnAll();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
+ me->CastStop();
+
+ DoStartMovement(me->getVictim());
events.ScheduleEvent(EVENT_BOLT, urand(5000,10000));
events.ScheduleEvent(EVENT_NOVA, 15000);
events.ScheduleEvent(EVENT_DETONATE, urand(30000,40000));
@@ -234,18 +441,25 @@ struct boss_kelthuzadAI : public BossAI
//here Lich King should respond to KelThuzad but I don't know which Creature to make talk
//so for now just make Kelthuzad says it.
DoScriptText(SAY_ANSWER_REQUEST, m_creature);
+
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (pPortals[i] && (pPortals[i]->getLootState() == GO_READY))
+ pPortals[i]->UseDoorOrButton();
+ }
}
}
- else if (GuardiansOfIcecrown_Count < RAID_MODE(2,4))
+ else if (nGuardiansOfIcecrownCount < RAID_MODE(2,4))
{
- if (GuardiansOfIcecrown_Timer <= diff)
+ if (uiGuardiansOfIcecrownTimer <= diff)
{
// TODO : Add missing text
- DoSummon(NPC_ICECROWN, Pos[RAND(2,5,8)]);
- ++GuardiansOfIcecrown_Count;
- GuardiansOfIcecrown_Timer = 5000;
+ if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2,5,8,11)]))
+ pGuardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
+ ++nGuardiansOfIcecrownCount;
+ uiGuardiansOfIcecrownTimer = 5000;
}
- else GuardiansOfIcecrown_Timer -= diff;
+ else uiGuardiansOfIcecrownTimer -= diff;
}
if (me->hasUnitState(UNIT_STAT_CASTING))
@@ -264,11 +478,101 @@ struct boss_kelthuzadAI : public BossAI
events.RepeatEvent(urand(15000,30000));
break;
case EVENT_CHAIN:
- if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true))
- DoCast(pTarget, SPELL_CHAINS_OF_KELTHUZAD);
- DoScriptText(RAND(SAY_CHAIN_1,SAY_CHAIN_2), me);
+ {
+ uint32 count = urand(1,3);
+ for (uint8 i = 1; i <= count; i++)
+ {
+ Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true);
+ if (pTarget && !pTarget->isCharmed() && (chained.find(pTarget->GetGUID()) == chained.end()))
+ {
+ DoCast(pTarget, SPELL_CHAINS_OF_KELTHUZAD);
+ float scale = pTarget->GetFloatValue(OBJECT_FIELD_SCALE_X);
+ chained.insert(std::make_pair(pTarget->GetGUID(), scale));
+ pTarget->SetFloatValue(OBJECT_FIELD_SCALE_X, scale * 2);
+ events.ScheduleEvent(EVENT_CHAINED_SPELL, 2000); //core has 2000ms to set unit flag charm
+ }
+ }
+ if (!chained.empty())
+ DoScriptText(RAND(SAY_CHAIN_1,SAY_CHAIN_2), me);
events.RepeatEvent(urand(100000,180000));
break;
+ }
+ case EVENT_CHAINED_SPELL:
+ {
+ std::map<uint64, float>::iterator itr;
+ for (itr = chained.begin(); itr != chained.end();)
+ {
+ if (Unit* player = Unit::GetPlayer((*itr).first))
+ {
+ if (!player->isCharmed())
+ {
+ player->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ itr = chained.erase(itr);
+ continue;
+ }
+
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, NotCharmedTargetSelector()))
+ {
+ switch(player->getClass())
+ {
+ case CLASS_DRUID:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_MOONFIRE, false);
+ else
+ player->CastSpell(m_creature, SPELL_LIFEBLOOM, false);
+ break;
+ case CLASS_HUNTER:
+ player->CastSpell(pTarget, RAND(SPELL_MULTI_SHOT, SPELL_VOLLEY), false);
+ break;
+ case CLASS_MAGE:
+ player->CastSpell(pTarget, RAND(SPELL_FROST_FIREBOLT, SPELL_ARCANE_MISSILES), false);
+ break;
+ case CLASS_WARLOCK:
+ player->CastSpell(pTarget, RAND(SPELL_CURSE_OF_AGONY, SPELL_SHADOW_BOLT), true);
+ break;
+ case CLASS_WARRIOR:
+ player->CastSpell(pTarget, RAND(SPELL_BLADESTORM, SPELL_CLEAVE), false);
+ break;
+ case CLASS_PALADIN:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_HAMMER_OF_JUSTICE, false);
+ else
+ player->CastSpell(m_creature, SPELL_HOLY_SHOCK, false);
+ break;
+ case CLASS_PRIEST:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_VAMPIRIC_TOUCH, false);
+ else
+ player->CastSpell(m_creature, SPELL_RENEW, false);
+ break;
+ case CLASS_SHAMAN:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_EARTH_SHOCK, false);
+ else
+ player->CastSpell(m_creature, SPELL_HEALING_WAVE, false);
+ break;
+ case CLASS_ROGUE:
+ player->CastSpell(pTarget, RAND(SPELL_HEMORRHAGE, SPELL_MUTILATE), false);
+ break;
+ case CLASS_DEATH_KNIGHT:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_PLAGUE_STRIKE, true);
+ else
+ player->CastSpell(pTarget, SPELL_HOWLING_BLAST, true);
+ break;
+ }
+ }
+ }
+ itr++;
+ }
+
+ if (chained.empty())
+ events.PopEvent();
+ else
+ events.RepeatEvent(5000);
+
+ break;
+ }
case EVENT_DETONATE:
{
std::vector<Unit*> unitList;
@@ -320,6 +624,63 @@ CreatureAI* GetAI_boss_kelthuzadAI(Creature* pCreature)
return new boss_kelthuzadAI (pCreature);
}
+bool AreaTrigger_at_kelthuzad_center(Player* pPlayer, const AreaTriggerEntry *at)
+{
+ if (pPlayer->isGameMaster())
+ return false;
+
+ ScriptedInstance* pInstance = pPlayer->GetInstanceData();
+ if (!pInstance || pInstance->IsEncounterInProgress() || pInstance->GetBossState(BOSS_KELTHUZAD) == DONE)
+ return false;
+
+ Creature* pKelthuzad = CAST_CRE(Unit::GetUnit(*pPlayer, pInstance->GetData64(DATA_KELTHUZAD)));
+ if (!pKelthuzad)
+ return false;
+
+ boss_kelthuzadAI* pKelthuzadAI = CAST_AI(boss_kelthuzadAI, pKelthuzad->AI());
+ if (!pKelthuzadAI)
+ return false;
+
+ pKelthuzadAI->AttackStart(pPlayer);
+ if (GameObject* trigger = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_TRIGGER)))
+ {
+ if (trigger->getLootState() == GO_READY)
+ trigger->UseDoorOrButton();
+
+ // Note: summon must be done by trigger and not by KT.
+ // Otherwise, they attack immediately as KT is in combat.
+ for (uint8 i = 0; i <= MAX_ABOMINATIONS; ++i)
+ {
+ if (Creature* sum = trigger->SummonCreature(NPC_ABOMINATION, PosAbominations[i]))
+ {
+ pKelthuzadAI->spawns.Summon(sum);
+ sum->GetMotionMaster()->MoveRandom(9.0f);
+ sum->SetReactState(REACT_DEFENSIVE);
+ }
+ }
+ for (uint8 i = 0; i <= MAX_WASTES; ++i)
+ {
+ if (Creature* sum = trigger->SummonCreature(NPC_WASTE, PosWastes[i]))
+ {
+ pKelthuzadAI->spawns.Summon(sum);
+ sum->GetMotionMaster()->MoveRandom(5.0f);
+ sum->SetReactState(REACT_DEFENSIVE);
+ }
+ }
+ for (uint8 i = 0; i <= MAX_WEAVERS; ++i)
+ {
+ if (Creature* sum = trigger->SummonCreature(NPC_WEAVER, PosWeavers[i]))
+ {
+ pKelthuzadAI->spawns.Summon(sum);
+ sum->GetMotionMaster()->MoveRandom(9.0f);
+ sum->SetReactState(REACT_DEFENSIVE);
+ }
+ }
+ }
+
+ return true;
+}
+
void AddSC_boss_kelthuzad()
{
Script *newscript;
@@ -327,4 +688,9 @@ void AddSC_boss_kelthuzad()
newscript->Name = "boss_kelthuzad";
newscript->GetAI = &GetAI_boss_kelthuzadAI;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_kelthuzad_center";
+ newscript->pAreaTrigger = &AreaTrigger_at_kelthuzad_center;
+ newscript->RegisterSelf();
}
diff --git a/src/scripts/northrend/naxxramas/instance_naxxramas.cpp b/src/scripts/northrend/naxxramas/instance_naxxramas.cpp
index 4ce5361988c..48ff18356e0 100644
--- a/src/scripts/northrend/naxxramas/instance_naxxramas.cpp
+++ b/src/scripts/northrend/naxxramas/instance_naxxramas.cpp
@@ -63,6 +63,11 @@ enum eEnums
GO_HORSEMEN_CHEST_HERO = 193426,
GO_HORSEMEN_CHEST = 181366, //four horsemen event, DoRespawnGameObject() when event == DONE
GO_GOTHIK_GATE = 181170,
+ GO_KELTHUZAD_PORTAL01 = 181402,
+ GO_KELTHUZAD_PORTAL02 = 181403,
+ GO_KELTHUZAD_PORTAL03 = 181404,
+ GO_KELTHUZAD_PORTAL04 = 181405,
+ GO_KELTHUZAD_TRIGGER = 181444,
SPELL_ERUPTION = 29371
};
@@ -120,6 +125,10 @@ struct instance_naxxramas : public InstanceData
uint64 uiFeugen;
uint64 uiStalagg;
+ uint64 uiKelthuzad;
+ uint64 uiKelthuzadTrigger;
+ uint64 uiPortals[4];
+
void OnCreatureCreate(Creature* pCreature, bool add)
{
switch(pCreature->GetEntry())
@@ -133,6 +142,7 @@ struct instance_naxxramas : public InstanceData
case 15928: uiThaddius = pCreature->GetGUID(); return;
case 15930: uiFeugen = pCreature->GetGUID(); return;
case 15929: uiStalagg = pCreature->GetGUID(); return;
+ case 15990: uiKelthuzad = pCreature->GetGUID(); return;
}
AddMinion(pCreature, add);
@@ -156,6 +166,11 @@ struct instance_naxxramas : public InstanceData
case GO_GOTHIK_GATE: pGothikGate = add ? pGo : NULL; break;
case GO_HORSEMEN_CHEST: HorsemenChest = add ? pGo : NULL; break;
case GO_HORSEMEN_CHEST_HERO: HorsemenChest = add ? pGo : NULL; break;
+ case GO_KELTHUZAD_PORTAL01: uiPortals[0] = pGo->GetGUID(); break;
+ case GO_KELTHUZAD_PORTAL02: uiPortals[1] = pGo->GetGUID(); break;
+ case GO_KELTHUZAD_PORTAL03: uiPortals[2] = pGo->GetGUID(); break;
+ case GO_KELTHUZAD_PORTAL04: uiPortals[3] = pGo->GetGUID(); break;
+ case GO_KELTHUZAD_TRIGGER: uiKelthuzadTrigger = pGo->GetGUID(); break;
}
AddDoor(pGo, add);
@@ -177,22 +192,37 @@ struct instance_naxxramas : public InstanceData
uint64 GetData64(uint32 id)
{
- if (id == DATA_FAERLINA)
+ switch(id)
+ {
+ case DATA_FAERLINA:
return uiFaerlina;
- if (id == DATA_THANE)
+ case DATA_THANE:
return uiThane;
- if (id == DATA_LADY)
+ case DATA_LADY:
return uiLady;
- if (id == DATA_BARON)
+ case DATA_BARON:
return uiBaron;
- if (id == DATA_SIR)
+ case DATA_SIR:
return uiSir;
- if (id == DATA_THADDIUS)
+ case DATA_THADDIUS:
return uiThaddius;
- if (id == DATA_FEUGEN)
+ case DATA_FEUGEN:
return uiFeugen;
- if (id == DATA_STALAGG)
+ case DATA_STALAGG:
return uiStalagg;
+ case DATA_KELTHUZAD:
+ return uiKelthuzad;
+ case DATA_KELTHUZAD_PORTAL01:
+ return uiPortals[0];
+ case DATA_KELTHUZAD_PORTAL02:
+ return uiPortals[1];
+ case DATA_KELTHUZAD_PORTAL03:
+ return uiPortals[2];
+ case DATA_KELTHUZAD_PORTAL04:
+ return uiPortals[3];
+ case DATA_KELTHUZAD_TRIGGER:
+ return uiKelthuzadTrigger;
+ }
return 0;
}
diff --git a/src/scripts/northrend/naxxramas/naxxramas.h b/src/scripts/northrend/naxxramas/naxxramas.h
index 48121ff1309..38e38b2ad53 100644
--- a/src/scripts/northrend/naxxramas/naxxramas.h
+++ b/src/scripts/northrend/naxxramas/naxxramas.h
@@ -55,7 +55,13 @@ enum Data64
DATA_SIR,
DATA_THADDIUS,
DATA_FEUGEN,
- DATA_STALAGG
+ DATA_STALAGG,
+ DATA_KELTHUZAD,
+ DATA_KELTHUZAD_PORTAL01,
+ DATA_KELTHUZAD_PORTAL02,
+ DATA_KELTHUZAD_PORTAL03,
+ DATA_KELTHUZAD_PORTAL04,
+ DATA_KELTHUZAD_TRIGGER,
};
#define GO_BIRTH 181356