TrinityCore
Loading...
Searching...
No Matches
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
151
153{
154 // Meteor Strike
157
158 // Halion Controller
160
161 // Orb Carrier
166
175
185
193
201
202Position const HalionSpawnPos = {3156.67f, 533.8108f, 72.98822f, 3.159046f};
203Position const HalionRespawnPos = {3156.625f, 533.2674f, 72.97205f, 0.0f};
204
206
212
214{
215 {74836, 74831},
216 {74835, 74830},
217 {74834, 74829},
218 {74833, 74828},
219 {74832, 74827},
220 {74826, 74826},
221 {74827, 74832},
222 {74828, 74833},
223 {74829, 74834},
224 {74830, 74835},
225 {74831, 74836}
226};
227
229{
230 public:
231 boss_halion() : CreatureScript("boss_halion") { }
232
233 struct boss_halionAI : public BossAI
234 {
235 boss_halionAI(Creature* creature) : BossAI(creature, DATA_HALION) { }
236
237 void EnterEvadeMode(EvadeReason why) override
238 {
241 controller->AI()->EnterEvadeMode(why);
242 }
243
265
266 void JustDied(Unit* /*killer*/) override
267 {
268 _JustDied();
269
272
273 if (Creature* twilightHalion = instance->GetCreature(DATA_TWILIGHT_HALION))
274 if (twilightHalion->IsAlive())
275 twilightHalion->KillSelf();
276
278 if (controller->IsAlive())
279 controller->KillSelf();
280 }
281
283
284 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
285 {
286 if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
287 damage = me->GetHealth() - 1;
288
290 {
293
294 me->CastStop();
295 me->SetUninteractible(true);
297
299 controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_TWO);
300 return;
301 }
302
304 {
305 // Don't consider copied damage.
306 if (!attacker || !me->InSamePhase(attacker))
307 return;
308
310 controller->AI()->SetData(DATA_MATERIAL_DAMAGE_TAKEN, damage);
311 }
312 }
313
314 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
315 {
316 if (spellInfo->Id == SPELL_TWILIGHT_MENDING)
318 }
319
320 void UpdateAI(uint32 diff) override
321 {
323 return;
324
325 if (!UpdateVictim())
326 return;
327
328 events.Update(diff);
329
331 return;
332
333 while (uint32 eventId = events.ExecuteEvent())
334 {
335 switch (eventId)
336 {
337 case EVENT_CLEAVE:
340 break;
341 case EVENT_TAIL_LASH:
344 break;
345 case EVENT_BREATH:
348 break;
350 // Flame ring is activated 5 seconds after starting encounter, EncounterStateForOpenDoor::NotInProgress is only instant.
352 if (GameObject* flameRing = instance->GetGameObject(i))
353 instance->HandleGameObject(ObjectGuid::Empty, false, flameRing);
354 break;
356 {
357 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
358 {
359 _meteorStrikePos = target->GetPosition();
361 .SetOriginalCaster(me->GetGUID()));
363 }
365 break;
366 }
368 {
369 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
372 break;
373 }
374 default:
375 break;
376 }
377 }
378 }
379
380 void SetData(uint32 index, uint32 value) override
381 {
382 if (index != DATA_FIGHT_PHASE)
383 return;
384
385 events.SetPhase(value);
386 }
387
388 private:
390 };
391
392 CreatureAI* GetAI(Creature* creature) const override
393 {
394 return GetRubySanctumAI<boss_halionAI>(creature);
395 }
396};
397
399
401{
402 public:
403 boss_twilight_halion() : CreatureScript("boss_twilight_halion") { }
404
406 {
408 {
410 if (!halion)
411 return;
412
413 // Using AddAura because no spell cast packet in sniffs.
414 halion->AddAura(SPELL_COPY_DAMAGE, me); // We use explicit targeting here to avoid conditions + SPELL_ATTR6_CANT_TARGET_SELF.
415 me->AddAura(SPELL_COPY_DAMAGE, halion);
417
418 me->SetHealth(halion->GetHealth());
419 PhasingHandler::AddPhase(me, 174, false);
424 }
425
437
438 void Reset() override { }
439 void EnterEvadeMode(EvadeReason /*why*/) override { }
440
441 void KilledUnit(Unit* victim) override
442 {
443 if (victim->GetTypeId() == TYPEID_PLAYER)
444 Talk(SAY_KILL);
445
446 // Victims should not be in the Twilight Realm
448 }
449
450 void JustDied(Unit* killer) override
451 {
453 {
454 // Ensure looting
455 halion->LowerPlayerDamageReq(halion->GetMaxHealth());
456
457 if (halion->IsAlive())
458 Unit::Kill(killer, halion);
459 }
460
462 if (controller->IsAlive())
463 controller->KillSelf();
464
466 }
467
468 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
469 {
470 if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
471 damage = me->GetHealth() - 1;
472 //Needed because we already have UNIT_FLAG_IN_COMBAT, otherwise JustEngagedWith won't ever be called
474 JustEngagedWith(attacker);
475
477 {
479 me->CastStop();
482 return;
483 }
484
486 {
487 // Don't consider copied damage.
488 if (!attacker || !me->InSamePhase(attacker))
489 return;
490
492 controller->AI()->SetData(DATA_TWILIGHT_DAMAGE_TAKEN, damage);
493 }
494 }
495
496 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
497 {
498 switch (spellInfo->Id)
499 {
502 controller->AI()->DoAction(ACTION_MONITOR_CORPOREALITY);
503 break;
506 break;
507 default:
508 break;
509 }
510 }
511
512 void UpdateAI(uint32 diff) override
513 {
515 return;
516
517 if (!UpdateVictim())
518 return;
519
520 events.Update(diff);
521
522 while (uint32 eventId = events.ExecuteEvent())
523 {
524 switch (eventId)
525 {
526 case EVENT_CLEAVE:
529 break;
530 case EVENT_TAIL_LASH:
533 break;
534 case EVENT_BREATH:
537 break;
539 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, SPELL_TWILIGHT_REALM))
542 break;
543 default:
544 break;
545 }
546 }
547 }
548 };
549
550 CreatureAI* GetAI(Creature* creature) const override
551 {
552 return GetRubySanctumAI<boss_twilight_halionAI>(creature);
553 }
554};
555
557{
558 public:
559 npc_halion_controller() : CreatureScript("npc_halion_controller") { }
560
562 {
564 _instance(creature->GetInstanceScript()), _summons(me)
565 {
566 Initialize();
567 }
568
576
585
586 void Reset() override
587 {
589 _events.Reset();
590 Initialize();
591
593 }
594
595 void JustSummoned(Creature* who) override
596 {
597 _summons.Summon(who);
598 }
599
600 void JustDied(Unit* /*killer*/) override
601 {
602 _events.Reset();
604
606 }
607
616
617 void JustExitedCombat() override
618 {
620 return;
621
622 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
623 {
624 twilightHalion->DespawnOrUnsummon();
626 }
627
629 {
630 halion->DespawnOrUnsummon();
632 }
633
636
637 me->DespawnOrUnsummon(0s, 30s);
638 }
639
640 void DoAction(int32 action) override
641 {
642 switch (action)
643 {
645 _events.Reset();
648 break;
651 return;
652
654 if (GameObject* tree = _instance->GetGameObject(i))
657 break;
659 {
660 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
661 {
662 Creature* halion = _instance->GetCreature(itr);
663 if (!halion)
664 continue;
665
666 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), false);
668
669 if (itr == DATA_TWILIGHT_HALION)
670 continue;
671
673 halion->SetUninteractible(false);
674 }
675
676 // Summon Twilight portals
678
680 // Hardcoding doesn't really matter here.
683
685 break;
686 }
689 break;
690 default:
691 break;
692 }
693 }
694
695 void UpdateAI(uint32 diff) override
696 {
697 // The IsEngaged() check is needed because that check should be false when Halion is
698 // not engaged, while it would return true without as UpdateVictim() checks for
699 // combat state.
700 if (me->IsEngaged() && !UpdateVictim())
701 return;
702
703 _events.Update(diff);
704
705 while (uint32 eventId = _events.ExecuteEvent())
706 {
707 switch (eventId)
708 {
712 break;
715 if (GameObject* tree = _instance->GetGameObject(i))
718 break;
721 if (GameObject* tree = _instance->GetGameObject(i))
724 break;
728 return;
730 halion->AI()->Talk(SAY_INTRO);
731 break;
733 if (_instance->GetCreature(DATA_HALION)) // Just check if physical Halion is spawned
734 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
735 twilightHalion->CastSpell(nullptr, SPELL_TWILIGHT_MENDING, true);
736 break;
739 halion->CastSpell(halion, SPELL_BERSERK, true);
741 halion->CastSpell(halion, SPELL_BERSERK, true);
742 break;
745 orbCarrier->AI()->DoAction(ACTION_WARNING_SHOOT);
747 break;
751 break;
754 break;
756 DoCheckEvade();
758 break;
759 default:
760 break;
761 }
762 }
763 }
764
766 {
767 Map::PlayerList const& players = me->GetMap()->GetPlayers();
768 for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
769 if (Player* player = i->GetSource())
770 if (player->IsAlive() && IsInBoundary(player) && !player->IsGameMaster())
771 return;
772
774 }
775
776 void SetData(uint32 id, uint32 value) override
777 {
778 switch (id)
779 {
781 _materialDamageTaken += value;
782 break;
784 _twilightDamageTaken += value;
785 break;
786 case DATA_FIGHT_PHASE:
787 _events.SetPhase(value);
788 switch (value)
789 {
790 case PHASE_ONE:
792 break;
793 case PHASE_TWO:
795 break;
796 default:
797 break;
798 }
799 break;
800 default:
801 break;
802 }
803 }
804
805 private:
807 // [0 , 0.98[: Corporeality goes down
808 // [0.98, 0.99]: Do nothing
809 // ]0.99, 1.01[: Twilight Mending
810 // [1.01, 1.02]: Do nothing
811 // ]1.02, +oo [: Corporeality goes up
813 {
816 {
820 return;
821 }
822
823 float damageRatio = float(_materialDamageTaken) / float(_twilightDamageTaken);
824
826 if (damageRatio < 0.98f) // [0 , 0.98[: Corporeality goes down
827 action = CORPOREALITY_DECREASE;
828 else if (0.99f < damageRatio && damageRatio < 1.01f) // ]0.99, 1.01[: Twilight Mending
830 else if (1.02f < damageRatio) // ]1.02, +oo [: Corporeality goes up
831 action = CORPOREALITY_INCREASE;
832
833 switch (action)
834 {
836 {
839 return;
840 }
842 {
844 return;
846 break;
847 }
849 {
851 return;
853 break;
854 }
856 {
860 return;
861 }
862 }
863
866
869
870 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
871 {
872 if (Creature* halion = _instance->GetCreature(itr))
873 {
874 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), true);
875
876 if (itr == DATA_TWILIGHT_HALION)
877 halion->AI()->Talk(oldValue < _materialCorporealityValue ? EMOTE_CORPOREALITY_TOT : EMOTE_CORPOREALITY_TIT, halion);
878 else // if (itr == DATA_HALION)
879 halion->AI()->Talk(oldValue > _materialCorporealityValue ? EMOTE_CORPOREALITY_POT : EMOTE_CORPOREALITY_PIP, halion);
880 }
881 }
882 }
883
884 uint32 GetSpell(uint8 pctValue, bool isTwilight = false) const
885 {
887 return isTwilight ? entry.twilightRealmSpell : entry.materialRealmSpell;
888 }
889
893
897 };
898
899 CreatureAI* GetAI(Creature* creature) const override
900 {
901 return GetRubySanctumAI<npc_halion_controllerAI>(creature);
902 }
903};
904
906{
907 public:
908 npc_orb_carrier() : CreatureScript("npc_orb_carrier") { }
909
911 {
912 npc_orb_carrierAI(Creature* creature) : ScriptedAI(creature),
913 _instance(creature->GetInstanceScript())
914 {
915 ASSERT(creature->GetVehicleKit());
916 }
917
918 void UpdateAI(uint32 diff) override
919 {
924 me->CastSpell(nullptr, SPELL_TRACK_ROTATION, false);
925
926 scheduler.Update(diff);
927 }
928
929 void DoAction(int32 action) override
930 {
931 switch (action)
932 {
934 {
935 Vehicle* vehicle = me->GetVehicleKit();
936 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
937 if (northOrb && northOrb->GetTypeId() == TYPEID_UNIT)
938 northOrb->ToCreature()->AI()->Talk(EMOTE_WARN_LASER);
939
940 scheduler.Schedule(Seconds(5), [this](TaskContext const& /*context*/)
941 {
943 });
944 break;
945 }
946 case ACTION_SHOOT:
947 {
948 Vehicle* vehicle = me->GetVehicleKit();
949 Unit* southOrb = vehicle->GetPassenger(SEAT_SOUTH);
950 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
951 if (southOrb && northOrb)
952 TriggerCutter(northOrb, southOrb);
953
954 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
955 twilightHalion->AI()->Talk(SAY_SPHERE_PULSE);
956
957 if (!IsHeroic())
958 return;
959
960 Unit* eastOrb = vehicle->GetPassenger(SEAT_EAST);
961 Unit* westOrb = vehicle->GetPassenger(SEAT_WEST);
962 if (eastOrb && westOrb)
963 TriggerCutter(eastOrb, westOrb);
964 break;
965 }
966 default:
967 break;
968 }
969 }
970 private:
973
974 void TriggerCutter(Unit* caster, Unit* target)
975 {
976 caster->CastSpell(caster, SPELL_TWILIGHT_PULSE_PERIODIC, true);
977 target->CastSpell(target, SPELL_TWILIGHT_PULSE_PERIODIC, true);
978 caster->CastSpell(target, SPELL_TWILIGHT_CUTTER, false);
979 }
980 };
981
982 CreatureAI* GetAI(Creature* creature) const override
983 {
984 return GetRubySanctumAI<npc_orb_carrierAI>(creature);
985 }
986};
987
989{
990 public:
991 npc_meteor_strike_initial() : CreatureScript("npc_meteor_strike_initial") { }
992
994 {
996 _instance(creature->GetInstanceScript())
997 {
998 SetCombatMovement(false);
999 }
1000
1001 void DoAction(int32 action) override
1002 {
1003 switch (action)
1004 {
1008 for (std::list<Creature*>::iterator itr = _meteorList.begin(); itr != _meteorList.end(); ++itr)
1009 (*itr)->AI()->DoAction(ACTION_METEOR_STRIKE_BURN);
1010 break;
1011 }
1012 }
1013
1014 void IsSummonedBy(WorldObject* summoner) override
1015 {
1016 Creature* owner = summoner->ToCreature();
1017 if (!owner)
1018 return;
1019
1020 // Let Controller count as summoner
1022 controller->AI()->JustSummoned(me);
1023
1026
1027 if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
1028 {
1029 Position const* ownerPos = halionAI->GetMeteorStrikePosition();
1030 float randomAdjustment = frand(static_cast<float>(M_PI / 5.0f), static_cast<float>(M_PI / 2.0f));
1031 float angle[4];
1032 angle[0] = me->GetAbsoluteAngle(ownerPos);
1033 angle[1] = angle[0] + randomAdjustment;
1034 angle[2] = angle[0] + static_cast<float>(M_PI);
1035 angle[3] = angle[2] + randomAdjustment;
1036
1037 _meteorList.clear();
1038 for (uint8 i = 0; i < 4; i++)
1039 {
1040 angle[i] = Position::NormalizeOrientation(angle[i]);
1041 me->SetOrientation(angle[i]);
1042 Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance
1044 _meteorList.push_back(meteor);
1045 }
1046 }
1047 }
1048
1049 void UpdateAI(uint32 /*diff*/) override { }
1050 void EnterEvadeMode(EvadeReason /*why*/) override { }
1051 private:
1053 std::list<Creature*> _meteorList;
1054 };
1055
1056 CreatureAI* GetAI(Creature* creature) const override
1057 {
1058 return GetRubySanctumAI<npc_meteor_strike_initialAI>(creature);
1059 }
1060};
1061
1063{
1064 public:
1065 npc_meteor_strike() : CreatureScript("npc_meteor_strike") { }
1066
1068 {
1070 _instance(creature->GetInstanceScript()), _spawnCount(0)
1071 {
1072 SetCombatMovement(false);
1073 }
1074
1075 void DoAction(int32 action) override
1076 {
1077 if (action == ACTION_METEOR_STRIKE_BURN)
1078 {
1080 me->setActive(true);
1081 me->SetFarVisible(true);
1083 }
1084 }
1085
1086 void IsSummonedBy(WorldObject* /*summoner*/) override
1087 {
1088 // Let Halion Controller count as summoner.
1090 controller->AI()->JustSummoned(me);
1091 }
1092
1093 void SetData(uint32 dataType, uint32 dataCount) override
1094 {
1095 if (dataType == DATA_SPAWNED_FLAMES)
1096 _spawnCount += dataCount;
1097 }
1098
1099 uint32 GetData(uint32 dataType) const override
1100 {
1101 if (dataType == DATA_SPAWNED_FLAMES)
1102 return _spawnCount;
1103 return 0;
1104 }
1105
1106 void UpdateAI(uint32 diff) override
1107 {
1108 _events.Update(diff);
1109
1111 {
1112 Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
1114 flame->AI()->SetGUID(me->GetGUID(), DATA_ROOT_GUID);
1115 }
1116 }
1117
1118 private:
1122 };
1123
1124 CreatureAI* GetAI(Creature* creature) const override
1125 {
1126 return GetRubySanctumAI<npc_meteor_strikeAI>(creature);
1127 }
1128};
1129
1131{
1132 public:
1133 npc_meteor_strike_flame() : CreatureScript("npc_meteor_strike_flame") { }
1134
1136 {
1138 _instance(creature->GetInstanceScript())
1139 {
1140 SetCombatMovement(false);
1141 }
1142
1143 void SetGUID(ObjectGuid const& guid, int32 id) override
1144 {
1145 if (id != DATA_ROOT_GUID)
1146 return;
1147
1148 _rootOwnerGuid = guid;
1150 }
1151
1152 void IsSummonedBy(WorldObject* /*summoner*/) override
1153 {
1154 // Let Halion Controller count as summoner.
1156 controller->AI()->JustSummoned(me);
1157 }
1158
1159 void UpdateAI(uint32 diff) override
1160 {
1161 _events.Update(diff);
1163 return;
1164
1166
1168 if (!meteorStrike)
1169 return;
1170
1171 meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1);
1172 if (meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5)
1173 return;
1174
1175 Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
1177 flame->AI()->SetGUID(_rootOwnerGuid, DATA_ROOT_GUID);
1178 }
1179
1180 void EnterEvadeMode(EvadeReason /*why*/) override { }
1181
1182 private:
1186 };
1187
1188 CreatureAI* GetAI(Creature* creature) const override
1189 {
1190 return GetRubySanctumAI<npc_meteor_strike_flameAI>(creature);
1191 }
1192};
1193
1195{
1196 public:
1197 npc_combustion_consumption() : CreatureScript("npc_combustion_consumption") { }
1198
1200 {
1202 _instance(creature->GetInstanceScript())
1203 {
1204 SetCombatMovement(false);
1205
1206 switch (creature->GetEntry())
1207 {
1208 case NPC_COMBUSTION:
1211 PhasingHandler::AddPhase(creature, DEFAULT_PHASE, false);
1212 if (IsHeroic())
1213 PhasingHandler::AddPhase(creature, 174, false);
1214 break;
1215 case NPC_CONSUMPTION:
1218 PhasingHandler::AddPhase(creature, 174, false);
1219 if (IsHeroic())
1220 PhasingHandler::AddPhase(creature, DEFAULT_PHASE, false);
1221 break;
1222 default: // Should never happen
1223 _explosionSpell = 0;
1224 _damageSpell = 0;
1225 break;
1226 }
1227 }
1228
1229 void IsSummonedBy(WorldObject* summoner) override
1230 {
1231 // Let Halion Controller count as summoner
1233 controller->AI()->JustSummoned(me);
1234
1235 _summonerGuid = summoner->GetGUID();
1236 }
1237
1238 void SetData(uint32 type, uint32 stackAmount) override
1239 {
1241
1242 if (type != DATA_STACKS_DISPELLED || !_damageSpell || !_explosionSpell || !summoner)
1243 return;
1244
1245 CastSpellExtraArgs args;
1246 args.AddSpellMod(SPELLVALUE_AURA_STACK, stackAmount + 1);
1249
1250 int32 damage = 1200 + (stackAmount * 1290); // Needs more research.
1251 CastSpellExtraArgs args2;
1252 args2.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
1253 summoner->CastSpell(summoner, _explosionSpell, args2);
1254 }
1255
1256 void UpdateAI(uint32 /*diff*/) override { }
1257
1258 private:
1263 };
1264
1265 CreatureAI* GetAI(Creature* creature) const override
1266 {
1267 return GetRubySanctumAI<npc_combustion_consumptionAI>(creature);
1268 }
1269};
1270
1272{
1273 public:
1274 npc_living_inferno() : CreatureScript("npc_living_inferno") { }
1275
1277 {
1278 npc_living_infernoAI(Creature* creature) : ScriptedAI(creature) { }
1279
1280 void IsSummonedBy(WorldObject* /*summoner*/) override
1281 {
1284
1285 // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs.
1287 scheduler.Schedule(Seconds(3), [this](TaskContext const& /*context*/)
1288 {
1290 });
1291 if (InstanceScript* instance = me->GetInstanceScript())
1292 if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
1293 {
1294 controller->AI()->DoAction(ACTION_ACTIVATE_EMBERS);
1295 controller->AI()->JustSummoned(me);
1296 }
1297 }
1298
1299 void JustDied(Unit* /*killer*/) override
1300 {
1301 me->DespawnOrUnsummon(1ms);
1302 }
1303
1304 void UpdateAI(uint32 diff) override
1305 {
1306 scheduler.Update(diff);
1308 }
1309
1310 private:
1312 };
1313
1314 CreatureAI* GetAI(Creature* creature) const override
1315 {
1316 return GetRubySanctumAI<npc_living_infernoAI>(creature);
1317 }
1318};
1319
1321{
1322 public:
1323 npc_living_ember() : CreatureScript("npc_living_ember") { }
1324
1326 {
1327 npc_living_emberAI(Creature* creature) : ScriptedAI(creature) { }
1328
1329 void IsSummonedBy(WorldObject* /*summoner*/) override
1330 {
1331 if (InstanceScript* instance = me->GetInstanceScript())
1332 if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
1333 controller->AI()->JustSummoned(me);
1334 }
1335
1336 void JustDied(Unit* /*killer*/) override
1337 {
1338 me->DespawnOrUnsummon(1ms);
1339 }
1340 };
1341
1342 CreatureAI* GetAI(Creature* creature) const override
1343 {
1344 return GetRubySanctumAI<npc_living_emberAI>(creature);
1345 }
1346};
1347
1349{
1350 public:
1351 go_twilight_portal() : GameObjectScript("go_twilight_portal") { }
1352
1354 {
1356 _instance(gameobject->GetInstanceScript()), _deleted(false)
1357 {
1358 switch (gameobject->GetEntry())
1359 {
1361 PhasingHandler::AddPhase(gameobject, 174, false);
1362 _spellId = gameobject->GetGOInfo()->goober.spell;
1363 break;
1364 case GO_HALION_PORTAL_1:
1365 case GO_HALION_PORTAL_2:
1366 PhasingHandler::AddPhase(gameobject, DEFAULT_PHASE, false);
1369 break;
1370 default:
1371 _spellId = 0;
1372 break;
1373 }
1374 }
1375
1376 bool OnGossipHello(Player* player) override
1377 {
1378 if (_spellId != 0)
1379 player->CastSpell(player, _spellId, true);
1380 return true;
1381 }
1382
1383 void UpdateAI(uint32 /*diff*/) override
1384 {
1386 return;
1387
1388 if (!_deleted)
1389 {
1390 _deleted = true;
1391 me->Delete();
1392 }
1393 }
1394
1395 private:
1399 };
1400
1401 GameObjectAI* GetAI(GameObject* gameobject) const override
1402 {
1403 return GetRubySanctumAI<go_twilight_portalAI>(gameobject);
1404 }
1405};
1406
1407// 74641 - Meteor Strike
1409{
1410 public:
1411 spell_halion_meteor_strike_marker() : SpellScriptLoader("spell_halion_meteor_strike_marker") { }
1412
1414 {
1415 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1416 {
1417 if (!GetCaster())
1418 return;
1419
1420 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
1421 if (Creature* creCaster = GetCaster()->ToCreature())
1422 creCaster->AI()->DoAction(ACTION_METEOR_STRIKE_AOE);
1423 }
1424
1429 };
1430
1431 AuraScript* GetAuraScript() const override
1432 {
1434 }
1435};
1436
1438{
1439 public:
1440 spell_halion_combustion_consumption(char const* scriptName, uint32 spell) : SpellScriptLoader(scriptName), _spellID(spell) { }
1441
1443 {
1444 public:
1446
1447 private:
1448 bool Validate(SpellInfo const* /*spellInfo*/) override
1449 {
1450 return ValidateSpellInfo({ _markSpell });
1451 }
1452
1453 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1454 {
1455 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
1456 return;
1457
1460 }
1461
1462 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1463 {
1465 }
1466
1467 void AddMarkStack(AuraEffect const* /*aurEff*/)
1468 {
1470 }
1471
1478
1480 };
1481
1482 AuraScript* GetAuraScript() const override
1483 {
1485 }
1486
1487 private:
1489};
1490
1491// 74629 - Combustion Periodic
1492// 74803 - Consumption Periodic
1494{
1495 public:
1496 spell_halion_combustion_consumption_periodic() : SpellScriptLoader("spell_halion_combustion_consumption_periodic") { }
1497
1499 {
1500 bool Validate(SpellInfo const* spellInfo) override
1501 {
1502 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
1503 }
1504
1505 void HandleTick(AuraEffect const* aurEff)
1506 {
1508 Unit* caster = GetCaster();
1509 if (!caster)
1510 return;
1511
1512 uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
1513 float radius = caster->GetObjectScale() * M_PI / 3;
1514
1515 CastSpellExtraArgs args(aurEff);
1516 args.OriginalCaster = caster->GetGUID();
1517 args.AddSpellMod(SPELLVALUE_RADIUS_MOD, radius);
1518 caster->CastSpell(nullptr, triggerSpell, args);
1519 }
1520
1525 };
1526
1531};
1532
1534{
1535 public:
1536 spell_halion_marks(char const* scriptName, uint32 summonSpell, uint32 removeSpell) : SpellScriptLoader(scriptName),
1537 _summonSpell(summonSpell), _removeSpell(removeSpell) { }
1538
1540 {
1541 public:
1543 _summonSpellId(summonSpell), _removeSpellId(removeSpell) { }
1544
1545 private:
1546 bool Validate(SpellInfo const* /*spell*/) override
1547 {
1549 }
1550
1552 void BeforeDispel(DispelInfo* dispelData)
1553 {
1554 // Prevent any stack from being removed at this point.
1555 dispelData->SetRemovedCharges(0);
1556
1557 if (Unit* dispelledUnit = GetUnitOwner())
1558 if (dispelledUnit->HasAura(_removeSpellId))
1559 dispelledUnit->RemoveAurasDueToSpell(_removeSpellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
1560 }
1561
1562 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1563 {
1564 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
1565 return;
1566
1567 // Stacks marker
1572 }
1573
1579
1582 };
1583
1584 AuraScript* GetAuraScript() const override
1585 {
1587 }
1588
1589 private:
1592};
1593
1594// 74610 - Fiery Combustion
1595// 74800 - Soul Consumption
1597{
1598 public:
1599 spell_halion_damage_aoe_summon() : SpellScriptLoader("spell_halion_damage_aoe_summon") { }
1600
1602 {
1604 {
1605 PreventHitDefaultEffect(effIndex);
1606 Unit* caster = GetCaster();
1607 uint32 entry = uint32(GetEffectInfo().MiscValue);
1608 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB));
1609 Milliseconds duration = Milliseconds(GetSpellInfo()->GetDuration());
1610
1611 Position pos = caster->GetPosition();
1612 if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id))
1613 if (summon->IsAIEnabled())
1614 summon->AI()->SetData(DATA_STACKS_DISPELLED, GetSpellValue()->EffectBasePoints[EFFECT_1]);
1615 }
1616
1621 };
1622
1623 SpellScript* GetSpellScript() const override
1624 {
1626 }
1627};
1628
1630{
1631 public:
1632 spell_halion_twilight_realm_handlers(char const* scriptName, uint32 beforeHitSpell, bool isApplyHandler) : SpellScriptLoader(scriptName),
1633 _beforeHitSpell(beforeHitSpell), _isApplyHandler(isApplyHandler)
1634 { }
1635
1637 {
1638 public:
1640 _isApply(isApplyHandler), _beforeHitSpellId(beforeHitSpell)
1641 { }
1642
1643 private:
1644 bool Validate(SpellInfo const* /*spell*/) override
1645 {
1647 }
1648
1649 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1650 {
1652 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
1653 instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED, nullptr);
1654 }
1655
1656 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1657 {
1658 Unit* target = GetTarget();
1659 if (!target)
1660 return;
1661
1663 if (InstanceScript* instance = target->GetInstanceScript())
1664 instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED, nullptr);
1665 }
1666
1677
1680 };
1681
1686
1687 private:
1690};
1691
1692// 75396 - Clear Debuffs
1694{
1695 public:
1696 spell_halion_clear_debuffs() : SpellScriptLoader("spell_halion_clear_debuffs") { }
1697
1699 {
1700 bool Validate(SpellInfo const* /*spell*/) override
1701 {
1703 }
1704
1705 void HandleScript(SpellEffIndex /*effIndex*/)
1706 {
1707 if (GetHitUnit()->HasAura(GetEffectInfo().CalcValueAsInt()))
1708 GetHitUnit()->RemoveAurasDueToSpell(GetEffectInfo().CalcValueAsInt());
1709 }
1710
1715 };
1716
1717 SpellScript* GetSpellScript() const override
1718 {
1720 }
1721};
1722
1724{
1725 public:
1726 TwilightCutterSelector(Unit* caster, Unit* target) : _caster(caster), _channelTarget(target) { }
1727
1729 {
1730 return !unit->IsInBetween(_caster, _channelTarget, 4.0f);
1731 }
1732
1733 private:
1736};
1737
1738// 74769, 77844, 77845, 77846 - Twilight Cutter
1740{
1741 public:
1742 spell_halion_twilight_cutter() : SpellScriptLoader("spell_halion_twilight_cutter") { }
1743
1745 {
1746 void RemoveNotBetween(std::list<WorldObject*>& unitList)
1747 {
1748 if (unitList.empty())
1749 return;
1750
1751 Unit* caster = GetCaster();
1752 auto const& channelObjects = caster->m_unitData->ChannelObjects;
1753 if (Unit* channelTarget = (channelObjects.size() == 1 ? ObjectAccessor::GetUnit(*caster, *channelObjects.begin()) : nullptr))
1754 {
1755 unitList.remove_if(TwilightCutterSelector(caster, channelTarget));
1756 return;
1757 }
1758
1759 // In case cutter caster werent found for some reason
1760 unitList.clear();
1761 }
1762
1767 };
1768
1769 SpellScript* GetSpellScript() const override
1770 {
1772 }
1773};
1774
1775// 74808 - Twilight Phasing
1777{
1778 public:
1779 spell_halion_twilight_phasing() : SpellScriptLoader("spell_halion_twilight_phasing") { }
1780
1782 {
1783 bool Validate(SpellInfo const* /*spell*/) override
1784 {
1786 }
1787
1788 void Phase()
1789 {
1790 Unit* caster = GetCaster();
1791 caster->CastSpell(caster->GetPosition(), SPELL_SUMMON_TWILIGHT_PORTAL, true);
1793 }
1794
1799 };
1800
1801 SpellScript* GetSpellScript() const override
1802 {
1804 }
1805};
1806
1807// 74805 - Summon Exit Portals
1809{
1810 public:
1811 spell_halion_summon_exit_portals() : SpellScriptLoader("spell_halion_summon_exit_portals") { }
1812
1814 {
1816 {
1817 Position const offset = { 0.0f, 20.0f, 0.0f, 0.0f };
1818 dest.RelocateOffset(offset);
1819 }
1820
1822 {
1823 Position const offset = { 0.0f, -20.0f, 0.0f, 0.0f };
1824 dest.RelocateOffset(offset);
1825 }
1826
1832 };
1833
1834 SpellScript* GetSpellScript() const override
1835 {
1837 }
1838};
1839
1840// 75880 - Spawn Living Embers
1871
1872// 75886, 75887 - Blazing Aura
1874{
1875 public:
1876 spell_halion_blazing_aura() : SpellScriptLoader("spell_halion_blazing_aura") { }
1877
1891
1892 SpellScript* GetSpellScript() const override
1893 {
1895 }
1896};
1897
1899{
1900 new boss_halion();
1902
1906 new npc_meteor_strike();
1908 new npc_orb_carrier();
1909 new npc_living_inferno();
1910 new npc_living_ember();
1911
1912 new go_twilight_portal();
1913
1915 new spell_halion_combustion_consumption("spell_halion_soul_consumption", SPELL_MARK_OF_CONSUMPTION);
1916 new spell_halion_combustion_consumption("spell_halion_fiery_combustion", SPELL_MARK_OF_COMBUSTION);
1917 new spell_halion_marks("spell_halion_mark_of_combustion", SPELL_FIERY_COMBUSTION_SUMMON, SPELL_FIERY_COMBUSTION);
1918 new spell_halion_marks("spell_halion_mark_of_consumption", SPELL_SOUL_CONSUMPTION_SUMMON, SPELL_SOUL_CONSUMPTION);
1921 new spell_halion_twilight_realm_handlers("spell_halion_leave_twilight_realm", SPELL_SOUL_CONSUMPTION, false);
1922 new spell_halion_twilight_realm_handlers("spell_halion_enter_twilight_realm", SPELL_FIERY_COMBUSTION, true);
1929}
#define M_PI
Definition Common.h:118
DB2Storage< SummonPropertiesEntry > sSummonPropertiesStore("SummonProperties.db2", &SummonPropertiesLoadInfo::Instance)
@ DIFFICULTY_25_HC
Definition DBCEnums.h:939
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
#define ASSERT
Definition Errors.h:80
@ IN_PROGRESS
@ FAIL
@ DONE
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED
@ ENCOUNTER_FRAME_ENGAGE
@ TEMPSUMMON_TIMED_DESPAWN
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
#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
@ EFFECT_1
@ EFFECT_0
@ 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
@ SPELLVALUE_AURA_STACK
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
@ TRIGGERED_IGNORE_SET_FACING
Will not adjust facing to target (if any)
@ SPELLVALUE_BASE_POINT1
@ SPELLVALUE_RADIUS_MOD
@ SPELLVALUE_BASE_POINT0
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define SpellDestinationTargetSelectFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define SpellHitFn(F)
#define AuraDispelFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
EvadeReason
#define CAST_AI(a, b)
Definition UnitAI.h:29
@ REACT_DEFENSIVE
DamageEffectType
@ UNIT_FLAG_IN_COMBAT
@ UNIT_STATE_CASTING
Definition Unit.h:276
@ ACTION_METEOR_STRIKE_AOE
@ ACTION_ACTIVATE_EMBERS
@ ACTION_MONITOR_CORPOREALITY
@ ACTION_METEOR_STRIKE_BURN
@ ACTION_SHOOT
@ ACTION_WARNING_SHOOT
@ DATA_TWILIGHT_DAMAGE_TAKEN
@ DATA_ROOT_GUID
@ DATA_MATERIAL_DAMAGE_TAKEN
@ DATA_FIGHT_PHASE
@ DATA_SPAWNED_FLAMES
@ DATA_STACKS_DISPELLED
@ SPELL_COSMETIC_FIRE_PILLAR
@ SPELL_CLEAVE
@ SPELL_METEOR_STRIKE_COUNTDOWN
@ SPELL_FIERY_COMBUSTION_SUMMON
@ SPELL_METEOR_STRIKE_FIRE_AURA_1
@ SPELL_TWILIGHT_PHASING
@ SPELL_DUSK_SHROUD
@ SPELL_SUMMON_TWILIGHT_PORTAL
@ SPELL_MARK_OF_COMBUSTION
@ SPELL_METEOR_STRIKE_AOE_DAMAGE
@ SPELL_DARK_BREATH
@ SPELL_TWILIGHT_DIVISION
@ SPELL_FLAME_BREATH
@ SPELL_TWILIGHT_CUTTER
@ SPELL_LEAVE_TWILIGHT_REALM
@ SPELL_TWILIGHT_PRECISION
@ SPELL_CLEAR_DEBUFFS
@ SPELL_COPY_DAMAGE
@ SPELL_SOUL_CONSUMPTION_SUMMON
@ SPELL_SOUL_CONSUMPTION
@ SPELL_TAIL_LASH
@ SPELL_SPAWN_LIVING_EMBERS
@ SPELL_SOUL_CONSUMPTION_EXPLOSION
@ SPELL_FIERY_COMBUSTION_EXPLOSION
@ SPELL_TWILIGHT_PULSE_PERIODIC
@ SPELL_TWILIGHT_MENDING
@ SPELL_BLAZING_AURA
@ SPELL_SUMMON_EXIT_PORTALS
@ SPELL_MARK_OF_CONSUMPTION
@ SPELL_METEOR_STRIKE
@ SPELL_TWILIGHT_CUTTER_TRIGGERED
@ SPELL_COMBUSTION_DAMAGE_AURA
@ SPELL_TRACK_ROTATION
@ SPELL_SUMMON_LIVING_EMBER
@ SPELL_FIERY_EXPLOSION
@ SPELL_SCALE_AURA
@ SPELL_CONSUMPTION_DAMAGE_AURA
@ SPELL_TWILIGHT_REALM
@ SPELL_FIERY_COMBUSTION
@ 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
@ EMOTE_WARN_LASER
@ SAY_AGGRO
@ SAY_SPHERE_PULSE
@ SAY_PHASE_TWO
@ SAY_KILL
@ EMOTE_CORPOREALITY_TOT
@ SAY_PHASE_THREE
@ EMOTE_CORPOREALITY_PIP
@ SAY_REGENERATE
@ SAY_METEOR_STRIKE
@ SAY_BERSERK
@ EMOTE_CORPOREALITY_POT
@ EMOTE_CORPOREALITY_TIT
@ SAY_INTRO
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
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
Unit * GetTarget() const
ObjectGuid GetCasterGUID() const
HookList< AuraDispelHandler > OnDispel
Unit * GetUnitOwner() const
uint8 GetStackAmount() const
Definition SpellAuras.h:238
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
EventMap events
void DoZoneInCombat()
Definition CreatureAI.h:169
virtual void JustSummoned(Creature *)
Definition CreatureAI.h:113
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
bool IsInBoundary(Position const *who=nullptr) const
bool UpdateVictim()
void SetBoundary(CreatureBoundary const *boundary, bool negativeBoundaries=false)
Creature *const me
Definition CreatureAI.h:63
bool IsEngaged() const override
void SetReactState(ReactStates st)
Definition Creature.h:174
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureAI * AI() const
Definition Creature.h:228
void SetRemovedCharges(uint8 amount)
Definition Unit.h:399
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
bool IsInPhase(uint8 phase) const
Definition EventMap.h:222
void SetPhase(uint8 phase)
Definition EventMap.cpp:32
void Reset()
Definition EventMap.cpp:25
GameObject *const me
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:203
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)
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:1186
Difficulty GetDifficultyID() const
Definition Map.h:360
PlayerList const & GetPlayers() const
Definition Map.h:403
static ObjectGuid const Empty
Definition ObjectGuid.h:314
bool IsEmpty() const
Definition ObjectGuid.h:362
float GetObjectScale() const
Definition Object.h:92
uint32 GetEntry() const
Definition Object.h:89
Creature * ToCreature()
Definition Object.h:121
static void AddPhase(WorldObject *object, uint32 phaseId, bool updateVisibility)
iterator end()
Definition RefManager.h:36
iterator begin()
Definition RefManager.h:35
uint32 TriggerSpell
Definition SpellInfo.h:234
uint32 const Id
Definition SpellInfo.h:328
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:588
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Unit * GetCaster() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
HookList< HitHandler > OnHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
SpellValue const * GetSpellValue() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
HookList< EffectHandler > OnEffectLaunch
SpellInfo const * GetSpellInfo() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
void Summon(Creature const *summon)
void DoZoneInCombat(uint32 entry=0)
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update()
Update the scheduler to the current time.
bool operator()(WorldObject *unit)
TwilightCutterSelector(Unit *caster, Unit *target)
virtual void SetData(uint32 id, uint32 value)
Definition UnitAI.h:75
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
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:162
virtual uint32 GetData(uint32 id) const
Definition UnitAI.h:74
Definition Unit.h:635
void CastStop(uint32 except_spellid=0)
Definition Unit.cpp:1186
void SetHealth(uint64 val)
Definition Unit.cpp:9973
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:12249
void SetUninteractible(bool apply)
Definition Unit.cpp:8564
uint64 GetHealth() const
Definition Unit.h:788
bool HealthBelowPctDamaged(float pct, uint32 damage) const
Definition Unit.h:793
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
Definition Unit.h:1881
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:846
Vehicle * GetVehicleKit() const
Definition Unit.h:1782
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3974
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.cpp:11225
Unit * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
Definition Vehicle.cpp:303
bool InSamePhase(PhaseShift const &phaseShift) const
Definition Object.h:314
Map * GetMap() const
Definition Object.h:411
InstanceScript * GetInstanceScript() const
Definition Object.cpp:396
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
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:1398
void setActive(bool isActiveObject)
Definition Object.cpp:276
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2755
void SetFarVisible(bool on)
Definition Object.cpp:327
bool IsInBetween(Position const &pos1, Position const &pos2, float size=0) const
Definition Object.cpp:653
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.
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
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
@ DATA_TWILIGHT_FLAME_RING
@ DATA_BURNING_TREE_1
@ DATA_GENERAL_ZARITHRIAN
@ DATA_BURNING_TREE_2
@ DATA_BURNING_TREE_3
@ DATA_BURNING_TREE_4
@ DATA_ORB_CARRIER
@ DATA_TWILIGHT_HALION
@ DATA_FLAME_RING
@ DATA_HALION
@ WORLDSTATE_CORPOREALITY_TOGGLE
@ WORLDSTATE_CORPOREALITY_MATERIAL
@ WORLDSTATE_CORPOREALITY_TWILIGHT
@ GO_HALION_PORTAL_1
@ GO_HALION_PORTAL_EXIT
@ GO_HALION_PORTAL_2
@ NPC_METEOR_STRIKE_NORTH
@ NPC_HALION
@ NPC_TWILIGHT_HALION
@ NPC_CONSUMPTION
@ NPC_METEOR_STRIKE_FLAME
@ NPC_LIVING_EMBER
@ NPC_COMBUSTION
@ ACTION_INTRO_HALION_2
@ ACTION_INTRO_HALION
CastSpellExtraArgs & SetOriginalCaster(ObjectGuid const &guid)
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
struct GameObjectTemplate::@197::@209 goober
constexpr void SetOrientation(float orientation)
Definition Position.h:82
static float NormalizeOrientation(float o)
Definition Position.cpp:207
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:136
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
bool IsHeroic() const
void SetCombatMovement(bool allowMovement)
virtual void UpdateAI(uint32 diff) override
void RelocateOffset(Position const &offset)
Definition Spell.cpp:90
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 DamageTaken(Unit *attacker, uint32 &damage, DamageEffectType, SpellInfo const *) 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 IsSummonedBy(WorldObject *) override
void IsSummonedBy(WorldObject *) 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 id) 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