TrinityCore
boss_halion.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ScriptMgr.h"
19#include "Containers.h"
20#include "DB2Stores.h"
21#include "GameObject.h"
22#include "GameObjectAI.h"
23#include "InstanceScript.h"
24#include "Map.h"
25#include "ObjectAccessor.h"
26#include "PhasingHandler.h"
27#include "Player.h"
28#include "ruby_sanctum.h"
29#include "ScriptedCreature.h"
30#include "Spell.h"
31#include "SpellAuraEffects.h"
32#include "SpellScript.h"
33#include "TemporarySummon.h"
34#include "Vehicle.h"
35
37{
38 // Shared
39 SAY_REGENERATE = 0, // Without pressure in both realms, %s begins to regenerate.
40
41 // Halion
42 SAY_INTRO = 1, // Meddlesome insects! You are too late. The Ruby Sanctum is lost!
43 SAY_AGGRO = 2, // Your world teeters on the brink of annihilation. You will ALL bear witness to the coming of a new age of DESTRUCTION!
44 SAY_METEOR_STRIKE = 3, // The heavens burn!
45 SAY_PHASE_TWO = 4, // You will find only suffering within the realm of twilight! Enter if you dare!
46 SAY_DEATH = 5, // Relish this victory, mortals, for it will be your last! This world will burn with the master's return!
47 SAY_KILL = 6, // Another "hero" falls.
48 SAY_BERSERK = 7, // Not good enough.
49 EMOTE_CORPOREALITY_POT = 8, // Your efforts force %s further out of the physical realm!
50 EMOTE_CORPOREALITY_PIP = 9, // Your companions' efforts force %s further into the physical realm!
51
52 // Twilight Halion
53 SAY_SPHERE_PULSE = 1, // Beware the shadow!
54 SAY_PHASE_THREE = 2, // I am the light and the darkness! Cower, mortals, before the herald of Deathwing!
55 EMOTE_CORPOREALITY_TIT = 3, // Your companions' efforts force %s further into the twilight realm!
56 EMOTE_CORPOREALITY_TOT = 4, // Your efforts force %s further out of the twilight realm!
57
58 EMOTE_WARN_LASER = 0 // The orbiting spheres pulse with dark energy!
59};
60
62{
63 // Halion
65 SPELL_CLEAVE = 74524,
68
73
74 // Combustion & Consumption
75 SPELL_SCALE_AURA = 70507, // Aura created in spell_dbc.
78
79 // Twilight Halion
81
86
87 // Living Inferno
91
92 // Halion Controller
96
97 // Meteor Strike
103
104 // Shadow Orb
105 SPELL_TWILIGHT_CUTTER = 74768, // Unknown dummy effect (EFFECT_0)
109
110 // Misc
111 SPELL_TWILIGHT_DIVISION = 75063, // Phase spell from phase 2 to phase 3
113 SPELL_TWILIGHT_PHASING = 74808, // Phase spell from phase 1 to phase 2
114 SPELL_SUMMON_TWILIGHT_PORTAL = 74809, // Summons go 202794
115 SPELL_SUMMON_EXIT_PORTALS = 74805, // Custom spell created in spell_dbc. // Used in Cataclysm, need a sniff of cata and up
120 SPELL_COPY_DAMAGE = 74810 // Aura not found in DBCs.
122
124{
125 // Halion
132
133 // Twilight Halion
135
136 // Meteor Strike
138
139 // Halion Controller
151
153{
154 // Meteor Strike
157
158 // Halion Controller
160
161 // Orb Carrier
166
168{
173 PHASE_THREE = 4
175
177{
184
186{
190 SEAT_WEST = 3
192
194{
200
201Position const HalionSpawnPos = {3156.67f, 533.8108f, 72.98822f, 3.159046f};
202Position const HalionRespawnPos = {3156.625f, 533.2674f, 72.97205f, 0.0f};
203
205
207{
210};
211
213{
214 {74836, 74831},
215 {74835, 74830},
216 {74834, 74829},
217 {74833, 74828},
218 {74832, 74827},
219 {74826, 74826},
220 {74827, 74832},
221 {74828, 74833},
222 {74829, 74834},
223 {74830, 74835},
224 {74831, 74836}
225};
226
228{
229 public:
230 boss_halion() : CreatureScript("boss_halion") { }
231
232 struct boss_halionAI : public BossAI
233 {
234 boss_halionAI(Creature* creature) : BossAI(creature, DATA_HALION) { }
235
236 void EnterEvadeMode(EvadeReason why) override
237 {
240 controller->AI()->EnterEvadeMode(why);
241 }
242
243 void JustEngagedWith(Unit* who) override
244 {
246
247 events.Reset();
249
258
260
262 controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_ONE);
263 }
264
265 void JustDied(Unit* /*killer*/) override
266 {
267 _JustDied();
268
271
272 if (Creature* twilightHalion = instance->GetCreature(DATA_TWILIGHT_HALION))
273 if (twilightHalion->IsAlive())
274 twilightHalion->KillSelf();
275
277 if (controller->IsAlive())
278 controller->KillSelf();
279 }
280
282
283 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
284 {
285 if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
286 damage = me->GetHealth() - 1;
287
289 {
292
293 me->CastStop();
294 me->SetUninteractible(true);
296
298 controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_TWO);
299 return;
300 }
301
303 {
304 // Don't consider copied damage.
305 if (!attacker || !me->InSamePhase(attacker))
306 return;
307
309 controller->AI()->SetData(DATA_MATERIAL_DAMAGE_TAKEN, damage);
310 }
311 }
312
313 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
314 {
315 if (spellInfo->Id == SPELL_TWILIGHT_MENDING)
317 }
318
319 void UpdateAI(uint32 diff) override
320 {
322 return;
323
324 if (!UpdateVictim())
325 return;
326
327 events.Update(diff);
328
330 return;
331
332 while (uint32 eventId = events.ExecuteEvent())
333 {
334 switch (eventId)
335 {
336 case EVENT_CLEAVE:
339 break;
340 case EVENT_TAIL_LASH:
343 break;
344 case EVENT_BREATH:
347 break;
349 // Flame ring is activated 5 seconds after starting encounter, EncounterStateForOpenDoor::NotInProgress is only instant.
351 if (GameObject* flameRing = instance->GetGameObject(i))
352 instance->HandleGameObject(ObjectGuid::Empty, false, flameRing);
353 break;
355 {
356 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
357 {
358 _meteorStrikePos = target->GetPosition();
360 .SetOriginalCaster(me->GetGUID()));
362 }
364 break;
365 }
367 {
368 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
371 break;
372 }
373 default:
374 break;
375 }
376 }
377 }
378
379 void SetData(uint32 index, uint32 value) override
380 {
381 if (index != DATA_FIGHT_PHASE)
382 return;
383
384 events.SetPhase(value);
385 }
386
387 private:
389 };
390
391 CreatureAI* GetAI(Creature* creature) const override
392 {
393 return GetRubySanctumAI<boss_halionAI>(creature);
394 }
395};
396
398
400{
401 public:
402 boss_twilight_halion() : CreatureScript("boss_twilight_halion") { }
403
405 {
407 {
409 if (!halion)
410 return;
411
412 // Using AddAura because no spell cast packet in sniffs.
413 halion->AddAura(SPELL_COPY_DAMAGE, me); // We use explicit targeting here to avoid conditions + SPELL_ATTR6_CANT_TARGET_SELF.
414 me->AddAura(SPELL_COPY_DAMAGE, halion);
416
417 me->SetHealth(halion->GetHealth());
418 PhasingHandler::AddPhase(me, 174, false);
423 }
424
425 void JustEngagedWith(Unit* who) override
426 {
428
433
435 }
436
437 void Reset() override { }
438 void EnterEvadeMode(EvadeReason /*why*/) override { }
439
440 void KilledUnit(Unit* victim) override
441 {
442 if (victim->GetTypeId() == TYPEID_PLAYER)
443 Talk(SAY_KILL);
444
445 // Victims should not be in the Twilight Realm
447 }
448
449 void JustDied(Unit* killer) override
450 {
452 {
453 // Ensure looting
454 halion->LowerPlayerDamageReq(halion->GetMaxHealth());
455
456 if (halion->IsAlive())
457 Unit::Kill(killer, halion);
458 }
459
461 if (controller->IsAlive())
462 controller->KillSelf();
463
465 }
466
467 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
468 {
469 if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
470 damage = me->GetHealth() - 1;
471 //Needed because we already have UNIT_FLAG_IN_COMBAT, otherwise JustEngagedWith won't ever be called
473 JustEngagedWith(attacker);
474
476 {
478 me->CastStop();
481 return;
482 }
483
485 {
486 // Don't consider copied damage.
487 if (!attacker || !me->InSamePhase(attacker))
488 return;
489
491 controller->AI()->SetData(DATA_TWILIGHT_DAMAGE_TAKEN, damage);
492 }
493 }
494
495 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
496 {
497 switch (spellInfo->Id)
498 {
501 controller->AI()->DoAction(ACTION_MONITOR_CORPOREALITY);
502 break;
505 break;
506 default:
507 break;
508 }
509 }
510
511 void UpdateAI(uint32 diff) override
512 {
514 return;
515
516 if (!UpdateVictim())
517 return;
518
519 events.Update(diff);
520
521 while (uint32 eventId = events.ExecuteEvent())
522 {
523 switch (eventId)
524 {
525 case EVENT_CLEAVE:
528 break;
529 case EVENT_TAIL_LASH:
532 break;
533 case EVENT_BREATH:
536 break;
538 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, SPELL_TWILIGHT_REALM))
541 break;
542 default:
543 break;
544 }
545 }
546 }
547 };
548
549 CreatureAI* GetAI(Creature* creature) const override
550 {
551 return GetRubySanctumAI<boss_twilight_halionAI>(creature);
552 }
553};
554
556{
557 public:
558 npc_halion_controller() : CreatureScript("npc_halion_controller") { }
559
561 {
563 _instance(creature->GetInstanceScript()), _summons(me)
564 {
565 Initialize();
566 }
567
569 {
574 }
575
576 void JustAppeared() override
577 {
579 return;
580
581 Reset();
583 }
584
585 void Reset() override
586 {
588 _events.Reset();
589 Initialize();
590
592 }
593
594 void JustSummoned(Creature* who) override
595 {
596 _summons.Summon(who);
597 }
598
599 void JustDied(Unit* /*killer*/) override
600 {
601 _events.Reset();
603
605 }
606
607 void JustEngagedWith(Unit* /*who*/) override
608 {
611
614 }
615
616 void JustExitedCombat() override
617 {
619 return;
620
621 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
622 {
623 twilightHalion->DespawnOrUnsummon();
625 }
626
628 {
629 halion->DespawnOrUnsummon();
631 }
632
635
636 me->DespawnOrUnsummon(0s, 30s);
637 }
638
639 void DoAction(int32 action) override
640 {
641 switch (action)
642 {
644 _events.Reset();
647 break;
650 return;
651
653 if (GameObject* tree = _instance->GetGameObject(i))
656 break;
658 {
659 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
660 {
661 Creature* halion = _instance->GetCreature(itr);
662 if (!halion)
663 continue;
664
665 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), false);
667
668 if (itr == DATA_TWILIGHT_HALION)
669 continue;
670
672 halion->SetUninteractible(false);
673 }
674
675 // Summon Twilight portals
677
679 // Hardcoding doesn't really matter here.
682
684 break;
685 }
688 break;
689 default:
690 break;
691 }
692 }
693
694 void UpdateAI(uint32 diff) override
695 {
696 // The IsEngaged() check is needed because that check should be false when Halion is
697 // not engaged, while it would return true without as UpdateVictim() checks for
698 // combat state.
699 if (me->IsEngaged() && !UpdateVictim())
700 return;
701
702 _events.Update(diff);
703
704 while (uint32 eventId = _events.ExecuteEvent())
705 {
706 switch (eventId)
707 {
711 break;
714 if (GameObject* tree = _instance->GetGameObject(i))
717 break;
720 if (GameObject* tree = _instance->GetGameObject(i))
723 break;
727 return;
729 halion->AI()->Talk(SAY_INTRO);
730 break;
732 if (_instance->GetCreature(DATA_HALION)) // Just check if physical Halion is spawned
733 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
734 twilightHalion->CastSpell(nullptr, SPELL_TWILIGHT_MENDING, true);
735 break;
738 halion->CastSpell(halion, SPELL_BERSERK, true);
740 halion->CastSpell(halion, SPELL_BERSERK, true);
741 break;
744 orbCarrier->AI()->DoAction(ACTION_WARNING_SHOOT);
746 break;
750 break;
753 break;
755 DoCheckEvade();
757 break;
758 default:
759 break;
760 }
761 }
762 }
763
765 {
766 Map::PlayerList const& players = me->GetMap()->GetPlayers();
767 for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
768 if (Player* player = i->GetSource())
769 if (player->IsAlive() && IsInBoundary(player) && !player->IsGameMaster())
770 return;
771
773 }
774
775 void SetData(uint32 id, uint32 value) override
776 {
777 switch (id)
778 {
780 _materialDamageTaken += value;
781 break;
783 _twilightDamageTaken += value;
784 break;
785 case DATA_FIGHT_PHASE:
786 _events.SetPhase(value);
787 switch (value)
788 {
789 case PHASE_ONE:
791 break;
792 case PHASE_TWO:
794 break;
795 default:
796 break;
797 }
798 break;
799 default:
800 break;
801 }
802 }
803
804 private:
806 // [0 , 0.98[: Corporeality goes down
807 // [0.98, 0.99]: Do nothing
808 // ]0.99, 1.01[: Twilight Mending
809 // [1.01, 1.02]: Do nothing
810 // ]1.02, +oo [: Corporeality goes up
812 {
815 {
819 return;
820 }
821
822 float damageRatio = float(_materialDamageTaken) / float(_twilightDamageTaken);
823
825 if (damageRatio < 0.98f) // [0 , 0.98[: Corporeality goes down
826 action = CORPOREALITY_DECREASE;
827 else if (0.99f < damageRatio && damageRatio < 1.01f) // ]0.99, 1.01[: Twilight Mending
829 else if (1.02f < damageRatio) // ]1.02, +oo [: Corporeality goes up
830 action = CORPOREALITY_INCREASE;
831
832 switch (action)
833 {
835 {
838 return;
839 }
841 {
843 return;
845 break;
846 }
848 {
850 return;
852 break;
853 }
855 {
859 return;
860 }
861 }
862
865
868
869 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
870 {
871 if (Creature* halion = _instance->GetCreature(itr))
872 {
873 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), true);
874
875 if (itr == DATA_TWILIGHT_HALION)
876 halion->AI()->Talk(oldValue < _materialCorporealityValue ? EMOTE_CORPOREALITY_TOT : EMOTE_CORPOREALITY_TIT, halion);
877 else // if (itr == DATA_HALION)
878 halion->AI()->Talk(oldValue > _materialCorporealityValue ? EMOTE_CORPOREALITY_POT : EMOTE_CORPOREALITY_PIP, halion);
879 }
880 }
881 }
882
883 uint32 GetSpell(uint8 pctValue, bool isTwilight = false) const
884 {
886 return isTwilight ? entry.twilightRealmSpell : entry.materialRealmSpell;
887 }
888
892
896 };
897
898 CreatureAI* GetAI(Creature* creature) const override
899 {
900 return GetRubySanctumAI<npc_halion_controllerAI>(creature);
901 }
902};
903
905{
906 public:
907 npc_orb_carrier() : CreatureScript("npc_orb_carrier") { }
908
910 {
911 npc_orb_carrierAI(Creature* creature) : ScriptedAI(creature),
912 _instance(creature->GetInstanceScript())
913 {
914 ASSERT(creature->GetVehicleKit());
915 }
916
917 void UpdateAI(uint32 diff) override
918 {
923 me->CastSpell(nullptr, SPELL_TRACK_ROTATION, false);
924
925 scheduler.Update(diff);
926 }
927
928 void DoAction(int32 action) override
929 {
930 switch (action)
931 {
933 {
934 Vehicle* vehicle = me->GetVehicleKit();
935 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
936 if (northOrb && northOrb->GetTypeId() == TYPEID_UNIT)
937 northOrb->ToCreature()->AI()->Talk(EMOTE_WARN_LASER);
938
939 scheduler.Schedule(Seconds(5), [this](TaskContext /*context*/)
940 {
942 });
943 break;
944 }
945 case ACTION_SHOOT:
946 {
947 Vehicle* vehicle = me->GetVehicleKit();
948 Unit* southOrb = vehicle->GetPassenger(SEAT_SOUTH);
949 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
950 if (southOrb && northOrb)
951 TriggerCutter(northOrb, southOrb);
952
953 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
954 twilightHalion->AI()->Talk(SAY_SPHERE_PULSE);
955
956 if (!IsHeroic())
957 return;
958
959 Unit* eastOrb = vehicle->GetPassenger(SEAT_EAST);
960 Unit* westOrb = vehicle->GetPassenger(SEAT_WEST);
961 if (eastOrb && westOrb)
962 TriggerCutter(eastOrb, westOrb);
963 break;
964 }
965 default:
966 break;
967 }
968 }
969 private:
972
973 void TriggerCutter(Unit* caster, Unit* target)
974 {
975 caster->CastSpell(caster, SPELL_TWILIGHT_PULSE_PERIODIC, true);
976 target->CastSpell(target, SPELL_TWILIGHT_PULSE_PERIODIC, true);
977 caster->CastSpell(target, SPELL_TWILIGHT_CUTTER, false);
978 }
979 };
980
981 CreatureAI* GetAI(Creature* creature) const override
982 {
983 return GetRubySanctumAI<npc_orb_carrierAI>(creature);
984 }
985};
986
988{
989 public:
990 npc_meteor_strike_initial() : CreatureScript("npc_meteor_strike_initial") { }
991
993 {
995 _instance(creature->GetInstanceScript())
996 {
997 SetCombatMovement(false);
998 }
999
1000 void DoAction(int32 action) override
1001 {
1002 switch (action)
1003 {
1007 for (std::list<Creature*>::iterator itr = _meteorList.begin(); itr != _meteorList.end(); ++itr)
1008 (*itr)->AI()->DoAction(ACTION_METEOR_STRIKE_BURN);
1009 break;
1010 }
1011 }
1012
1013 void IsSummonedBy(WorldObject* summoner) override
1014 {
1015 Creature* owner = summoner->ToCreature();
1016 if (!owner)
1017 return;
1018
1019 // Let Controller count as summoner
1021 controller->AI()->JustSummoned(me);
1022
1025
1026 if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
1027 {
1028 Position const* ownerPos = halionAI->GetMeteorStrikePosition();
1029 float randomAdjustment = frand(static_cast<float>(M_PI / 5.0f), static_cast<float>(M_PI / 2.0f));
1030 float angle[4];
1031 angle[0] = me->GetAbsoluteAngle(ownerPos);
1032 angle[1] = angle[0] + randomAdjustment;
1033 angle[2] = angle[0] + static_cast<float>(M_PI);
1034 angle[3] = angle[2] + randomAdjustment;
1035
1036 _meteorList.clear();
1037 for (uint8 i = 0; i < 4; i++)
1038 {
1039 angle[i] = Position::NormalizeOrientation(angle[i]);
1040 me->SetOrientation(angle[i]);
1041 Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance
1043 _meteorList.push_back(meteor);
1044 }
1045 }
1046 }
1047
1048 void UpdateAI(uint32 /*diff*/) override { }
1049 void EnterEvadeMode(EvadeReason /*why*/) override { }
1050 private:
1052 std::list<Creature*> _meteorList;
1053 };
1054
1055 CreatureAI* GetAI(Creature* creature) const override
1056 {
1057 return GetRubySanctumAI<npc_meteor_strike_initialAI>(creature);
1058 }
1059};
1060
1062{
1063 public:
1064 npc_meteor_strike() : CreatureScript("npc_meteor_strike") { }
1065
1067 {
1069 _instance(creature->GetInstanceScript()), _spawnCount(0)
1070 {
1071 SetCombatMovement(false);
1072 }
1073
1074 void DoAction(int32 action) override
1075 {
1076 if (action == ACTION_METEOR_STRIKE_BURN)
1077 {
1079 me->setActive(true);
1080 me->SetFarVisible(true);
1082 }
1083 }
1084
1085 void IsSummonedBy(WorldObject* /*summoner*/) override
1086 {
1087 // Let Halion Controller count as summoner.
1089 controller->AI()->JustSummoned(me);
1090 }
1091
1092 void SetData(uint32 dataType, uint32 dataCount) override
1093 {
1094 if (dataType == DATA_SPAWNED_FLAMES)
1095 _spawnCount += dataCount;
1096 }
1097
1098 uint32 GetData(uint32 dataType) const override
1099 {
1100 if (dataType == DATA_SPAWNED_FLAMES)
1101 return _spawnCount;
1102 return 0;
1103 }
1104
1105 void UpdateAI(uint32 diff) override
1106 {
1107 _events.Update(diff);
1108
1110 {
1111 Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
1113 flame->AI()->SetGUID(me->GetGUID());
1114 }
1115 }
1116
1117 private:
1121 };
1122
1123 CreatureAI* GetAI(Creature* creature) const override
1124 {
1125 return GetRubySanctumAI<npc_meteor_strikeAI>(creature);
1126 }
1127};
1128
1130{
1131 public:
1132 npc_meteor_strike_flame() : CreatureScript("npc_meteor_strike_flame") { }
1133
1135 {
1137 _instance(creature->GetInstanceScript())
1138 {
1139 SetCombatMovement(false);
1140 }
1141
1142 void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
1143 {
1144 _rootOwnerGuid = guid;
1146 }
1147
1148 void IsSummonedBy(WorldObject* /*summoner*/) override
1149 {
1150 // Let Halion Controller count as summoner.
1152 controller->AI()->JustSummoned(me);
1153 }
1154
1155 void UpdateAI(uint32 diff) override
1156 {
1157 _events.Update(diff);
1159 return;
1160
1162
1164 if (!meteorStrike)
1165 return;
1166
1167 meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1);
1168 if (meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5)
1169 return;
1170
1171 Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
1173 flame->AI()->SetGUID(_rootOwnerGuid);
1174 }
1175
1176 void EnterEvadeMode(EvadeReason /*why*/) override { }
1177
1178 private:
1182 };
1183
1184 CreatureAI* GetAI(Creature* creature) const override
1185 {
1186 return GetRubySanctumAI<npc_meteor_strike_flameAI>(creature);
1187 }
1188};
1189
1191{
1192 public:
1193 npc_combustion_consumption() : CreatureScript("npc_combustion_consumption") { }
1194
1196 {
1198 _instance(creature->GetInstanceScript())
1199 {
1200 SetCombatMovement(false);
1201
1202 switch (creature->GetEntry())
1203 {
1204 case NPC_COMBUSTION:
1207 PhasingHandler::AddPhase(creature, DEFAULT_PHASE, false);
1208 if (IsHeroic())
1209 PhasingHandler::AddPhase(creature, 174, false);
1210 break;
1211 case NPC_CONSUMPTION:
1214 PhasingHandler::AddPhase(creature, 174, false);
1215 if (IsHeroic())
1216 PhasingHandler::AddPhase(creature, DEFAULT_PHASE, false);
1217 break;
1218 default: // Should never happen
1219 _explosionSpell = 0;
1220 _damageSpell = 0;
1221 break;
1222 }
1223 }
1224
1225 void IsSummonedBy(WorldObject* summoner) override
1226 {
1227 // Let Halion Controller count as summoner
1229 controller->AI()->JustSummoned(me);
1230
1231 _summonerGuid = summoner->GetGUID();
1232 }
1233
1234 void SetData(uint32 type, uint32 stackAmount) override
1235 {
1237
1238 if (type != DATA_STACKS_DISPELLED || !_damageSpell || !_explosionSpell || !summoner)
1239 return;
1240
1241 CastSpellExtraArgs args;
1242 args.AddSpellMod(SPELLVALUE_AURA_STACK, stackAmount + 1);
1245
1246 int32 damage = 1200 + (stackAmount * 1290); // Needs more research.
1247 CastSpellExtraArgs args2;
1248 args2.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
1249 summoner->CastSpell(summoner, _explosionSpell, args2);
1250 }
1251
1252 void UpdateAI(uint32 /*diff*/) override { }
1253
1254 private:
1259 };
1260
1261 CreatureAI* GetAI(Creature* creature) const override
1262 {
1263 return GetRubySanctumAI<npc_combustion_consumptionAI>(creature);
1264 }
1265};
1266
1268{
1269 public:
1270 npc_living_inferno() : CreatureScript("npc_living_inferno") { }
1271
1273 {
1274 npc_living_infernoAI(Creature* creature) : ScriptedAI(creature) { }
1275
1276 void IsSummonedBy(WorldObject* /*summoner*/) override
1277 {
1280
1281 // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs.
1283 scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/)
1284 {
1286 });
1287 if (InstanceScript* instance = me->GetInstanceScript())
1288 if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
1289 {
1290 controller->AI()->DoAction(ACTION_ACTIVATE_EMBERS);
1291 controller->AI()->JustSummoned(me);
1292 }
1293 }
1294
1295 void JustDied(Unit* /*killer*/) override
1296 {
1297 me->DespawnOrUnsummon(1ms);
1298 }
1299
1300 void UpdateAI(uint32 diff) override
1301 {
1302 scheduler.Update(diff);
1304 }
1305
1306 private:
1308 };
1309
1310 CreatureAI* GetAI(Creature* creature) const override
1311 {
1312 return GetRubySanctumAI<npc_living_infernoAI>(creature);
1313 }
1314};
1315
1317{
1318 public:
1319 npc_living_ember() : CreatureScript("npc_living_ember") { }
1320
1322 {
1323 npc_living_emberAI(Creature* creature) : ScriptedAI(creature) { }
1324
1325 void IsSummonedBy(WorldObject* /*summoner*/) override
1326 {
1327 if (InstanceScript* instance = me->GetInstanceScript())
1328 if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
1329 controller->AI()->JustSummoned(me);
1330 }
1331
1332 void JustDied(Unit* /*killer*/) override
1333 {
1334 me->DespawnOrUnsummon(1ms);
1335 }
1336 };
1337
1338 CreatureAI* GetAI(Creature* creature) const override
1339 {
1340 return GetRubySanctumAI<npc_living_emberAI>(creature);
1341 }
1342};
1343
1345{
1346 public:
1347 go_twilight_portal() : GameObjectScript("go_twilight_portal") { }
1348
1350 {
1352 _instance(gameobject->GetInstanceScript()), _deleted(false)
1353 {
1354 switch (gameobject->GetEntry())
1355 {
1357 PhasingHandler::AddPhase(gameobject, 174, false);
1358 _spellId = gameobject->GetGOInfo()->goober.spell;
1359 break;
1360 case GO_HALION_PORTAL_1:
1361 case GO_HALION_PORTAL_2:
1362 PhasingHandler::AddPhase(gameobject, DEFAULT_PHASE, false);
1365 break;
1366 default:
1367 _spellId = 0;
1368 break;
1369 }
1370 }
1371
1372 bool OnGossipHello(Player* player) override
1373 {
1374 if (_spellId != 0)
1375 player->CastSpell(player, _spellId, true);
1376 return true;
1377 }
1378
1379 void UpdateAI(uint32 /*diff*/) override
1380 {
1382 return;
1383
1384 if (!_deleted)
1385 {
1386 _deleted = true;
1387 me->Delete();
1388 }
1389 }
1390
1391 private:
1395 };
1396
1397 GameObjectAI* GetAI(GameObject* gameobject) const override
1398 {
1399 return GetRubySanctumAI<go_twilight_portalAI>(gameobject);
1400 }
1401};
1402
1403// 74641 - Meteor Strike
1405{
1406 public:
1407 spell_halion_meteor_strike_marker() : SpellScriptLoader("spell_halion_meteor_strike_marker") { }
1408
1410 {
1411 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1412 {
1413 if (!GetCaster())
1414 return;
1415
1416 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
1417 if (Creature* creCaster = GetCaster()->ToCreature())
1418 creCaster->AI()->DoAction(ACTION_METEOR_STRIKE_AOE);
1419 }
1420
1421 void Register() override
1422 {
1424 }
1425 };
1426
1427 AuraScript* GetAuraScript() const override
1428 {
1430 }
1431};
1432
1434{
1435 public:
1436 spell_halion_combustion_consumption(char const* scriptName, uint32 spell) : SpellScriptLoader(scriptName), _spellID(spell) { }
1437
1439 {
1440 public:
1442
1443 private:
1444 bool Validate(SpellInfo const* /*spellInfo*/) override
1445 {
1446 return ValidateSpellInfo({ _markSpell });
1447 }
1448
1449 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1450 {
1451 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
1452 return;
1453
1456 }
1457
1458 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1459 {
1461 }
1462
1463 void AddMarkStack(AuraEffect const* /*aurEff*/)
1464 {
1466 }
1467
1468 void Register() override
1469 {
1473 }
1474
1476 };
1477
1478 AuraScript* GetAuraScript() const override
1479 {
1481 }
1482
1483 private:
1485};
1486
1487// 74629 - Combustion Periodic
1488// 74803 - Consumption Periodic
1490{
1491 public:
1492 spell_halion_combustion_consumption_periodic() : SpellScriptLoader("spell_halion_combustion_consumption_periodic") { }
1493
1495 {
1496 bool Validate(SpellInfo const* spellInfo) override
1497 {
1498 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
1499 }
1500
1501 void HandleTick(AuraEffect const* aurEff)
1502 {
1504 Unit* caster = GetCaster();
1505 if (!caster)
1506 return;
1507
1508 uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
1509 int32 radius = caster->GetObjectScale() * M_PI * 10000 / 3;
1510
1511 CastSpellExtraArgs args(aurEff);
1512 args.OriginalCaster = caster->GetGUID();
1513 args.AddSpellMod(SPELLVALUE_RADIUS_MOD, radius);
1514 caster->CastSpell(nullptr, triggerSpell, args);
1515 }
1516
1517 void Register() override
1518 {
1520 }
1521 };
1522
1523 AuraScript* GetAuraScript() const override
1524 {
1526 }
1527};
1528
1530{
1531 public:
1532 spell_halion_marks(char const* scriptName, uint32 summonSpell, uint32 removeSpell) : SpellScriptLoader(scriptName),
1533 _summonSpell(summonSpell), _removeSpell(removeSpell) { }
1534
1536 {
1537 public:
1539 _summonSpellId(summonSpell), _removeSpellId(removeSpell) { }
1540
1541 private:
1542 bool Validate(SpellInfo const* /*spell*/) override
1543 {
1545 }
1546
1548 void BeforeDispel(DispelInfo* dispelData)
1549 {
1550 // Prevent any stack from being removed at this point.
1551 dispelData->SetRemovedCharges(0);
1552
1553 if (Unit* dispelledUnit = GetUnitOwner())
1554 if (dispelledUnit->HasAura(_removeSpellId))
1555 dispelledUnit->RemoveAurasDueToSpell(_removeSpellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
1556 }
1557
1558 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1559 {
1560 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
1561 return;
1562
1563 // Stacks marker
1568 }
1569
1570 void Register() override
1571 {
1574 }
1575
1578 };
1579
1580 AuraScript* GetAuraScript() const override
1581 {
1583 }
1584
1585 private:
1588};
1589
1590// 74610 - Fiery Combustion
1591// 74800 - Soul Consumption
1593{
1594 public:
1595 spell_halion_damage_aoe_summon() : SpellScriptLoader("spell_halion_damage_aoe_summon") { }
1596
1598 {
1600 {
1601 PreventHitDefaultEffect(effIndex);
1602 Unit* caster = GetCaster();
1603 uint32 entry = uint32(GetEffectInfo().MiscValue);
1604 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB));
1605 Milliseconds duration = Milliseconds(GetSpellInfo()->GetDuration());
1606
1607 Position pos = caster->GetPosition();
1608 if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id))
1609 if (summon->IsAIEnabled())
1610 summon->AI()->SetData(DATA_STACKS_DISPELLED, GetSpellValue()->EffectBasePoints[EFFECT_1]);
1611 }
1612
1613 void Register() override
1614 {
1616 }
1617 };
1618
1619 SpellScript* GetSpellScript() const override
1620 {
1622 }
1623};
1624
1626{
1627 public:
1628 spell_halion_twilight_realm_handlers(char const* scriptName, uint32 beforeHitSpell, bool isApplyHandler) : SpellScriptLoader(scriptName),
1629 _beforeHitSpell(beforeHitSpell), _isApplyHandler(isApplyHandler)
1630 { }
1631
1633 {
1634 public:
1636 _isApply(isApplyHandler), _beforeHitSpellId(beforeHitSpell)
1637 { }
1638
1639 private:
1640 bool Validate(SpellInfo const* /*spell*/) override
1641 {
1643 }
1644
1645 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1646 {
1648 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
1649 instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED, nullptr);
1650 }
1651
1652 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1653 {
1654 Unit* target = GetTarget();
1655 if (!target)
1656 return;
1657
1659 if (InstanceScript* instance = target->GetInstanceScript())
1660 instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED, nullptr);
1661 }
1662
1663 void Register() override
1664 {
1665 if (!_isApply)
1666 {
1669 }
1670 else
1672 }
1673
1676 };
1677
1678 AuraScript* GetAuraScript() const override
1679 {
1681 }
1682
1683 private:
1686};
1687
1688// 75396 - Clear Debuffs
1690{
1691 public:
1692 spell_halion_clear_debuffs() : SpellScriptLoader("spell_halion_clear_debuffs") { }
1693
1695 {
1696 bool Validate(SpellInfo const* /*spell*/) override
1697 {
1699 }
1700
1701 void HandleScript(SpellEffIndex /*effIndex*/)
1702 {
1703 if (GetHitUnit()->HasAura(GetEffectInfo().CalcValue()))
1705 }
1706
1707 void Register() override
1708 {
1710 }
1711 };
1712
1713 SpellScript* GetSpellScript() const override
1714 {
1716 }
1717};
1718
1720{
1721 public:
1722 TwilightCutterSelector(Unit* caster, Unit* target) : _caster(caster), _channelTarget(target) { }
1723
1725 {
1726 return !unit->IsInBetween(_caster, _channelTarget, 4.0f);
1727 }
1728
1729 private:
1732};
1733
1734// 74769, 77844, 77845, 77846 - Twilight Cutter
1736{
1737 public:
1738 spell_halion_twilight_cutter() : SpellScriptLoader("spell_halion_twilight_cutter") { }
1739
1741 {
1742 void RemoveNotBetween(std::list<WorldObject*>& unitList)
1743 {
1744 if (unitList.empty())
1745 return;
1746
1747 Unit* caster = GetCaster();
1748 auto const& channelObjects = caster->m_unitData->ChannelObjects;
1749 if (Unit* channelTarget = (channelObjects.size() == 1 ? ObjectAccessor::GetUnit(*caster, *channelObjects.begin()) : nullptr))
1750 {
1751 unitList.remove_if(TwilightCutterSelector(caster, channelTarget));
1752 return;
1753 }
1754
1755 // In case cutter caster werent found for some reason
1756 unitList.clear();
1757 }
1758
1759 void Register() override
1760 {
1762 }
1763 };
1764
1765 SpellScript* GetSpellScript() const override
1766 {
1768 }
1769};
1770
1771// 74808 - Twilight Phasing
1773{
1774 public:
1775 spell_halion_twilight_phasing() : SpellScriptLoader("spell_halion_twilight_phasing") { }
1776
1778 {
1779 bool Validate(SpellInfo const* /*spell*/) override
1780 {
1782 }
1783
1784 void Phase()
1785 {
1786 Unit* caster = GetCaster();
1787 caster->CastSpell(caster->GetPosition(), SPELL_SUMMON_TWILIGHT_PORTAL, true);
1789 }
1790
1791 void Register() override
1792 {
1794 }
1795 };
1796
1797 SpellScript* GetSpellScript() const override
1798 {
1800 }
1801};
1802
1803// 74805 - Summon Exit Portals
1805{
1806 public:
1807 spell_halion_summon_exit_portals() : SpellScriptLoader("spell_halion_summon_exit_portals") { }
1808
1810 {
1812 {
1813 Position const offset = { 0.0f, 20.0f, 0.0f, 0.0f };
1814 dest.RelocateOffset(offset);
1815 }
1816
1818 {
1819 Position const offset = { 0.0f, -20.0f, 0.0f, 0.0f };
1820 dest.RelocateOffset(offset);
1821 }
1822
1823 void Register() override
1824 {
1827 }
1828 };
1829
1830 SpellScript* GetSpellScript() const override
1831 {
1833 }
1834};
1835
1836// 75880 - Spawn Living Embers
1838{
1839 public:
1840 spell_halion_spawn_living_embers() : SpellScriptLoader("spell_halion_spawn_living_embers") { }
1841
1843 {
1844 void SelectMeteorFlames(std::list<WorldObject*>& unitList)
1845 {
1846 if (!unitList.empty())
1848 }
1849
1850 void HandleScript(SpellEffIndex /* effIndex */)
1851 {
1853 }
1854
1855 void Register() override
1856 {
1859 }
1860 };
1861
1862 SpellScript* GetSpellScript() const override
1863 {
1865 }
1866};
1867
1868// 75886, 75887 - Blazing Aura
1870{
1871 public:
1872 spell_halion_blazing_aura() : SpellScriptLoader("spell_halion_blazing_aura") { }
1873
1875 {
1877 {
1878 PreventHitDefaultEffect(effIndex);
1879 GetHitUnit()->CastSpell(GetHitUnit(), GetEffectInfo().TriggerSpell);
1880 }
1881
1882 void Register() override
1883 {
1885 }
1886 };
1887
1888 SpellScript* GetSpellScript() const override
1889 {
1891 }
1892};
1893
1895{
1896 new boss_halion();
1898
1902 new npc_meteor_strike();
1904 new npc_orb_carrier();
1905 new npc_living_inferno();
1906 new npc_living_ember();
1907
1908 new go_twilight_portal();
1909
1911 new spell_halion_combustion_consumption("spell_halion_soul_consumption", SPELL_MARK_OF_CONSUMPTION);
1912 new spell_halion_combustion_consumption("spell_halion_fiery_combustion", SPELL_MARK_OF_COMBUSTION);
1913 new spell_halion_marks("spell_halion_mark_of_combustion", SPELL_FIERY_COMBUSTION_SUMMON, SPELL_FIERY_COMBUSTION);
1914 new spell_halion_marks("spell_halion_mark_of_consumption", SPELL_SOUL_CONSUMPTION_SUMMON, SPELL_SOUL_CONSUMPTION);
1917 new spell_halion_twilight_realm_handlers("spell_halion_leave_twilight_realm", SPELL_SOUL_CONSUMPTION, false);
1918 new spell_halion_twilight_realm_handlers("spell_halion_enter_twilight_realm", SPELL_FIERY_COMBUSTION, true);
1925}
Texts
Actions
#define M_PI
Definition: Common.h:115
DB2Storage< SummonPropertiesEntry > sSummonPropertiesStore("SummonProperties.db2", &SummonPropertiesLoadInfo::Instance)
@ DIFFICULTY_25_HC
Definition: DBCEnums.h:880
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
#define ASSERT
Definition: Errors.h:68
@ IN_PROGRESS
@ FAIL
@ DONE
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED
@ ENCOUNTER_FRAME_ENGAGE
@ TEMPSUMMON_TIMED_DESPAWN
Definition: ObjectDefines.h:65
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
#define DEFAULT_PHASE
Definition: PhaseShift.h:31
Spells
Definition: PlayerAI.cpp:32
@ SPELL_BERSERK
Definition: PlayerAI.cpp:371
float frand(float min, float max)
Definition: Random.cpp:55
Milliseconds randtime(Milliseconds min, Milliseconds max)
Definition: Random.cpp:62
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_SRC_AREA_ENTRY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ TARGET_DEST_CASTER
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_FORCE_CAST
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_DEATH
@ AURA_REMOVE_BY_EXPIRE
@ AURA_REMOVE_BY_ENEMY_SPELL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PHASE
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ TRIGGERED_IGNORE_SET_FACING
Will not adjust facing to target (if any)
Definition: SpellDefines.h:256
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:231
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:197
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:229
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:196
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
#define SpellDestinationTargetSelectFn(F, I, N)
Definition: SpellScript.h:874
#define AuraEffectApplyFn(F, I, N, M)
Definition: SpellScript.h:2029
#define SpellHitFn(F)
Definition: SpellScript.h:854
#define AuraDispelFn(F)
Definition: SpellScript.h:2018
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2040
EvadeReason
Definition: UnitAICommon.h:30
#define CAST_AI(a, b)
Definition: UnitAI.h:28
@ REACT_DEFENSIVE
Definition: UnitDefines.h:507
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_FLAG_IN_COMBAT
Definition: UnitDefines.h:163
@ UNIT_STATE_CASTING
Definition: Unit.h:270
@ ACTION_METEOR_STRIKE_AOE
@ ACTION_ACTIVATE_EMBERS
@ ACTION_MONITOR_CORPOREALITY
@ ACTION_METEOR_STRIKE_BURN
@ ACTION_SHOOT
@ ACTION_WARNING_SHOOT
@ DATA_TWILIGHT_DAMAGE_TAKEN
@ DATA_MATERIAL_DAMAGE_TAKEN
@ DATA_FIGHT_PHASE
@ DATA_SPAWNED_FLAMES
@ DATA_STACKS_DISPELLED
@ SPELL_COSMETIC_FIRE_PILLAR
Definition: boss_halion.cpp:93
@ SPELL_CLEAVE
Definition: boss_halion.cpp:65
@ SPELL_METEOR_STRIKE_COUNTDOWN
Definition: boss_halion.cpp:98
@ SPELL_FIERY_COMBUSTION_SUMMON
Definition: boss_halion.cpp:72
@ SPELL_METEOR_STRIKE_FIRE_AURA_1
@ SPELL_TWILIGHT_PHASING
@ SPELL_DUSK_SHROUD
@ SPELL_SUMMON_TWILIGHT_PORTAL
@ SPELL_MARK_OF_COMBUSTION
Definition: boss_halion.cpp:70
@ SPELL_METEOR_STRIKE_AOE_DAMAGE
Definition: boss_halion.cpp:99
@ SPELL_DARK_BREATH
Definition: boss_halion.cpp:80
@ SPELL_TWILIGHT_DIVISION
@ SPELL_FLAME_BREATH
Definition: boss_halion.cpp:64
@ SPELL_TWILIGHT_CUTTER
@ SPELL_LEAVE_TWILIGHT_REALM
@ SPELL_TWILIGHT_PRECISION
@ SPELL_CLEAR_DEBUFFS
Definition: boss_halion.cpp:95
@ SPELL_COPY_DAMAGE
@ SPELL_SOUL_CONSUMPTION_SUMMON
Definition: boss_halion.cpp:85
@ SPELL_SOUL_CONSUMPTION
Definition: boss_halion.cpp:83
@ SPELL_TAIL_LASH
Definition: boss_halion.cpp:67
@ SPELL_SPAWN_LIVING_EMBERS
Definition: boss_halion.cpp:89
@ SPELL_SOUL_CONSUMPTION_EXPLOSION
Definition: boss_halion.cpp:84
@ SPELL_FIERY_COMBUSTION_EXPLOSION
Definition: boss_halion.cpp:71
@ SPELL_TWILIGHT_PULSE_PERIODIC
@ SPELL_TWILIGHT_MENDING
@ SPELL_BLAZING_AURA
Definition: boss_halion.cpp:88
@ SPELL_SUMMON_EXIT_PORTALS
@ SPELL_MARK_OF_CONSUMPTION
Definition: boss_halion.cpp:82
@ SPELL_METEOR_STRIKE
Definition: boss_halion.cpp:66
@ SPELL_TWILIGHT_CUTTER_TRIGGERED
@ SPELL_COMBUSTION_DAMAGE_AURA
Definition: boss_halion.cpp:76
@ SPELL_TRACK_ROTATION
@ SPELL_SUMMON_LIVING_EMBER
Definition: boss_halion.cpp:90
@ SPELL_FIERY_EXPLOSION
Definition: boss_halion.cpp:94
@ SPELL_SCALE_AURA
Definition: boss_halion.cpp:75
@ SPELL_CONSUMPTION_DAMAGE_AURA
Definition: boss_halion.cpp:77
@ SPELL_TWILIGHT_REALM
@ SPELL_FIERY_COMBUSTION
Definition: boss_halion.cpp:69
@ SPELL_BIRTH_NO_VISUAL
@ SPELL_METEOR_STRIKE_FIRE_AURA_2
@ PHASE_ONE
@ PHASE_INTRO
@ PHASE_ALL
@ PHASE_THREE
@ PHASE_TWO
boss_halion::boss_halionAI HalionAI
uint8 const MAX_CORPOREALITY_STATE
Position const HalionRespawnPos
CorporealityEntry const _corporealityReference[MAX_CORPOREALITY_STATE]
@ SAY_DEATH
Definition: boss_halion.cpp:46
@ EMOTE_WARN_LASER
Definition: boss_halion.cpp:58
@ SAY_AGGRO
Definition: boss_halion.cpp:43
@ SAY_SPHERE_PULSE
Definition: boss_halion.cpp:53
@ SAY_PHASE_TWO
Definition: boss_halion.cpp:45
@ SAY_KILL
Definition: boss_halion.cpp:47
@ EMOTE_CORPOREALITY_TOT
Definition: boss_halion.cpp:56
@ SAY_PHASE_THREE
Definition: boss_halion.cpp:54
@ EMOTE_CORPOREALITY_PIP
Definition: boss_halion.cpp:50
@ SAY_REGENERATE
Definition: boss_halion.cpp:39
@ SAY_METEOR_STRIKE
Definition: boss_halion.cpp:44
@ SAY_BERSERK
Definition: boss_halion.cpp:48
@ EMOTE_CORPOREALITY_POT
Definition: boss_halion.cpp:49
@ EMOTE_CORPOREALITY_TIT
Definition: boss_halion.cpp:55
@ SAY_INTRO
Definition: boss_halion.cpp:42
void AddSC_boss_halion()
Position const HalionSpawnPos
CorporealityEvent
@ CORPOREALITY_TWILIGHT_MENDING
@ CORPOREALITY_DECREASE
@ CORPOREALITY_INCREASE
@ CORPOREALITY_NONE
@ EVENT_SHADOW_PULSARS_SHOOT
@ EVENT_TWILIGHT_MENDING
@ EVENT_ACTIVATE_EMBERS
@ EVENT_SPAWN_METEOR_FLAME
@ EVENT_START_INTRO
@ EVENT_EVADE_CHECK
@ EVENT_ACTIVATE_FIREWALL
@ EVENT_TRIGGER_BERSERK
@ EVENT_FIERY_COMBUSTION
@ EVENT_INTRO_PROGRESS_1
@ EVENT_INTRO_PROGRESS_2
@ EVENT_TAIL_LASH
@ EVENT_CHECK_CORPOREALITY
@ EVENT_BREATH
@ EVENT_SOUL_CONSUMPTION
@ EVENT_CLEAVE
@ EVENT_INTRO_PROGRESS_3
@ EVENT_METEOR_STRIKE
OrbCarrierSeats
@ SEAT_NORTH
@ SEAT_WEST
@ SEAT_SOUTH
@ SEAT_EAST
SpellEffectInfo const & GetSpellEffectInfo() const
Aura * GetBase() const
void PreventDefaultAction()
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2039
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
HookList< EffectApplyHandler > AfterEffectApply
Definition: SpellScript.h:2028
Unit * GetCaster() const
Unit * GetTarget() const
ObjectGuid GetCasterGUID() const
HookList< AuraDispelHandler > OnDispel
Definition: SpellScript.h:2013
Unit * GetUnitOwner() const
uint8 GetStackAmount() const
Definition: SpellAuras.h:189
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
EventMap events
void _JustDied()
void DoZoneInCombat()
Definition: CreatureAI.h:161
virtual void JustSummoned(Creature *)
Definition: CreatureAI.h:111
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool IsInBoundary(Position const *who=nullptr) const
Definition: CreatureAI.cpp:426
bool UpdateVictim()
Definition: CreatureAI.cpp:245
void SetBoundary(CreatureBoundary const *boundary, bool negativeBoundaries=false)
Definition: CreatureAI.cpp:446
Creature *const me
Definition: CreatureAI.h:61
bool IsEngaged() const override
Definition: Creature.cpp:3601
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
CreatureAI * AI() const
Definition: Creature.h:214
void SetRemovedCharges(uint8 amount)
Definition: Unit.h:393
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Repeat(Milliseconds time)
Definition: EventMap.cpp:63
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool IsInPhase(uint8 phase) const
Definition: EventMap.h:217
void SetPhase(uint8 phase)
Definition: EventMap.cpp:28
void Reset()
Definition: EventMap.cpp:21
GameObject *const me
Definition: GameObjectAI.h:50
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:202
void Delete()
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
void HandleGameObject(ObjectGuid guid, bool open, GameObject *go=nullptr)
void DoUpdateWorldState(int32 worldStateId, int32 value)
virtual ObjectGuid GetGuidData(uint32 type) const override
CreatureBoundary const * GetBossBoundary(uint32 id) const
EncounterState GetBossState(uint32 id) const
void SendEncounterUnit(EncounterFrameType type, Unit const *unit, Optional< int32 > param1={}, Optional< int32 > param2={})
GameObject * GetGameObject(uint32 type)
iterator end()
Definition: MapRefManager.h:35
iterator begin()
Definition: MapRefManager.h:34
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, Milliseconds duration=0ms, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty, SmoothPhasingInfo const *smoothPhasingInfo=nullptr)
Definition: Object.cpp:1836
Difficulty GetDifficultyID() const
Definition: Map.h:324
PlayerList const & GetPlayers() const
Definition: Map.h:367
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
bool IsEmpty() const
Definition: ObjectGuid.h:319
static Creature * ToCreature(Object *o)
Definition: Object.h:219
float GetObjectScale() const
Definition: Object.h:164
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static void AddPhase(WorldObject *object, uint32 phaseId, bool updateVisibility)
uint32 TriggerSpell
Definition: SpellInfo.h:237
uint32 const Id
Definition: SpellInfo.h:325
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Definition: SpellScript.h:173
Unit * GetCaster() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
Definition: SpellScript.h:873
HookList< HitHandler > OnHit
Definition: SpellScript.h:850
HookList< EffectHandler > OnEffectHit
Definition: SpellScript.h:839
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
SpellValue const * GetSpellValue() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
SpellInfo const * GetSpellInfo() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
void Summon(Creature const *summon)
void DoZoneInCombat(uint32 entry=0)
TaskScheduler & Schedule(std::chrono::duration< Rep, Period > time, task_handler_t task)
TaskScheduler & Update(success_t const &callback=nullptr)
bool operator()(WorldObject *unit)
TwilightCutterSelector(Unit *caster, Unit *target)
virtual void SetData(uint32, uint32)
Definition: UnitAI.h:74
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
virtual uint32 GetData(uint32) const
Definition: UnitAI.h:73
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
Definition: Unit.h:627
void CastStop(uint32 except_spellid=0)
Definition: Unit.cpp:1135
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
UF::UpdateField< UF::UnitData, 0, TYPEID_UNIT > m_unitData
Definition: Unit.h:1814
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:11618
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
uint64 GetHealth() const
Definition: Unit.h:776
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition: Unit.h:781
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
Vehicle * GetVehicleKit() const
Definition: Unit.h:1711
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition: Unit.cpp:10591
Unit * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
Definition: Vehicle.cpp:291
bool InSamePhase(PhaseShift const &phaseShift) const
Definition: Object.h:527
Map * GetMap() const
Definition: Object.h:624
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition: Object.cpp:2025
void setActive(bool isActiveObject)
Definition: Object.cpp:922
Position GetNearPosition(float dist, float angle)
Definition: Object.cpp:3409
void SetFarVisible(bool on)
Definition: Object.cpp:973
bool IsInBetween(Position const &pos1, Position const &pos2, float size=0) const
Definition: Object.cpp:1304
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
GameObjectAI * GetAI(GameObject *gameobject) 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
SpellScript * GetSpellScript() const override
SpellScript * GetSpellScript() const override
AuraScript * GetAuraScript() const override
spell_halion_combustion_consumption(char const *scriptName, uint32 spell)
AuraScript * GetAuraScript() const override
SpellScript * GetSpellScript() const override
void BeforeDispel(DispelInfo *dispelData)
We were purged. Force removed stacks to zero and trigger the appropriated remove handler.
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
spell_halion_marks_AuraScript(uint32 summonSpell, uint32 removeSpell)
AuraScript * GetAuraScript() const override
spell_halion_marks(char const *scriptName, uint32 summonSpell, uint32 removeSpell)
AuraScript * GetAuraScript() const override
SpellScript * GetSpellScript() const override
SpellScript * GetSpellScript() const override
SpellScript * GetSpellScript() const override
SpellScript * GetSpellScript() const override
spell_halion_twilight_realm_handlers_AuraScript(uint32 beforeHitSpell, bool isApplyHandler)
AuraScript * GetAuraScript() const override
spell_halion_twilight_realm_handlers(char const *scriptName, uint32 beforeHitSpell, bool isApplyHandler)
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:67
@ DATA_HALION_CONTROLLER
Definition: ruby_sanctum.h:43
@ DATA_TWILIGHT_FLAME_RING
Definition: ruby_sanctum.h:51
@ DATA_BURNING_TREE_1
Definition: ruby_sanctum.h:46
@ DATA_GENERAL_ZARITHRIAN
Definition: ruby_sanctum.h:32
@ DATA_BURNING_TREE_2
Definition: ruby_sanctum.h:47
@ DATA_BURNING_TREE_3
Definition: ruby_sanctum.h:48
@ DATA_BURNING_TREE_4
Definition: ruby_sanctum.h:49
@ DATA_ORB_CARRIER
Definition: ruby_sanctum.h:44
@ DATA_TWILIGHT_HALION
Definition: ruby_sanctum.h:37
@ DATA_FLAME_RING
Definition: ruby_sanctum.h:50
@ DATA_HALION
Definition: ruby_sanctum.h:34
@ WORLDSTATE_CORPOREALITY_TOGGLE
Definition: ruby_sanctum.h:124
@ WORLDSTATE_CORPOREALITY_MATERIAL
Definition: ruby_sanctum.h:122
@ WORLDSTATE_CORPOREALITY_TWILIGHT
Definition: ruby_sanctum.h:123
@ GO_HALION_PORTAL_1
Definition: ruby_sanctum.h:107
@ GO_HALION_PORTAL_EXIT
Definition: ruby_sanctum.h:109
@ GO_HALION_PORTAL_2
Definition: ruby_sanctum.h:108
@ NPC_METEOR_STRIKE_NORTH
Definition: ruby_sanctum.h:92
@ NPC_HALION
Definition: ruby_sanctum.h:80
@ NPC_TWILIGHT_HALION
Definition: ruby_sanctum.h:81
@ NPC_CONSUMPTION
Definition: ruby_sanctum.h:98
@ NPC_METEOR_STRIKE_FLAME
Definition: ruby_sanctum.h:96
@ NPC_LIVING_EMBER
Definition: ruby_sanctum.h:84
@ NPC_COMBUSTION
Definition: ruby_sanctum.h:97
@ ACTION_INTRO_HALION_2
Definition: ruby_sanctum.h:61
@ ACTION_INTRO_HALION
Definition: ruby_sanctum.h:60
CastSpellExtraArgs & SetOriginalCaster(ObjectGuid const &guid)
Definition: SpellDefines.h:471
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
Definition: SpellDefines.h:474
ObjectGuid OriginalCaster
Definition: SpellDefines.h:482
struct GameObjectTemplate::@213::@225 goober
constexpr void SetOrientation(float orientation)
Definition: Position.h:71
static float NormalizeOrientation(float o)
Definition: Position.cpp:135
float GetAbsoluteAngle(float x, float y) const
Definition: Position.h:125
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
bool IsHeroic() const
void SetCombatMovement(bool allowMovement)
virtual void UpdateAI(uint32 diff) override
void RelocateOffset(Position const &offset)
Definition: Spell.cpp:122
void JustEngagedWith(Unit *who) override
void EnterEvadeMode(EvadeReason why) override
boss_halionAI(Creature *creature)
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void JustDied(Unit *) override
void DamageTaken(Unit *attacker, uint32 &damage, DamageEffectType, SpellInfo const *) override
void UpdateAI(uint32 diff) override
Position const * GetMeteorStrikePosition() const
void SetData(uint32 index, uint32 value) override
void KilledUnit(Unit *victim) override
void DamageTaken(Unit *attacker, uint32 &damage, DamageEffectType, SpellInfo const *) override
void EnterEvadeMode(EvadeReason) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
go_twilight_portalAI(GameObject *gameobject)
bool OnGossipHello(Player *player) override
void SetData(uint32 type, uint32 stackAmount) override
void IsSummonedBy(WorldObject *summoner) override
void SetData(uint32 id, uint32 value) override
uint32 GetSpell(uint8 pctValue, bool isTwilight=false) const
void JustSummoned(Creature *who) override
void IsSummonedBy(WorldObject *) override
void IsSummonedBy(WorldObject *) override
void UpdateAI(uint32 diff) override
void SetData(uint32 dataType, uint32 dataCount) override
void DoAction(int32 action) override
void IsSummonedBy(WorldObject *) override
uint32 GetData(uint32 dataType) const override
void UpdateAI(uint32 diff) override
void SetGUID(ObjectGuid const &guid, int32) override
void IsSummonedBy(WorldObject *summoner) override
npc_orb_carrierAI(Creature *creature)
void DoAction(int32 action) override
void TriggerCutter(Unit *caster, Unit *target)
void UpdateAI(uint32 diff) override