Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_valithria_dreamwalker.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 "SpellAuraEffects.h"
10#include "Cell.h"
11#include "CellImpl.h"
12#include "GridNotifiers.h"
13#include "GridNotifiersImpl.h"
14#include "icecrown_citadel.h"
15
31
33{
34 // Valithria Dreamwalker
50
51 // The Lich King
60
61 // Risen Archmage
67
68 // Blazing Skeleton
71
72 // Suppresser
74
75 // Blistering Zombie
77
78 // Gluttonous Abomination
81
82 // Dream Cloud
84
85 // Nightmare Cloud
87};
88
89#define SUMMON_PORTAL RAID_MODE<uint32>(SPELL_PRE_SUMMON_DREAM_PORTAL, SPELL_PRE_SUMMON_DREAM_PORTAL, \
90 SPELL_PRE_SUMMON_NIGHTMARE_PORTAL, SPELL_PRE_SUMMON_NIGHTMARE_PORTAL)
91
92#define EMERALD_VIGOR RAID_MODE<uint32>(SPELL_EMERALD_VIGOR, SPELL_EMERALD_VIGOR, \
93 SPELL_TWISTED_NIGHTMARE, SPELL_TWISTED_NIGHTMARE)
94
96{
97 // Valithria Dreamwalker
102
103 // The Lich King
109
110 // Risen Archmage
114
115 // Blazing Skeleton
118
119 // Suppresser
121
122 // Gluttonous Abomination
124
125 // Dream Cloud
126 // Nightmare Cloud
129};
130
137
138Position const ValithriaSpawnPos = {4210.813f, 2484.443f, 364.9558f, 0.01745329f};
139
141{
142 public:
143 // look for all permanently spawned Risen Archmages that are not yet in combat
144 bool operator()(Creature* creature)
145 {
146 return creature->IsAlive() && creature->GetEntry() == NPC_RISEN_ARCHMAGE &&
147 creature->GetDBTableGUIDLow() && !creature->IsInCombat();
148 }
149};
150
151struct ManaVoidSelector : public SF_UNARY_FUNCTION<Unit*, bool>
152{
153 explicit ManaVoidSelector(WorldObject const* source) : _source(source) { }
154
155 bool operator()(Unit* unit) const
156 {
157 return unit->getPowerType() == POWER_MANA && _source->GetDistance(unit) > 15.0f;
158 }
159
161};
162
164{
165 public:
166 DelayedCastEvent(Creature* trigger, uint32 spellId, uint64 originalCaster, uint32 despawnTime) : _trigger(trigger), _originalCaster(originalCaster), _spellId(spellId), _despawnTime(despawnTime)
167 {
168 }
169
170 bool Execute(uint64 /*time*/, uint32 /*diff*/)
171 {
172 _trigger->CastSpell(_trigger, _spellId, false, NULL, NULL, _originalCaster);
173 if (_despawnTime)
174 _trigger->DespawnOrUnsummon(_despawnTime);
175 return true;
176 }
177
178 private:
183};
184
186{
187 public:
188 AuraRemoveEvent(Creature* trigger, uint32 spellId) : _trigger(trigger), _spellId(spellId)
189 {
190 }
191
192 bool Execute(uint64 /*time*/, uint32 /*diff*/)
193 {
194 _trigger->RemoveAurasDueToSpell(_spellId);
195 return true;
196 }
197
198 private:
201};
202
204{
205 public:
206 explicit ValithriaDespawner(Creature* creature) : _creature(creature)
207 {
208 }
209
210 bool Execute(uint64 /*currTime*/, uint32 /*diff*/)
211 {
213 _creature->VisitNearbyGridObject(333.0f, worker);
214 return true;
215 }
216
217 void operator()(Creature* creature) const
218 {
219 switch (creature->GetEntry())
220 {
222 if (InstanceScript* instance = creature->GetInstanceScript())
223 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature);
224 break;
226 case NPC_SUPPRESSER:
229 case NPC_MANA_VOID:
231 case NPC_ROT_WORM:
232 creature->DespawnOrUnsummon();
233 return;
235 if (!creature->GetDBTableGUIDLow())
236 {
237 creature->DespawnOrUnsummon();
238 return;
239 }
240 creature->Respawn(true);
241 break;
242 default:
243 return;
244 }
245
246 uint32 corpseDelay = creature->GetCorpseDelay();
247 uint32 respawnDelay = creature->GetRespawnDelay();
248 creature->SetCorpseDelay(1);
249 creature->SetRespawnDelay(10);
250
251 if (CreatureData const* data = creature->GetCreatureData())
252 creature->SetPosition(data->posX, data->posY, data->posZ, data->orientation);
253 creature->DespawnOrUnsummon();
254
255 creature->SetCorpseDelay(corpseDelay);
256 creature->SetRespawnDelay(respawnDelay);
257 }
258
259 private:
261};
262
264{
265 public:
266 boss_valithria_dreamwalker() : CreatureScript("boss_valithria_dreamwalker") { }
267
269 {
271 _instance(creature->GetInstanceScript()), _portalCount(RAID_MODE<uint32>(3, 8, 3, 8))
272 {
273 }
274
276 {
277 if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow()))
278 if (data->curhealth)
279 _spawnHealth = data->curhealth;
280
281 if (!me->isDead())
282 Reset();
283 }
284
286 {
287 me->SetHealth(_spawnHealth);
288 me->SetReactState(REACT_PASSIVE);
289 me->LoadCreaturesAddon(true);
290 // immune to percent heals
291 me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_OBS_MOD_HEALTH, true);
292 me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
293 // Glyph of Dispel Magic - not a percent heal by effect, its cast with custom basepoints
294 me->ApplySpellImmune(0, IMMUNITY_ID, 56131, true);
295 _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
296 _missedPortals = 0;
299 _justDied = false;
300 _done = false;
301 }
302
303 void AttackStart(Unit* /*target*/) OVERRIDE
304 {
305 }
306
308 {
309 if (action != ACTION_ENTER_COMBAT)
310 return;
311
313 _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
314 _events.ScheduleEvent(EVENT_INTRO_TALK, 15000);
315 _events.ScheduleEvent(EVENT_DREAM_PORTAL, std::rand() % 48000 + 45000);
316 if (IsHeroic())
317 _events.ScheduleEvent(EVENT_BERSERK, 420000);
318 }
319
320 void HealReceived(Unit* healer, uint32& heal) OVERRIDE
321 {
322 if (!me->hasLootRecipient())
323 me->SetLootRecipient(healer);
324
325 me->LowerPlayerDamageReq(heal);
326
327 // encounter complete
328 if (me->HealthAbovePctHealed(100, heal) && !_done)
329 {
330 _done = true;
332 _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
333 me->RemoveAurasDueToSpell(SPELL_CORRUPTION_VALITHRIA);
336 _events.ScheduleEvent(EVENT_DREAM_SLIP, 3500);
338 lichKing->AI()->EnterEvadeMode();
339 }
340 else if (!_over75PercentTalkDone && me->HealthAbovePctHealed(75, heal))
341 {
344 }
345 else if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == NOT_STARTED)
346 if (Creature* archmage = me->FindNearestCreature(NPC_RISEN_ARCHMAGE, 30.0f))
347 archmage->AI()->DoZoneInCombat(); // call EnterCombat on one of them, that will make it all start
348 }
349
350 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
351 {
352 if (me->HealthBelowPctDamaged(25, damage))
353 {
355 {
358 }
359
360 if (damage > me->GetHealth())
361 {
362 damage = 0;
363 if (!_justDied)
364 {
365 _justDied = true;
367 _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
369 trigger->AI()->DoAction(ACTION_DEATH);
370 }
371 }
372 }
373 }
374
375 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
376 {
377 if (spell->Id == SPELL_DREAM_SLIP)
378 {
381 // this display id was found in sniff instead of the one on aura
382 me->SetDisplayId(11686);
384 me->DespawnOrUnsummon(4000);
386 lichKing->CastSpell(lichKing, SPELL_SPAWN_CHEST, false);
387
389 me->Kill(trigger);
390 }
391 }
392
394 {
395 if (summon->GetEntry() == NPC_DREAM_PORTAL_PRE_EFFECT)
396 {
397 summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_DREAM_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000));
398 summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_DREAM_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000));
399 }
400 else if (summon->GetEntry() == NPC_NIGHTMARE_PORTAL_PRE_EFFECT)
401 {
402 summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_NIGHTMARE_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000));
403 summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_NIGHTMARE_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000));
404 }
405 }
406
408 {
409 if (summon->GetEntry() == NPC_DREAM_PORTAL || summon->GetEntry() == NPC_NIGHTMARE_PORTAL)
410 if (summon->AI()->GetData(MISSED_PORTALS))
412 }
413
415 {
416 // does not enter combat
418 return;
419
420 _events.Update(diff);
421
422 if (me->HasUnitState(UNIT_STATE_CASTING))
423 return;
424
425 while (uint32 eventId = _events.ExecuteEvent())
426 {
427 switch (eventId)
428 {
429 case EVENT_INTRO_TALK:
431 break;
432 case EVENT_BERSERK:
434 break;
436 if (!IsHeroic())
438 for (uint32 i = 0; i < _portalCount; ++i)
440 _events.ScheduleEvent(EVENT_DREAM_PORTAL, std::rand() % 48000 + 45000);
441 break;
442 case EVENT_DREAM_SLIP:
444 break;
445 default:
446 break;
447 }
448 }
449 }
450
452 {
453 if (type == MISSED_PORTALS)
454 return _missedPortals;
455
456 return 0;
457 }
458
459 private:
468 bool _done;
469 };
470
472 {
474 }
475};
476
478{
479 public:
480 npc_green_dragon_combat_trigger() : CreatureScript("npc_green_dragon_combat_trigger") { }
481
483 {
487
489 {
490 _Reset();
491 me->SetReactState(REACT_PASSIVE);
492 }
493
495 {
496 if (!instance->CheckRequiredBosses(DATA_VALITHRIA_DREAMWALKER, target->ToPlayer()))
497 {
499 instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
500 return;
501 }
502
503 me->setActive(true);
507 valithria->AI()->DoAction(ACTION_ENTER_COMBAT);
508 }
509
511 {
512 if (target->GetTypeId() == TypeID::TYPEID_PLAYER)
513 BossAI::AttackStart(target);
514 }
515
516 bool CanAIAttack(Unit const* target) const OVERRIDE
517 {
518 return target->GetTypeId() == TypeID::TYPEID_PLAYER;
519 }
520
526
528 {
529 if (action == ACTION_DEATH)
530 {
532 me->m_Events.AddEvent(new ValithriaDespawner(me), me->m_Events.CalculateTime(5000));
533 }
534 }
535
536 void UpdateAI(uint32 /*diff*/) OVERRIDE
537 {
538 if (!me->IsInCombat())
539 return;
540
541 std::list<HostileReference*> const& threatList = me->getThreatManager().getThreatList();
542 if (threatList.empty())
543 {
545 return;
546 }
547
548 // check evade every second tick
549 _evadeCheck ^= true;
550 if (!_evadeCheck)
551 return;
552
553 // check if there is any player on threatlist, if not - evade
554 for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
555 if (Unit* target = (*itr)->getTarget())
556 if (target->GetTypeId() == TypeID::TYPEID_PLAYER)
557 return; // found any player, return
558
560 }
561
562 private:
564 };
565
570};
571
573{
574 public:
575 npc_the_lich_king_controller() : CreatureScript("npc_the_lich_king_controller") { }
576
578 {
580 _instance(creature->GetInstanceScript())
581 {
582 }
583
585 {
586 _events.Reset();
588 _events.ScheduleEvent(EVENT_SUPPRESSER_SUMMONER, 10000);
589 _events.ScheduleEvent(EVENT_BLISTERING_ZOMBIE_SUMMONER, 15000);
590 _events.ScheduleEvent(EVENT_RISEN_ARCHMAGE_SUMMONER, 20000);
591 _events.ScheduleEvent(EVENT_BLAZING_SKELETON_SUMMONER, 30000);
592 me->SetReactState(REACT_PASSIVE);
593 }
594
596 {
597 me->setActive(false);
598 }
599
600 void EnterCombat(Unit* /*target*/) OVERRIDE
601 {
603 me->setActive(true);
604 }
605
607 {
608 // must not be in dream phase
609 summon->SetPhaseMask((summon->GetPhaseMask() & ~0x10), true);
610 if (summon->GetEntry() != NPC_SUPPRESSER)
611 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
612 summon->AI()->AttackStart(target);
613 }
614
616 {
617 if (!UpdateVictim())
618 return;
619
620 _events.Update(diff);
621
622 if (me->HasUnitState(UNIT_STATE_CASTING))
623 return;
624
625 while (uint32 eventId = _events.ExecuteEvent())
626 {
627 switch (eventId)
628 {
631 break;
634 break;
637 break;
640 break;
643 break;
644 default:
645 break;
646 }
647 }
648 }
649
650 private:
653 };
654
656 {
657 return new npc_the_lich_king_controllerAI(creature);
658 }
659};
660
662{
663 public:
664 npc_risen_archmage() : CreatureScript("npc_risen_archmage") { }
665
667 {
669 _instance(creature->GetInstanceScript())
670 {
671 }
672
673 bool CanAIAttack(Unit const* target) const OVERRIDE
674 {
675 return target->GetEntry() != NPC_VALITHRIA_DREAMWALKER;
676 }
677
679 {
680 _events.Reset();
681 _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, std::rand() % 15000 + 5000);
682 _events.ScheduleEvent(EVENT_MANA_VOID, std::rand() % 25000 + 20000);
683 _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, std::rand() % 20000 + 10000);
684 _canCallEnterCombat = true;
685 }
686
687 void EnterCombat(Unit* /*target*/) OVERRIDE
688 {
689 me->FinishSpell(CURRENT_CHANNELED_SPELL, false);
690 if (me->GetDBTableGUIDLow() && _canCallEnterCombat)
691 {
692 std::list<Creature*> archmages;
693 RisenArchmageCheck check;
694 Skyfire::CreatureListSearcher<RisenArchmageCheck> searcher(me, archmages, check);
695 me->VisitNearbyGridObject(100.0f, searcher);
696 for (std::list<Creature*>::iterator itr = archmages.begin(); itr != archmages.end(); ++itr)
697 (*itr)->AI()->DoAction(ACTION_ENTER_COMBAT);
698
700 lichKing->AI()->DoZoneInCombat();
701
703 trigger->AI()->DoZoneInCombat();
704 }
705 }
706
708 {
709 if (action != ACTION_ENTER_COMBAT)
710 return;
711
712 _canCallEnterCombat = false;
714 _canCallEnterCombat = true;
715 }
716
718 {
719 if (summon->GetEntry() == NPC_COLUMN_OF_FROST)
720 summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_COLUMN_OF_FROST_DAMAGE, 0, 8000), summon->m_Events.CalculateTime(2000));
721 else if (summon->GetEntry() == NPC_MANA_VOID)
722 summon->DespawnOrUnsummon(36000);
723 }
724
726 {
727 if (!me->IsInCombat())
728 if (me->GetDBTableGUIDLow())
729 if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
731
732 if (!UpdateVictim())
733 return;
734
735 _events.Update(diff);
736
737 if (me->HasUnitState(UNIT_STATE_CASTING))
738 return;
739
740 while (uint32 eventId = _events.ExecuteEvent())
741 {
742 switch (eventId)
743 {
746 _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, std::rand() % 15000 + 8000);
747 break;
748 case EVENT_MANA_VOID:
750 DoCast(target, SPELL_MANA_VOID);
751 _events.ScheduleEvent(EVENT_MANA_VOID, std::rand() % 25000 + 20000);
752 break;
754 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -10.0f, true))
756 _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, std::rand() % 25000 + 15000);
757 break;
758 default:
759 break;
760 }
761 }
762
764 }
765
766 private:
770 };
771
773 {
775 }
776};
777
779{
780 public:
781 npc_blazing_skeleton() : CreatureScript("npc_blazing_skeleton") { }
782
784 {
786 {
787 }
788
790 {
791 _events.Reset();
792 _events.ScheduleEvent(EVENT_FIREBALL, std::rand() % 4000 + 2000);
793 _events.ScheduleEvent(EVENT_LEY_WASTE, std::rand() % 20000 + 15000);
794 }
795
797 {
798 if (!UpdateVictim())
799 return;
800
801 _events.Update(diff);
802
803 if (me->HasUnitState(UNIT_STATE_CASTING))
804 return;
805
806 while (uint32 eventId = _events.ExecuteEvent())
807 {
808 switch (eventId)
809 {
810 case EVENT_FIREBALL:
811 if (!me->IsWithinMeleeRange(me->GetVictim()))
813 _events.ScheduleEvent(EVENT_FIREBALL, std::rand() % 4000 + 2000);
814 break;
815 case EVENT_LEY_WASTE:
817 _events.ScheduleEvent(EVENT_LEY_WASTE, std::rand() % 20000 + 15000);
818 break;
819 default:
820 break;
821 }
822 }
823
825 }
826
827 private:
829 };
830
832 {
834 }
835};
836
838{
839 public:
840 npc_suppresser() : CreatureScript("npc_suppresser") { }
841
843 {
844 npc_suppresserAI(Creature* creature) : ScriptedAI(creature),
845 _instance(creature->GetInstanceScript())
846 {
847 }
848
850 {
851 _events.Reset();
852 _events.ScheduleEvent(EVENT_SUPPRESSION, std::rand() % 15000 + 10000);
853 me->SetReactState(REACT_PASSIVE);
854 }
855
856 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
857 {
859 AttackStart(valithria);
860 }
861
863 {
864 if (!UpdateVictim())
865 return;
866
867 _events.Update(diff);
868
869 if (me->HasUnitState(UNIT_STATE_CASTING))
870 return;
871
872 // this code will never be reached while channeling
873 while (uint32 eventId = _events.ExecuteEvent())
874 {
875 switch (eventId)
876 {
879 _events.ScheduleEvent(EVENT_SUPPRESSION, 5000);
880 break;
881 default:
882 break;
883 }
884 }
885
886 // this creature has REACT_PASSIVE so it does not always have victim here
887 if (Unit* victim = me->GetVictim())
888 if (victim->GetEntry() != NPC_VALITHRIA_DREAMWALKER)
890 }
891
892 private:
895 };
896
898 {
900 }
901};
902
904{
905 public:
906 npc_blistering_zombie() : CreatureScript("npc_blistering_zombie") { }
907
909 {
911 {
912 }
913
914 void JustDied(Unit* /*killer*/) OVERRIDE
915 {
916 DoCast(me, SPELL_ACID_BURST, true);
917 }
918
919 void UpdateAI(uint32 /*diff*/) OVERRIDE
920 {
921 if (!UpdateVictim())
922 return;
923
925 }
926 };
927
929 {
931 }
932};
933
935{
936 public:
937 npc_gluttonous_abomination() : CreatureScript("npc_gluttonous_abomination") { }
938
940 {
942 {
943 }
944
946 {
947 _events.Reset();
948 _events.ScheduleEvent(EVENT_GUT_SPRAY, std::rand() % 13000 + 10000);
949 }
950
951 void JustDied(Unit* /*killer*/) OVERRIDE
952 {
954 }
955
957 {
958 if (!UpdateVictim())
959 return;
960
961 _events.Update(diff);
962
963 if (me->HasUnitState(UNIT_STATE_CASTING))
964 return;
965
966 while (uint32 eventId = _events.ExecuteEvent())
967 {
968 switch (eventId)
969 {
970 case EVENT_GUT_SPRAY:
972 _events.ScheduleEvent(EVENT_GUT_SPRAY, std::rand() % 13000 + 10000);
973 break;
974 default:
975 break;
976 }
977 }
978
980 }
981
982 private:
984 };
985
987 {
989 }
990};
991
993{
994 public:
995 npc_dream_portal() : CreatureScript("npc_dream_portal") { }
996
998 {
999 npc_dream_portalAI(Creature* creature) : CreatureAI(creature),
1000 _used(false)
1001 {
1002 }
1003
1004 void OnSpellClick(Unit* /*clicker*/, bool& result) OVERRIDE
1005 {
1006 if (!result)
1007 return;
1008
1009 _used = true;
1010 me->DespawnOrUnsummon();
1011 }
1012
1014 {
1015 return (type == MISSED_PORTALS && _used) ? 0 : 1;
1016 }
1017
1018 void UpdateAI(uint32 /*diff*/) OVERRIDE
1019 {
1020 UpdateVictim();
1021 }
1022
1023 private:
1024 bool _used;
1025 };
1026
1028 {
1030 }
1031};
1032
1034{
1035 public:
1036 npc_dream_cloud() : CreatureScript("npc_dream_cloud") { }
1037
1039 {
1040 npc_dream_cloudAI(Creature* creature) : ScriptedAI(creature),
1041 _instance(creature->GetInstanceScript())
1042 {
1043 }
1044
1046 {
1047 _events.Reset();
1048 _events.ScheduleEvent(EVENT_CHECK_PLAYER, 1000);
1049 me->SetCorpseDelay(0); // remove corpse immediately
1050 me->LoadCreaturesAddon(true);
1051 }
1052
1054 {
1055 // trigger
1056 if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) != IN_PROGRESS)
1057 return;
1058
1059 _events.Update(diff);
1060
1061 while (uint32 eventId = _events.ExecuteEvent())
1062 {
1063 switch (eventId)
1064 {
1065 case EVENT_CHECK_PLAYER:
1066 {
1067 Player* player = NULL;
1070 me->VisitNearbyWorldObject(7.5f, searcher);
1071 _events.ScheduleEvent(player ? EVENT_EXPLODE : EVENT_CHECK_PLAYER, 1000);
1072 break;
1073 }
1074 case EVENT_EXPLODE:
1075 me->GetMotionMaster()->MoveIdle();
1076 // must use originalCaster the same for all clouds to allow stacking
1077 me->CastSpell(me, EMERALD_VIGOR, false, NULL, NULL, _instance->GetData64(DATA_VALITHRIA_DREAMWALKER));
1078 me->DespawnOrUnsummon(100);
1079 break;
1080 default:
1081 break;
1082 }
1083 }
1084 }
1085
1086 private:
1089 };
1090
1092 {
1094 }
1095};
1096
1098{
1099 public:
1100 spell_dreamwalker_mana_void() : SpellScriptLoader("spell_dreamwalker_mana_void") { }
1101
1103 {
1105
1106 void PeriodicTick(AuraEffect const* aurEff)
1107 {
1108 // first 3 ticks have amplitude 1 second
1109 // remaining tick every 500ms
1110 if (aurEff->GetTickNumber() <= 5)
1111 if (!(aurEff->GetTickNumber() & 1))
1113 }
1114
1119 };
1120
1125};
1126
1164
1166{
1167 public:
1168 spell_dreamwalker_summoner() : SpellScriptLoader("spell_dreamwalker_summoner") { }
1169
1171 {
1173
1175 {
1176 if (!GetCaster()->GetInstanceScript())
1177 return false;
1178 return true;
1179 }
1180
1181 void FilterTargets(std::list<WorldObject*>& targets)
1182 {
1183 targets.remove_if(Skyfire::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
1184 if (targets.empty())
1185 return;
1186
1188 targets.clear();
1189 targets.push_back(target);
1190 }
1191
1193 {
1194 PreventHitDefaultEffect(effIndex);
1195 if (!GetHitUnit())
1196 return;
1197
1198 GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true, NULL, NULL, GetCaster()->GetInstanceScript()->GetData64(DATA_VALITHRIA_LICH_KING));
1199 }
1200
1206 };
1207
1212};
1213
1215{
1216 public:
1217 spell_dreamwalker_summon_suppresser() : SpellScriptLoader("spell_dreamwalker_summon_suppresser") { }
1218
1220 {
1222
1223 void PeriodicTick(AuraEffect const* /*aurEff*/)
1224 {
1226 Unit* caster = GetCaster();
1227 if (!caster)
1228 return;
1229
1230 std::list<Creature*> summoners;
1234 if (summoners.empty())
1235 return;
1236
1237 for (uint32 i = 0; i < 3; ++i)
1238 caster->CastSpell(summoners.front(), SPELL_SUMMON_SUPPRESSER, true);
1239 for (uint32 i = 0; i < 3; ++i)
1240 caster->CastSpell(summoners.back(), SPELL_SUMMON_SUPPRESSER, true);
1241 }
1242
1247 };
1248
1253};
1254
1256{
1257 public:
1258 spell_dreamwalker_summon_suppresser_effect() : SpellScriptLoader("spell_dreamwalker_summon_suppresser_effect") { }
1259
1261 {
1263
1265 {
1266 if (!GetCaster()->GetInstanceScript())
1267 return false;
1268 return true;
1269 }
1270
1272 {
1273 PreventHitDefaultEffect(effIndex);
1274 if (!GetHitUnit())
1275 return;
1276
1277 GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true, NULL, NULL, GetCaster()->GetInstanceScript()->GetData64(DATA_VALITHRIA_LICH_KING));
1278 }
1279
1284 };
1285
1290};
1291
1322
1353
1388
1390{
1391 public:
1392 spell_dreamwalker_twisted_nightmares() : SpellScriptLoader("spell_dreamwalker_twisted_nightmares") { }
1393
1395 {
1397
1399 {
1400 PreventHitDefaultEffect(effIndex);
1401 // impossible with TARGET_UNIT_CASTER
1402 //if (!GetHitUnit())
1403 // return;
1404
1405 if (InstanceScript* instance = GetHitUnit()->GetInstanceScript())
1406 GetHitUnit()->CastSpell((Unit*)NULL, GetSpellInfo()->Effects[effIndex].TriggerSpell, true, NULL, NULL, instance->GetData64(DATA_VALITHRIA_DREAMWALKER));
1407 }
1408
1413 };
1414
1419};
1420
1422{
1423 public:
1424 achievement_portal_jockey() : AchievementCriteriaScript("achievement_portal_jockey") { }
1425
1426 bool OnCheck(Player* /*source*/, Unit* target) OVERRIDE
1427 {
1428 return target && !target->GetAI()->GetData(MISSED_PORTALS);
1429 }
1430};
1431
Actions
const T & RAND(const T &v1, const T &v2)
std::int32_t int32
Definition Define.h:73
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ IN_PROGRESS
@ NOT_STARTED
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
@ TYPEID_PLAYER
Definition Object.h:55
#define sObjectMgr
Definition ObjectMgr.h:1617
void GetCreatureListWithEntryInGrid(std::list< Creature * > &list, WorldObject *source, uint32 entry, float maxSearchRange)
SpellEffIndex
@ EFFECT_0
@ EFFECT_2
@ POWER_MANA
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_FORCE_CAST
@ SPELL_EFFECT_HEAL_PCT
@ TARGET_UNIT_SRC_AREA_ENTRY
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_ID
@ SPELL_AURA_OBS_MOD_HEALTH
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectUpdatePeriodicFn(F, I, N)
#define SF_UNARY_FUNCTION
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:1110
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_PASSIVE
Definition Unit.h:1156
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ SPELL_FIREBALL
@ SPELL_COPY_DAMAGE
@ SPELL_FROSTBOLT_VOLLEY
const SummonerInfo summoners[]
@ EVENT_BERSERK
@ EVENT_FIREBALL
@ SPELL_ACHIEVEMENT_CHECK
#define EMERALD_VIGOR
void AddSC_boss_valithria_dreamwalker()
@ SPELL_SUMMON_NIGHTMARE_PORTAL
@ SPELL_NIGHTMARE_CLOUD_VISUAL
@ SPELL_TIMER_GLUTTONOUS_ABOMINATION
@ SPELL_NIGHTMARE_PORTAL_VISUAL_PRE
@ SPELL_AWARD_REPUTATION_BOSS_KILL
@ SPELL_PRE_SUMMON_DREAM_PORTAL
@ SPELL_TIMER_BLAZING_SKELETON
@ SPELL_TIMER_BLISTERING_ZOMBIE
@ SPELL_PRE_SUMMON_NIGHTMARE_PORTAL
@ SPELL_COLUMN_OF_FROST_DAMAGE
@ SPELL_DREAM_PORTAL_VISUAL_PRE
#define SUMMON_PORTAL
Position const ValithriaSpawnPos
@ EVENT_BLISTERING_ZOMBIE_SUMMONER
@ EVENT_RISEN_ARCHMAGE_SUMMONER
@ EVENT_BLAZING_SKELETON_SUMMONER
@ EVENT_GLUTTONOUS_ABOMINATION_SUMMONER
AchievementCriteriaScript(const char *name)
uint32 GetTickNumber() const
int32 GetPeriodicTimer() const
void SetPeriodicTimer(int32 periodicTimer)
AuraRemoveEvent(Creature *trigger, uint32 spellId)
bool Execute(uint64, uint32)
void PreventDefaultAction()
HookList< EffectPeriodicHandler > OnEffectPeriodic
WorldObject * GetOwner() const
Unit * GetCaster() const
HookList< EffectUpdatePeriodicHandler > OnEffectUpdatePeriodic
uint32 GetId() const
InstanceScript *const instance
void _JustReachedHome()
BossAI(Creature *creature, uint32 bossId)
CreatureAI(Creature *creature)
Definition CreatureAI.h:69
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:56
virtual void EnterEvadeMode()
void Respawn(bool force=false)
uint32 GetDBTableGUIDLow() const
Definition Creature.h:445
void DespawnOrUnsummon(uint32 msTimeToDespawn=0)
void SetRespawnDelay(uint32 delay)
Definition Creature.h:603
void SetPosition(float x, float y, float z, float o)
CreatureData const * GetCreatureData() const
Definition Creature.h:525
uint32 GetRespawnDelay() const
Definition Creature.h:602
void SetCorpseDelay(uint32 delay)
Definition Creature.h:450
uint32 GetCorpseDelay() const
Definition Creature.h:451
CreatureScript(const char *name)
DelayedCastEvent(Creature *trigger, uint32 spellId, uint64 originalCaster, uint32 despawnTime)
static Creature * GetCreature(WorldObject const &u, uint64 guid)
uint32 GetEntry() const
Definition Object.h:125
bool operator()(Creature *creature)
SpellInfo const * GetSpellInfo()
void PreventHitDefaultEffect(SpellEffIndex effIndex)
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
Unit * GetCaster()
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
SpellScriptLoader(const char *name)
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
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:16
Definition Unit.h:1367
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
bool IsAlive() const
Definition Unit.h:2032
Powers getPowerType() const
Definition Unit.h:1651
bool IsInCombat() const
Definition Unit.h:1896
void operator()(Creature *creature) const
ValithriaDespawner(Creature *creature)
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
bool OnCheck(Player *, Unit *target) 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
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
CreatureAI * GetAI(Creature *creature) const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
PrepareSpellScript(spell_dreamwalker_summoner_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
@ NPC_WORLD_TRIGGER
@ ACTION_ENTER_COMBAT
@ NPC_MANA_VOID
@ NPC_RISEN_ARCHMAGE
@ NPC_VALITHRIA_DREAMWALKER
@ NPC_SUPPRESSER
@ NPC_NIGHTMARE_PORTAL_PRE_EFFECT
@ NPC_BLAZING_SKELETON
@ NPC_NIGHTMARE_PORTAL
@ NPC_DREAM_PORTAL
@ NPC_ROT_WORM
@ NPC_GLUTTONOUS_ABOMINATION
@ NPC_COLUMN_OF_FROST
@ NPC_BLISTERING_ZOMBIE
@ NPC_DREAM_PORTAL_PRE_EFFECT
CreatureAI * GetIcecrownCitadelAI(Creature *creature)
@ LIGHT_S_HAMMER_TELEPORT
@ DATA_VALITHRIA_LICH_KING
@ DATA_VALITHRIA_TRIGGER
@ DATA_VALITHRIA_DREAMWALKER
void RandomResizeList(std::list< T > &list, uint32 size)
Definition Containers.h:19
C::value_type const & SelectRandomContainerElement(C const &container)
Definition Containers.h:48
bool operator()(Unit *unit) const
ManaVoidSelector(WorldObject const *source)
bool IsHeroic() const
Creature * me
const T & RAID_MODE(const T &normal10, const T &normal25) const
ScriptedAI(Creature *creature)
void AttackStart(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void OnSpellClick(Unit *, bool &result) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
bool CanAIAttack(Unit const *target) const OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================