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:
@@ -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`='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 */
|
||||
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);
|
||||
|
||||
@@ -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_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
|
||||
};
|
||||
|
||||
//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
|
||||
{
|
||||
boss_kelthuzadAI(Creature* c) : BossAI(c, BOSS_KELTHUZAD) {}
|
||||
|
||||
uint32 GuardiansOfIcecrown_Count;
|
||||
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);
|
||||
}
|
||||
|
||||
Phase=0;
|
||||
nAbomination=0;
|
||||
nWeaver=0;
|
||||
chained.clear();
|
||||
spawns.DespawnAll();
|
||||
|
||||
FindGameObjects();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
else if (GuardiansOfIcecrown_Count < RAID_MODE(2,4))
|
||||
|
||||
for (uint8 i = 0; i <= 3; ++i)
|
||||
{
|
||||
if (GuardiansOfIcecrown_Timer <= diff)
|
||||
if (pPortals[i] && (pPortals[i]->getLootState() == GO_READY))
|
||||
pPortals[i]->UseDoorOrButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nGuardiansOfIcecrownCount < RAID_MODE(2,4))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user