Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_blood_prince_council.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 "icecrown_citadel.h"
11#include "Player.h"
12
45
47{
51
52 // Heroic mode
56
57 // Prince Keleseth
62
63 // Dark Nucleus
66
67 // Prince Taldaram
72
73 // Ball of Flame
74 SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891, // cast from creature_template_addon (needed cast before entering world)
77 SPELL_FLAMES = 71393,
79
80 // Ball of Inferno Flame
83
84 // Prince Valanar
90
91 // Kinetic Bomb
96
97 // Shock Vortex
100};
101
124
133
139
141{
143};
144
146{
147 public:
148 StandUpEvent(Creature& owner) : BasicEvent(), _owner(owner) { }
149
150 bool Execute(uint64 /*eventTime*/, uint32 /*diff*/)
151 {
152 _owner.HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
153 return true;
154 }
155
156 private:
158};
159
160Position const introFinalPos = {4660.490f, 2769.200f, 430.0000f, 0.000000f};
161Position const triggerPos = {4680.231f, 2769.134f, 379.9256f, 3.121708f};
162Position const triggerEndPos = {4680.180f, 2769.150f, 365.5000f, 3.121708f};
163
165{
166 public:
167 boss_blood_council_controller() : CreatureScript("boss_blood_council_controller") { }
168
170 {
174
176 {
177 events.Reset();
178 me->SetReactState(REACT_PASSIVE);
180 _resetCounter = 0;
181
183 }
184
186 {
187 if (instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) == IN_PROGRESS)
188 return;
189
190 if (!instance->CheckRequiredBosses(DATA_BLOOD_PRINCE_COUNCIL, who->ToPlayer()))
191 {
193 instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
194 return;
195 }
196
198
200
202 {
203 instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, keleseth);
204 DoZoneInCombat(keleseth);
205 }
206
208 {
209 instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, taldaram);
210 DoZoneInCombat(taldaram);
211 }
212
214 {
215 instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, valanar);
216 DoZoneInCombat(valanar);
217 }
218
219 events.ScheduleEvent(EVENT_INVOCATION_OF_BLOOD, 46500);
220
222 if (std::rand() % 1)
223 {
226 }
227 else
228 {
231 }
232 }
233
234 void SetData(uint32 /*type*/, uint32 data) OVERRIDE
235 {
236 _resetCounter += uint8(data);
237 if (_resetCounter == 3)
239 }
240
242 {
243 _resetCounter = 0;
245 keleseth->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
246
248 taldaram->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
249
251 valanar->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
252 }
253
254 void JustDied(Unit* killer) OVERRIDE
255 {
256 _JustDied();
257 // kill all prices
258 for (uint8 i = 0; i < 3; ++i)
259 {
260 if (++_invocationStage == 3)
262
264 {
265 // make sure looting is allowed
266 if (me->IsDamageEnoughForLootingAndReward())
267 prince->LowerPlayerDamageReq(prince->GetMaxHealth());
268 killer->Kill(prince);
269 }
270 }
271 }
272
274 {
275 if (!UpdateVictim())
276 return;
277
278 events.Update(diff);
279
280 if (me->HasUnitState(UNIT_STATE_CASTING))
281 return;
282
283 while (uint32 eventId = events.ExecuteEvent())
284 {
285 switch (eventId)
286 {
288 {
290 if (++_invocationStage == 3)
292
294 if (oldPrince)
295 {
296 oldPrince->AI()->DoAction(ACTION_REMOVE_INVOCATION);
297 if (newPrince)
298 oldPrince->CastSpell(newPrince, _invocationOrder[_invocationStage].visualSpell, true);
299 }
300
301 if (newPrince)
302 {
303 newPrince->SetHealth(me->GetHealth());
304 newPrince->AI()->Talk(uint8(_invocationOrder[_invocationStage].textId));
305 }
306
308 events.ScheduleEvent(EVENT_INVOCATION_OF_BLOOD, 46500);
309 break;
310 }
311 default:
312 break;
313 }
314 }
315 }
316
317 private:
319 {
324
325 InvocationData(uint64 _guid, uint32 _spellId, uint32 _textId, uint32 _visualSpell)
326 {
327 guid = _guid;
328 spellId = _spellId;
329 textId = _textId;
330 visualSpell = _visualSpell;
331 }
332
335
338 };
339
344};
345
347{
348 public:
349 boss_prince_keleseth_icc() : CreatureScript("boss_prince_keleseth_icc") { }
350
352 {
354 {
355 _isEmpowered = false;
356 _spawnHealth = creature->GetMaxHealth();
357 }
358
360 {
361 if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow()))
362 if (data->curhealth)
363 _spawnHealth = data->curhealth;
364
365 if (!me->isDead())
367
368 me->SetReactState(REACT_DEFENSIVE);
369 }
370
372 {
373 events.Reset();
374 summons.DespawnAll();
375
377 _isEmpowered = false;
378 me->SetHealth(_spawnHealth);
380 me->SetReactState(REACT_DEFENSIVE);
381 }
382
383 void EnterCombat(Unit* /*who*/) OVERRIDE
384 {
386 DoZoneInCombat(controller);
387
388 events.ScheduleEvent(EVENT_BERSERK, 600000);
389 events.ScheduleEvent(EVENT_SHADOW_RESONANCE, std::rand() % 15000 + 10000);
390 events.ScheduleEvent(EVENT_SHADOW_LANCE, 2000);
391
392 if (IsHeroic())
393 {
394 me->AddAura(SPELL_SHADOW_PRISON, me);
396 }
397 }
398
399 void JustDied(Unit* /*killer*/) OVERRIDE
400 {
401 events.Reset();
402 summons.DespawnAll();
403
405 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
406 }
407
409 {
410 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
411 me->SetHealth(_spawnHealth);
412 _isEmpowered = false;
414 {
416 controller->AI()->SetData(0, 1);
417 }
418 }
419
421 {
423 me->SetHealth(_spawnHealth);
424 }
425
426 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
427 {
428 if (spell->Id == SPELL_INVOCATION_OF_BLOOD_KELESETH)
430 }
431
433 {
434 summons.Summon(summon);
435 Position pos;
436 me->GetPosition(&pos);
437 float maxRange = me->GetDistance2d(summon);
438 float angle = me->GetAngle(summon);
439 me->MovePositionToFirstCollision(pos, maxRange, angle);
440 summon->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
441 summon->ToTempSummon()->SetTempSummonType(TempSummonType::TEMPSUMMON_CORPSE_DESPAWN);
442 }
443
444 void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) OVERRIDE
445 {
446 if (damageType != SPELL_DIRECT_DAMAGE)
447 return;
448
449 if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000))
451 }
452
453 void DamageTaken(Unit* attacker, uint32& damage) OVERRIDE
454 {
455 if (!_isEmpowered)
456 {
457 me->AddThreat(attacker, float(damage));
458 damage = 0;
459 }
460 }
461
463 {
464 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER)
466 }
467
469 {
470 switch (action)
471 {
472 case ACTION_STAND_UP:
473 me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH);
477 me->ForceValuesUpdateAtIndex(UNIT_FIELD_NPC_FLAGS); // was in sniff. don't ask why
478 me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
479 break;
483 _isEmpowered = true;
484 break;
486 me->SetHealth(_spawnHealth);
487 me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE);
488 me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_KELESETH);
489 _isEmpowered = false;
490 break;
491 default:
492 break;
493 }
494 }
495
497 {
498 if (!CheckBoundary(me))
499 {
502 taldaram->AI()->EnterEvadeMode();
503
505 valanar->AI()->EnterEvadeMode();
506
507 return false;
508 }
509
510 return true;
511 }
512
514 {
515 if (!UpdateVictim() || !CheckRoom())
516 return;
517
518 events.Update(diff);
519
520 if (me->HasUnitState(UNIT_STATE_CASTING))
521 return;
522
523 while (uint32 eventId = events.ExecuteEvent())
524 {
525 switch (eventId)
526 {
527 case EVENT_BERSERK:
530 break;
534 events.ScheduleEvent(EVENT_SHADOW_RESONANCE, std::rand() % 15000 + 10000);
535 break;
537 if (_isEmpowered)
539 else
541 events.ScheduleEvent(EVENT_SHADOW_LANCE, 2000);
542 break;
543 default:
544 break;
545 }
546 }
547
548 // does not melee
549 }
550
551 private:
554 };
555
557 {
559 }
560};
561
563{
564 public:
565 boss_prince_taldaram_icc() : CreatureScript("boss_prince_taldaram_icc") { }
566
568 {
570 {
571 _isEmpowered = false;
572 _spawnHealth = creature->GetMaxHealth();
573 }
574
576 {
577 if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow()))
578 if (data->curhealth)
579 _spawnHealth = data->curhealth;
580
581 if (!me->isDead())
583
584 me->SetReactState(REACT_DEFENSIVE);
585 }
586
588 {
589 events.Reset();
590 summons.DespawnAll();
591
593 _isEmpowered = false;
594 me->SetHealth(_spawnHealth);
596 me->SetReactState(REACT_DEFENSIVE);
597 }
598
600
601 {
602 }
603
604 void EnterCombat(Unit* /*who*/) OVERRIDE
605 {
607 DoZoneInCombat(controller);
608
609 events.ScheduleEvent(EVENT_BERSERK, 600000);
610 events.ScheduleEvent(EVENT_GLITTERING_SPARKS, std::rand() % 15000 + 12000);
611 events.ScheduleEvent(EVENT_CONJURE_FLAME, 20000);
612 if (IsHeroic())
613 me->AddAura(SPELL_SHADOW_PRISON, me);
614 }
615
616 void JustDied(Unit* /*killer*/) OVERRIDE
617 {
618 events.Reset();
619 summons.DespawnAll();
620
622 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
623 }
624
626 {
627 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
628 me->SetHealth(_spawnHealth);
629 _isEmpowered = false;
631 {
633 controller->AI()->SetData(0, 1);
634 }
635 }
636
638 {
640 me->SetHealth(_spawnHealth);
641 }
642
643 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
644 {
645 if (spell->Id == SPELL_INVOCATION_OF_BLOOD_TALDARAM)
647 }
648
650 {
651 summons.Summon(summon);
652 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -10.0f, true); // first try at distance
653 if (!target)
654 target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); // too bad for you raiders, its going to boom
655
656 if (summon->GetEntry() == NPC_BALL_OF_INFERNO_FLAME && target)
657 Talk(EMOTE_TALDARAM_FLAME, target);
658
659 if (target)
660 summon->AI()->SetGUID(target->GetGUID());
661 }
662
663 void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) OVERRIDE
664 {
665 if (damageType != SPELL_DIRECT_DAMAGE)
666 return;
667
668 if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000))
670 }
671
672 void DamageTaken(Unit* attacker, uint32& damage) OVERRIDE
673 {
674 if (!_isEmpowered)
675 {
676 me->AddThreat(attacker, float(damage));
677 damage = 0;
678 }
679 }
680
682 {
683 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER)
685 }
686
688 {
689 switch (action)
690 {
691 case ACTION_STAND_UP:
692 me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH);
696 me->ForceValuesUpdateAtIndex(UNIT_FIELD_NPC_FLAGS); // was in sniff. don't ask why
697 me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
698 break;
702 _isEmpowered = true;
703 break;
705 me->SetHealth(_spawnHealth);
706 me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE);
707 me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_TALDARAM);
708 _isEmpowered = false;
709 break;
710 default:
711 break;
712 }
713 }
714
716 {
717 if (!CheckBoundary(me))
718 {
721 keleseth->AI()->EnterEvadeMode();
722
724 valanar->AI()->EnterEvadeMode();
725
726 return false;
727 }
728
729 return true;
730 }
731
733 {
734 if (!UpdateVictim() || !CheckRoom())
735 return;
736
737 events.Update(diff);
738
739 if (me->HasUnitState(UNIT_STATE_CASTING))
740 return;
741
742 while (uint32 eventId = events.ExecuteEvent())
743 {
744 switch (eventId)
745 {
746 case EVENT_BERSERK:
749 break;
752 events.ScheduleEvent(EVENT_GLITTERING_SPARKS, std::rand() % 50000 + 15000);
753 break;
755 if (_isEmpowered)
756 {
758 events.ScheduleEvent(EVENT_CONJURE_FLAME, std::rand() % 25000 + 15000);
759 }
760 else
761 {
763 events.ScheduleEvent(EVENT_CONJURE_FLAME, std::rand() % 30000 + 20000);
764 }
766 break;
767 default:
768 break;
769 }
770 }
771
773 }
774
775 private:
778 };
779
781 {
783 }
784};
785
787{
788 public:
789 boss_prince_valanar_icc() : CreatureScript("boss_prince_valanar_icc") { }
790
792 {
794 {
795 _isEmpowered = false;
796 _spawnHealth = creature->GetMaxHealth();
797 }
798
800 {
801 if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow()))
802 if (data->curhealth)
803 _spawnHealth = data->curhealth;
804
805 if (!me->isDead())
807
808 me->SetReactState(REACT_DEFENSIVE);
809 }
810
812 {
813 events.Reset();
814 summons.DespawnAll();
815
817 _isEmpowered = false;
818 me->SetHealth(me->GetMaxHealth());
820 me->SetReactState(REACT_DEFENSIVE);
821 }
822
824
825 {
826 }
827
828 void EnterCombat(Unit* /*who*/) OVERRIDE
829 {
831 DoZoneInCombat(controller);
832
833 events.ScheduleEvent(EVENT_BERSERK, 600000);
834 events.ScheduleEvent(EVENT_KINETIC_BOMB, std::rand() % 24000 + 18000);
835 events.ScheduleEvent(EVENT_SHOCK_VORTEX, std::rand() % 20000 + 15000);
836 if (IsHeroic())
837 me->AddAura(SPELL_SHADOW_PRISON, me);
838 }
839
840 void JustDied(Unit* /*killer*/) OVERRIDE
841 {
842 events.Reset();
843 summons.DespawnAll();
844
846 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
847 }
848
850 {
851 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
852 me->SetHealth(me->GetMaxHealth());
853 _isEmpowered = false;
855 {
857 controller->AI()->SetData(0, 1);
858 }
859 }
860
862 {
864 me->SetHealth(_spawnHealth);
865 }
866
868 {
869 switch (summon->GetEntry())
870 {
872 summon->SetReactState(REACT_PASSIVE);
873 summon->CastSpell(summon, SPELL_KINETIC_BOMB, true, NULL, NULL, me->GetGUID());
874 break;
875 case NPC_KINETIC_BOMB:
876 {
877 float x, y, z;
878 summon->GetPosition(x, y, z);
879 float ground_Z = summon->GetMap()->GetHeight(summon->GetPhaseMask(), x, y, z, true, 500.0f);
880 summon->GetMotionMaster()->MovePoint(POINT_KINETIC_BOMB_IMPACT, x, y, ground_Z);
881 summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
882 break;
883 }
884 case NPC_SHOCK_VORTEX:
885 summon->CastSpell(summon, SPELL_SHOCK_VORTEX_DUMMY, true);
886 summon->CastSpell(summon, SPELL_SHOCK_VORTEX_PERIODIC, true);
887 break;
888 default:
889 break;
890 }
891 summons.Summon(summon);
892 if (me->IsInCombat())
893 DoZoneInCombat(summon);
894 }
895
896 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
897 {
898 if (spell->Id == SPELL_INVOCATION_OF_BLOOD_VALANAR)
900 }
901
902 void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) OVERRIDE
903 {
904 if (damageType != SPELL_DIRECT_DAMAGE)
905 return;
906
907 if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000))
909 }
910
911 void DamageTaken(Unit* attacker, uint32& damage) OVERRIDE
912 {
913 if (!_isEmpowered)
914 {
915 me->AddThreat(attacker, float(damage));
916 damage = 0;
917 }
918 }
919
921 {
922 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER)
924 }
925
927 {
928 switch (action)
929 {
930 case ACTION_STAND_UP:
931 me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH);
935 me->ForceValuesUpdateAtIndex(UNIT_FIELD_NPC_FLAGS); // was in sniff. don't ask why
936 me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
937 break;
941 _isEmpowered = true;
942 break;
944 me->SetHealth(_spawnHealth);
945 me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE);
946 me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_VALANAR);
947 _isEmpowered = false;
948 break;
949 default:
950 break;
951 }
952 }
953
955 {
956 if (!CheckBoundary(me))
957 {
960 keleseth->AI()->EnterEvadeMode();
961
963 taldaram->AI()->EnterEvadeMode();
964
965 return false;
966 }
967
968 return true;
969 }
970
972 {
973 if (!UpdateVictim() || !CheckRoom())
974 return;
975
976 events.Update(diff);
977
978 if (me->HasUnitState(UNIT_STATE_CASTING))
979 return;
980
981 while (uint32 eventId = events.ExecuteEvent())
982 {
983 switch (eventId)
984 {
985 case EVENT_BERSERK:
988 break;
990 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
991 {
994 }
995 events.ScheduleEvent(EVENT_KINETIC_BOMB, std::rand() % 24000 + 18000);
996 break;
998 if (_isEmpowered)
999 {
1002 events.ScheduleEvent(EVENT_SHOCK_VORTEX, 30000);
1003 }
1004 else
1005 {
1006 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
1007 DoCast(target, SPELL_SHOCK_VORTEX);
1008 events.ScheduleEvent(EVENT_SHOCK_VORTEX, std::rand() % 23000 + 18000);
1009 }
1010 break;
1011 default:
1012 break;
1013 }
1014 }
1015
1017 }
1018
1019 private:
1022 };
1023
1025 {
1027 }
1028};
1029
1031{
1032 public:
1033 npc_blood_queen_lana_thel() : CreatureScript("npc_blood_queen_lana_thel") { }
1034
1036 {
1038 {
1039 _introDone = false;
1040 _instance = creature->GetInstanceScript();
1041 }
1042
1044 {
1045 _events.Reset();
1046 me->SetDisableGravity(true);
1047 if (_instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) == DONE)
1048 {
1049 me->SetVisible(false);
1050 _introDone = true;
1051 }
1052 else
1053 me->SetVisible(true);
1054 }
1055
1057
1058 {
1059 if (_introDone)
1060 return;
1061
1062 if (!me->IsWithinDistInMap(who, 35.0f, false))
1063 return;
1064
1065 _introDone = true;
1067 _events.SetPhase(1);
1068 _events.ScheduleEvent(EVENT_INTRO_1, 14000);
1069 // summon a visual trigger
1071 {
1072 summon->CastSpell(summon, SPELL_OOC_INVOCATION_VISUAL, true);
1073 summon->SetSpeed(MOVE_FLIGHT, 0.15f, true);
1074 summon->GetMotionMaster()->MovePoint(0, triggerEndPos);
1075 }
1076 }
1077
1079 {
1080 if (type == POINT_MOTION_TYPE && id == POINT_INTRO_DESPAWN)
1081 me->SetVisible(false);
1082 }
1083
1085 {
1086 if (!_events.GetPhaseMask())
1087 return;
1088
1089 _events.Update(diff);
1090
1091 if (_events.ExecuteEvent() == EVENT_INTRO_1)
1092 {
1094 me->GetMotionMaster()->MovePoint(POINT_INTRO_DESPAWN, introFinalPos);
1095 _events.Reset();
1096
1097 // remove Feign Death from princes
1099 keleseth->AI()->DoAction(ACTION_STAND_UP);
1100
1102 taldaram->AI()->DoAction(ACTION_STAND_UP);
1103
1105 {
1106 valanar->AI()->DoAction(ACTION_STAND_UP);
1107 valanar->SetHealth(valanar->GetMaxHealth());
1108 }
1109 }
1110 }
1111
1112 private:
1116 };
1117
1119 {
1121 }
1122};
1123
1125{
1126 public:
1127 npc_ball_of_flame() : CreatureScript("npc_ball_of_flame") { }
1128
1130 {
1131 npc_ball_of_flameAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
1132 {
1133 _despawnTimer = 0;
1134 }
1135
1137 {
1138 me->CastSpell(me, SPELL_BALL_OF_FLAMES_VISUAL, true);
1139 if (me->GetEntry() == NPC_BALL_OF_INFERNO_FLAME)
1140 {
1141 me->CastSpell(me, SPELL_BALL_OF_FLAMES_PROC, true);
1142 me->CastSpell(me, SPELL_BALL_OF_FLAMES_PERIODIC, true);
1143 }
1144 }
1145
1147 {
1148 if (type == CHASE_MOTION_TYPE && id == GUID_LOPART(_chaseGUID) && _chaseGUID)
1149 {
1150 me->RemoveAurasDueToSpell(SPELL_BALL_OF_FLAMES_PERIODIC);
1152 _despawnTimer = 1000;
1153 _chaseGUID = 0;
1154 }
1155 }
1156
1157 void SetGUID(uint64 guid, int32 /*type*/) OVERRIDE
1158 {
1159 _chaseGUID = guid;
1160 }
1161
1163 {
1164 if (action == ACTION_FLAME_BALL_CHASE)
1166 {
1167 // need to clear states now because this call is before AuraEffect is fully removed
1168 me->ClearUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED);
1169 if (target && me->Attack(target, true))
1170 me->GetMotionMaster()->MoveChase(target, 1.0f);
1171 }
1172 }
1173
1174 void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) OVERRIDE
1175 {
1176 if (damageType != SPELL_DIRECT_DAMAGE)
1177 return;
1178
1179 if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000))
1181 }
1182
1184 {
1185 if (!_despawnTimer)
1186 return;
1187
1188 if (_despawnTimer <= diff)
1189 {
1190 _despawnTimer = 0;
1192 }
1193 else
1194 _despawnTimer -= diff;
1195 }
1196
1197 private:
1201 };
1202
1204 {
1206 }
1207};
1208
1210{
1211 public:
1212 npc_kinetic_bomb() : CreatureScript("npc_kinetic_bomb") { }
1213
1215 {
1216 npc_kinetic_bombAI(Creature* creature) : ScriptedAI(creature) { }
1217
1219 {
1220 _events.Reset();
1221 me->SetWalk(true);
1222 me->CastSpell(me, SPELL_UNSTABLE, true);
1223 me->CastSpell(me, SPELL_KINETIC_BOMB_VISUAL, true);
1224 me->SetReactState(REACT_PASSIVE);
1225 me->GetPosition(_x, _y, _groundZ);
1226 me->DespawnOrUnsummon(60000);
1227 _groundZ = me->GetMap()->GetHeight(me->GetPhaseMask(), _x, _y, _groundZ, true, 500.0f);
1228 }
1229
1231 {
1232 if (action == SPELL_KINETIC_BOMB_EXPLOSION)
1233 _events.ScheduleEvent(EVENT_BOMB_DESPAWN, 1000);
1234 else if (action == ACTION_KINETIC_BOMB_JUMP)
1235 {
1236 if (!me->HasAura(SPELL_KINETIC_BOMB_KNOCKBACK))
1237 me->GetMotionMaster()->MoveCharge(_x, _y, me->GetPositionZ() + 100.0f, me->GetSpeed(MOVE_RUN), 0);
1238 _events.RescheduleEvent(EVENT_CONTINUE_FALLING, 3000);
1239 }
1240 }
1241
1243 {
1244 _events.Update(diff);
1245
1246 while (uint32 eventId = _events.ExecuteEvent())
1247 {
1248 switch (eventId)
1249 {
1250 case EVENT_BOMB_DESPAWN:
1251 me->SetVisible(false);
1252 me->DespawnOrUnsummon(5000);
1253 break;
1255 me->GetMotionMaster()->MoveCharge(_x, _y, _groundZ, me->GetSpeed(MOVE_WALK), POINT_KINETIC_BOMB_IMPACT);
1256 break;
1257 default:
1258 break;
1259 }
1260 }
1261 }
1262
1263 private:
1265 float _x;
1266 float _y;
1268 };
1269
1271 {
1273 }
1274};
1275
1277{
1278 public:
1279 npc_dark_nucleus() : CreatureScript("npc_dark_nucleus") { }
1280
1282 {
1284 {
1285 _lockedTarget = false;
1286 _targetAuraCheck = 0;
1287 }
1288
1290 {
1291 me->SetReactState(REACT_DEFENSIVE);
1292 me->CastSpell(me, SPELL_SHADOW_RESONANCE_AURA, true);
1293 }
1294
1296 {
1297 _targetAuraCheck = 1000;
1298 if (me->GetDistance(who) >= 15.0f)
1299 {
1300 DoStartMovement(who);
1301 return;
1302 }
1303
1305 me->ClearUnitState(UNIT_STATE_CASTING);
1306 }
1307
1309
1310 {
1312 }
1313
1314 void DamageTaken(Unit* attacker, uint32& /*damage*/) OVERRIDE
1315 {
1316 if (attacker == me)
1317 return;
1318
1319 me->DeleteThreatList();
1320 me->AddThreat(attacker, 500000000.0f);
1321 }
1322
1324 {
1325 if (!UpdateVictim())
1326 return;
1327
1328 if (_targetAuraCheck <= diff)
1329 {
1330 _targetAuraCheck = 1000;
1331 if (Unit* victim = me->GetVictim())
1332 {
1333 if (me->GetDistance(victim) < 15.0f &&
1334 !victim->HasAura(SPELL_SHADOW_RESONANCE_RESIST, me->GetGUID()))
1335 {
1337 me->ClearUnitState(UNIT_STATE_CASTING);
1338 }
1339 else
1340 MoveInLineOfSight(me->GetVictim());
1341 }
1342 }
1343 else
1344 _targetAuraCheck -= diff;
1345 }
1346
1347 private:
1350 };
1351
1353 {
1355 }
1356};
1357
1384
1411
1413{
1414 public:
1415 spell_taldaram_flame_ball_visual() : SpellScriptLoader("spell_taldaram_flame_ball_visual") { }
1416
1418 {
1420
1422 {
1423 if (GetCaster()->GetEntry() == NPC_BALL_OF_FLAME || GetCaster()->GetEntry() == NPC_BALL_OF_INFERNO_FLAME)
1424 return true;
1425 return false;
1426 }
1427
1428 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1429 {
1430 Creature* target = GetTarget()->ToCreature();
1431 if (!target)
1432 return;
1433
1434 // SPELL_FLAME_SPHERE_SPAWN_EFFECT
1436 {
1437 target->CastSpell(target, SPELL_BALL_OF_FLAMES, true);
1439 }
1440 else // SPELL_FLAME_SPHERE_DEATH_EFFECT
1441 target->DespawnOrUnsummon();
1442 }
1443
1448 };
1449
1451 {
1453 }
1454};
1455
1482
1484{
1485 public:
1486 spell_valanar_kinetic_bomb() : SpellScriptLoader("spell_valanar_kinetic_bomb") { }
1487
1489 {
1491
1493 {
1494 WorldLocation summonPos = *GetExplTargetDest();
1495 Position offset = {0.0f, 0.0f, 20.0f, 0.0f};
1496 summonPos.RelocateOffset(offset);
1497 SetExplTargetDest(summonPos);
1498 GetHitDest()->RelocateOffset(offset);
1499 }
1500
1505 };
1506
1508 {
1510
1511 void HandleDummyTick(AuraEffect const* /*aurEff*/)
1512 {
1513 Unit* target = GetTarget();
1514 if (target->GetTypeId() != TypeID::TYPEID_UNIT)
1515 return;
1516
1517 if (Creature* bomb = target->FindNearestCreature(NPC_KINETIC_BOMB, 1.0f, true))
1518 {
1519 bomb->CastSpell(bomb, SPELL_KINETIC_BOMB_EXPLOSION, true);
1520 bomb->RemoveAurasDueToSpell(SPELL_KINETIC_BOMB_VISUAL);
1521 target->RemoveAura(GetAura());
1522 bomb->AI()->DoAction(SPELL_KINETIC_BOMB_EXPLOSION);
1523 }
1524 }
1525
1530 };
1531
1536
1541};
1542
1569
1571{
1572 public:
1573 spell_valanar_kinetic_bomb_absorb() : SpellScriptLoader("spell_valanar_kinetic_bomb_absorb") { }
1574
1576 {
1578
1579 void OnAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)
1580 {
1581 absorbAmount = CalculatePct(dmgInfo.GetDamage(), aurEff->GetAmount());
1582 RoundToInterval<uint32>(absorbAmount, 0, dmgInfo.GetDamage());
1583 dmgInfo.AbsorbDamage(absorbAmount);
1584 }
1585
1590 };
1591
1596};
1597
1624
1626{
1627 public:
1628 spell_blood_council_shadow_prison_damage() : SpellScriptLoader("spell_blood_council_shadow_prison_damage") { }
1629
1631 {
1633
1635 {
1636 if (Aura* aur = GetHitUnit()->GetAura(GetSpellInfo()->Id))
1637 if (AuraEffect const* eff = aur->GetEffect(EFFECT_1))
1638 SetHitDamage(GetHitDamage() + eff->GetAmount());
1639 }
1640
1645 };
1646
1651};
1652
Actions
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
@ DONE
@ NOT_STARTED
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
@ CHASE_MOTION_TYPE
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
@ TEMPSUMMON_CORPSE_DESPAWN
Definition Object.h:72
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
uint32 GUID_LOPART(uint64 x)
#define sObjectMgr
Definition ObjectMgr.h:1617
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ EMOTE_ONESHOT_ROAR
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SUMMON
@ UNIT_DYNFLAG_DEAD
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_MOD_STUN
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
#define SpellEffectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectAbsorbFn(F, I)
#define SpellHitFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ UNIT_STATE_STUNNED
Definition Unit.h:515
@ MOVE_FLIGHT
Definition Unit.h:561
@ MOVE_RUN
Definition Unit.h:556
@ MOVE_WALK
Definition Unit.h:555
@ REACT_DEFENSIVE
Definition Unit.h:1157
@ REACT_PASSIVE
Definition Unit.h:1156
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ UNIT_FLAG2_FEIGN_DEATH
Definition Unit.h:663
DamageEffectType
Definition Unit.h:613
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:615
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS2
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_FLAGS
@ OBJECT_FIELD_DYNAMIC_FLAGS
T RoundToInterval(T &num, T floor, T ceil)
Definition Util.h:121
T CalculatePct(T base, U pct)
Definition Util.h:103
Position const triggerPos
@ SPELL_SHADOW_RESONANCE_RESIST
@ SPELL_INVOCATION_OF_BLOOD_VALANAR
@ SPELL_INVOCATION_OF_BLOOD_TALDARAM
@ SPELL_BALL_OF_FLAMES_PERIODIC
@ SPELL_KINETIC_BOMB_TARGET
@ SPELL_FLAME_SPHERE_DEATH_EFFECT
@ SPELL_BALL_OF_FLAMES_VISUAL
@ SPELL_KINETIC_BOMB_KNOCKBACK
@ SPELL_FLAME_SPHERE_SPAWN_EFFECT
@ SPELL_EMPOWERED_SHADOW_LANCE
@ SPELL_SHADOW_PRISON_DUMMY
@ SPELL_OOC_INVOCATION_VISUAL
@ SPELL_BALL_OF_FLAMES_PROC
@ SPELL_KINETIC_BOMB_EXPLOSION
@ SPELL_INVOCATION_OF_BLOOD_KELESETH
@ SPELL_KINETIC_BOMB_VISUAL
@ SPELL_SHADOW_PRISON_DAMAGE
@ SPELL_SHOCK_VORTEX_PERIODIC
@ SPELL_SHADOW_RESONANCE_AURA
@ SPELL_CONJURE_EMPOWERED_FLAME
@ SPELL_INVOCATION_VISUAL_ACTIVE
@ SPELL_EMPOWERED_SHOCK_VORTEX
void AddSC_boss_blood_prince_council()
Position const triggerEndPos
@ EMOTE_TALDARAM_INVOCATION
@ EMOTE_KELESETH_INVOCATION
@ EMOTE_VALANAR_SHOCK_VORTEX
Position const introFinalPos
#define SPELL_BERSERK
@ EVENT_BERSERK
@ SPELL_FLAME_SPHERE_DEATH_EFFECT
@ SPELL_FLAME_SPHERE_SPAWN_EFFECT
@ EVENT_INTRO_1
@ EVENT_INTRO_2
int32 GetAmount() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
Unit * GetCaster() const
HookList< EffectAbsorbHandler > OnEffectAbsorb
Aura * GetAura() const
Unit * GetTarget() const
InstanceScript *const instance
SummonList summons
EventMap events
BossAI(Creature *creature, uint32 bossId)
bool CheckBoundary(Unit *who)
virtual void MoveInLineOfSight(Unit *)
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
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()
virtual void EnterEvadeMode()
void DespawnOrUnsummon(uint32 msTimeToDespawn=0)
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
void AbsorbDamage(uint32 amount)
Definition Unit.cpp:105
uint32 GetDamage() const
Definition Unit.h:923
static Creature * GetCreature(WorldObject const &u, uint64 guid)
static Player * GetPlayer(WorldObject const &, uint64 guid)
uint64 GetGUID() const
Definition Object.h:119
TypeID GetTypeId() const
Definition Object.h:131
Creature * ToCreature()
Definition Object.h:207
Creature * GetHitCreature()
Aura * GetHitAura()
WorldLocation const * GetExplTargetDest()
void SetExplTargetDest(WorldLocation &loc)
HookList< HitHandler > AfterHit
SpellInfo const * GetSpellInfo()
HookList< HitHandler > OnHit
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
WorldLocation * GetHitDest()
int32 GetEffectValue()
void SetHitDamage(int32 damage)
Unit * GetCaster()
HookList< HitHandler > BeforeHit
int32 GetHitDamage()
SpellScriptLoader(const char *name)
StandUpEvent(Creature &owner)
bool Execute(uint64, uint32)
virtual void DoAction(int32)
Definition UnitAI.h:126
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
Definition Unit.h:1367
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
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)
uint32 GetMaxHealth() const
Definition Unit.h:1604
void SetHealth(uint32 val)
Definition Unit.cpp:5162
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2801
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
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
PrepareAuraScript(spell_valanar_kinetic_bomb_AuraScript)
PrepareSpellScript(spell_valanar_kinetic_bomb_SpellScript)
void OnAbsorb(AuraEffect *aurEff, DamageInfo &dmgInfo, uint32 &absorbAmount)
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
@ NPC_KINETIC_BOMB
@ NPC_SHOCK_VORTEX
@ NPC_BALL_OF_FLAME
@ NPC_FLOATING_TRIGGER
@ NPC_BALL_OF_INFERNO_FLAME
@ NPC_KINETIC_BOMB_TARGET
CreatureAI * GetIcecrownCitadelAI(Creature *creature)
@ LIGHT_S_HAMMER_TELEPORT
@ DATA_ORB_WHISPERER_ACHIEVEMENT
@ DATA_BLOOD_PRINCE_COUNCIL
@ DATA_BLOOD_PRINCES_CONTROL
@ DATA_PRINCE_TALDARAM_GUID
@ DATA_PRINCE_VALANAR_GUID
@ DATA_PRINCE_KELESETH_GUID
float GetPositionZ() const
Definition Object.h:330
float GetOrientation() const
Definition Object.h:331
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
void RelocateOffset(Position const &offset)
Definition Object.cpp:1841
bool IsHeroic() const
Creature * me
const T & RAID_MODE(const T &normal10, const T &normal25) const
ScriptedAI(Creature *creature)
void DoStartMovement(Unit *target, float distance=0.0f, float angle=0.0f)
InvocationData(uint64 _guid, uint32 _spellId, uint32 _textId, uint32 _visualSpell)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
struct boss_blood_council_controller::boss_blood_council_controllerAI::InvocationData _invocationOrder[3]
void DamageDealt(Unit *, uint32 &damage, DamageEffectType damageType) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void DamageTaken(Unit *attacker, uint32 &damage) OVERRIDE
void DamageTaken(Unit *attacker, uint32 &damage) OVERRIDE
void DamageDealt(Unit *, uint32 &damage, DamageEffectType damageType) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void DamageDealt(Unit *, uint32 &damage, DamageEffectType damageType) OVERRIDE
void DamageTaken(Unit *attacker, uint32 &damage) 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 DamageDealt(Unit *, uint32 &damage, DamageEffectType damageType) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void DamageTaken(Unit *attacker, uint32 &) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================