Fix Script Naxxramas/Kel Thusad. Thanks Ille.

Fixes issue 650.
Fixes issue 659.
Fixes issue 809. Thanks PrinceCreed.

script changes
- added spawnpoints and spawn creatures in corners
	* they react defensive, otherwise they assist the minions
kelthuzad spawns
- added functionality to area trigger
	* fight begins when player enters green circle
- added functionality to kelthuzad trigger
	* trigger is activated when player enters green circle
	* trigger disappears after 5s
- added functionality to window portals
	* at 45% portals open to let guardians in
- chained can be 3 at once
- added spells to chained
	* for every class two spells
- changed timers on enter combat
- set combat reach to 2 for guardians
- Fix emote when enter combat and when enter phase 2.

NOTE: some db updates may still be necessary to have better locations of portals and EventAI updates.
For more info, see sql in attachment of #659 and http://trinitydatabase.org/index.php?/topic/14304-boss-naxxramas-kelthuzad on tdb forum.

--HG--
branch : trunk
This commit is contained in:
Trazom62
2010-02-27 16:41:44 +01:00
parent d9056adc8a
commit 6146c33732
5 changed files with 459 additions and 51 deletions
+3
View File
@@ -878,6 +878,9 @@ UPDATE `creature_template` SET `ScriptName`='boss_kelthuzad' WHERE `entry`=15990
UPDATE `creature_template` SET `ScriptName`='' WHERE `entry` IN (16062,30000); UPDATE `creature_template` SET `ScriptName`='' WHERE `entry` IN (16062,30000);
UPDATE `creature_template` SET `ScriptName`='trigger_periodic' WHERE `entry` IN (16474,16697,16129); UPDATE `creature_template` SET `ScriptName`='trigger_periodic' WHERE `entry` IN (16474,16697,16129);
DELETE FROM `areatrigger_scripts` WHERE `entry`=4112;
INSERT INTO `areatrigger_scripts`(`entry`,`ScriptName`) VALUES(4112,'at_kelthuzad_center');
/* NETHERSTORM */ /* NETHERSTORM */
UPDATE `gameobject_template` SET `ScriptName`='go_manaforge_control_console' WHERE `entry` IN (183770,183956,184311,184312); UPDATE `gameobject_template` SET `ScriptName`='go_manaforge_control_console' WHERE `entry` IN (183770,183956,184311,184312);
UPDATE `creature_template` SET `ScriptName`='npc_manaforge_control_console' WHERE `entry` IN (20209,20417,20418,20440); UPDATE `creature_template` SET `ScriptName`='npc_manaforge_control_console' WHERE `entry` IN (20209,20417,20418,20440);
@@ -0,0 +1,3 @@
-- areatrigger for Kelthuzads chamber center
DELETE FROM `areatrigger_scripts` WHERE `entry`=4112;
INSERT INTO `areatrigger_scripts`(`entry`,`ScriptName`) VALUES(4112,'at_kelthuzad_center');
@@ -38,7 +38,7 @@ enum Yells
SAY_TAUNT2 = -1533091, //not used SAY_TAUNT2 = -1533091, //not used
SAY_TAUNT3 = -1533092, //not used SAY_TAUNT3 = -1533092, //not used
SAY_TAUNT4 = -1533093, //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_1 = -1533094, //start of phase 2
SAY_AGGRO_2 = -1533095, SAY_AGGRO_2 = -1533095,
SAY_AGGRO_3 = -1533096, SAY_AGGRO_3 = -1533096,
@@ -60,6 +60,7 @@ enum Event
EVENT_BOLT, EVENT_BOLT,
EVENT_NOVA, EVENT_NOVA,
EVENT_CHAIN, EVENT_CHAIN,
EVENT_CHAINED_SPELL,
EVENT_DETONATE, EVENT_DETONATE,
EVENT_FISSURE, EVENT_FISSURE,
EVENT_BLAST, EVENT_BLAST,
@@ -68,6 +69,7 @@ enum Event
EVENT_ABOMIN, EVENT_ABOMIN,
EVENT_WEAVER, EVENT_WEAVER,
EVENT_ICECROWN, EVENT_ICECROWN,
EVENT_TRIGGER,
EVENT_PHASE, EVENT_PHASE,
}; };
@@ -83,7 +85,40 @@ enum Spells
SPELL_MANA_DETONATION = 27819, SPELL_MANA_DETONATION = 27819,
SPELL_FROST_BLAST = 27808, SPELL_FROST_BLAST = 27808,
SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect 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 enum Creatures
@@ -98,41 +133,183 @@ const Position Pos[12] =
{ {
{3783.272705, -5062.697266, 143.711203, 3.617599}, //LEFT_FAR {3783.272705, -5062.697266, 143.711203, 3.617599}, //LEFT_FAR
{3730.291260, -5027.239258, 143.956909, 4.461900}, //LEFT_MIDDLE {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 {3759.355225, -5174.128418, 143.802383, 2.170104}, //RIGHT_FAR
{3700.724365, -5185.123047, 143.928024, 1.309310}, //RIGHT_MIDDLE {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 {3754.431396, -5080.727734, 142.036316, 3.736189}, //LEFT_FAR
{3724.396484, -5061.330566, 142.032700, 4.564785}, //LEFT_MIDDLE {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 {3687.571777, -5126.831055, 142.017807, 0.604023}, //RIGHT_FAR
{3707.990733, -5151.450195, 142.032562, 1.376855}, //RIGHT_MIDDLE {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
};
//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] =
{
{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},
};
// 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 struct boss_kelthuzadAI : public BossAI
{ {
boss_kelthuzadAI(Creature* c) : BossAI(c, BOSS_KELTHUZAD) {} boss_kelthuzadAI(Creature* c) : BossAI(c, BOSS_KELTHUZAD), spawns(c)
{
uint32 GuardiansOfIcecrown_Count; uiFaction = m_creature->getFaction();
}
uint32 Phase; uint32 Phase;
uint32 GuardiansOfIcecrown_Timer; uint32 uiGuardiansOfIcecrownTimer;
uint32 uiFaction;
uint8 nGuardiansOfIcecrownCount;
uint8 nAbomination; uint8 nAbomination;
uint8 nWeaver; 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() void Reset()
{ {
_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();
Phase=0; FindGameObjects();
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() void KilledUnit()
@@ -144,22 +321,49 @@ struct boss_kelthuzadAI : public BossAI
{ {
_JustDied(); _JustDied();
DoScriptText(SAY_DEATH, m_creature); 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) void EnterCombat(Unit* who)
{ {
me->setFaction(uiFaction);
_EnterCombat(); _EnterCombat();
DoCast(me, SPELL_KELTHUZAD_CHANNEL); FindGameObjects();
DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me); for (uint8 i = 0; i <= 3; ++i)
Phase=1; {
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (pPortals[i])
me->SetReactState(REACT_PASSIVE); pPortals[i]->ResetDoorOrButton();
events.ScheduleEvent(EVENT_WASTE, 30000); }
events.ScheduleEvent(EVENT_ABOMIN, 60000); DoCast(me, SPELL_KELTHUZAD_CHANNEL, false);
events.ScheduleEvent(EVENT_WEAVER, 80000); 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); 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) void UpdateAI(const uint32 diff)
{ {
if (!UpdateCombatState()) if (!UpdateCombatState())
@@ -185,9 +389,7 @@ struct boss_kelthuzadAI : public BossAI
events.RepeatEvent(20000); events.RepeatEvent(20000);
} }
else else
{
events.PopEvent(); events.PopEvent();
}
break; break;
case EVENT_WEAVER: case EVENT_WEAVER:
if (nWeaver < 8) if (nWeaver < 8)
@@ -197,16 +399,21 @@ struct boss_kelthuzadAI : public BossAI
events.RepeatEvent(25000); events.RepeatEvent(25000);
} }
else else
{
events.PopEvent(); events.PopEvent();
} break;
case EVENT_TRIGGER:
if (pKTTrigger)
pKTTrigger->SetPhaseMask(2, true);
events.PopEvent();
break; break;
case EVENT_PHASE: case EVENT_PHASE:
// TODO : Add missing text
events.Reset(); events.Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
me->SetReactState(REACT_AGGRESSIVE); spawns.DespawnAll();
me->InterruptNonMeleeSpells(false); 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_BOLT, urand(5000,10000));
events.ScheduleEvent(EVENT_NOVA, 15000); events.ScheduleEvent(EVENT_NOVA, 15000);
events.ScheduleEvent(EVENT_DETONATE, urand(30000,40000)); 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 //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. //so for now just make Kelthuzad says it.
DoScriptText(SAY_ANSWER_REQUEST, m_creature); 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 // TODO : Add missing text
DoSummon(NPC_ICECROWN, Pos[RAND(2,5,8)]); if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2,5,8,11)]))
++GuardiansOfIcecrown_Count; pGuardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
GuardiansOfIcecrown_Timer = 5000; ++nGuardiansOfIcecrownCount;
uiGuardiansOfIcecrownTimer = 5000;
} }
else GuardiansOfIcecrown_Timer -= diff; else uiGuardiansOfIcecrownTimer -= diff;
} }
if (me->hasUnitState(UNIT_STAT_CASTING)) if (me->hasUnitState(UNIT_STAT_CASTING))
@@ -264,11 +478,101 @@ struct boss_kelthuzadAI : public BossAI
events.RepeatEvent(urand(15000,30000)); events.RepeatEvent(urand(15000,30000));
break; break;
case EVENT_CHAIN: case EVENT_CHAIN:
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true)) {
DoCast(pTarget, SPELL_CHAINS_OF_KELTHUZAD); uint32 count = urand(1,3);
DoScriptText(RAND(SAY_CHAIN_1,SAY_CHAIN_2), me); 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)); events.RepeatEvent(urand(100000,180000));
break; 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: case EVENT_DETONATE:
{ {
std::vector<Unit*> unitList; std::vector<Unit*> unitList;
@@ -320,6 +624,63 @@ CreatureAI* GetAI_boss_kelthuzadAI(Creature* pCreature)
return new boss_kelthuzadAI (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() void AddSC_boss_kelthuzad()
{ {
Script *newscript; Script *newscript;
@@ -327,4 +688,9 @@ void AddSC_boss_kelthuzad()
newscript->Name = "boss_kelthuzad"; newscript->Name = "boss_kelthuzad";
newscript->GetAI = &GetAI_boss_kelthuzadAI; newscript->GetAI = &GetAI_boss_kelthuzadAI;
newscript->RegisterSelf(); newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "at_kelthuzad_center";
newscript->pAreaTrigger = &AreaTrigger_at_kelthuzad_center;
newscript->RegisterSelf();
} }
@@ -63,6 +63,11 @@ enum eEnums
GO_HORSEMEN_CHEST_HERO = 193426, GO_HORSEMEN_CHEST_HERO = 193426,
GO_HORSEMEN_CHEST = 181366, //four horsemen event, DoRespawnGameObject() when event == DONE GO_HORSEMEN_CHEST = 181366, //four horsemen event, DoRespawnGameObject() when event == DONE
GO_GOTHIK_GATE = 181170, 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 SPELL_ERUPTION = 29371
}; };
@@ -120,6 +125,10 @@ struct instance_naxxramas : public InstanceData
uint64 uiFeugen; uint64 uiFeugen;
uint64 uiStalagg; uint64 uiStalagg;
uint64 uiKelthuzad;
uint64 uiKelthuzadTrigger;
uint64 uiPortals[4];
void OnCreatureCreate(Creature* pCreature, bool add) void OnCreatureCreate(Creature* pCreature, bool add)
{ {
switch(pCreature->GetEntry()) switch(pCreature->GetEntry())
@@ -133,6 +142,7 @@ struct instance_naxxramas : public InstanceData
case 15928: uiThaddius = pCreature->GetGUID(); return; case 15928: uiThaddius = pCreature->GetGUID(); return;
case 15930: uiFeugen = pCreature->GetGUID(); return; case 15930: uiFeugen = pCreature->GetGUID(); return;
case 15929: uiStalagg = pCreature->GetGUID(); return; case 15929: uiStalagg = pCreature->GetGUID(); return;
case 15990: uiKelthuzad = pCreature->GetGUID(); return;
} }
AddMinion(pCreature, add); AddMinion(pCreature, add);
@@ -156,6 +166,11 @@ struct instance_naxxramas : public InstanceData
case GO_GOTHIK_GATE: pGothikGate = add ? pGo : NULL; break; case GO_GOTHIK_GATE: pGothikGate = add ? pGo : NULL; break;
case GO_HORSEMEN_CHEST: HorsemenChest = 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_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); AddDoor(pGo, add);
@@ -177,22 +192,37 @@ struct instance_naxxramas : public InstanceData
uint64 GetData64(uint32 id) uint64 GetData64(uint32 id)
{ {
if (id == DATA_FAERLINA) switch(id)
{
case DATA_FAERLINA:
return uiFaerlina; return uiFaerlina;
if (id == DATA_THANE) case DATA_THANE:
return uiThane; return uiThane;
if (id == DATA_LADY) case DATA_LADY:
return uiLady; return uiLady;
if (id == DATA_BARON) case DATA_BARON:
return uiBaron; return uiBaron;
if (id == DATA_SIR) case DATA_SIR:
return uiSir; return uiSir;
if (id == DATA_THADDIUS) case DATA_THADDIUS:
return uiThaddius; return uiThaddius;
if (id == DATA_FEUGEN) case DATA_FEUGEN:
return uiFeugen; return uiFeugen;
if (id == DATA_STALAGG) case DATA_STALAGG:
return uiStalagg; 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; return 0;
} }
+7 -1
View File
@@ -55,7 +55,13 @@ enum Data64
DATA_SIR, DATA_SIR,
DATA_THADDIUS, DATA_THADDIUS,
DATA_FEUGEN, 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 #define GO_BIRTH 181356