Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_lady_deathwhisper.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#include "ObjectMgr.h"
7#include "ScriptMgr.h"
8#include "ScriptedCreature.h"
9#include "PoolMgr.h"
10#include "Group.h"
11#include "icecrown_citadel.h"
12#include "SpellInfo.h"
13#include "Player.h"
14
40
42{
43 // Lady Deathwhisper
52 SPELL_SHADOW_CHANNELING = 43897, // Prefight, during intro
56
57 // Achievement
58 SPELL_FULL_HOUSE = 72827, // does not exist in dbc but still can be used for criteria check
59
60 // Both Adds
62
63 // Fanatics
70
71 // Adherents
80
81 // Vengeful Shade
87
88 // Darnavan
90 SPELL_CHARGE = 65927,
95};
96
145
153
164
165#define NPC_DARNAVAN RAID_MODE<uint32>(NPC_DARNAVAN_10, NPC_DARNAVAN_25, NPC_DARNAVAN_10, NPC_DARNAVAN_25)
166#define NPC_DARNAVAN_CREDIT RAID_MODE<uint32>(NPC_DARNAVAN_CREDIT_10, NPC_DARNAVAN_CREDIT_25, NPC_DARNAVAN_CREDIT_10, NPC_DARNAVAN_CREDIT_25)
167#define QUEST_DEPROGRAMMING RAID_MODE<uint32>(QUEST_DEPROGRAMMING_10, QUEST_DEPROGRAMMING_25, QUEST_DEPROGRAMMING_10, QUEST_DEPROGRAMMING_25)
168
170
171#define GUID_CULTIST 1
172
174{
175 {-578.7066f, 2154.167f, 51.01529f, 1.692969f}, // 1 Left Door 1 (Cult Fanatic)
176 {-598.9028f, 2155.005f, 51.01530f, 1.692969f}, // 2 Left Door 2 (Cult Adherent)
177 {-619.2864f, 2154.460f, 51.01530f, 1.692969f}, // 3 Left Door 3 (Cult Fanatic)
178 {-578.6996f, 2269.856f, 51.01529f, 4.590216f}, // 4 Right Door 1 (Cult Adherent)
179 {-598.9688f, 2269.264f, 51.01529f, 4.590216f}, // 5 Right Door 2 (Cult Fanatic)
180 {-619.4323f, 2268.523f, 51.01530f, 4.590216f}, // 6 Right Door 3 (Cult Adherent)
181 {-524.2480f, 2211.920f, 62.90960f, 3.141592f}, // 7 Upper (Random Cultist)
182};
183
185{
186 public:
187 DaranavanMoveEvent(Creature& darnavan) : _darnavan(darnavan) { }
188
189 bool Execute(uint64 /*time*/, uint32 /*diff*/)
190 {
191 _darnavan.GetMotionMaster()->MovePoint(POINT_DESPAWN, SummonPositions[6]);
192 return true;
193 }
194
195 private:
197};
198
200{
201 public:
202 boss_lady_deathwhisper() : CreatureScript("boss_lady_deathwhisper") { }
203
205 {
207 _dominateMindCount(RAID_MODE<uint8>(0, 1, 1, 3)), _introDone(false)
208 {
209 }
210
212 {
213 _Reset();
214 me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA));
215 events.SetPhase(PHASE_ONE);
216 _waveCounter = 0;
218 _darnavanGUID = 0;
220 me->RemoveAurasDueToSpell(SPELL_BERSERK);
221 me->RemoveAurasDueToSpell(SPELL_MANA_BARRIER);
222 me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
223 me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false);
224 }
225
227
228 {
229 if (!_introDone && me->IsWithinDistInMap(who, 110.0f))
230 {
231 _introDone = true;
233 events.SetPhase(PHASE_INTRO);
234 events.ScheduleEvent(EVENT_INTRO_2, 11000, 0, PHASE_INTRO);
235 events.ScheduleEvent(EVENT_INTRO_3, 21000, 0, PHASE_INTRO);
236 events.ScheduleEvent(EVENT_INTRO_4, 31500, 0, PHASE_INTRO);
237 events.ScheduleEvent(EVENT_INTRO_5, 39500, 0, PHASE_INTRO);
238 events.ScheduleEvent(EVENT_INTRO_6, 48500, 0, PHASE_INTRO);
239 events.ScheduleEvent(EVENT_INTRO_7, 58000, 0, PHASE_INTRO);
240 }
241 }
242
244 {
246 return;
247
248 if (victim && me->Attack(victim, true) && !events.IsInPhase(PHASE_ONE))
249 me->GetMotionMaster()->MoveChase(victim);
250 }
251
253 {
254 if (!instance->CheckRequiredBosses(DATA_LADY_DEATHWHISPER, who->ToPlayer()))
255 {
257 instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
258 return;
259 }
260
261 me->setActive(true);
263
264 events.Reset();
265 events.SetPhase(PHASE_ONE);
266 // phase-independent events
267 events.ScheduleEvent(EVENT_BERSERK, 600000);
268 events.ScheduleEvent(EVENT_DEATH_AND_DECAY, 10000);
269 // phase one only
270 events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, 5000, 0, PHASE_ONE);
271 events.ScheduleEvent(EVENT_P1_SHADOW_BOLT, std::rand() % 6000 + 5500, 0, PHASE_ONE);
272 events.ScheduleEvent(EVENT_P1_EMPOWER_CULTIST, std::rand() % 30000 + 20000, 0, PHASE_ONE);
274 events.ScheduleEvent(EVENT_DOMINATE_MIND_H, 27000);
275
278 me->RemoveAurasDueToSpell(SPELL_SHADOW_CHANNELING);
280
282 }
283
284 void JustDied(Unit* killer) OVERRIDE
285 {
287
288 std::set<uint32> livingAddEntries;
289 // Full House achievement
290 for (SummonList::iterator itr = summons.begin(); itr != summons.end(); ++itr)
291 if (Unit* unit = ObjectAccessor::GetUnit(*me, *itr))
292 if (unit->IsAlive() && unit->GetEntry() != NPC_VENGEFUL_SHADE)
293 livingAddEntries.insert(unit->GetEntry());
294
295 if (livingAddEntries.size() >= 5)
297
299 {
300 if (darnavan->IsAlive())
301 {
302 darnavan->setFaction(35);
303 darnavan->CombatStop(true);
304 darnavan->GetMotionMaster()->MoveIdle();
305 darnavan->SetReactState(REACT_PASSIVE);
306 darnavan->m_Events.AddEvent(new DaranavanMoveEvent(*darnavan), darnavan->m_Events.CalculateTime(10000));
307 darnavan->AI()->Talk(SAY_DARNAVAN_RESCUED);
308 if (Player* owner = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
309 {
310 if (Group* group = owner->GetGroup())
311 {
312 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
313 if (Player* member = itr->GetSource())
314 member->KilledMonsterCredit(NPC_DARNAVAN_CREDIT, 0);
315 }
316 else
317 owner->KilledMonsterCredit(NPC_DARNAVAN_CREDIT, 0);
318 }
319 }
320 }
321
322 _JustDied();
323 }
324
326 {
328 instance->SetBossState(DATA_LADY_DEATHWHISPER, FAIL);
329
330 summons.DespawnAll();
332 {
333 darnavan->DespawnOrUnsummon();
334 _darnavanGUID = 0;
335 }
336 }
337
339 {
340 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER)
341 Talk(SAY_KILL);
342 }
343
344 void DamageTaken(Unit* /*damageDealer*/, uint32& damage) OVERRIDE
345 {
346 // phase transition
347 if (events.IsInPhase(PHASE_ONE) && damage > uint32(me->GetPower(POWER_MANA)))
348 {
351 DoStartMovement(me->GetVictim());
352 damage -= me->GetPower(POWER_MANA);
353 me->SetPower(POWER_MANA, 0);
354 me->RemoveAurasDueToSpell(SPELL_MANA_BARRIER);
355 events.SetPhase(PHASE_TWO);
356 events.ScheduleEvent(EVENT_P2_FROSTBOLT, std::rand() % 12000 + 10000, 0, PHASE_TWO);
357 events.ScheduleEvent(EVENT_P2_FROSTBOLT_VOLLEY, std::rand() % 21000 + 19000, 0, PHASE_TWO);
358 events.ScheduleEvent(EVENT_P2_TOUCH_OF_INSIGNIFICANCE, std::rand() % 9000 + 6000, 0, PHASE_TWO);
359 events.ScheduleEvent(EVENT_P2_SUMMON_SHADE, std::rand() % 15000 + 12000, 0, PHASE_TWO);
360 // on heroic mode Lady Deathwhisper is immune to taunt effects in phase 2 and continues summoning adds
361 if (IsHeroic())
362 {
363 me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
364 me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
365 events.ScheduleEvent(EVENT_P2_SUMMON_WAVE, 45000, 0, PHASE_TWO);
366 }
367 }
368 }
369
371 {
372 if (summon->GetEntry() == NPC_DARNAVAN)
373 _darnavanGUID = summon->GetGUID();
374 else
375 summons.Summon(summon);
376
377 Unit* target = NULL;
378 if (summon->GetEntry() == NPC_VENGEFUL_SHADE)
379 {
380 target = ObjectAccessor::GetUnit(*me, _nextVengefulShadeTargetGUID); // Vengeful Shade
382 }
383 else
384 target = SelectTarget(SELECT_TARGET_RANDOM); // Wave adds
385
386 summon->AI()->AttackStart(target); // CAN be NULL
387 if (summon->GetEntry() == NPC_REANIMATED_FANATIC)
388 summon->CastSpell(summon, SPELL_FANATIC_S_DETERMINATION, true);
389 else if (summon->GetEntry() == NPC_REANIMATED_ADHERENT)
390 summon->CastSpell(summon, SPELL_ADHERENT_S_DETERMINATION, true);
391 }
392
394 {
395 if ((!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) || !CheckInRoom())
396 return;
397
398 events.Update(diff);
399
400 if (me->HasUnitState(UNIT_STATE_CASTING) && !events.IsInPhase(PHASE_INTRO))
401 return;
402
403 while (uint32 eventId = events.ExecuteEvent())
404 {
405 switch (eventId)
406 {
407 case EVENT_INTRO_2:
409 break;
410 case EVENT_INTRO_3:
412 break;
413 case EVENT_INTRO_4:
415 break;
416 case EVENT_INTRO_5:
418 break;
419 case EVENT_INTRO_6:
421 break;
422 case EVENT_INTRO_7:
424 break;
428 events.ScheduleEvent(EVENT_DEATH_AND_DECAY, std::rand() % 30000 + 22000);
429 break;
432 for (uint8 i = 0; i < _dominateMindCount; i++)
433 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_DOMINATE_MIND_H))
435 events.ScheduleEvent(EVENT_DOMINATE_MIND_H, std::rand() % 45000 + 40000);
436 break;
438 SummonWaveP1();
439 events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, IsHeroic() ? 45000 : 60000, 0, PHASE_ONE);
440 break;
443 DoCast(target, SPELL_SHADOW_BOLT);
444 events.ScheduleEvent(EVENT_P1_SHADOW_BOLT, std::rand() % 8000 + 5000, 0, PHASE_ONE);
445 break;
448 break;
451 events.ScheduleEvent(EVENT_P1_EMPOWER_CULTIST, std::rand() % 25000 + 18000);
452 break;
455 events.ScheduleEvent(EVENT_P2_FROSTBOLT, std::rand() % 11000 + 10000, 0, PHASE_TWO);
456 break;
459 events.ScheduleEvent(EVENT_P2_FROSTBOLT_VOLLEY, std::rand() % 15000 + 13000, 0, PHASE_TWO);
460 break;
463 events.ScheduleEvent(EVENT_P2_TOUCH_OF_INSIGNIFICANCE, std::rand() % 13000 + 9000, 0, PHASE_TWO);
464 break;
466 if (Unit* shadeTarget = SelectTarget(SELECT_TARGET_RANDOM, 1))
467 {
468 _nextVengefulShadeTargetGUID = shadeTarget->GetGUID();
469 DoCast(shadeTarget, SPELL_SUMMON_SHADE);
470 }
471 events.ScheduleEvent(EVENT_P2_SUMMON_SHADE, std::rand() % 23000 + 18000, 0, PHASE_TWO);
472 break;
474 SummonWaveP2();
475 events.ScheduleEvent(EVENT_P2_SUMMON_WAVE, 45000, 0, PHASE_TWO);
476 break;
477 case EVENT_BERSERK:
480 break;
481 }
482 }
483
484 // We should not melee attack when barrier is up
485 if (me->HasAura(SPELL_MANA_BARRIER))
486 return;
487
489 }
490
491 // summoning function for first phase
493 {
494 uint8 addIndex = _waveCounter & 1;
495 uint8 addIndexOther = uint8(addIndex ^ 1);
496
497 // Summon first add, replace it with Darnavan if weekly quest is active
498 if (_waveCounter || !sPoolMgr->IsSpawnedObject<Quest>(QUEST_DEPROGRAMMING))
499 Summon(SummonEntries[addIndex], SummonPositions[addIndex * 3]);
500 else
501 Summon(NPC_DARNAVAN, SummonPositions[addIndex * 3]);
502
503 Summon(SummonEntries[addIndexOther], SummonPositions[addIndex * 3 + 1]);
504 Summon(SummonEntries[addIndex], SummonPositions[addIndex * 3 + 2]);
505 if (Is25ManRaid())
506 {
507 Summon(SummonEntries[addIndexOther], SummonPositions[addIndexOther * 3]);
508 Summon(SummonEntries[addIndex], SummonPositions[addIndexOther * 3 + 1]);
509 Summon(SummonEntries[addIndexOther], SummonPositions[addIndexOther * 3 + 2]);
510 Summon(SummonEntries[std::rand() % 1], SummonPositions[6]);
511 }
512
513 ++_waveCounter;
514 }
515
516 // summoning function for second phase
518 {
519 if (Is25ManRaid())
520 {
521 uint8 addIndex = _waveCounter & 1;
522 Summon(SummonEntries[addIndex], SummonPositions[addIndex * 3]);
523 Summon(SummonEntries[addIndex ^ 1], SummonPositions[addIndex * 3 + 1]);
524 Summon(SummonEntries[addIndex], SummonPositions[addIndex * 3+ 2]);
525 }
526 else
527 Summon(SummonEntries[std::rand() % 1], SummonPositions[6]);
528
529 ++_waveCounter;
530 }
531
532 // helper for summoning wave mobs
533 void Summon(uint32 entry, const Position& pos)
534 {
535 if (TempSummon* summon = me->SummonCreature(entry, pos, TempSummonType::TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000))
536 summon->AI()->DoCast(summon, SPELL_TELEPORT_VISUAL);
537 }
538
539 void SetGUID(uint64 guid, int32 id/* = 0*/) OVERRIDE
540 {
541 if (id != GUID_CULTIST)
542 return;
543
544 _reanimationQueue.push_back(guid);
545 events.ScheduleEvent(EVENT_P1_REANIMATE_CULTIST, 3000, 0, PHASE_ONE);
546 }
547
549 {
550 if (_reanimationQueue.empty())
551 return;
552
553 uint64 cultistGUID = _reanimationQueue.front();
554 Creature* cultist = ObjectAccessor::GetCreature(*me, cultistGUID);
555 _reanimationQueue.pop_front();
556 if (!cultist)
557 return;
558
561 }
562
563 void SpellHitTarget(Unit* target, SpellInfo const* spell) OVERRIDE
564 {
565 if (spell->Id == SPELL_DARK_MARTYRDOM_T)
566 {
567 Position pos;
568 target->GetPosition(&pos);
569 if (target->GetEntry() == NPC_CULT_FANATIC)
571 else
573
574 if (TempSummon* summon = target->ToTempSummon())
575 summon->UnSummon();
576 }
577 }
578
580 {
581 if (summons.empty())
582 return;
583
584 std::list<Creature*> temp;
585 for (SummonList::iterator itr = summons.begin(); itr != summons.end(); ++itr)
586 if (Creature* cre = ObjectAccessor::GetCreature(*me, *itr))
587 if (cre->IsAlive() && (cre->GetEntry() == NPC_CULT_FANATIC || cre->GetEntry() == NPC_CULT_ADHERENT))
588 temp.push_back(cre);
589
590 // noone to empower
591 if (temp.empty())
592 return;
593
594 // select random cultist
598 }
599
600 private:
603 std::deque<uint64> _reanimationQueue;
607 };
608
610 {
612 }
613};
614
616
618{
619 public:
620 npc_cult_fanatic() : CreatureScript("npc_cult_fanatic") { }
621
623 {
624 npc_cult_fanaticAI(Creature* creature) : ScriptedAI(creature) { }
625
627 {
628 Events.Reset();
629 Events.ScheduleEvent(EVENT_FANATIC_NECROTIC_STRIKE, std::rand() % 12000 + 10000);
630 Events.ScheduleEvent(EVENT_FANATIC_SHADOW_CLEAVE, std::rand() % 16000 + 14000);
631 Events.ScheduleEvent(EVENT_FANATIC_VAMPIRIC_MIGHT, std::rand() % 27000 + 20000);
632 if (me->GetEntry() == NPC_CULT_FANATIC)
633 Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, std::rand() % 32000 + 18000);
634 }
635
636 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
637 {
638 if (spell->Id == SPELL_DARK_TRANSFORMATION)
639 me->UpdateEntry(NPC_DEFORMED_FANATIC);
640 else if (spell->Id == SPELL_DARK_TRANSFORMATION_T)
641 {
643 me->InterruptNonMeleeSpells(true);
645 }
646 }
647
649 {
650 if (!UpdateVictim())
651 return;
652
653 Events.Update(diff);
654
655 if (me->HasUnitState(UNIT_STATE_CASTING))
656 return;
657
658 while (uint32 eventId = Events.ExecuteEvent())
659 {
660 switch (eventId)
661 {
664 Events.ScheduleEvent(EVENT_FANATIC_NECROTIC_STRIKE, std::rand() % 13000 + 11000);
665 break;
668 Events.ScheduleEvent(EVENT_FANATIC_SHADOW_CLEAVE, std::rand() % 11000 + 9500);
669 break;
672 Events.ScheduleEvent(EVENT_FANATIC_VAMPIRIC_MIGHT, std::rand() % 27000 + 20000);
673 break;
676 Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, std::rand() % 21000 + 16000);
677 break;
678 }
679 }
680
682 }
683
684 protected:
686 };
687
689 {
691 }
692};
693
695{
696 public:
697 npc_cult_adherent() : CreatureScript("npc_cult_adherent") { }
698
700 {
701 npc_cult_adherentAI(Creature* creature) : ScriptedAI(creature) { }
702
704 {
705 Events.Reset();
706 Events.ScheduleEvent(EVENT_ADHERENT_FROST_FEVER, std::rand() % 12000 + 10000);
707 Events.ScheduleEvent(EVENT_ADHERENT_DEATHCHILL, std::rand() % 16000 + 14000);
708 Events.ScheduleEvent(EVENT_ADHERENT_CURSE_OF_TORPOR, std::rand() % 16000 + 14000);
709 Events.ScheduleEvent(EVENT_ADHERENT_SHORUD_OF_THE_OCCULT, std::rand() % 39000 + 32000);
710 if (me->GetEntry() == NPC_CULT_ADHERENT)
711 Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, std::rand() % 32000 + 18000);
712 }
713
714 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
715 {
716 if (spell->Id == SPELL_DARK_EMPOWERMENT)
717 me->UpdateEntry(NPC_EMPOWERED_ADHERENT);
718 else if (spell->Id == SPELL_DARK_EMPOWERMENT_T)
719 {
721 me->InterruptNonMeleeSpells(true);
723 }
724 }
725
727 {
728 if (!UpdateVictim())
729 return;
730
731 Events.Update(diff);
732
733 if (me->HasUnitState(UNIT_STATE_CASTING))
734 return;
735
736 while (uint32 eventId = Events.ExecuteEvent())
737 {
738 switch (eventId)
739 {
742 Events.ScheduleEvent(EVENT_ADHERENT_FROST_FEVER, std::rand() % 13000 + 9000);
743 break;
745 if (me->GetEntry() == NPC_EMPOWERED_ADHERENT)
747 else
749 Events.ScheduleEvent(EVENT_ADHERENT_DEATHCHILL, std::rand() % 13000 + 9000);
750 break;
752 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
754 Events.ScheduleEvent(EVENT_ADHERENT_CURSE_OF_TORPOR, std::rand() % 13000 + 9000);
755 break;
758 Events.ScheduleEvent(EVENT_ADHERENT_SHORUD_OF_THE_OCCULT, std::rand() % 32000 + 27000);
759 break;
762 Events.ScheduleEvent(EVENT_CULTIST_DARK_MARTYRDOM, std::rand() % 21000 + 16000);
763 break;
764 }
765 }
766
768 }
769
770 protected:
772 };
773
775 {
777 }
778};
779
781{
782 public:
783 npc_vengeful_shade() : CreatureScript("npc_vengeful_shade") { }
784
786 {
792
794 {
796 }
797
798 void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) OVERRIDE
799 {
800 switch (spell->Id)
801 {
806 me->Kill(me);
807 break;
808 default:
809 break;
810 }
811 }
812 };
813
815 {
817 }
818};
819
821{
822 public:
823 npc_darnavan() : CreatureScript("npc_darnavan") { }
824
826 {
827 npc_darnavanAI(Creature* creature) : ScriptedAI(creature)
828 {
829 }
830
832 {
833 _events.Reset();
834 _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, 10000);
835 _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, std::rand() % 25000 + 20000);
836 _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, std::rand() % 30000 + 25000);
837 _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, std::rand() % 8000 + 5000);
838 _canCharge = true;
839 _canShatter = true;
840 }
841
842 void JustDied(Unit* killer) OVERRIDE
843 {
844 _events.Reset();
845 if (Player* owner = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
846 {
847 if (Group* group = owner->GetGroup())
848 {
849 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
850 if (Player* member = itr->GetSource())
851 member->FailQuest(QUEST_DEPROGRAMMING);
852 }
853 else
854 owner->FailQuest(QUEST_DEPROGRAMMING);
855 }
856 }
857
859 {
860 if (type != POINT_MOTION_TYPE || id != POINT_DESPAWN)
861 return;
862
863 me->DespawnOrUnsummon();
864 }
865
866 void EnterCombat(Unit* /*victim*/) OVERRIDE
867 {
869 }
870
872 {
873 if (!UpdateVictim())
874 return;
875
876 _events.Update(diff);
877
878 if (me->HasUnitState(UNIT_STATE_CASTING))
879 return;
880
881 if (_canShatter && me->GetVictim() && me->GetVictim()->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL))
882 {
884 _canShatter = false;
885 _events.ScheduleEvent(EVENT_DARNAVAN_SHATTERING_THROW, 30000);
886 return;
887 }
888
889 if (_canCharge && !me->IsWithinMeleeRange(me->GetVictim()))
890 {
892 _canCharge = false;
893 _events.ScheduleEvent(EVENT_DARNAVAN_CHARGE, 20000);
894 return;
895 }
896
897 while (uint32 eventId = _events.ExecuteEvent())
898 {
899 switch (eventId)
900 {
903 _events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, std::rand() % 100000 + 90000);
904 break;
906 _canCharge = true;
907 break;
910 _events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, std::rand() % 120000 + 90000);
911 break;
914 _events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, std::rand() % 30000 + 15000);
915 break;
917 _canShatter = true;
918 break;
921 _events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, std::rand() % 7000 + 3000);
922 break;
923 }
924 }
925
927 }
928
929 private:
933 };
934
936 {
938 }
939};
940
942{
943 public:
944 spell_deathwhisper_mana_barrier() : SpellScriptLoader("spell_deathwhisper_mana_barrier") { }
945
947 {
949
950 void HandlePeriodicTick(AuraEffect const* /*aurEff*/)
951 {
953 if (Unit* caster = GetCaster())
954 {
955 int32 missingHealth = int32(caster->GetMaxHealth() - caster->GetHealth());
956 caster->ModifyHealth(missingHealth);
957 caster->ModifyPower(POWER_MANA, -missingHealth);
958 }
959 }
960
965 };
966
971};
972
974{
975 public:
976 spell_cultist_dark_martyrdom() : SpellScriptLoader("spell_cultist_dark_martyrdom") { }
977
979 {
981
982 void HandleEffect(SpellEffIndex /*effIndex*/)
983 {
984 if (GetCaster()->IsSummon())
985 if (Unit* owner = GetCaster()->ToTempSummon()->GetSummoner())
986 owner->GetAI()->SetGUID(GetCaster()->GetGUID(), GUID_CULTIST);
987
989 GetCaster()->SetDisplayId(uint32(GetCaster()->GetEntry() == NPC_CULT_FANATIC ? 38009 : 38010));
990 }
991
996 };
997
1002};
1003
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:193
@ DIFFICULTY_10MAN_NORMAL
Definition DBCEnums.h:334
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
@ IN_PROGRESS
@ FAIL
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Definition Object.h:73
#define sPoolMgr
Definition PoolMgr.h:154
SpellEffIndex
@ EFFECT_0
@ EFFECT_2
@ POWER_MANA
@ SPELL_EFFECT_ATTACK_ME
@ SPELL_EFFECT_FORCE_DESELECT
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ SPELL_SCHOOL_MASK_NORMAL
@ SPELL_AURA_MOD_TAUNT
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
#define SpellEffectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_PASSIVE
Definition Unit.h:1156
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ SPELL_CHARGE
@ SAY_BERSERK
@ PHASE_INTRO
@ SPELL_FROSTBOLT
#define SAY_DEATH
#define SAY_AGGRO
#define SAY_KILL
@ SPELL_SHATTERING_THROW
@ SPELL_INTIMIDATING_SHOUT
#define SPELL_BERSERK
@ SPELL_MORTAL_STRIKE
@ SPELL_SHADOW_BOLT
@ SPELL_BLADESTORM
@ PHASE_ONE
@ PHASE_TWO
@ SPELL_SHADOW_CHANNELING
#define NPC_DARNAVAN_CREDIT
@ ACTION_COMPLETE_QUEST
@ NPC_DARNAVAN_CREDIT_25
@ NPC_DARNAVAN_CREDIT_10
void AddSC_boss_lady_deathwhisper()
@ SPELL_DARK_MARTYRDOM_ADHERENT
@ SPELL_DARK_TRANSFORMATION_T
@ SPELL_CURSE_OF_TORPOR
@ SPELL_DARK_EMPOWERMENT
@ SPELL_DEATHCHILL_BLAST
@ SPELL_VENGEFUL_BLAST_10H
@ SPELL_FANATIC_S_DETERMINATION
@ SPELL_DARK_TRANSFORMATION
@ SPELL_SHATTERING_THROW
@ SPELL_VENGEFUL_BLAST_PASSIVE
@ SPELL_SHORUD_OF_THE_OCCULT
@ SPELL_DARK_EMPOWERMENT_T
@ SPELL_TOUCH_OF_INSIGNIFICANCE
@ SPELL_DARK_MARTYRDOM_FANATIC
@ SPELL_VENGEFUL_BLAST_25N
@ SPELL_DEATH_AND_DECAY
@ SPELL_TELEPORT_VISUAL
@ SPELL_MORTAL_STRIKE
@ SPELL_DARK_MARTYRDOM_T
@ SPELL_DEATHCHILL_BOLT
@ SPELL_ADHERENT_S_DETERMINATION
@ SPELL_NECROTIC_STRIKE
@ SPELL_FROSTBOLT_VOLLEY
@ SPELL_VENGEFUL_BLAST_25H
@ SPELL_VAMPIRIC_MIGHT
@ SPELL_SHADOW_CLEAVE
@ SPELL_INTIMIDATING_SHOUT
@ SPELL_SHADOW_CHANNELING
@ SPELL_DOMINATE_MIND_H
@ SPELL_VENGEFUL_BLAST
boss_lady_deathwhisper::boss_lady_deathwhisperAI DeathwisperAI
@ EVENT_P2_FROSTBOLT_VOLLEY
@ EVENT_DARNAVAN_INTIMIDATING_SHOUT
@ EVENT_DARNAVAN_SHATTERING_THROW
@ EVENT_ADHERENT_SHORUD_OF_THE_OCCULT
@ EVENT_P2_SUMMON_SHADE
@ EVENT_P2_TOUCH_OF_INSIGNIFICANCE
@ EVENT_CULTIST_DARK_MARTYRDOM
@ EVENT_ADHERENT_FROST_FEVER
@ EVENT_ADHERENT_DEATHCHILL
@ EVENT_P1_REANIMATE_CULTIST
@ EVENT_ADHERENT_CURSE_OF_TORPOR
@ EVENT_DARNAVAN_MORTAL_STRIKE
@ EVENT_DARNAVAN_SUNDER_ARMOR
@ EVENT_DARNAVAN_CHARGE
@ EVENT_DOMINATE_MIND_H
@ EVENT_FANATIC_NECROTIC_STRIKE
@ EVENT_P1_EMPOWER_CULTIST
@ EVENT_FANATIC_SHADOW_CLEAVE
@ EVENT_DARNAVAN_BLADESTORM
@ EVENT_FANATIC_VAMPIRIC_MIGHT
@ EVENT_DEATH_AND_DECAY
#define GUID_CULTIST
#define NPC_DARNAVAN
uint32 const SummonEntries[2]
@ SAY_DARNAVAN_RESCUED
@ SAY_DARK_TRANSFORMATION
@ SAY_DARK_EMPOWERMENT
Position const SummonPositions[7]
#define QUEST_DEPROGRAMMING
@ EVENT_BERSERK
@ SPELL_DEATH_AND_DECAY
@ EVENT_INTRO_4
@ EVENT_INTRO_2
@ EVENT_INTRO_5
@ EVENT_INTRO_3
@ SPELL_TELEPORT_VISUAL
Definition chapter5.cpp:145
void PreventDefaultAction()
HookList< EffectPeriodicHandler > OnEffectPeriodic
Unit * GetCaster() const
InstanceScript *const instance
void _JustReachedHome()
bool CheckInRoom()
SummonList summons
EventMap events
BossAI(Creature *creature, uint32 bossId)
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureScript(const char *name)
bool Execute(uint64, uint32)
DaranavanMoveEvent(Creature &darnavan)
Definition Group.h:147
GroupReference * next()
static Creature * GetCreature(WorldObject const &u, uint64 guid)
static Unit * GetUnit(WorldObject const &, uint64 guid)
uint32 GetEntry() const
Definition Object.h:125
HookList< EffectHandler > OnEffectHitTarget
Unit * GetCaster()
SpellScriptLoader(const char *name)
StorageType::iterator iterator
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
void Kill(Unit *victim, bool durabilityLoss=true)
Definition Unit.cpp:6342
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:2355
TempSummon * ToTempSummon()
Definition Unit.h:2821
virtual void SetDisplayId(uint32 modelId)
Definition Unit.cpp:5941
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
PrepareSpellScript(spell_cultist_dark_martyrdom_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
@ EVENT_INTRO_6
@ EVENT_INTRO_7
@ NPC_CULT_ADHERENT
@ NPC_EMPOWERED_ADHERENT
@ NPC_DEFORMED_FANATIC
@ NPC_REANIMATED_ADHERENT
@ NPC_CULT_FANATIC
@ NPC_REANIMATED_FANATIC
@ NPC_VENGEFUL_SHADE
CreatureAI * GetIcecrownCitadelAI(Creature *creature)
@ LIGHT_S_HAMMER_TELEPORT
@ DATA_LADY_DEATHWHISPER
Position const SummonPositions[10]
C::value_type const & SelectRandomContainerElement(C const &container)
Definition Containers.h:48
void GetPosition(float &x, float &y) const
Definition Object.h:333
bool IsHeroic() const
void DoStartNoMovement(Unit *target)
DifficultyID GetDifficulty() const
Creature * me
const T & RAID_MODE(const T &normal10, const T &normal25) const
ScriptedAI(Creature *creature)
bool Is25ManRaid() const
void DoStartMovement(Unit *target, float distance=0.0f, float angle=0.0f)
void SpellHitTarget(Unit *target, SpellInfo const *spell) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void MovementInform(uint32 type, uint32 id) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JustDied(Unit *killer) OVERRIDE
void SpellHitTarget(Unit *, SpellInfo const *spell) OVERRIDE