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
228// 39863 - Halion
229struct boss_halion : public BossAI
230{
231 boss_halion(Creature* creature) : BossAI(creature, DATA_HALION) { }
232
233 void EnterEvadeMode(EvadeReason why) override
234 {
237 controller->AI()->EnterEvadeMode(why);
238 }
239
261
262 void JustDied(Unit* /*killer*/) override
263 {
264 _JustDied();
265
268
269 if (Creature* twilightHalion = instance->GetCreature(DATA_TWILIGHT_HALION))
270 if (twilightHalion->IsAlive())
271 twilightHalion->KillSelf();
272
274 if (controller->IsAlive())
275 controller->KillSelf();
276 }
277
279
280 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
281 {
282 if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
283 damage = me->GetHealth() - 1;
284
286 {
289
290 me->CastStop();
291 me->SetUninteractible(true);
293
295 controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_TWO);
296 return;
297 }
298
300 {
301 // Don't consider copied damage.
302 if (!attacker || !me->InSamePhase(attacker))
303 return;
304
306 controller->AI()->SetData(DATA_MATERIAL_DAMAGE_TAKEN, damage);
307 }
308 }
309
310 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
311 {
312 if (spellInfo->Id == SPELL_TWILIGHT_MENDING)
314 }
315
316 void UpdateAI(uint32 diff) override
317 {
319 return;
320
321 if (!UpdateVictim())
322 return;
323
324 events.Update(diff);
325
327 return;
328
329 while (uint32 eventId = events.ExecuteEvent())
330 {
331 switch (eventId)
332 {
333 case EVENT_CLEAVE:
336 break;
337 case EVENT_TAIL_LASH:
340 break;
341 case EVENT_BREATH:
344 break;
346 // Flame ring is activated 5 seconds after starting encounter, EncounterStateForOpenDoor::NotInProgress is only instant.
348 if (GameObject* flameRing = instance->GetGameObject(i))
349 instance->HandleGameObject(ObjectGuid::Empty, false, flameRing);
350 break;
352 {
353 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
354 {
355 _meteorStrikePos = target->GetPosition();
357 .SetOriginalCaster(me->GetGUID()));
359 }
361 break;
362 }
364 {
365 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
368 break;
369 }
370 default:
371 break;
372 }
373 }
374 }
375
376 void SetData(uint32 index, uint32 value) override
377 {
378 if (index != DATA_FIGHT_PHASE)
379 return;
380
381 events.SetPhase(value);
382 }
383
384private:
386};
387
389
390// 40142 - Halion
392{
394 {
396 if (!halion)
397 return;
398
399 // Using AddAura because no spell cast packet in sniffs.
400 halion->AddAura(SPELL_COPY_DAMAGE, me); // We use explicit targeting here to avoid conditions + SPELL_ATTR6_CANT_TARGET_SELF.
401 me->AddAura(SPELL_COPY_DAMAGE, halion);
403
404 me->SetHealth(halion->GetHealth());
405 PhasingHandler::AddPhase(me, 174, false);
410 }
411
423
424 void Reset() override { }
425 void EnterEvadeMode(EvadeReason /*why*/) override { }
426
427 void KilledUnit(Unit* victim) override
428 {
429 if (victim->GetTypeId() == TYPEID_PLAYER)
430 Talk(SAY_KILL);
431
432 // Victims should not be in the Twilight Realm
434 }
435
436 void JustDied(Unit* killer) override
437 {
439 {
440 // Ensure looting
441
442 halion->LowerPlayerDamageReq(halion->GetMaxHealth());
443
444 if (halion->IsAlive())
445 Unit::Kill(killer, halion);
446 }
447
449 if (controller->IsAlive())
450 controller->KillSelf();
451
453 }
454
455 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
456 {
457 if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
458 damage = me->GetHealth() - 1;
459 //Needed because we already have UNIT_FLAG_IN_COMBAT, otherwise JustEngagedWith won't ever be called
461 JustEngagedWith(attacker);
462
464 {
466 me->CastStop();
469 return;
470 }
471
473 {
474 // Don't consider copied damage.
475 if (!attacker || !me->InSamePhase(attacker))
476 return;
477
479 controller->AI()->SetData(DATA_TWILIGHT_DAMAGE_TAKEN, damage);
480 }
481 }
482
483 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
484 {
485 switch (spellInfo->Id)
486 {
489 controller->AI()->DoAction(ACTION_MONITOR_CORPOREALITY);
490 break;
493 break;
494 default:
495 break;
496 }
497 }
498
499 void UpdateAI(uint32 diff) override
500 {
502 return;
503
504 if (!UpdateVictim())
505 return;
506
507 events.Update(diff);
508
509 while (uint32 eventId = events.ExecuteEvent())
510 {
511 switch (eventId)
512 {
513 case EVENT_CLEAVE:
516 break;
517 case EVENT_TAIL_LASH:
520 break;
521 case EVENT_BREATH:
524 break;
526 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, SPELL_TWILIGHT_REALM))
529 break;
530 default:
531 break;
532 }
533 }
534 }
535};
536
537// 40146 - Halion Controller
539{
541 _instance(creature->GetInstanceScript()), _summons(me)
542 {
543 Initialize();
544 }
545
553
562
563 void Reset() override
564 {
566 _events.Reset();
567 Initialize();
568
570 }
571
572 void JustSummoned(Creature* who) override
573 {
574 _summons.Summon(who);
575 }
576
577 void JustDied(Unit* /*killer*/) override
578 {
579 _events.Reset();
581
583 }
584
593
594 void JustExitedCombat() override
595 {
597 return;
598
599 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
600 {
601 twilightHalion->DespawnOrUnsummon();
603 }
604
606 {
607 halion->DespawnOrUnsummon();
609 }
610
613
614 me->DespawnOrUnsummon(0s, 30s);
615 }
616
617 void DoAction(int32 action) override
618 {
619 switch (action)
620 {
622 _events.Reset();
625 break;
628 return;
629
631 if (GameObject* tree = _instance->GetGameObject(i))
634 break;
636 {
637 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
638 {
639 Creature* halion = _instance->GetCreature(itr);
640 if (!halion)
641 continue;
642
643 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), false);
645
646 if (itr == DATA_TWILIGHT_HALION)
647 continue;
648
650 halion->SetUninteractible(false);
651 }
652
653 // Summon Twilight portals
655
657 // Hardcoding doesn't really matter here.
660
662 break;
663 }
666 break;
667 default:
668 break;
669 }
670 }
671
672 void UpdateAI(uint32 diff) override
673 {
674 // The IsEngaged() check is needed because that check should be false when Halion is
675 // not engaged, while it would return true without as UpdateVictim() checks for
676 // combat state.
677 if (me->IsEngaged() && !UpdateVictim())
678 return;
679
680 _events.Update(diff);
681
682 while (uint32 eventId = _events.ExecuteEvent())
683 {
684 switch (eventId)
685 {
689 break;
692 if (GameObject* tree = _instance->GetGameObject(i))
695 break;
698 if (GameObject* tree = _instance->GetGameObject(i))
701 break;
705 return;
707 halion->AI()->Talk(SAY_INTRO);
708 break;
710 if (_instance->GetCreature(DATA_HALION)) // Just check if physical Halion is spawned
711 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
712 twilightHalion->CastSpell(nullptr, SPELL_TWILIGHT_MENDING, true);
713 break;
716 halion->CastSpell(halion, SPELL_BERSERK, true);
718 halion->CastSpell(halion, SPELL_BERSERK, true);
719 break;
722 orbCarrier->AI()->DoAction(ACTION_WARNING_SHOOT);
724 break;
728 break;
731 break;
733 DoCheckEvade();
735 break;
736 default:
737 break;
738 }
739 }
740 }
741
743 {
744 Map::PlayerList const& players = me->GetMap()->GetPlayers();
745 for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
746 if (Player* player = i->GetSource())
747 if (player->IsAlive() && IsInBoundary(player) && !player->IsGameMaster())
748 return;
749
751 }
752
753 void SetData(uint32 id, uint32 value) override
754 {
755 switch (id)
756 {
758 _materialDamageTaken += value;
759 break;
761 _twilightDamageTaken += value;
762 break;
763 case DATA_FIGHT_PHASE:
764 _events.SetPhase(value);
765 switch (value)
766 {
767 case PHASE_ONE:
769 break;
770 case PHASE_TWO:
772 break;
773 default:
774 break;
775 }
776 break;
777 default:
778 break;
779 }
780 }
781
782private:
784 // [0 , 0.98[: Corporeality goes down
785 // [0.98, 0.99]: Do nothing
786 // ]0.99, 1.01[: Twilight Mending
787 // [1.01, 1.02]: Do nothing
788 // ]1.02, +oo [: Corporeality goes up
790 {
793 {
797 return;
798 }
799
800 float damageRatio = float(_materialDamageTaken) / float(_twilightDamageTaken);
801
803 if (damageRatio < 0.98f) // [0 , 0.98[: Corporeality goes down
804 action = CORPOREALITY_DECREASE;
805 else if (0.99f < damageRatio && damageRatio < 1.01f) // ]0.99, 1.01[: Twilight Mending
807 else if (1.02f < damageRatio) // ]1.02, +oo [: Corporeality goes up
808 action = CORPOREALITY_INCREASE;
809
810 switch (action)
811 {
813 {
816 return;
817 }
819 {
821 return;
823 break;
824 }
826 {
828 return;
830 break;
831 }
833 {
837 return;
838 }
839 }
840
843
846
847 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
848 {
849 if (Creature* halion = _instance->GetCreature(itr))
850 {
851 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), true);
852
853 if (itr == DATA_TWILIGHT_HALION)
854 halion->AI()->Talk(oldValue < _materialCorporealityValue ? EMOTE_CORPOREALITY_TOT : EMOTE_CORPOREALITY_TIT, halion);
855 else // if (itr == DATA_HALION)
856 halion->AI()->Talk(oldValue > _materialCorporealityValue ? EMOTE_CORPOREALITY_POT : EMOTE_CORPOREALITY_PIP, halion);
857 }
858 }
859 }
860
861 uint32 GetSpell(uint8 pctValue, bool isTwilight = false) const
862 {
864 return isTwilight ? entry.twilightRealmSpell : entry.materialRealmSpell;
865 }
866
870
874};
875
876// 40081 - Orb Carrier
878{
879 npc_orb_carrier(Creature* creature) : ScriptedAI(creature),
880 _instance(creature->GetInstanceScript())
881 {
882 ASSERT(creature->GetVehicleKit());
883 }
884
885 void UpdateAI(uint32 diff) override
886 {
891 me->CastSpell(nullptr, SPELL_TRACK_ROTATION, false);
892
893 scheduler.Update(diff);
894 }
895
896 void DoAction(int32 action) override
897 {
898 switch (action)
899 {
901 {
902 Vehicle* vehicle = me->GetVehicleKit();
903 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
904 if (northOrb && northOrb->GetTypeId() == TYPEID_UNIT)
905 northOrb->ToCreature()->AI()->Talk(EMOTE_WARN_LASER);
906
907 scheduler.Schedule(Seconds(5), [this](TaskContext const& /*context*/)
908 {
910 });
911 break;
912 }
913 case ACTION_SHOOT:
914 {
915 Vehicle* vehicle = me->GetVehicleKit();
916 Unit* southOrb = vehicle->GetPassenger(SEAT_SOUTH);
917 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
918 if (southOrb && northOrb)
919 TriggerCutter(northOrb, southOrb);
920
921 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
922 twilightHalion->AI()->Talk(SAY_SPHERE_PULSE);
923
924 if (!IsHeroic())
925 return;
926
927 Unit* eastOrb = vehicle->GetPassenger(SEAT_EAST);
928 Unit* westOrb = vehicle->GetPassenger(SEAT_WEST);
929 if (eastOrb && westOrb)
930 TriggerCutter(eastOrb, westOrb);
931 break;
932 }
933 default:
934 break;
935 }
936 }
937private:
940
941 void TriggerCutter(Unit* caster, Unit* target)
942 {
943 caster->CastSpell(caster, SPELL_TWILIGHT_PULSE_PERIODIC, true);
944 target->CastSpell(target, SPELL_TWILIGHT_PULSE_PERIODIC, true);
945 caster->CastSpell(target, SPELL_TWILIGHT_CUTTER, false);
946 }
947};
948
949// 40029 - Meteor Strike
951{
953 _instance(creature->GetInstanceScript())
954 {
955 SetCombatMovement(false);
956 }
957
958 void DoAction(int32 action) override
959 {
960 switch (action)
961 {
965 for (std::list<Creature*>::iterator itr = _meteorList.begin(); itr != _meteorList.end(); ++itr)
966 (*itr)->AI()->DoAction(ACTION_METEOR_STRIKE_BURN);
967 break;
968 }
969 }
970
971 void IsSummonedBy(WorldObject* summoner) override
972 {
973 Creature* owner = summoner->ToCreature();
974 if (!owner)
975 return;
976
977 // Let Controller count as summoner
979 controller->AI()->JustSummoned(me);
980
983
984 if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
985 {
986 Position const* ownerPos = halionAI->GetMeteorStrikePosition();
987 float randomAdjustment = frand(static_cast<float>(M_PI / 5.0f), static_cast<float>(M_PI / 2.0f));
988 float angle[4];
989 angle[0] = me->GetAbsoluteAngle(ownerPos);
990 angle[1] = angle[0] + randomAdjustment;
991 angle[2] = angle[0] + static_cast<float>(M_PI);
992 angle[3] = angle[2] + randomAdjustment;
993
994 _meteorList.clear();
995 for (uint8 i = 0; i < 4; i++)
996 {
997 angle[i] = Position::NormalizeOrientation(angle[i]);
998 me->SetOrientation(angle[i]);
999 Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance
1001 _meteorList.push_back(meteor);
1002 }
1003 }
1004 }
1005
1006 void UpdateAI(uint32 /*diff*/) override { }
1007 void EnterEvadeMode(EvadeReason /*why*/) override { }
1008private:
1010 std::list<Creature*> _meteorList;
1011};
1012
1013// 40041, 40042, 40043, 40044 - Meteor Strike
1015{
1016 npc_meteor_strike(Creature* creature) : ScriptedAI(creature),
1017 _instance(creature->GetInstanceScript()), _spawnCount(0)
1018 {
1019 SetCombatMovement(false);
1020 }
1021
1022 void DoAction(int32 action) override
1023 {
1024 if (action == ACTION_METEOR_STRIKE_BURN)
1025 {
1027 me->setActive(true);
1028 me->SetFarVisible(true);
1030 }
1031 }
1032
1033 void IsSummonedBy(WorldObject* /*summoner*/) override
1034 {
1035 // Let Halion Controller count as summoner.
1037 controller->AI()->JustSummoned(me);
1038 }
1039
1040 void SetData(uint32 dataType, uint32 dataCount) override
1041 {
1042 if (dataType == DATA_SPAWNED_FLAMES)
1043 _spawnCount += dataCount;
1044 }
1045
1046 uint32 GetData(uint32 dataType) const override
1047 {
1048 if (dataType == DATA_SPAWNED_FLAMES)
1049 return _spawnCount;
1050 return 0;
1051 }
1052
1053 void UpdateAI(uint32 diff) override
1054 {
1055 _events.Update(diff);
1056
1058 {
1059 Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
1061 flame->AI()->SetGUID(me->GetGUID(), DATA_ROOT_GUID);
1062 }
1063 }
1064
1065private:
1069};
1070
1071// 40055 - Meteor Strike
1073{
1075 _instance(creature->GetInstanceScript())
1076 {
1077 SetCombatMovement(false);
1078 }
1079
1080 void SetGUID(ObjectGuid const& guid, int32 id) override
1081 {
1082 if (id != DATA_ROOT_GUID)
1083 return;
1084
1085 _rootOwnerGuid = guid;
1087 }
1088
1089 void IsSummonedBy(WorldObject* /*summoner*/) override
1090 {
1091 // Let Halion Controller count as summoner.
1093 controller->AI()->JustSummoned(me);
1094 }
1095
1096 void UpdateAI(uint32 diff) override
1097 {
1098 _events.Update(diff);
1100 return;
1101
1103
1105 if (!meteorStrike)
1106 return;
1107
1108 meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1);
1109 if (meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5)
1110 return;
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(_rootOwnerGuid, DATA_ROOT_GUID);
1115 }
1116
1117 void EnterEvadeMode(EvadeReason /*why*/) override { }
1118
1119private:
1123};
1124
1125// 40001 - Combustion
1126// 40135 - Consumption
1128{
1130 _instance(creature->GetInstanceScript())
1131 {
1132 SetCombatMovement(false);
1133
1134 switch (creature->GetEntry())
1135 {
1136 case NPC_COMBUSTION:
1139 PhasingHandler::AddPhase(creature, DEFAULT_PHASE, false);
1140 if (IsHeroic())
1141 PhasingHandler::AddPhase(creature, 174, false);
1142 break;
1143 case NPC_CONSUMPTION:
1146 PhasingHandler::AddPhase(creature, 174, false);
1147 if (IsHeroic())
1148 PhasingHandler::AddPhase(creature, DEFAULT_PHASE, false);
1149 break;
1150 default: // Should never happen
1151 _explosionSpell = 0;
1152 _damageSpell = 0;
1153 break;
1154 }
1155 }
1156
1157 void IsSummonedBy(WorldObject* summoner) override
1158 {
1159 // Let Halion Controller count as summoner
1161 controller->AI()->JustSummoned(me);
1162
1163 _summonerGuid = summoner->GetGUID();
1164 }
1165
1166 void SetData(uint32 type, uint32 stackAmount) override
1167 {
1169
1170 if (type != DATA_STACKS_DISPELLED || !_damageSpell || !_explosionSpell || !summoner)
1171 return;
1172 CastSpellExtraArgs args;
1173 args.AddSpellMod(SPELLVALUE_AURA_STACK, stackAmount + 1);
1176
1177 int32 damage = 1200 + (stackAmount * 1290); // Needs more research.
1178 CastSpellExtraArgs args2;
1179 args2.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
1180 summoner->CastSpell(summoner, _explosionSpell, args2);
1181 }
1182
1183 void UpdateAI(uint32 /*diff*/) override { }
1184
1185private:
1190};
1191
1192// 40681 - Living Inferno
1194{
1195 npc_living_inferno(Creature* creature) : ScriptedAI(creature) { }
1196
1197 void IsSummonedBy(WorldObject* /*summoner*/) override
1198 {
1201
1202 // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs.
1204 scheduler.Schedule(Seconds(3), [this](TaskContext const& /*context*/)
1205 {
1207 });
1208
1209 if (InstanceScript* instance = me->GetInstanceScript())
1210 if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
1211 {
1212 controller->AI()->DoAction(ACTION_ACTIVATE_EMBERS);
1213 controller->AI()->JustSummoned(me);
1214 }
1215 }
1216
1217 void JustDied(Unit* /*killer*/) override
1218 {
1219 me->DespawnOrUnsummon(1ms);
1220 }
1221
1222 void UpdateAI(uint32 diff) override
1223 {
1224 scheduler.Update(diff);
1226 }
1227
1228private:
1230};
1231
1232// 40683 - Living Ember
1234{
1235 npc_living_ember(Creature* creature) : ScriptedAI(creature) { }
1236
1237 void IsSummonedBy(WorldObject* /*summoner*/) override
1238 {
1239 if (InstanceScript* instance = me->GetInstanceScript())
1240 if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
1241 controller->AI()->JustSummoned(me);
1242 }
1243
1244 void JustDied(Unit* /*killer*/) override
1245 {
1246 me->DespawnOrUnsummon(1ms);
1247 }
1248};
1249
1250// 202794, 202796 - Twilight Portal
1252{
1253 go_twilight_portal(GameObject* gameobject) : GameObjectAI(gameobject),
1254 _instance(gameobject->GetInstanceScript()), _deleted(false)
1255 {
1256 switch (gameobject->GetEntry())
1257 {
1259 PhasingHandler::AddPhase(gameobject, 174, false);
1260 _spellId = gameobject->GetGOInfo()->goober.spell;
1261 break;
1262 case GO_HALION_PORTAL_1:
1263 case GO_HALION_PORTAL_2:
1264 PhasingHandler::AddPhase(gameobject, DEFAULT_PHASE, false);
1267 break;
1268 default:
1269 _spellId = 0;
1270 break;
1271 }
1272 }
1273
1274 bool OnGossipHello(Player* player) override
1275 {
1276 if (_spellId != 0)
1277 player->CastSpell(player, _spellId, true);
1278 return true;
1279 }
1280
1281 void UpdateAI(uint32 /*diff*/) override
1282 {
1284 return;
1285
1286 if (!_deleted)
1287 {
1288 _deleted = true;
1289 me->Delete();
1290 }
1291 }
1292
1293private:
1297};
1298
1299// 74641 - Meteor Strike
1301{
1302 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1303 {
1304 if (!GetCaster())
1305 return;
1306
1307 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
1308 if (Creature* creCaster = GetCaster()->ToCreature())
1309 creCaster->AI()->DoAction(ACTION_METEOR_STRIKE_AOE);
1310 }
1311
1316};
1317
1318// 74792 - Soul Consumption
1319// 74562 - Fiery Combustion
1359
1360// 74629 - Combustion Periodic
1361// 74803 - Consumption Periodic
1363{
1364 bool Validate(SpellInfo const* spellInfo) override
1365 {
1366 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
1367 }
1368
1369 void HandleTick(AuraEffect const* aurEff)
1370 {
1372 Unit* caster = GetCaster();
1373 if (!caster)
1374 return;
1375
1376 uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
1377 float radius = caster->GetObjectScale() * M_PI / 3;
1378
1379 CastSpellExtraArgs args(aurEff);
1380 args.OriginalCaster = caster->GetGUID();
1381 args.AddSpellMod(SPELLVALUE_RADIUS_MOD, radius);
1382 caster->CastSpell(nullptr, triggerSpell, args);
1383 }
1384
1389};
1390
1391// 74567 - Mark of Combustion
1392// 74795 - Mark of Consumption
1394{
1395public:
1396 spell_halion_marks(uint32 summonSpell, uint32 removeSpell) : AuraScript(),
1397 _summonSpellId(summonSpell), _removeSpellId(removeSpell) { }
1398
1399private:
1400 bool Validate(SpellInfo const* /*spell*/) override
1401 {
1403 }
1404
1406 void BeforeDispel(DispelInfo* dispelData)
1407 {
1408 // Prevent any stack from being removed at this point.
1409 dispelData->SetRemovedCharges(0);
1410
1411 if (Unit* dispelledUnit = GetUnitOwner())
1412 if (dispelledUnit->HasAura(_removeSpellId))
1413 dispelledUnit->RemoveAurasDueToSpell(_removeSpellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
1414 }
1415
1416 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1417 {
1418 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
1419 return;
1420
1421 // Stacks marker
1426 }
1427
1433
1436};
1437
1438// 74610 - Fiery Combustion
1439// 74800 - Soul Consumption
1441{
1443 {
1444 PreventHitDefaultEffect(effIndex);
1445 Unit* caster = GetCaster();
1446 uint32 entry = uint32(GetEffectInfo().MiscValue);
1447 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB));
1448 Milliseconds duration = Milliseconds(GetSpellInfo()->GetDuration());
1449
1450 Position pos = caster->GetPosition();
1451 if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id))
1452 if (summon->IsAIEnabled())
1453 summon->AI()->SetData(DATA_STACKS_DISPELLED, GetSpellValue()->EffectBasePoints[EFFECT_1]);
1454 }
1455
1460};
1461
1462// 74812 - Leave Twilight Realm
1463// 74807 - Twilight Realm
1465{
1466public:
1467 spell_halion_twilight_realm_handlers(uint32 beforeHitSpell, bool isApplyHandler) : AuraScript(),
1468 _isApply(isApplyHandler), _beforeHitSpellId(beforeHitSpell)
1469 { }
1470
1471private:
1472 bool Validate(SpellInfo const* /*spell*/) override
1473 {
1475 }
1476
1477 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1478 {
1480 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
1481 instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED, nullptr);
1482 }
1483
1484 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1485 {
1486 Unit* target = GetTarget();
1487 if (!target)
1488 return;
1489
1491 if (InstanceScript* instance = target->GetInstanceScript())
1492 instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED, nullptr);
1493 }
1494
1505
1508};
1509
1510// 75396 - Clear Debuffs
1512{
1513 bool Validate(SpellInfo const* /*spell*/) override
1514 {
1516 }
1517
1518 void HandleScript(SpellEffIndex /*effIndex*/)
1519 {
1520 if (GetHitUnit()->HasAura(GetEffectInfo().CalcValueAsInt()))
1521 GetHitUnit()->RemoveAurasDueToSpell(GetEffectInfo().CalcValueAsInt());
1522 }
1523
1528};
1529
1531{
1532 public:
1533 TwilightCutterSelector(Unit* caster, Unit* target) : _caster(caster), _channelTarget(target) { }
1534
1536 {
1537 return !unit->IsInBetween(_caster, _channelTarget, 4.0f);
1538 }
1539
1540 private:
1543};
1544
1545// 74769, 77844, 77845, 77846 - Twilight Cutter
1547{
1548 void RemoveNotBetween(std::list<WorldObject*>& unitList)
1549 {
1550 if (unitList.empty())
1551 return;
1552
1553 Unit* caster = GetCaster();
1554 UF::DynamicUpdateFieldBase<ObjectGuid> const& channelObjects = caster->m_unitData->ChannelObjects;
1555 if (Unit* channelTarget = (channelObjects.size() == 1 ? ObjectAccessor::GetUnit(*caster, *channelObjects.begin()) : nullptr))
1556 {
1557 unitList.remove_if(TwilightCutterSelector(caster, channelTarget));
1558 return;
1559 }
1560
1561 // In case cutter caster werent found for some reason
1562 unitList.clear();
1563 }
1564
1569};
1570
1571// 74808 - Twilight Phasing
1573{
1574 bool Validate(SpellInfo const* /*spellInfo*/) override
1575 {
1577 }
1578
1579 void Phase()
1580 {
1581 Unit* caster = GetCaster();
1582 caster->CastSpell(caster->GetPosition(), SPELL_SUMMON_TWILIGHT_PORTAL, true);
1584 }
1585
1586 void Register() override
1587 {
1589 }
1590};
1591
1592// 74805 - Summon Exit Portals
1594{
1596 {
1597 Position const offset = { 0.0f, 20.0f, 0.0f, 0.0f };
1598 dest.RelocateOffset(offset);
1599 }
1600
1602 {
1603 Position const offset = { 0.0f, -20.0f, 0.0f, 0.0f };
1604 dest.RelocateOffset(offset);
1605 }
1606
1612};
1613
1614// 75880 - Spawn Living Embers
1634
1635// 75886, 75887 - Blazing Aura
1649
1651{
1654
1663
1665
1681}
#define M_PI
Definition Common.h:118
DB2Storage< SummonPropertiesEntry > sSummonPropertiesStore("SummonProperties.db2", &SummonPropertiesLoadInfo::Instance)
@ DIFFICULTY_25_HC
Definition DBCEnums.h:942
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:72
@ 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
@ SPELL_BERSERK
Definition PlayerAI.cpp:371
float frand(float min, float max)
Definition Random.cpp:56
Milliseconds randtime(Milliseconds min, Milliseconds max)
Definition Random.cpp:63
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
#define RegisterSpellScriptWithArgs(spell_script, script_name,...)
Definition ScriptMgr.h:1382
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_FORCE_CAST
@ TARGET_UNIT_SRC_AREA_ENTRY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ TARGET_DEST_CASTER
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:290
HalionEvents
@ 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
HalionActions
@ ACTION_METEOR_STRIKE_AOE
@ ACTION_ACTIVATE_EMBERS
@ ACTION_MONITOR_CORPOREALITY
@ ACTION_METEOR_STRIKE_BURN
@ ACTION_SHOOT
@ ACTION_WARNING_SHOOT
HalionSpells
@ 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
HalionMisc
@ DATA_TWILIGHT_DAMAGE_TAKEN
@ DATA_ROOT_GUID
@ DATA_MATERIAL_DAMAGE_TAKEN
@ DATA_FIGHT_PHASE
@ DATA_SPAWNED_FLAMES
@ DATA_STACKS_DISPELLED
boss_halion HalionAI
uint8 const MAX_CORPOREALITY_STATE
HalionPhases
@ PHASE_ONE
@ PHASE_INTRO
@ PHASE_ALL
@ PHASE_THREE
@ PHASE_TWO
Position const HalionRespawnPos
CorporealityEntry const _corporealityReference[MAX_CORPOREALITY_STATE]
void AddSC_boss_halion()
HalionTexts
@ 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
Position const HalionSpawnPos
CorporealityEvent
@ CORPOREALITY_TWILIGHT_MENDING
@ CORPOREALITY_DECREASE
@ CORPOREALITY_INCREASE
@ CORPOREALITY_NONE
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:180
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureAI * AI() const
Definition Creature.h:235
void SetRemovedCharges(uint8 amount)
Definition Unit.h:413
void Update(uint32 time)
Definition EventMap.h:77
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
EventId ExecuteEvent()
Definition EventMap.cpp:77
bool IsInPhase(PhaseIndex phase) const
Definition EventMap.h:246
void SetPhase(PhaseIndex phase)
Definition EventMap.cpp:32
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:40
void Reset()
Definition EventMap.cpp:25
GameObject *const me
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:209
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:1191
Difficulty GetDifficultyID() const
Definition Map.h:363
PlayerList const & GetPlayers() const
Definition Map.h:408
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:590
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
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
SpellValue const * GetSpellValue() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
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)
std::vector< T >::const_iterator begin() const
std::size_t size() const
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:172
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:71
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:162
virtual uint32 GetData(uint32 id) const
Definition UnitAI.h:74
Definition Unit.h:647
void CastStop(uint32 except_spellid=0)
Definition Unit.cpp:1191
void SetHealth(uint64 val)
Definition Unit.cpp:10041
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:12344
void SetUninteractible(bool apply)
Definition Unit.cpp:8583
uint64 GetHealth() const
Definition Unit.h:800
bool HealthBelowPctDamaged(float pct, uint32 damage) const
Definition Unit.h:805
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
Definition Unit.h:1897
bool HasUnitState(const uint32 f) const
Definition Unit.h:755
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:861
Vehicle * GetVehicleKit() const
Definition Unit.h:1798
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.cpp:11311
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:394
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
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:1403
void setActive(bool isActiveObject)
Definition Object.cpp:274
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2760
void SetFarVisible(bool on)
Definition Object.cpp:325
bool IsInBetween(Position const &pos1, Position const &pos2, float size=0) const
Definition Object.cpp:651
void HandleScript(SpellEffIndex effIndex)
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *spellInfo) override
void HandleTick(AuraEffect const *aurEff)
void OnApply(AuraEffect const *, AuraEffectHandleModes)
spell_halion_combustion_consumption(uint32 spellID)
void AddMarkStack(AuraEffect const *)
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
void HandleSummon(SpellEffIndex effIndex)
void Register() override
spell_halion_marks(uint32 summonSpell, uint32 removeSpell)
bool Validate(SpellInfo 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)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
void SelectMeteorFlames(std::list< WorldObject * > &unitList)
void SetDest1(SpellDestination &dest)
void SetDest0(SpellDestination &dest)
void RemoveNotBetween(std::list< WorldObject * > &unitList)
bool Validate(SpellInfo const *) override
spell_halion_twilight_realm_handlers(uint32 beforeHitSpell, bool isApplyHandler)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void OnApply(AuraEffect const *, AuraEffectHandleModes)
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
#define RegisterRubySanctumCreatureAI(ai_name)
@ 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
#define RegisterRubySanctumGameObjectAI(ai_name)
@ 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::@199::@211 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 SetData(uint32 index, uint32 value) override
boss_halion(Creature *creature)
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
Position _meteorStrikePos
void JustDied(Unit *) override
void UpdateAI(uint32 diff) override
void EnterEvadeMode(EvadeReason why) override
void DamageTaken(Unit *attacker, uint32 &damage, DamageEffectType, SpellInfo const *) override
Position const * GetMeteorStrikePosition() const
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void DamageTaken(Unit *attacker, uint32 &damage, DamageEffectType, SpellInfo const *) override
void JustEngagedWith(Unit *who) override
void KilledUnit(Unit *victim) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void Reset() override
void EnterEvadeMode(EvadeReason) override
boss_twilight_halion(Creature *creature)
void JustDied(Unit *killer) override
void UpdateAI(uint32) override
go_twilight_portal(GameObject *gameobject)
InstanceScript * _instance
bool OnGossipHello(Player *player) override
void SetData(uint32 type, uint32 stackAmount) override
void IsSummonedBy(WorldObject *summoner) override
void UpdateAI(uint32) override
npc_combustion_consumption(Creature *creature)
void JustAppeared() override
void JustDied(Unit *) override
void DoAction(int32 action) override
void JustExitedCombat() override
void SetData(uint32 id, uint32 value) override
uint32 GetSpell(uint8 pctValue, bool isTwilight=false) const
void JustSummoned(Creature *who) override
void JustEngagedWith(Unit *) override
void Reset() override
void UpdateAI(uint32 diff) override
npc_halion_controller(Creature *creature)
InstanceScript * _instance
npc_living_ember(Creature *creature)
void IsSummonedBy(WorldObject *) override
void JustDied(Unit *) override
npc_living_inferno(Creature *creature)
void IsSummonedBy(WorldObject *) override
void UpdateAI(uint32 diff) override
TaskScheduler scheduler
void JustDied(Unit *) override
npc_meteor_strike_flame(Creature *creature)
void IsSummonedBy(WorldObject *) override
InstanceScript * _instance
void UpdateAI(uint32 diff) override
void SetGUID(ObjectGuid const &guid, int32 id) override
void EnterEvadeMode(EvadeReason) override
std::list< Creature * > _meteorList
void DoAction(int32 action) override
void UpdateAI(uint32) override
void IsSummonedBy(WorldObject *summoner) override
npc_meteor_strike_initial(Creature *creature)
void EnterEvadeMode(EvadeReason) override
void IsSummonedBy(WorldObject *) override
InstanceScript * _instance
npc_meteor_strike(Creature *creature)
void DoAction(int32 action) override
void UpdateAI(uint32 diff) override
void SetData(uint32 dataType, uint32 dataCount) override
uint32 GetData(uint32 dataType) const override
void DoAction(int32 action) override
void TriggerCutter(Unit *caster, Unit *target)
InstanceScript * _instance
npc_orb_carrier(Creature *creature)
void UpdateAI(uint32 diff) override
TaskScheduler scheduler