Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_kelthuzad.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6/* ScriptData
7SDName: Boss_KelThuzad
8SD%Complete: 80%
9SDComment: VERIFY SCRIPT
10SDCategory: Naxxramas
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "SpellScript.h"
16#include "SpellAuraEffects.h"
17#include "naxxramas.h"
18#include "Player.h"
19
21{
22 //when shappiron dies. dialog between kel and lich king (in this order)
23 SAY_SAPP_DIALOG1 = 0, //not used
24 SAY_SAPP_DIALOG2_LICH = 1, //not used
25 SAY_SAPP_DIALOG3 = 2, //not used
26 SAY_SAPP_DIALOG4_LICH = 3, //not used
27 SAY_SAPP_DIALOG5 = 4, //not used
28 SAY_CAT_DIED = 5, //when cat dies, not used
29 //when each of the 4 wing bosses dies
36 SAY_REQUEST_AID = 12, //start of phase 3
37 SAY_ANSWER_REQUEST = 13, //lich king answer
38 SAY_SUMMON_MINIONS = 14, //start of phase 1
40};
41
62
64{
74 SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect
77
78 //spells for chained
79 //warlock
82 //shaman
85 //mage
88 //rogue
91 //paladin
94 //priest
96 SPELL_RENEW = 48068,
97 //hunter
99 SPELL_VOLLEY = 58434,
100 //warrior
103 //druid
106 //death knight
109
110 // Abomination spells
113};
114
116{
117 NPC_WASTE = 16427, // Soldiers of the Frozen Wastes
118 NPC_ABOMINATION = 16428, // Unstoppable Abominations
119 NPC_WEAVER = 16429, // Soul Weavers
120 NPC_ICECROWN = 16441 // Guardians of Icecrown
121};
122
123const Position Pos[12] =
124{
125 {3783.272705f, -5062.697266f, 143.711203f, 3.617599f}, //LEFT_FAR
126 {3730.291260f, -5027.239258f, 143.956909f, 4.461900f}, //LEFT_MIDDLE
127 {3757.6f, -5172.0f, 143.7f, 1.97f}, //WINDOW_PORTAL05
128 {3759.355225f, -5174.128418f, 143.802383f, 2.170104f}, //RIGHT_FAR
129 {3700.724365f, -5185.123047f, 143.928024f, 1.309310f}, //RIGHT_MIDDLE
130 {3700.86f, -5181.29f, 143.928024f, 1.42f}, //WINDOW_PORTAL04
131 {3754.431396f, -5080.727734f, 142.036316f, 3.736189f}, //LEFT_FAR
132 {3724.396484f, -5061.330566f, 142.032700f, 4.564785f}, //LEFT_MIDDLE
133 {3732.02f, -5028.53f, 143.92f, 4.49f}, //WINDOW_PORTAL02
134 {3687.571777f, -5126.831055f, 142.017807f, 0.604023f}, //RIGHT_FAR
135 {3707.990733f, -5151.450195f, 142.032562f, 1.376855f}, //RIGHT_MIDDLE
136 {3782.76f, -5062.97f, 143.79f, 3.82f}, //WINDOW_PORTAL03
137};
138
139//creatures in corners
140//Unstoppable Abominations
141#define MAX_ABOMINATIONS 21
143{
144 {3755.52f, -5155.22f, 143.480f, 2.0f},
145 {3744.35f, -5164.03f, 143.590f, 2.00f},
146 {3749.28f, -5159.04f, 143.190f, 2.0f},
147 {3774.47f, -5076.28f, 143.528f, 2.15912f},
148 {3765.94f, -5074.15f, 143.186f, 3.77233f},
149 {3763.15f, -5063.36f, 143.694f, 3.77233f},
150 {3737.81f, -5045.69f, 143.709f, 4.9033f},
151 {3728.13f, -5045.01f, 143.355f, 1.45069f},
152 {3721.56f, -5048.35f, 143.542f, 1.45069f},
153 {3689.55f, -5049.66f, 143.637f, 5.2104f},
154 {3681.71f, -5053.03f, 143.242f, 2.47957f},
155 {3677.64f, -5061.44f, 143.358f, 2.47957f},
156 {3654.2f, -5090.87f, 143.469f, 1.0313f},
157 {3650.39f, -5097.45f, 143.496f, 2.5047f},
158 {3658.7f, -5103.59f, 143.607f, 3.3278f},
159 {3659.02f, -5133.97f, 143.624f, 3.84538f},
160 {3666.33f, -5139.34f, 143.183f, 3.84538f},
161 {3669.74f, -5149.63f, 143.678f, 0.528643f},
162 {3695.53f, -5169.53f, 143.671f, 2.11908f},
163 {3701.98f, -5166.51f, 143.395f, 1.24257f},
164 {3709.62f, -5169.15f, 143.576f, 5.97695f},
165};
166
167//Soldiers of the Frozen Wastes
168#define MAX_WASTES 49
170{
171 {3754.41f, -5147.24f, 143.204f, 2.0f},
172 {3754.68f, -5156.17f, 143.418f, 2.0f},
173 {3757.91f, -5160.12f, 143.503f, 2.0f},
174 {3752.67f, -5164.6f, 143.395f, 2.0f},
175 {3745.42f, -5164.47f, 143.565f, 2.74587f},
176 {3741.2f, -5155.92f, 143.17f, 5.29134f},
177 {3746.57f, -5148.82f, 143.176f, 5.07772f},
178 {3778.14f, -5070.1f, 143.568f, 3.16208f},
179 {3775.09f, -5078.97f, 143.65f, 2.81022f},
180 {3773.54f, -5083.47f, 143.758f, 3.21549f},
181 {3765, -5078.29f, 143.176f, 4.36688f},
182 {3766.94f, -5072.63f, 143.184f, 5.27951f},
183 {3762.68f, -5064.94f, 143.635f, 3.95297f},
184 {3769.9f, -5059.94f, 143.74f, 3.36549f},
185 {3736.33f, -5042.18f, 143.643f, 5.9471f},
186 {3727.51f, -5040.58f, 143.502f, 0.871859f},
187 {3719.89f, -5049.64f, 143.58f, 4.75172f},
188 {3720.69f, -5044.43f, 143.662f, 1.87245f},
189 {3725.69f, -5048.99f, 143.363f, 2.48271f},
190 {3732.33f, -5054.01f, 143.44f, 3.59405f},
191 {3738.09f, -5051.06f, 143.718f, 4.70931f},
192 {3682.76f, -5063.5f, 143.175f, 0.636238f},
193 {3686.7f, -5060.58f, 143.18f, 0.636238f},
194 {3682.45f, -5057.21f, 143.184f, 5.61252f},
195 {3677.57f, -5053.34f, 143.369f, 1.52531f},
196 {3677.3f, -5062.26f, 143.369f, 2.73482f},
197 {3691.21f, -5053.02f, 143.421f, 5.93218f},
198 {3685.22f, -5053.34f, 143.314f, 4.70303f},
199 {3652.11f, -5088.47f, 143.555f, 0.793317f},
200 {3648.23f, -5093.21f, 143.311f, 1.18837f},
201 {3648.14f, -5100.11f, 143.632f, 2.12221f},
202 {3653.88f, -5099.7f, 143.558f, 3.04348f},
203 {3661.23f, -5100.33f, 143.42f, 4.08335f},
204 {3663.49f, -5092.77f, 143.346f, 4.47134f},
205 {3661.85f, -5087.99f, 143.571f, 1.0148f},
206 {3664.56f, -5149.01f, 143.532f, 0.0762528f},
207 {3665.01f, -5142.04f, 143.201f, 1.72009f},
208 {3671.15f, -5142.92f, 143.174f, 4.81535f},
209 {3670.18f, -5134.38f, 143.177f, 5.37534f},
210 {3664.33f, -5131.69f, 143.262f, 5.39576f},
211 {3658.21f, -5133.63f, 143.662f, 1.3863f},
212 {3659.7f, -5144.49f, 143.363f, 2.32328f},
213 {3705.71f, -5179.63f, 143.746f, 1.06743f},
214 {3696.77f, -5177.45f, 143.759f, 5.36748f},
215 {3700.97f, -5173.13f, 143.52f, 3.26575f},
216 {3708.53f, -5172.19f, 143.573f, 3.26575f},
217 {3712.49f, -5167.62f, 143.657f, 5.63295f},
218 {3704.89f, -5161.84f, 143.239f, 5.63295f},
219 {3695.66f, -5164.63f, 143.674f, 1.54416f},
220};
221
222//Soul Weavers
223#define MAX_WEAVERS 7
225{
226 {3752.45f, -5168.35f, 143.562f, 1.6094f},
227 {3772.2f, -5070.04f, 143.329f, 1.93686f},
228 {3732.28f, -5032.88f, 143.771f, 3.08355f},
229 {3689.05f, -5055.7f, 143.172f, 6.09554f},
230 {3649.45f, -5093.17f, 143.299f, 2.51805f},
231 {3659.7f, -5144.49f, 143.363f, 4.08806f},
232 {3704.71f, -5175.96f, 143.597f, 3.36549f},
233};
234
235// predicate function to select not charmed target
236struct NotCharmedTargetSelector : public SF_UNARY_FUNCTION<Unit*, bool>
237{
239
240 bool operator()(Unit const* target) const
241 {
242 return !target->IsCharmed();
243 }
244};
245
247{
248public:
249 boss_kelthuzad() : CreatureScript("boss_kelthuzad") { }
250
251 struct boss_kelthuzadAI : public BossAI
252 {
253 boss_kelthuzadAI(Creature* creature) : BossAI(creature, BOSS_KELTHUZAD), spawns(creature)
254 {
255 uiFaction = me->getFaction();
256 }
257
261
265
266 std::map<uint64, float> chained;
267
270
271 SummonList spawns; // adds spawn by the trigger. kept in separated list (i.e. not in summons)
272
274 {
275 std::map<uint64, float>::const_iterator itr;
276 for (itr = chained.begin(); itr != chained.end(); ++itr)
277 {
278 if (Player* charmed = ObjectAccessor::GetPlayer(*me, itr->first))
279 charmed->SetObjectScale(itr->second);
280 }
281
282 chained.clear();
283 }
284
286 {
287 _Reset();
288
289 PortalsGUID[0] = PortalsGUID[1] = PortalsGUID[2] = PortalsGUID[3] = 0;
290 KTTriggerGUID = 0;
291
292 me->setFaction(35);
294
296 spawns.DespawnAll();
297
299
300 if (instance)
302
303 if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID))
304 {
305 pKTTrigger->ResetDoorOrButton();
306 pKTTrigger->SetPhaseMask(1, true);
307 }
308
309 for (uint8 i = 0; i <= 3; ++i)
310 {
311 if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
312 {
313 if (!((pPortal->getLootState() == LootState::GO_READY) || (pPortal->getLootState() == LootState::GO_NOT_READY)))
314 pPortal->ResetDoorOrButton();
315 }
316 }
317
319 uiGuardiansOfIcecrownTimer = 5000; //5 seconds for summoning each Guardian of Icecrown in phase 3
320
321 Phase = 0;
322 nAbomination = 0;
323 nWeaver = 0;
324 }
325
326 void KilledUnit(Unit* /*victim*/) OVERRIDE
327 {
328 Talk(SAY_SLAY);
329 }
330
331 void JustDied(Unit* /*killer*/) OVERRIDE
332 {
333 _JustDied();
335
337 }
338
339 void EnterCombat(Unit* /*who*/) OVERRIDE
340 {
341 me->setFaction(uiFaction);
342
343 _EnterCombat();
345 for (uint8 i = 0; i <= 3; ++i)
346 {
347 if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
348 pPortal->ResetDoorOrButton();
349 }
352 Phase = 1;
354 me->SetFloatValue(UNIT_FIELD_COMBAT_REACH, 4);
355 me->SetFloatValue(UNIT_FIELD_BOUNDING_RADIUS, 4);
356 events.ScheduleEvent(EVENT_TRIGGER, 5000);
357 events.ScheduleEvent(EVENT_WASTE, 15000);
358 events.ScheduleEvent(EVENT_ABOMIN, 30000);
359 events.ScheduleEvent(EVENT_WEAVER, 50000);
360 events.ScheduleEvent(EVENT_PHASE, 228000);
361 }
362
371
373 {
374 if (!UpdateVictim())
375 return;
376
377 events.Update(diff);
378
379 if (Phase == 1)
380 {
381 while (uint32 eventId = events.GetEvent())
382 {
383 switch (eventId)
384 {
385 case EVENT_WASTE:
386 DoSummon(NPC_WASTE, Pos[RAND(0, 3, 6, 9)]);
387 events.RepeatEvent(std::rand() % 5000 + 2000);
388 break;
389 case EVENT_ABOMIN:
390 if (nAbomination < 8)
391 {
392 DoSummon(NPC_ABOMINATION, Pos[RAND(1, 4, 7, 10)]);
393 nAbomination++;
394 events.RepeatEvent(20000);
395 }
396 else
397 events.PopEvent();
398 break;
399 case EVENT_WEAVER:
400 if (nWeaver < 8)
401 {
402 DoSummon(NPC_WEAVER, Pos[RAND(0, 3, 6, 9)]);
403 nWeaver++;
404 events.RepeatEvent(25000);
405 }
406 else
407 events.PopEvent();
408 break;
409 case EVENT_TRIGGER:
410 if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID))
411 pKTTrigger->SetPhaseMask(2, true);
412 events.PopEvent();
413 break;
414 case EVENT_PHASE:
415 events.Reset();
417 spawns.DespawnAll();
419 me->CastStop();
420
421 DoStartMovement(me->GetVictim());
422 events.ScheduleEvent(EVENT_BOLT, std::rand() % 10000 + 5000);
423 events.ScheduleEvent(EVENT_NOVA, 15000);
424 events.ScheduleEvent(EVENT_DETONATE, std::rand() % 40000 + 30000);
425 events.ScheduleEvent(EVENT_FISSURE, std::rand() % 30000 + 10000);
426 events.ScheduleEvent(EVENT_BLAST, std::rand() % 120000 + 60000);
428 events.ScheduleEvent(EVENT_CHAIN, std::rand() % 60000 + 30000);
429 Phase = 2;
430 break;
431 default:
432 events.PopEvent();
433 break;
434 }
435 }
436 }
437 else
438 {
439 //start phase 3 when we are 45% health
440 if (Phase != 3)
441 {
442 if (HealthBelowPct(45))
443 {
444 Phase = 3;
446 //here Lich King should respond to KelThuzad but I don't know which Creature to make talk
447 //so for now just make Kelthuzad says it.
449
450 for (uint8 i = 0; i <= 3; ++i)
451 {
452 if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
453 {
454 if (pPortal->getLootState() == LootState::GO_READY)
455 pPortal->UseDoorOrButton();
456 }
457 }
458 }
459 }
460 else if (nGuardiansOfIcecrownCount < RAID_MODE(2, 4))
461 {
462 if (uiGuardiansOfIcecrownTimer <= diff)
463 {
465 if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
466 pGuardian->SetFloatValue(UNIT_FIELD_COMBAT_REACH, 2);
469 }
470 else uiGuardiansOfIcecrownTimer -= diff;
471 }
472
473 if (me->HasUnitState(UNIT_STATE_CASTING))
474 return;
475
476 if (uint32 eventId = events.GetEvent())
477 {
478 switch (eventId)
479 {
480 case EVENT_BOLT:
482 events.RepeatEvent(std::rand() % 10000 + 5000);
483 break;
484 case EVENT_NOVA:
486 events.RepeatEvent(std::rand() % 30000 + 15000);
487 break;
488 case EVENT_CHAIN:
489 {
490 uint32 count = std::rand() % 3 + 1;
491 for (uint8 i = 1; i <= count; i++)
492 {
493 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true);
494 if (target && !target->IsCharmed() && (chained.find(target->GetGUID()) == chained.end()))
495 {
497 float scale = target->GetObjectScale();
498 chained.insert(std::make_pair(target->GetGUID(), scale));
499 target->SetObjectScale(scale * 2);
500 events.ScheduleEvent(EVENT_CHAINED_SPELL, 2000); //core has 2000ms to set unit flag charm
501 }
502 }
503 if (!chained.empty())
505 events.RepeatEvent(std::rand() % 180000 + 100000);
506 break;
507 }
509 {
510 std::map<uint64, float>::iterator itr;
511 for (itr = chained.begin(); itr != chained.end();)
512 {
513 if (Unit* player = ObjectAccessor::GetPlayer(*me, itr->first))
514 {
515 if (!player->IsCharmed())
516 {
517 player->SetObjectScale(itr->second);
518 std::map<uint64, float>::iterator next = itr;
519 ++next;
520 chained.erase(itr);
521 itr = next;
522 continue;
523 }
524
526 {
527 switch (player->getClass())
528 {
529 case CLASS_DRUID:
530 if (std::rand() % 1)
531 player->CastSpell(target, SPELL_MOONFIRE, false);
532 else
533 player->CastSpell(me, SPELL_LIFEBLOOM, false);
534 break;
535 case CLASS_HUNTER:
536 player->CastSpell(target, RAND(SPELL_MULTI_SHOT, SPELL_VOLLEY), false);
537 break;
538 case CLASS_MAGE:
539 player->CastSpell(target, RAND(SPELL_FROST_FIREBOLT, SPELL_ARCANE_MISSILES), false);
540 break;
541 case CLASS_WARLOCK:
542 player->CastSpell(target, RAND(SPELL_CURSE_OF_AGONY, SPELL_SHADOW_BOLT), true);
543 break;
544 case CLASS_WARRIOR:
545 player->CastSpell(target, RAND(SPELL_BLADESTORM, SPELL_CLEAVE), false);
546 break;
547 case CLASS_PALADIN:
548 if (std::rand() % 1)
549 player->CastSpell(target, SPELL_HAMMER_OF_JUSTICE, false);
550 else
551 player->CastSpell(me, SPELL_HOLY_SHOCK, false);
552 break;
553 case CLASS_PRIEST:
554 if (std::rand() % 1)
555 player->CastSpell(target, SPELL_VAMPIRIC_TOUCH, false);
556 else
557 player->CastSpell(me, SPELL_RENEW, false);
558 break;
559 case CLASS_SHAMAN:
560 if (std::rand() % 1)
561 player->CastSpell(target, SPELL_EARTH_SHOCK, false);
562 else
563 player->CastSpell(me, SPELL_HEALING_WAVE, false);
564 break;
565 case CLASS_ROGUE:
566 player->CastSpell(target, RAND(SPELL_HEMORRHAGE, SPELL_MUTILATE), false);
567 break;
569 if (std::rand() % 1)
570 player->CastSpell(target, SPELL_PLAGUE_STRIKE, true);
571 else
572 player->CastSpell(target, SPELL_HOWLING_BLAST, true);
573 break;
574 }
575 }
576 }
577 ++itr;
578 }
579
580 if (chained.empty())
581 events.PopEvent();
582 else
583 events.RepeatEvent(5000);
584
585 break;
586 }
587 case EVENT_DETONATE:
588 {
589 std::vector<Unit*> unitList;
590 ThreatContainer::StorageType const &threatList = me->getThreatManager().getThreatList();
591 for (ThreatContainer::StorageType::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
592 {
593 Unit* const target = (*itr)->getTarget();
594
595 if (target->GetTypeId() == TypeID::TYPEID_PLAYER
596 && target->getPowerType() == POWER_MANA
597 && target->GetPower(POWER_MANA))
598 {
599 unitList.push_back(target);
600 }
601 }
602
603 if (!unitList.empty())
604 {
605 std::vector<Unit*>::const_iterator itr = unitList.begin();
606 advance(itr, rand()%unitList.size());
609 }
610
611 events.RepeatEvent(std::rand() % 50000 + 20000);
612 break;
613 }
614 case EVENT_FISSURE:
615 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
617 events.RepeatEvent(std::rand() % 45000 + 10000);
618 break;
619 case EVENT_BLAST:
620 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, RAID_MODE(1, 0), 0, true))
621 DoCast(target, SPELL_FROST_BLAST);
622 if (rand()%2)
624 events.RepeatEvent(std::rand() % 90000 + 30000);
625 break;
626 default:
627 events.PopEvent();
628 break;
629 }
630 }
631
633 }
634 }
635 };
636
638 {
639 return new boss_kelthuzadAI(creature);
640 }
641};
642
644{
645public:
646 at_kelthuzad_center() : AreaTriggerScript("at_kelthuzad_center") { }
647
648 bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) OVERRIDE
649 {
650 if (player->IsGameMaster())
651 return false;
652
653 InstanceScript* instance = player->GetInstanceScript();
654 if (!instance || instance->IsEncounterInProgress() || instance->GetBossState(BOSS_KELTHUZAD) == DONE)
655 return false;
656
657 Creature* pKelthuzad = Unit::GetCreature(*player, instance->GetData64(DATA_KELTHUZAD));
658 if (!pKelthuzad)
659 return false;
660
662 if (!pKelthuzadAI)
663 return false;
664
665 pKelthuzadAI->AttackStart(player);
666 if (GameObject* trigger = instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_TRIGGER)))
667 {
668 if (trigger->getLootState() == LootState::GO_READY)
669 trigger->UseDoorOrButton();
670
671 // Note: summon must be done by trigger and not by KT.
672 // Otherwise, they attack immediately as KT is in combat.
673 for (uint8 i = 0; i < MAX_ABOMINATIONS; ++i)
674 {
676 {
677 pKelthuzadAI->spawns.Summon(sum);
678 sum->GetMotionMaster()->MoveRandom(9.0f);
679 sum->SetReactState(REACT_DEFENSIVE);
680 }
681 }
682 for (uint8 i = 0; i < MAX_WASTES; ++i)
683 {
684 if (Creature* sum = trigger->SummonCreature(NPC_WASTE, PosWastes[i]))
685 {
686 pKelthuzadAI->spawns.Summon(sum);
687 sum->GetMotionMaster()->MoveRandom(5.0f);
688 sum->SetReactState(REACT_DEFENSIVE);
689 }
690 }
691 for (uint8 i = 0; i < MAX_WEAVERS; ++i)
692 {
693 if (Creature* sum = trigger->SummonCreature(NPC_WEAVER, PosWeavers[i]))
694 {
695 pKelthuzadAI->spawns.Summon(sum);
696 sum->GetMotionMaster()->MoveRandom(9.0f);
697 sum->SetReactState(REACT_DEFENSIVE);
698 }
699 }
700 }
701
702 return true;
703 }
704};
705
707{
708 public:
709 npc_kelthuzad_abomination() : CreatureScript("npc_kelthuzad_abomination") { }
710
712 {
714 {
715 _instance = creature->GetInstanceScript();
716 }
717
719 {
720 _events.Reset();
721 _events.ScheduleEvent(EVENT_MORTAL_WOUND, std::rand() % 5000 + 2000);
722 DoCast(me, SPELL_FRENZY, true);
723 }
724
726 {
727 if (!UpdateVictim())
728 return;
729
730 _events.Update(diff);
731
732 while (uint32 eventId = _events.ExecuteEvent())
733 {
734 switch (eventId)
735 {
738 _events.ScheduleEvent(EVENT_MORTAL_WOUND, std::rand() % 15000 + 10000);
739 break;
740 default:
741 break;
742 }
743 }
744 }
745
746 void JustDied(Unit* /*killer*/) OVERRIDE
747 {
748 if (_instance)
750 }
751
752 private:
755 };
756
758 {
759 return new npc_kelthuzad_abominationAI(creature);
760 }
761};
762
764{
765 public:
766 spell_kelthuzad_detonate_mana() : SpellScriptLoader("spell_kelthuzad_detonate_mana") { }
767
769 {
771
772 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
773 {
774 if (!sSpellMgr->GetSpellInfo(SPELL_MANA_DETONATION_DAMAGE))
775 return false;
776 return true;
777 }
778
779 void HandleScript(AuraEffect const* aurEff)
780 {
782
783 Unit* target = GetTarget();
784 if (int32 mana = int32(target->GetMaxPower(POWER_MANA) / 10))
785 {
786 mana = target->ModifyPower(POWER_MANA, -mana);
787 target->CastCustomSpell(SPELL_MANA_DETONATION_DAMAGE, SPELLVALUE_BASE_POINT0, -mana * 10, target, true, NULL, aurEff);
788 }
789 }
790
795 };
796
801};
802
804{
805 public:
806 achievement_just_cant_get_enough() : AchievementCriteriaScript("achievement_just_cant_get_enough") { }
807
808 bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
809 {
810 if (!target)
811 return false;
812
813 if (InstanceScript* instance = target->GetInstanceScript())
814 if (instance->GetData(DATA_ABOMINATION_KILLED) >= 18)
815 return true;
816
817 return false;
818 }
819};
820
const T & RAND(const T &v1, const T &v2)
@ DIFFICULTY_25MAN_NORMAL
Definition DBCEnums.h:335
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ DONE
@ TYPEID_PLAYER
Definition Object.h:55
#define CAST_AI(a, b)
@ EFFECT_0
@ POWER_MANA
@ CLASS_HUNTER
@ CLASS_DRUID
@ CLASS_SHAMAN
@ CLASS_PRIEST
@ CLASS_WARRIOR
@ CLASS_WARLOCK
@ CLASS_MAGE
@ CLASS_DEATH_KNIGHT
@ CLASS_PALADIN
@ CLASS_ROGUE
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
#define sSpellMgr
Definition SpellMgr.h:744
#define AuraEffectPeriodicFn(F, I, N)
#define SF_UNARY_FUNCTION
@ SPELLVALUE_BASE_POINT0
Definition Unit.h:114
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_DEFENSIVE
Definition Unit.h:1157
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_DISABLE_MOVE
Definition Unit.h:627
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_TOPAGGRO
Definition UnitAI.h:24
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_BOUNDING_RADIUS
@ UNIT_FIELD_FLAGS
@ UNIT_FIELD_COMBAT_REACH
Creatures
@ SPELL_CLEAVE
@ SAY_SLAY
@ EVENT_BOLT
@ SPELL_HAMMER_OF_JUSTICE
#define SAY_DEATH
#define SAY_AGGRO
@ SPELL_FRENZY
@ EVENT_NONE
#define SPELL_BERSERK
@ SPELL_SHADOW_BOLT
@ SPELL_BLADESTORM
@ EVENT_PHASE
const Position Pos[12]
@ NPC_ICECROWN
@ NPC_WASTE
@ NPC_ABOMINATION
@ NPC_WEAVER
@ SAY_FROST_BLAST
@ SAY_SAPP_DIALOG4_LICH
@ SAY_DEATH
@ SAY_CHAIN
@ SAY_SAPP_DIALOG2_LICH
@ SAY_AGGRO
@ SAY_SAPP_DIALOG1
@ SAY_SPECIAL
@ SAY_ANSWER_REQUEST
@ SAY_SAPP_DIALOG5
@ SAY_SAPP_DIALOG3
@ SAY_SLAY
@ SAY_SUMMON_MINIONS
@ SAY_CAT_DIED
@ SAY_REQUEST_AID
#define MAX_WEAVERS
const Position PosAbominations[MAX_ABOMINATIONS]
const Position PosWastes[MAX_WASTES]
void AddSC_boss_kelthuzad()
@ SPELL_HAMMER_OF_JUSTICE
@ SPELL_MOONFIRE
@ SPELL_MANA_DETONATION_DAMAGE
@ SPELL_CLEAVE
@ SPELL_FROST_BOLT
@ SPELL_PLAGUE_STRIKE
@ SPELL_SHADOW_FISURE
@ SPELL_VAMPIRIC_TOUCH
@ SPELL_HOWLING_BLAST
@ SPELL_LIFEBLOOM
@ SPELL_FROST_FIREBOLT
@ SPELL_CHAINS_OF_KELTHUZAD
@ H_SPELL_FROST_BOLT_AOE
@ H_SPELL_FROST_BOLT
@ SPELL_HOLY_SHOCK
@ SPELL_SHADOW_BOLT
@ SPELL_KELTHUZAD_CHANNEL
@ SPELL_CURSE_OF_AGONY
@ SPELL_FROST_BLAST
@ SPELL_RENEW
@ SPELL_HEALING_WAVE
@ SPELL_FRENZY
@ SPELL_BLADESTORM
@ SPELL_HEMORRHAGE
@ SPELL_MULTI_SHOT
@ SPELL_MORTAL_WOUND
@ SPELL_VOLLEY
@ SPELL_MANA_DETONATION
@ SPELL_MUTILATE
@ SPELL_EARTH_SHOCK
@ SPELL_FROST_BOLT_AOE
@ SPELL_ARCANE_MISSILES
#define MAX_ABOMINATIONS
const Position PosWeavers[MAX_WEAVERS]
#define MAX_WASTES
@ EVENT_BLAST
@ EVENT_WEAVER
@ EVENT_MORTAL_WOUND
@ EVENT_WASTE
@ EVENT_BOLT
@ EVENT_TRIGGER
@ EVENT_ICECROWN
@ EVENT_ABOMIN
@ EVENT_NOVA
@ EVENT_DETONATE
@ EVENT_PHASE
@ EVENT_CHAINED_SPELL
@ EVENT_CHAIN
@ EVENT_FISSURE
@ SPELL_VAMPIRIC_TOUCH
@ SPELL_VOID_BLAST
Definition boss_muru.cpp:50
@ SPELL_EARTH_SHOCK
@ SPELL_MORTAL_WOUND
@ EVENT_MORTAL_WOUND
@ SPELL_HEALING_WAVE
@ SPELL_PLAGUE_STRIKE
Definition chapter1.cpp:32
AchievementCriteriaScript(const char *name)
AreaTriggerScript(const char *name)
void PreventDefaultAction()
HookList< EffectPeriodicHandler > OnEffectPeriodic
Unit * GetTarget() const
InstanceScript *const instance
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
Creature * DoSummon(uint32 entry, Position const &pos, uint32 despawnTime=30000, TempSummonType summonType=TempSummonType::TEMPSUMMON_CORPSE_TIMED_DESPAWN)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
EncounterState GetBossState(uint32 id) const
virtual bool IsEncounterInProgress() const
GameObject * GetGameObject(uint64 guid)
Definition Map.cpp:3184
static Player * GetPlayer(WorldObject const &, uint64 guid)
float GetObjectScale() const
Definition Object.h:128
uint64 GetGUID() const
Definition Object.h:119
TypeID GetTypeId() const
Definition Object.h:131
virtual void SetObjectScale(float scale)
Definition Object.h:129
SpellScriptLoader(const char *name)
void Summon(Creature const *summon)
std::list< HostileReference * > StorageType
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition UnitAI.cpp:66
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
void DoCastAOE(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:176
Definition Unit.h:1367
bool IsCharmed() const
Definition Unit.h:2136
int32 GetMaxPower(Powers power) const
Definition Unit.cpp:5246
int32 ModifyPower(Powers power, int32 val)
Definition Unit.cpp:4081
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
int32 GetPower(Powers power) const
Definition Unit.cpp:5237
void CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
Powers getPowerType() const
Definition Unit.h:1651
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
TempSummon * SummonCreature(uint32 id, Position const &pos, TempSummonType spwtype=TempSummonType::TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0) const
Definition Object.cpp:2703
virtual uint64 GetData64(uint32) const
Definition ZoneScript.h:32
bool OnCheck(Player *, Unit *target) OVERRIDE
bool OnTrigger(Player *player, const AreaTriggerEntry *) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
@ DATA_KELTHUZAD
Definition naxxramas.h:54
@ DATA_KELTHUZAD_PORTAL02
Definition naxxramas.h:56
@ DATA_KELTHUZAD_PORTAL01
Definition naxxramas.h:55
@ DATA_KELTHUZAD_PORTAL04
Definition naxxramas.h:58
@ DATA_KELTHUZAD_TRIGGER
Definition naxxramas.h:59
@ DATA_KELTHUZAD_PORTAL03
Definition naxxramas.h:57
@ BOSS_KELTHUZAD
Definition naxxramas.h:27
@ DATA_ABOMINATION_KILLED
Definition naxxramas.h:40
bool operator()(Unit const *target) const
DifficultyID GetDifficulty() const
Creature * me
bool HealthBelowPct(uint32 pct) const
const T & RAID_MODE(const T &normal10, const T &normal25) const
ScriptedAI(Creature *creature)
void AttackStart(Unit *) OVERRIDE
void DoStartMovement(Unit *target, float distance=0.0f, float angle=0.0f)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
std::map< uint64, float > chained
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================