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 "DBCStores.h"
21#include "GameObject.h"
22#include "GameObjectAI.h"
23#include "InstanceScript.h"
24#include "Map.h"
25#include "ObjectAccessor.h"
26#include "Player.h"
27#include "ruby_sanctum.h"
28#include "ScriptedCreature.h"
29#include "Spell.h"
30#include "SpellAuraEffects.h"
31#include "SpellScript.h"
32#include "TemporarySummon.h"
33#include "Vehicle.h"
34
36{
37 // Shared
38 SAY_REGENERATE = 0, // Without pressure in both realms, %s begins to regenerate.
39
40 // Halion
41 SAY_INTRO = 1, // Meddlesome insects! You are too late. The Ruby Sanctum is lost!
42 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!
43 SAY_METEOR_STRIKE = 3, // The heavens burn!
44 SAY_PHASE_TWO = 4, // You will find only suffering within the realm of twilight! Enter if you dare!
45 SAY_DEATH = 5, // Relish this victory, mortals, for it will be your last! This world will burn with the master's return!
46 SAY_KILL = 6, // Another "hero" falls.
47 SAY_BERSERK = 7, // Not good enough.
48 EMOTE_CORPOREALITY_POT = 8, // Your efforts force %s further out of the physical realm!
49 EMOTE_CORPOREALITY_PIP = 9, // Your companions' efforts force %s further into the physical realm!
50
51 // Twilight Halion
52 SAY_SPHERE_PULSE = 1, // Beware the shadow!
53 SAY_PHASE_THREE = 2, // I am the light and the darkness! Cower, mortals, before the herald of Deathwing!
54 EMOTE_CORPOREALITY_TIT = 3, // Your companions' efforts force %s further into the twilight realm!
55 EMOTE_CORPOREALITY_TOT = 4, // Your efforts force %s further out of the twilight realm!
56
57 EMOTE_WARN_LASER = 0 // The orbiting spheres pulse with dark energy!
58};
59
61{
62 // Halion
64 SPELL_CLEAVE = 74524,
67
72
73 // Combustion & Consumption
74 SPELL_SCALE_AURA = 70507, // Aura created in spell_dbc.
77
78 // Twilight Halion
80
85
86 // Living Inferno
90
91 // Halion Controller
95
96 // Meteor Strike
102
103 // Shadow Orb
104 SPELL_TWILIGHT_CUTTER = 74768, // Unknown dummy effect (EFFECT_0)
108
109 // Misc
110 SPELL_TWILIGHT_DIVISION = 75063, // Phase spell from phase 2 to phase 3
112 SPELL_TWILIGHT_PHASING = 74808, // Phase spell from phase 1 to phase 2
113 SPELL_SUMMON_TWILIGHT_PORTAL = 74809, // Summons go 202794
114 SPELL_SUMMON_EXIT_PORTALS = 74805, // Custom spell created in spell_dbc. // Used in Cataclysm, need a sniff of cata and up
119 SPELL_COPY_DAMAGE = 74810 // Aura not found in DBCs.
121
150
152{
153 // Meteor Strike
156
157 // Halion Controller
159
160 // Orb Carrier
165
174
183
191
199
200Position const HalionSpawnPos = {3156.67f, 533.8108f, 72.98822f, 3.159046f};
201Position const HalionRespawnPos = {3156.625f, 533.2674f, 72.97205f, 0.0f};
202
204
210
212{
213 {74836, 74831},
214 {74835, 74830},
215 {74834, 74829},
216 {74833, 74828},
217 {74832, 74827},
218 {74826, 74826},
219 {74827, 74832},
220 {74828, 74833},
221 {74829, 74834},
222 {74830, 74835},
223 {74831, 74836}
224};
225
226// 39863 - Halion
227struct boss_halion : public BossAI
228{
229 boss_halion(Creature* creature) : BossAI(creature, DATA_HALION) { }
230
231 void EnterEvadeMode(EvadeReason why) override
232 {
235 controller->AI()->EnterEvadeMode(why);
236 }
237
259
260 void JustDied(Unit* /*killer*/) override
261 {
262 _JustDied();
263
266
267 if (Creature* twilightHalion = instance->GetCreature(DATA_TWILIGHT_HALION))
268 if (twilightHalion->IsAlive())
269 twilightHalion->KillSelf();
270
272 if (controller->IsAlive())
273 controller->KillSelf();
274 }
275
277
278 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
279 {
280 if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
281 damage = me->GetHealth() - 1;
282
284 {
287
288 me->CastStop();
291
293 controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_TWO);
294 return;
295 }
296
298 {
299 // Don't consider copied damage.
300 if (!me->InSamePhase(attacker))
301 return;
302
304 controller->AI()->SetData(DATA_MATERIAL_DAMAGE_TAKEN, damage);
305 }
306 }
307
308 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
309 {
310 if (spellInfo->Id == SPELL_TWILIGHT_MENDING)
312 }
313
314 void UpdateAI(uint32 diff) override
315 {
317 return;
318
319 if (!UpdateVictim())
320 return;
321
322 events.Update(diff);
323
325 return;
326
327 while (uint32 eventId = events.ExecuteEvent())
328 {
329 switch (eventId)
330 {
331 case EVENT_CLEAVE:
334 break;
335 case EVENT_TAIL_LASH:
338 break;
339 case EVENT_BREATH:
342 break;
344 // Flame ring is activated 5 seconds after starting encounter, DOOR_TYPE_ROOM is only instant.
346 if (GameObject* flameRing = instance->GetGameObject(i))
347 instance->HandleGameObject(ObjectGuid::Empty, false, flameRing);
348 break;
350 {
351 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
352 {
353 _meteorStrikePos = target->GetPosition();
356 }
358 break;
359 }
361 {
362 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
365 break;
366 }
367 default:
368 break;
369 }
370 }
371
373 }
374
375 void SetData(uint32 index, uint32 value) override
376 {
377 if (index != DATA_FIGHT_PHASE)
378 return;
379
380 events.SetPhase(value);
381 }
382
383private:
385};
386
388
389// 40142 - Halion
391{
393 {
395 if (!halion)
396 return;
397
398 // Using AddAura because no spell cast packet in sniffs.
399 halion->AddAura(SPELL_COPY_DAMAGE, me); // We use explicit targeting here to avoid conditions + SPELL_ATTR6_CANT_TARGET_SELF.
400 me->AddAura(SPELL_COPY_DAMAGE, halion);
402
403 me->SetHealth(halion->GetHealth());
404 me->SetPhaseMask(0x20, true);
409 }
410
422
423 void Reset() override { }
424 void EnterEvadeMode(EvadeReason /*why*/) override { }
425
426 void KilledUnit(Unit* victim) override
427 {
428 if (victim->GetTypeId() == TYPEID_PLAYER)
429 Talk(SAY_KILL);
430
431 // Victims should not be in the Twilight Realm
433 }
434
435 void JustDied(Unit* killer) override
436 {
438 {
439 // Ensure looting
441 halion->LowerPlayerDamageReq(halion->GetMaxHealth());
442
443 if (halion->IsAlive())
444 Unit::Kill(killer, halion);
445 }
446
448 if (controller->IsAlive())
449 controller->KillSelf();
450
452 }
453
454 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
455 {
456 if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
457 damage = me->GetHealth() - 1;
458 //Needed because we already have UNIT_FLAG_IN_COMBAT, otherwise JustEngagedWith won't ever be called
460 JustEngagedWith(attacker);
461
463 {
465 me->CastStop();
468 return;
469 }
470
472 {
473 // Don't consider copied damage.
474 if (!me->InSamePhase(attacker))
475 return;
476
478 controller->AI()->SetData(DATA_TWILIGHT_DAMAGE_TAKEN, damage);
479 }
480 }
481
482 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
483 {
484 switch (spellInfo->Id)
485 {
488 controller->AI()->DoAction(ACTION_MONITOR_CORPOREALITY);
489 break;
492 break;
493 default:
494 break;
495 }
496 }
497
498 void UpdateAI(uint32 diff) override
499 {
501 return;
502
503 if (!UpdateVictim())
504 return;
505
506 events.Update(diff);
507
508 while (uint32 eventId = events.ExecuteEvent())
509 {
510 switch (eventId)
511 {
512 case EVENT_CLEAVE:
515 break;
516 case EVENT_TAIL_LASH:
519 break;
520 case EVENT_BREATH:
523 break;
525 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, SPELL_TWILIGHT_REALM))
528 break;
529 default:
530 break;
531 }
532 }
533
535 }
536};
537
538// 40146 - Halion Controller
540{
542 _instance(creature->GetInstanceScript()), _summons(me)
543 {
544 Initialize();
545 }
546
554
563
564 void Reset() override
565 {
567 _events.Reset();
568 Initialize();
569
571 }
572
573 void JustSummoned(Creature* who) override
574 {
575 _summons.Summon(who);
576 }
577
578 void JustDied(Unit* /*killer*/) override
579 {
580 _events.Reset();
582
584 }
585
594
595 void JustExitedCombat() override
596 {
598 return;
599
600 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
601 {
602 twilightHalion->DespawnOrUnsummon();
604 }
605
607 {
608 halion->DespawnOrUnsummon();
610 }
611
614
615 me->DespawnOrUnsummon(0s, 30s);
616 }
617
618 void DoAction(int32 action) override
619 {
620 switch (action)
621 {
623 _events.Reset();
626 break;
629 return;
630
632 if (GameObject* tree = _instance->GetGameObject(i))
635 break;
637 {
638 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
639 {
640 Creature* halion = _instance->GetCreature(itr);
641 if (!halion)
642 continue;
643
644 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), false);
646
647 if (itr == DATA_TWILIGHT_HALION)
648 continue;
649
652 }
653
654 // Summon Twilight portals
656
658 // Hardcoding doesn't really matter here.
661
663 break;
664 }
667 break;
668 default:
669 break;
670 }
671 }
672
673 void UpdateAI(uint32 diff) override
674 {
675 // The IsEngaged() check is needed because that check should be false when Halion is
676 // not engaged, while it would return true without as UpdateVictim() checks for
677 // combat state.
678 if (me->IsEngaged() && !UpdateVictim())
679 return;
680
681 _events.Update(diff);
682
683 while (uint32 eventId = _events.ExecuteEvent())
684 {
685 switch (eventId)
686 {
690 break;
693 if (GameObject* tree = _instance->GetGameObject(i))
696 break;
699 if (GameObject* tree = _instance->GetGameObject(i))
702 break;
706 return;
708 halion->AI()->Talk(SAY_INTRO);
709 break;
711 if (_instance->GetCreature(DATA_HALION)) // Just check if physical Halion is spawned
712 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
713 twilightHalion->CastSpell(nullptr, SPELL_TWILIGHT_MENDING, true);
714 break;
717 halion->CastSpell(halion, SPELL_BERSERK, true);
719 halion->CastSpell(halion, SPELL_BERSERK, true);
720 break;
723 orbCarrier->AI()->DoAction(ACTION_WARNING_SHOOT);
725 break;
729 break;
732 break;
734 DoCheckEvade();
736 break;
737 default:
738 break;
739 }
740 }
741 }
742
744 {
745 Map::PlayerList const& players = me->GetMap()->GetPlayers();
746 for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
747 if (Player* player = i->GetSource())
748 if (player->IsAlive() && IsInBoundary(player) && !player->IsGameMaster())
749 return;
750
752 }
753
754 void SetData(uint32 id, uint32 value) override
755 {
756 switch (id)
757 {
759 _materialDamageTaken += value;
760 break;
762 _twilightDamageTaken += value;
763 break;
764 case DATA_FIGHT_PHASE:
765 _events.SetPhase(value);
766 switch (value)
767 {
768 case PHASE_ONE:
770 break;
771 case PHASE_TWO:
773 break;
774 default:
775 break;
776 }
777 break;
778 default:
779 break;
780 }
781 }
782
783private:
785 // [0 , 0.98[: Corporeality goes down
786 // [0.98, 0.99]: Do nothing
787 // ]0.99, 1.01[: Twilight Mending
788 // [1.01, 1.02]: Do nothing
789 // ]1.02, +oo [: Corporeality goes up
791 {
794 {
798 return;
799 }
800
801 float damageRatio = float(_materialDamageTaken) / float(_twilightDamageTaken);
802
804 if (damageRatio < 0.98f) // [0 , 0.98[: Corporeality goes down
805 action = CORPOREALITY_DECREASE;
806 else if (0.99f < damageRatio && damageRatio < 1.01f) // ]0.99, 1.01[: Twilight Mending
808 else if (1.02f < damageRatio) // ]1.02, +oo [: Corporeality goes up
809 action = CORPOREALITY_INCREASE;
810
811 switch (action)
812 {
814 {
817 return;
818 }
820 {
822 return;
824 break;
825 }
827 {
829 return;
831 break;
832 }
834 {
838 return;
839 }
840 }
841
844
847
848 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
849 {
850 if (Creature* halion = _instance->GetCreature(itr))
851 {
852 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), true);
853
854 if (itr == DATA_TWILIGHT_HALION)
855 halion->AI()->Talk(oldValue < _materialCorporealityValue ? EMOTE_CORPOREALITY_TOT : EMOTE_CORPOREALITY_TIT, halion);
856 else // if (itr == DATA_HALION)
857 halion->AI()->Talk(oldValue > _materialCorporealityValue ? EMOTE_CORPOREALITY_POT : EMOTE_CORPOREALITY_PIP, halion);
858 }
859 }
860 }
861
862 uint32 GetSpell(uint8 pctValue, bool isTwilight = false) const
863 {
865 return isTwilight ? entry.twilightRealmSpell : entry.materialRealmSpell;
866 }
867
871
875};
876
877// 40081 - Orb Carrier
879{
880 npc_orb_carrier(Creature* creature) : ScriptedAI(creature),
881 _instance(creature->GetInstanceScript())
882 {
883 ASSERT(creature->GetVehicleKit());
884 }
885
886 void UpdateAI(uint32 diff) override
887 {
892 me->CastSpell(nullptr, SPELL_TRACK_ROTATION, false);
893
894 scheduler.Update(diff);
895 }
896
897 void DoAction(int32 action) override
898 {
899 switch (action)
900 {
902 {
903 Vehicle* vehicle = me->GetVehicleKit();
904 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
905 if (northOrb && northOrb->GetTypeId() == TYPEID_UNIT)
906 northOrb->ToCreature()->AI()->Talk(EMOTE_WARN_LASER);
907
908 scheduler.Schedule(Seconds(5), [this](TaskContext /*context*/)
909 {
911 });
912 break;
913 }
914 case ACTION_SHOOT:
915 {
916 Vehicle* vehicle = me->GetVehicleKit();
917 Unit* southOrb = vehicle->GetPassenger(SEAT_SOUTH);
918 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
919 if (southOrb && northOrb)
920 TriggerCutter(northOrb, southOrb);
921
922 if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
923 twilightHalion->AI()->Talk(SAY_SPHERE_PULSE);
924
925 if (!IsHeroic())
926 return;
927
928 Unit* eastOrb = vehicle->GetPassenger(SEAT_EAST);
929 Unit* westOrb = vehicle->GetPassenger(SEAT_WEST);
930 if (eastOrb && westOrb)
931 TriggerCutter(eastOrb, westOrb);
932 break;
933 }
934 default:
935 break;
936 }
937 }
938private:
941
942 void TriggerCutter(Unit* caster, Unit* target)
943 {
944 caster->CastSpell(caster, SPELL_TWILIGHT_PULSE_PERIODIC, true);
945 target->CastSpell(target, SPELL_TWILIGHT_PULSE_PERIODIC, true);
946 caster->CastSpell(target, SPELL_TWILIGHT_CUTTER, false);
947 }
948};
949
950// 40029 - Meteor Strike
952{
954 _instance(creature->GetInstanceScript())
955 {
956 SetCombatMovement(false);
957 }
958
959 void DoAction(int32 action) override
960 {
961 switch (action)
962 {
966 for (std::list<Creature*>::iterator itr = _meteorList.begin(); itr != _meteorList.end(); ++itr)
967 (*itr)->AI()->DoAction(ACTION_METEOR_STRIKE_BURN);
968 break;
969 }
970 }
971
972 void IsSummonedBy(WorldObject* summoner) override
973 {
974 Creature* owner = summoner->ToCreature();
975 if (!owner)
976 return;
977
978 // Let Controller count as summoner
980 controller->AI()->JustSummoned(me);
981
984
985 if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
986 {
987 Position const* ownerPos = halionAI->GetMeteorStrikePosition();
988 float randomAdjustment = frand(static_cast<float>(M_PI / 5.0f), static_cast<float>(M_PI / 2.0f));
989 float angle[4];
990 angle[0] = me->GetAbsoluteAngle(ownerPos);
991 angle[1] = angle[0] + randomAdjustment;
992 angle[2] = angle[0] + static_cast<float>(M_PI);
993 angle[3] = angle[2] + randomAdjustment;
994
995 _meteorList.clear();
996 for (uint8 i = 0; i < 4; i++)
997 {
998 angle[i] = Position::NormalizeOrientation(angle[i]);
999 me->SetOrientation(angle[i]);
1000 Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance
1002 _meteorList.push_back(meteor);
1003 }
1004 }
1005 }
1006
1007 void UpdateAI(uint32 /*diff*/) override { }
1008 void EnterEvadeMode(EvadeReason /*why*/) override { }
1009private:
1011 std::list<Creature*> _meteorList;
1012};
1013
1014// 40041, 40042, 40043, 40044 - Meteor Strike
1016{
1017 npc_meteor_strike(Creature* creature) : ScriptedAI(creature),
1018 _instance(creature->GetInstanceScript()), _spawnCount(0)
1019 {
1020 SetCombatMovement(false);
1021 }
1022
1023 void DoAction(int32 action) override
1024 {
1025 if (action == ACTION_METEOR_STRIKE_BURN)
1026 {
1028 me->setActive(true);
1029 me->SetFarVisible(true);
1031 }
1032 }
1033
1034 void IsSummonedBy(WorldObject* /*summoner*/) override
1035 {
1036 // Let Halion Controller count as summoner.
1038 controller->AI()->JustSummoned(me);
1039 }
1040
1041 void SetData(uint32 dataType, uint32 dataCount) override
1042 {
1043 if (dataType == DATA_SPAWNED_FLAMES)
1044 _spawnCount += dataCount;
1045 }
1046
1047 uint32 GetData(uint32 dataType) const override
1048 {
1049 if (dataType == DATA_SPAWNED_FLAMES)
1050 return _spawnCount;
1051 return 0;
1052 }
1053
1054 void UpdateAI(uint32 diff) override
1055 {
1056 _events.Update(diff);
1057
1059 {
1060 Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
1062 flame->AI()->SetGUID(me->GetGUID());
1063 }
1064 }
1065
1066private:
1070};
1071
1072// 40055 - Meteor Strike
1074{
1076 _instance(creature->GetInstanceScript())
1077 {
1078 SetCombatMovement(false);
1079 }
1080
1081 void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
1082 {
1083 _rootOwnerGuid = guid;
1085 }
1086
1087 void IsSummonedBy(WorldObject* /*summoner*/) override
1088 {
1089 // Let Halion Controller count as summoner.
1091 controller->AI()->JustSummoned(me);
1092 }
1093
1094 void UpdateAI(uint32 diff) override
1095 {
1096 _events.Update(diff);
1098 return;
1099
1101
1103 if (!meteorStrike)
1104 return;
1105
1106 meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1);
1107 if (meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5)
1108 return;
1109
1110 Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
1112 flame->AI()->SetGUID(_rootOwnerGuid);
1113 }
1114
1115 void EnterEvadeMode(EvadeReason /*why*/) override { }
1116
1117private:
1121};
1122
1123// 40001 - Combustion
1124// 40135 - Consumption
1126{
1128 _instance(creature->GetInstanceScript())
1129 {
1130 SetCombatMovement(false);
1131
1132 switch (creature->GetEntry())
1133 {
1134 case NPC_COMBUSTION:
1137 creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x01, true);
1138 break;
1139 case NPC_CONSUMPTION:
1142 creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x20, true);
1143 break;
1144 default: // Should never happen
1145 _explosionSpell = 0;
1146 _damageSpell = 0;
1147 break;
1148 }
1149 }
1150
1151 void IsSummonedBy(WorldObject* summoner) override
1152 {
1153 // Let Halion Controller count as summoner
1155 controller->AI()->JustSummoned(me);
1156
1157 _summonerGuid = summoner->GetGUID();
1158 }
1159
1160 void SetData(uint32 type, uint32 stackAmount) override
1161 {
1163
1164 if (type != DATA_STACKS_DISPELLED || !_damageSpell || !_explosionSpell || !summoner)
1165 return;
1166
1167 CastSpellExtraArgs args;
1168 args.AddSpellMod(SPELLVALUE_AURA_STACK, stackAmount + 1);
1171
1172 int32 damage = 1200 + (stackAmount * 1290); // Needs more research.
1173 CastSpellExtraArgs args2;
1174 args2.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
1175 summoner->CastSpell(summoner, _explosionSpell, args2);
1176 }
1177
1178 void UpdateAI(uint32 /*diff*/) override { }
1179
1180private:
1185};
1186
1187// 40681 - Living Inferno
1189{
1190 npc_living_inferno(Creature* creature) : ScriptedAI(creature) { }
1191
1192 void IsSummonedBy(WorldObject* /*summoner*/) override
1193 {
1196
1197 // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs.
1199 scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/)
1200 {
1202 });
1203
1204 if (InstanceScript* instance = me->GetInstanceScript())
1205 if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
1206 {
1207 controller->AI()->DoAction(ACTION_ACTIVATE_EMBERS);
1208 controller->AI()->JustSummoned(me);
1209 }
1210 }
1211
1212 void JustDied(Unit* /*killer*/) override
1213 {
1214 me->DespawnOrUnsummon(1ms);
1215 }
1216
1217 void UpdateAI(uint32 diff) override
1218 {
1219 scheduler.Update(diff);
1221 }
1222
1223private:
1225};
1226
1227// 40683 - Living Ember
1229{
1230 npc_living_ember(Creature* creature) : ScriptedAI(creature) { }
1231
1232 void IsSummonedBy(WorldObject* /*summoner*/) override
1233 {
1234 if (InstanceScript* instance = me->GetInstanceScript())
1235 if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
1236 controller->AI()->JustSummoned(me);
1237 }
1238
1239 void JustDied(Unit* /*killer*/) override
1240 {
1241 me->DespawnOrUnsummon(1ms);
1242 }
1243};
1244
1245// 202794, 202796 - Twilight Portal
1247{
1248 go_twilight_portal(GameObject* gameobject) : GameObjectAI(gameobject),
1249 _instance(gameobject->GetInstanceScript()), _deleted(false)
1250 {
1251 switch (gameobject->GetEntry())
1252 {
1254 gameobject->SetPhaseMask(0x20, true);
1255 _spellId = gameobject->GetGOInfo()->goober.spellId;
1256 break;
1257 case GO_HALION_PORTAL_1:
1258 case GO_HALION_PORTAL_2:
1259 gameobject->SetPhaseMask(0x1, true);
1262 break;
1263 default:
1264 _spellId = 0;
1265 break;
1266 }
1267 }
1268
1269 bool OnGossipHello(Player* player) override
1270 {
1271 if (_spellId != 0)
1272 player->CastSpell(player, _spellId, true);
1273 return true;
1274 }
1275
1276 void UpdateAI(uint32 /*diff*/) override
1277 {
1279 return;
1280
1281 if (!_deleted)
1282 {
1283 _deleted = true;
1284 me->Delete();
1285 }
1286 }
1287
1288private:
1292};
1293
1294// 74641 - Meteor Strike
1296{
1298
1299 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1300 {
1301 if (!GetCaster())
1302 return;
1303
1304 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
1305 if (Creature* creCaster = GetCaster()->ToCreature())
1306 creCaster->AI()->DoAction(ACTION_METEOR_STRIKE_AOE);
1307 }
1308
1313};
1314
1315// 74792 - Soul Consumption
1316// 74562 - Fiery Combustion
1318{
1320
1321public:
1323
1324private:
1325 bool Validate(SpellInfo const* /*spellInfo*/) override
1326 {
1327 return ValidateSpellInfo({ _markSpell });
1328 }
1329
1330 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1331 {
1332 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
1333 return;
1334
1335 if (GetTarget()->HasAura(_markSpell))
1337 }
1338
1339 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1340 {
1342 }
1343
1344 void AddMarkStack(AuraEffect const* /*aurEff*/)
1345 {
1347 }
1348
1355
1357};
1358
1359// 74629 - Combustion Periodic
1360// 74803 - Consumption Periodic
1362{
1364
1365 bool Validate(SpellInfo const* spellInfo) override
1366 {
1367 return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
1368 }
1369
1370 void HandleTick(AuraEffect const* aurEff)
1371 {
1373 Unit* caster = GetCaster();
1374 if (!caster)
1375 return;
1376
1377 uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
1378 int32 radius = caster->GetObjectScale() * M_PI * 10000 / 3;
1379
1380 CastSpellExtraArgs args(aurEff);
1381 args.OriginalCaster = caster->GetGUID();
1382 args.AddSpellMod(SPELLVALUE_RADIUS_MOD, radius);
1383 caster->CastSpell(nullptr, triggerSpell, args);
1384 }
1385
1390};
1391
1392// 74567 - Mark of Combustion
1393// 74795 - Mark of Consumption
1395{
1397
1398public:
1399 spell_halion_marks(uint32 summonSpell, uint32 removeSpell) : AuraScript(),
1400 _summonSpellId(summonSpell), _removeSpellId(removeSpell) { }
1401
1402private:
1403 bool Validate(SpellInfo const* /*spell*/) override
1404 {
1406 }
1407
1409 void BeforeDispel(DispelInfo* dispelData)
1410 {
1411 // Prevent any stack from being removed at this point.
1412 dispelData->SetRemovedCharges(0);
1413
1414 if (Unit* dispelledUnit = GetUnitOwner())
1415 if (dispelledUnit->HasAura(_removeSpellId))
1416 dispelledUnit->RemoveAurasDueToSpell(_removeSpellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
1417 }
1418
1419 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1420 {
1421 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
1422 return;
1423
1424 // Stacks marker
1428 }
1429
1435
1438};
1439
1440// 74610 - Fiery Combustion
1441// 74800 - Soul Consumption
1443{
1445
1447 {
1448 PreventHitDefaultEffect(effIndex);
1449 Unit* caster = GetCaster();
1450 uint32 entry = uint32(GetEffectInfo().MiscValue);
1451 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB));
1452 uint32 duration = uint32(GetSpellInfo()->GetDuration());
1453
1454 Position pos = caster->GetPosition();
1455 if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id))
1456 if (summon->IsAIEnabled())
1457 summon->AI()->SetData(DATA_STACKS_DISPELLED, GetSpellValue()->EffectBasePoints[EFFECT_1]);
1458 }
1459
1464};
1465
1466// 74812 - Leave Twilight Realm
1467// 74807 - Twilight Realm
1469{
1471
1472public:
1473 spell_halion_twilight_realm_handlers(uint32 beforeHitSpell, bool isApplyHandler) : AuraScript(),
1474 _isApply(isApplyHandler), _beforeHitSpellId(beforeHitSpell)
1475 { }
1476
1477private:
1478 bool Validate(SpellInfo const* /*spell*/) override
1479 {
1481 }
1482
1483 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1484 {
1486 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
1487 instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED);
1488 }
1489
1490 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1491 {
1492 Unit* target = GetTarget();
1493 if (!target)
1494 return;
1495
1497 if (InstanceScript* instance = target->GetInstanceScript())
1498 instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED);
1499 }
1500
1511
1514};
1515
1516// 75396 - Clear Debuffs
1518{
1520
1521 bool Validate(SpellInfo const* /*spell*/) override
1522 {
1524 }
1525
1526 void HandleScript(SpellEffIndex /*effIndex*/)
1527 {
1528 if (GetHitUnit()->HasAura(GetEffectInfo().CalcValue()))
1530 }
1531
1536};
1537
1539{
1540 public:
1541 TwilightCutterSelector(Unit* caster, Unit* target) : _caster(caster), _channelTarget(target) { }
1542
1544 {
1545 return !unit->IsInBetween(_caster, _channelTarget, 4.0f);
1546 }
1547
1548 private:
1551};
1552
1553// 74769, 77844, 77845, 77846 - Twilight Cutter
1555{
1557
1558 void RemoveNotBetween(std::list<WorldObject*>& unitList)
1559 {
1560 if (unitList.empty())
1561 return;
1562
1563 Unit* caster = GetCaster();
1564 if (Unit* channelTarget = ObjectAccessor::GetUnit(*caster, caster->GetChannelObjectGuid()))
1565 {
1566 unitList.remove_if(TwilightCutterSelector(caster, channelTarget));
1567 return;
1568 }
1569
1570 // In case cutter caster werent found for some reason
1571 unitList.clear();
1572 }
1573
1578};
1579
1580// 74808 - Twilight Phasing
1582{
1584
1585 bool Validate(SpellInfo const* /*spellInfo*/) override
1586 {
1588 }
1589
1590 void Phase()
1591 {
1592 Unit* caster = GetCaster();
1593 caster->CastSpell(caster->GetPosition(), SPELL_SUMMON_TWILIGHT_PORTAL, true);
1595 }
1596
1597 void Register() override
1598 {
1600 }
1601};
1602
1603// 74805 - Summon Exit Portals
1605{
1607
1609 {
1610 Position const offset = { 0.0f, 20.0f, 0.0f, 0.0f };
1611 dest.RelocateOffset(offset);
1612 }
1613
1615 {
1616 Position const offset = { 0.0f, -20.0f, 0.0f, 0.0f };
1617 dest.RelocateOffset(offset);
1618 }
1619
1625};
1626
1627// 75880 - Spawn Living Embers
1649
1650// 75886, 75887 - Blazing Aura
1666
1668{
1671
1680
1682
1698}
#define M_PI
Definition Common.h:72
@ RAID_DIFFICULTY_25MAN_HEROIC
Definition DBCEnums.h:289
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:27
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
#define ASSERT
Definition Errors.h:68
@ IN_PROGRESS
@ FAIL
@ DONE
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED
@ ENCOUNTER_FRAME_ENGAGE
@ TEMPSUMMON_TIMED_DESPAWN
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
@ 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
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
#define RegisterSpellScriptWithArgs(spell_script, script_name,...)
Definition ScriptMgr.h:1127
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
@ AURA_REMOVE_BY_DEATH
@ AURA_REMOVE_BY_EXPIRE
@ AURA_REMOVE_BY_ENEMY_SPELL
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PHASE
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
@ SPELLVALUE_AURA_STACK
@ 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)
#define CAST_AI(a, b)
Definition UnitAI.h:27
@ REACT_DEFENSIVE
@ UNIT_FLAG_IN_COMBAT
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
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_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:164
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
EventMap events
virtual void JustSummoned(Creature *)
Definition CreatureAI.h:136
@ EVADE_REASON_BOUNDARY
Definition CreatureAI.h:95
@ EVADE_REASON_NO_HOSTILES
Definition CreatureAI.h:94
void DoZoneInCombat(Creature *creature=nullptr)
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:82
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
void SetPhaseMask(uint32 newPhaseMask, bool update) override
Definition Creature.cpp:652
bool IsEngaged() const override
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
bool IsDamageEnoughForLootingAndReward() const
Definition Creature.h:321
CreatureAI * AI() const
Definition Creature.h:154
void SetRemovedCharges(uint8 amount)
Definition Unit.h:407
void Update(uint32 time)
Definition EventMap.h:67
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
EventId ExecuteEvent()
Definition EventMap.cpp:73
bool IsInPhase(PhaseIndex phase) const
Definition EventMap.h:236
void SetPhase(PhaseIndex phase)
Definition EventMap.cpp:28
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
GameObject *const me
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:102
void Delete()
void SetPhaseMask(uint32 newPhaseMask, bool update) override
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
void HandleGameObject(ObjectGuid guid, bool open, GameObject *go=nullptr)
virtual ObjectGuid GetGuidData(uint32 type) const override
CreatureBoundary const * GetBossBoundary(uint32 id) const
EncounterState GetBossState(uint32 id) const
GameObject * GetGameObject(uint32 type)
void DoUpdateWorldState(uint32 worldstateId, uint32 worldstateValue)
void SendEncounterUnit(EncounterFrameType type, Unit const *unit=nullptr, uint8 param1=0, uint8 param2=0)
iterator end()
iterator begin()
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1852
Difficulty GetDifficulty() const
Definition Map.h:412
PlayerList const & GetPlayers() const
Definition Map.h:448
static ObjectGuid const Empty
Definition ObjectGuid.h:140
bool IsEmpty() const
Definition ObjectGuid.h:172
static Creature * ToCreature(Object *o)
Definition Object.h:186
float GetObjectScale() const
Definition Object.h:84
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 TriggerSpell
Definition SpellInfo.h:228
uint32 Id
Definition SpellInfo.h:289
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:483
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(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler & Update(success_t const &callback=EmptyCallback)
bool operator()(WorldObject *unit)
TwilightCutterSelector(Unit *caster, Unit *target)
virtual void SetData(uint32, uint32)
Definition UnitAI.h:156
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
virtual uint32 GetData(uint32) const
Definition UnitAI.h:155
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
Definition Unit.h:769
void CastStop(uint32 except_spellid=0)
Definition Unit.cpp:988
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:11964
void SetHealth(uint32 val)
Definition Unit.cpp:9361
uint32 GetHealth() const
Definition Unit.h:913
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
ObjectGuid GetChannelObjectGuid() const
Definition Unit.h:1460
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition Unit.h:918
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true)
Definition Unit.cpp:10930
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
Vehicle * GetVehicleKit() const
Definition Unit.h:1735
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
Unit * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
Definition Vehicle.cpp:296
Map * GetMap() const
Definition Object.h:449
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
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:1992
void setActive(bool isActiveObject)
Definition Object.cpp:991
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:3250
bool InSamePhase(uint32 phasemask) const
Definition Object.h:369
void SetFarVisible(bool on)
Definition Object.cpp:1014
bool IsInBetween(Position const &pos1, Position const &pos2, float size=0) const
Definition Object.cpp:1349
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
PrepareSpellScript(spell_halion_blazing_aura)
void HandleScript(SpellEffIndex effIndex)
void HandleScript(SpellEffIndex)
PrepareSpellScript(spell_halion_clear_debuffs)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_halion_combustion_consumption_periodic)
bool Validate(SpellInfo const *spellInfo) override
void HandleTick(AuraEffect const *aurEff)
void OnApply(AuraEffect const *, AuraEffectHandleModes)
spell_halion_combustion_consumption(uint32 spellID)
PrepareAuraScript(spell_halion_combustion_consumption)
void AddMarkStack(AuraEffect const *)
bool Validate(SpellInfo const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
void HandleSummon(SpellEffIndex effIndex)
PrepareSpellScript(spell_halion_damage_aoe_summon)
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)
PrepareAuraScript(spell_halion_marks)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_halion_meteor_strike_marker)
void SelectMeteorFlames(std::list< WorldObject * > &unitList)
PrepareSpellScript(spell_halion_spawn_living_embers)
void SetDest1(SpellDestination &dest)
void SetDest0(SpellDestination &dest)
PrepareSpellScript(spell_halion_summon_exit_portals)
PrepareSpellScript(spell_halion_twilight_cutter)
void RemoveNotBetween(std::list< WorldObject * > &unitList)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_halion_twilight_phasing)
spell_halion_twilight_realm_handlers(uint32 beforeHitSpell, bool isApplyHandler)
PrepareAuraScript(spell_halion_twilight_realm_handlers)
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:66
#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
@ GO_HALION_PORTAL_1
@ GO_HALION_PORTAL_EXIT
@ GO_HALION_PORTAL_2
@ WORLDSTATE_CORPOREALITY_TOGGLE
@ WORLDSTATE_CORPOREALITY_MATERIAL
@ WORLDSTATE_CORPOREALITY_TWILIGHT
#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 & AddSpellMod(SpellValueMod mod, int32 val)
ObjectGuid OriginalCaster
struct GameObjectTemplate::@191::@202 goober
static float NormalizeOrientation(float o)
Definition Position.cpp:156
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:128
void SetOrientation(float orientation)
Definition Position.h:74
void GetPosition(float &x, float &y) const
Definition Position.h:84
bool IsHeroic() const
void SetCombatMovement(bool allowMovement)
virtual void UpdateAI(uint32 diff) override
void RelocateOffset(Position const &offset)
Definition Spell.cpp:110
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
void SetGUID(ObjectGuid const &guid, int32) override
npc_meteor_strike_flame(Creature *creature)
void IsSummonedBy(WorldObject *) override
InstanceScript * _instance
void UpdateAI(uint32 diff) 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