Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_halion.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "ScriptMgr.h"
7#include "SpellScript.h"
8#include "SpellAuraEffects.h"
9#include "Spell.h"
10#include "Vehicle.h"
11#include "GameObjectAI.h"
12#include "ScriptedCreature.h"
13#include "ruby_sanctum.h"
14#include "Player.h"
15
16/* ScriptData
17SDName: ruby_sanctum
18SDAuthors: Kaelima, Warpten
19SD%Complete: 90%
20SDComment: Based on Kaelima's initial work (half of it). Corporeality handling is a pure guess, we lack info.
21SDCategory: Chamber of Aspects
22EndScriptData */
23
25{
26 // Shared
27 SAY_REGENERATE = 0, // Without pressure in both realms, %s begins to regenerate.
28
29 // Halion
30 SAY_INTRO = 1, // Meddlesome insects! You are too late. The Ruby Sanctum is lost!
31 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!
32 SAY_METEOR_STRIKE = 3, // The heavens burn!
33 SAY_PHASE_TWO = 4, // You will find only suffering within the realm of twilight! Enter if you dare!
34 SAY_DEATH = 5, // Relish this victory, mortals, for it will be your last! This world will burn with the master's return!
35 SAY_KILL = 6, // Another "hero" falls.
36 SAY_BERSERK = 7, // Not good enough.
37 EMOTE_CORPOREALITY_POT = 8, // Your efforts force %s further out of the physical realm!
38 EMOTE_CORPOREALITY_PIP = 9, // Your companions' efforts force %s further into the physical realm!
39
40 // Twilight Halion
41 SAY_SPHERE_PULSE = 1, // Beware the shadow!
42 SAY_PHASE_THREE = 2, // I am the light and the darkness! Cower, mortals, before the herald of Deathwing!
43 EMOTE_CORPOREALITY_TIT = 3, // Your companions' efforts force %s further into the twilight realm!
44 EMOTE_CORPOREALITY_TOT = 4, // Your efforts force %s further out of the twilight realm!
45
46 EMOTE_WARN_LASER = 0, // The orbiting spheres pulse with dark energy!
47};
48
50{
51 // Halion
53 SPELL_CLEAVE = 74524,
56
61
62 // Combustion & Consumption
63 SPELL_SCALE_AURA = 70507, // Aura created in spell_dbc.
66
67 // Twilight Halion
69
74
75 // Living Inferno
77
78 // Halion Controller
82
83 // Meteor Strike
89
90 // Shadow Orb
91 SPELL_TWILIGHT_CUTTER = 74768, // Unknown dummy effect (EFFECT_0)
95
96 // Misc
97 SPELL_TWILIGHT_DIVISION = 75063, // Phase spell from phase 2 to phase 3
99 SPELL_TWILIGHT_PHASING = 74808, // Phase spell from phase 1 to phase 2
100 SPELL_SUMMON_TWILIGHT_PORTAL = 74809, // Summons go 202794
101 SPELL_SUMMON_EXIT_PORTALS = 74805, // Custom spell created in spell_dbc.
106 SPELL_COPY_DAMAGE = 74810 // Aura not found in DBCs.
107};
108
135
137{
138 // Meteor Strike
141
142 // Halion Controller
144
145 // Orb Carrier
147};
148
157
166
174
182
183Position const HalionSpawnPos = {3156.67f, 533.8108f, 72.98822f, 3.159046f};
184
186
192
194 {74836, 74831},
195 {74835, 74830},
196 {74834, 74829},
197 {74833, 74828},
198 {74832, 74827},
199 {74826, 74826},
200 {74827, 74832},
201 {74828, 74833},
202 {74829, 74834},
203 {74830, 74835},
204 {74831, 74836}
205};
206
208{
209 generic_halionAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), _canEvade(false) { }
210
211 void EnterCombat(Unit* /*who*/) OVERRIDE
212 {
213 _EnterCombat();
214 me->AddAura(SPELL_TWILIGHT_PRECISION, me);
215 _canEvade = false;
216 events.ScheduleEvent(EVENT_CLEAVE, std::rand() % 10000 + 8000);
217 events.ScheduleEvent(EVENT_TAIL_LASH, 10000);
218 events.ScheduleEvent(EVENT_BREATH, std::rand() % 15000 + 10000);
219 }
220
222 {
223 _canEvade = false;
224 _Reset();
225 }
226
228 {
229 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
231 }
232
234 {
235 switch (eventId)
236 {
237 case EVENT_CLEAVE:
239 events.ScheduleEvent(EVENT_CLEAVE, std::rand() % 10000 + 8000);
240 break;
241 case EVENT_TAIL_LASH:
243 events.ScheduleEvent(EVENT_TAIL_LASH, 10000);
244 break;
245 case EVENT_BREATH:
247 events.ScheduleEvent(EVENT_BREATH, std::rand() % 12000 + 10000);
248 break;
249 }
250 }
251
253 {
254 if (!UpdateVictim() || me->HasUnitState(UNIT_STATE_CASTING))
255 return;
256
257 events.Update(diff);
258
259 while (uint32 eventId = events.ExecuteEvent())
260 ExecuteEvent(eventId);
261
263 }
264
265 void SetData(uint32 index, uint32 dataValue) OVERRIDE
266 {
267 switch (index)
268 {
270 _canEvade = (dataValue == 1);
271 break;
272 default:
273 break;
274 }
275 }
276
277 void SpellHit(Unit* /*who*/, SpellInfo const* spellInfo) OVERRIDE
278 {
279 if (spellInfo->Id == SPELL_TWILIGHT_MENDING)
281 }
282
283protected:
285};
286
288{
289 public:
290 boss_halion() : CreatureScript("boss_halion") { }
291
293 {
295 {
296 me->SetHomePosition(HalionSpawnPos);
297 }
298
300 {
302 me->SetReactState(REACT_DEFENSIVE);
303 me->RemoveAurasDueToSpell(SPELL_TWILIGHT_PHASING);
305 }
306
308 {
309 // Phase 1: We always can evade. Phase 2 & 3: We can evade if and only if the controller tells us to.
310 if (events.IsInPhase(PHASE_ONE) || _canEvade)
312 }
313
315 {
317
318 events.Reset();
319 events.SetPhase(PHASE_ONE);
320
322
323 instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
324 instance->SetBossState(DATA_HALION, IN_PROGRESS);
325
326 events.ScheduleEvent(EVENT_ACTIVATE_FIREWALL, 5000);
327 events.ScheduleEvent(EVENT_METEOR_STRIKE, std::rand() % 25000 + 20000);
328 events.ScheduleEvent(EVENT_FIERY_COMBUSTION, std::rand() % 18000 + 15000);
329
331 controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_ONE);
332 }
333
334 void JustDied(Unit* /*killer*/) OVERRIDE
335 {
336 _JustDied();
337
339 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
340
341 if (Creature* twilightHalion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TWILIGHT_HALION)))
342 if (twilightHalion->IsAlive())
343 twilightHalion->Kill(twilightHalion);
344
346 if (controller->IsAlive())
347 controller->Kill(controller);
348 }
349
351
352 void DamageTaken(Unit* attacker, uint32& damage) OVERRIDE
353 {
354 if (me->HealthBelowPctDamaged(75, damage) && events.IsInPhase(PHASE_ONE))
355 {
356 events.SetPhase(PHASE_TWO);
358
359 me->CastStop();
362
364 controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_TWO);
365 return;
366 }
367
368 if (events.IsInPhase(PHASE_THREE))
369 {
370 // Don't consider copied damage.
371 if (!me->InSamePhase(attacker))
372 return;
373
375 controller->AI()->SetData(DATA_MATERIAL_DAMAGE_TAKEN, damage);
376 }
377 }
378
380 {
381 if (events.IsInPhase(PHASE_TWO))
382 return;
383
385 }
386
388 {
389 switch (eventId)
390 {
392 // Flame ring is activated 5 seconds after starting encounter, DOOR_TYPE_ROOM is only instant.
394 if (GameObject* flameRing = ObjectAccessor::GetGameObject(*me, instance->GetData64(i)))
395 instance->HandleGameObject(instance->GetData64(DATA_FLAME_RING), false, flameRing);
396 break;
398 {
399 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_TWILIGHT_REALM))
400 {
401 target->GetPosition(&_meteorStrikePos);
402 me->CastSpell(_meteorStrikePos.GetPositionX(), _meteorStrikePos.GetPositionY(), _meteorStrikePos.GetPositionZ(), SPELL_METEOR_STRIKE, true, NULL, NULL, me->GetGUID());
404 }
405 events.ScheduleEvent(EVENT_METEOR_STRIKE, 40000);
406 break;
407 }
409 {
410 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_TWILIGHT_REALM))
412 events.ScheduleEvent(EVENT_FIERY_COMBUSTION, 25000);
413 break;
414 }
415 default:
417 break;
418 }
419 }
420
421 void SetData(uint32 index, uint32 value) OVERRIDE
422 {
423 switch (index)
424 {
425 case DATA_FIGHT_PHASE:
426 events.SetPhase(value);
427 break;
428 default:
429 generic_halionAI::SetData(index, value);
430 }
431 }
432
433 private:
435 };
436
438 {
439 return GetRubySanctumAI<boss_halionAI>(creature);
440 }
441};
442
444
446{
447 public:
448 boss_twilight_halion() : CreatureScript("boss_twilight_halion") { }
449
451 {
453 {
455 if (!halion)
456 return;
457
458 // Using AddAura because no spell cast packet in sniffs.
459 halion->AddAura(SPELL_COPY_DAMAGE, me); // We use explicit targeting here to avoid conditions + SPELL_ATTR6_CANT_TARGET_SELF.
460 me->AddAura(SPELL_COPY_DAMAGE, halion);
461 me->AddAura(SPELL_DUSK_SHROUD, me);
462
463 me->SetHealth(halion->GetHealth());
464 me->SetPhaseMask(0x20, true);
465 me->SetReactState(REACT_AGGRESSIVE);
466 }
467
469 {
470 events.Reset();
471 events.SetPhase(PHASE_TWO);
472
474
475 events.ScheduleEvent(EVENT_SOUL_CONSUMPTION, 20000);
476
477 instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 2);
478 }
479
480 // Never evade
482
484 {
485 if (victim->GetTypeId() == TypeID::TYPEID_PLAYER)
486 Talk(SAY_KILL);
487
488 // Victims should not be in the Twilight Realm
489 me->CastSpell(victim, SPELL_LEAVE_TWILIGHT_REALM, true);
490 }
491
492 void JustDied(Unit* killer) OVERRIDE
493 {
494 if (Creature* halion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION)))
495 {
496 // Ensure looting
497 if (me->IsDamageEnoughForLootingAndReward())
498 halion->LowerPlayerDamageReq(halion->GetMaxHealth());
499
500 if (halion->IsAlive())
501 killer->Kill(halion);
502 }
503
505 if (controller->IsAlive())
506 controller->Kill(controller);
507
508 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
509 }
510
511 void DamageTaken(Unit* attacker, uint32& damage) OVERRIDE
512 {
513 if (me->HealthBelowPctDamaged(50, damage) && events.IsInPhase(PHASE_TWO))
514 {
515 events.SetPhase(PHASE_THREE);
516 me->CastStop();
519 return;
520 }
521
522 if (events.IsInPhase(PHASE_THREE))
523 {
524 // Don't consider copied damage.
525 if (!me->InSamePhase(attacker))
526 return;
527
529 controller->AI()->SetData(DATA_TWILIGHT_DAMAGE_TAKEN, damage);
530 }
531 }
532
533 void SpellHit(Unit* who, SpellInfo const* spell) OVERRIDE
534 {
535 switch (spell->Id)
536 {
539 controller->AI()->DoAction(ACTION_MONITOR_CORPOREALITY);
540 break;
541 default:
542 generic_halionAI::SpellHit(who, spell);
543 break;
544 }
545 }
546
548 {
549 switch (eventId)
550 {
552 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, SPELL_TWILIGHT_REALM))
554 events.ScheduleEvent(EVENT_SOUL_CONSUMPTION, 20000);
555 break;
556 default:
558 break;
559 }
560 }
561
562 private:
564 };
565
567 {
569 }
570};
571
573{
574 public:
575 npc_halion_controller() : CreatureScript("npc_halion_controller") { }
576
578 {
580 _instance(creature->GetInstanceScript()), _summons(me)
581 {
582 me->SetPhaseMask(me->GetPhaseMask() | 0x20, true);
583 }
584
586 {
587 _summons.DespawnAll();
588 _events.Reset();
592
594 }
595
597 {
598 _summons.Summon(who);
599 }
600
601 void JustDied(Unit* /*killer*/) OVERRIDE
602 {
603 _events.Reset();
604 _summons.DespawnAll();
605
607 }
608
609 void EnterCombat(Unit* /*who*/) OVERRIDE
610 {
613
615 }
616
618 {
619 if (Creature* twilightHalion = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_TWILIGHT_HALION)))
620 twilightHalion->DespawnOrUnsummon();
621
622 if (Creature* halion = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HALION)))
623 {
624 halion->AI()->SetData(DATA_EVADE_METHOD, 1);
625 halion->AI()->EnterEvadeMode();
626 }
627
628 _instance->SetBossState(DATA_HALION, FAIL);
629 }
630
632 {
633 switch (action)
634 {
636 _events.Reset();
637 _events.SetPhase(PHASE_INTRO);
638 _events.ScheduleEvent(EVENT_START_INTRO, 2000);
639 break;
641 {
642 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
643 {
644 Creature* halion = ObjectAccessor::GetCreature(*me, _instance->GetData64(itr));
645 if (!halion)
646 continue;
647
648 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), false);
650
651 if (itr == DATA_TWILIGHT_HALION)
652 continue;
653
656 }
657
658 // Summon Twilight portals
660
661 _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TOGGLE, 1);
662 // Hardcoding doesn't really matter here.
663 _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_MATERIAL, 50);
664 _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TWILIGHT, 50);
665
666 _events.ScheduleEvent(EVENT_CHECK_CORPOREALITY, 7500);
667 }
668 default:
669 break;
670 }
671 }
672
674 {
675 // The IsInCombat() 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 (!(_events.IsInPhase(PHASE_INTRO)) && me->IsInCombat() && !UpdateVictim())
679 {
681 return;
682 }
683
684 _events.Update(diff);
685
686 while (uint32 eventId = _events.ExecuteEvent())
687 {
688 switch (eventId)
689 {
692 _events.ScheduleEvent(EVENT_INTRO_PROGRESS_1, 4000);
693 break;
696 if (GameObject* tree = ObjectAccessor::GetGameObject(*me, _instance->GetData64(i)))
697 _instance->HandleGameObject(_instance->GetData64(i), true, tree);
698 _events.ScheduleEvent(EVENT_INTRO_PROGRESS_2, 4000);
699 break;
702 if (GameObject* tree = ObjectAccessor::GetGameObject(*me, _instance->GetData64(i)))
703 _instance->HandleGameObject(_instance->GetData64(i), true, tree);
704 _events.ScheduleEvent(EVENT_INTRO_PROGRESS_3, 4000);
705 break;
708 if (Creature* halion = me->GetMap()->SummonCreature(NPC_HALION, HalionSpawnPos))
709 halion->AI()->Talk(SAY_INTRO);
710 break;
712 if (ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HALION))) // Just check if physical Halion is spawned
713 if (Creature* twilightHalion = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_TWILIGHT_HALION)))
714 twilightHalion->CastSpell((Unit*)NULL, SPELL_TWILIGHT_MENDING, true);
715 break;
717 for (uint8 i = DATA_HALION; i <= DATA_TWILIGHT_HALION; i++)
718 if (Creature* halion = ObjectAccessor::GetCreature(*me, _instance->GetData64(i)))
719 halion->CastSpell(halion, SPELL_BERSERK, true);
720 break;
722 if (Creature* twilightHalion = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_TWILIGHT_HALION)))
723 twilightHalion->AI()->Talk(SAY_SPHERE_PULSE);
724
725 if (Creature* orbCarrier = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ORB_CARRIER)))
726 orbCarrier->AI()->DoAction(ACTION_SHOOT);
727
728 _events.ScheduleEvent(EVENT_SHADOW_PULSARS_SHOOT, 29000);
729 break;
732 _events.ScheduleEvent(EVENT_CHECK_CORPOREALITY, 5000);
733 break;
734 default:
735 break;
736 }
737 }
738 }
739
741 {
742 switch (id)
743 {
745 _materialDamageTaken += value;
746 break;
748 _twilightDamageTaken += value;
749 break;
750 case DATA_FIGHT_PHASE:
751 _events.SetPhase(value);
752 switch (value)
753 {
754 case PHASE_ONE:
756 break;
757 case PHASE_TWO:
758 _events.ScheduleEvent(EVENT_SHADOW_PULSARS_SHOOT, 29000);
759 break;
760 default:
761 break;
762 }
763 break;
764 default:
765 break;
766 }
767 }
768
769 private:
771 // [0 , 0.98[: Corporeality goes down
772 // [0.98, 0.99]: Do nothing
773 // ]0.99, 1.01[: Twilight Mending
774 // [1.01, 1.02]: Do nothing
775 // ]1.02, +oo [: Corporeality goes up
777 {
780 {
781 _events.ScheduleEvent(EVENT_TWILIGHT_MENDING, 100);
784 return;
785 }
786
787 float damageRatio = float(_materialDamageTaken) / float(_twilightDamageTaken);
788
790 if (damageRatio < 0.98f) // [0 , 0.98[: Corporeality goes down
791 action = CORPOREALITY_DECREASE;
792 else if (0.99f < damageRatio && damageRatio < 1.01f) // ]0.99, 1.01[: Twilight Mending
794 else if (1.02f < damageRatio) // ]1.02, +oo [: Corporeality goes up
795 action = CORPOREALITY_INCREASE;
796
797 switch (action)
798 {
800 {
803 return;
804 }
806 {
808 return;
810 break;
811 }
813 {
815 return;
817 break;
818 }
820 {
821 _events.ScheduleEvent(EVENT_TWILIGHT_MENDING, 100);
824 return;
825 }
826 }
827
830
833
834 for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
835 {
836 if (Creature* halion = ObjectAccessor::GetCreature(*me, _instance->GetData64(itr)))
837 {
839 halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), true);
840
841 if (itr == DATA_TWILIGHT_HALION)
842 halion->AI()->Talk(oldValue < _materialCorporealityValue ? EMOTE_CORPOREALITY_TOT : EMOTE_CORPOREALITY_TIT, halion);
843 else // if (itr == DATA_HALION)
844 halion->AI()->Talk(oldValue > _materialCorporealityValue ? EMOTE_CORPOREALITY_POT : EMOTE_CORPOREALITY_PIP, halion);
845 }
846 }
847 }
848
849 void RemoveCorporeality(Creature* who, bool isTwilight = false)
850 {
851 for (uint8 i = 0; i < MAX_CORPOREALITY_STATE; i++)
852 {
853 uint32 spellID = (isTwilight ? _corporealityReference[i].twilightRealmSpell : _corporealityReference[i].materialRealmSpell);
854 if (who->HasAura(spellID))
855 {
856 who->RemoveAurasDueToSpell(spellID);
857 break;
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
878 {
880 }
881};
882
884
886{
887 public:
888 npc_orb_carrier() : CreatureScript("npc_orb_carrier") { }
889
891 {
892 npc_orb_carrierAI(Creature* creature) : ScriptedAI(creature),
893 instance(creature->GetInstanceScript())
894 {
895 ASSERT(creature->GetVehicleKit());
896 }
897
898 void UpdateAI(uint32 /*diff*/) OVERRIDE
899 {
903 if (!me->HasUnitState(UNIT_STATE_CASTING))
904 me->CastSpell((Unit*)NULL, SPELL_TRACK_ROTATION, false);
905
910 if (Creature* rotationFocus = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ORB_ROTATION_FOCUS)))
911 me->SetFacingToObject(rotationFocus); // setInFront
912 }
913
915 {
916 if (action == ACTION_SHOOT)
917 {
918 Vehicle* vehicle = me->GetVehicleKit();
919 Unit* southOrb = vehicle->GetPassenger(SEAT_SOUTH);
920 Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
921 if (southOrb && northOrb)
922 {
923 if (northOrb->GetTypeId() == TypeID::TYPEID_UNIT)
924 northOrb->ToCreature()->AI()->Talk(EMOTE_WARN_LASER);
925 TriggerCutter(northOrb, southOrb);
926 }
927
928 if (!IsHeroic())
929 return;
930
931 Unit* eastOrb = vehicle->GetPassenger(SEAT_EAST);
932 Unit* westOrb = vehicle->GetPassenger(SEAT_WEST);
933 if (eastOrb && westOrb)
934 TriggerCutter(eastOrb, westOrb);
935 }
936 }
937 private:
939
940 void TriggerCutter(Unit* caster, Unit* target)
941 {
942 caster->CastSpell(caster, SPELL_TWILIGHT_PULSE_PERIODIC, true);
943 target->CastSpell(target, SPELL_TWILIGHT_PULSE_PERIODIC, true);
944 caster->CastSpell(target, SPELL_TWILIGHT_CUTTER, false);
945 }
946 };
947
949 {
951 }
952};
953
955{
956 public:
957 npc_meteor_strike_initial() : CreatureScript("npc_meteor_strike_initial") { }
958
960 {
962 _instance(creature->GetInstanceScript())
963 {
964 SetCombatMovement(false);
965 }
966
968 {
969 switch (action)
970 {
974 for (std::list<Creature*>::iterator itr = _meteorList.begin(); itr != _meteorList.end(); ++itr)
975 (*itr)->AI()->DoAction(ACTION_METEOR_STRIKE_BURN);
976 break;
977 }
978 }
979
980 void IsSummonedBy(Unit* summoner) OVERRIDE
981 {
982 Creature* owner = summoner->ToCreature();
983 if (!owner)
984 return;
985
986 // Let Halion Controller count as summoner
988 controller->AI()->JustSummoned(me);
989
991 DoCast(me, SPELL_BIRTH_NO_VISUAL); // Unknown purpose
992
993 if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
994 {
995 Position const* ownerPos = halionAI->GetMeteorStrikePosition();
996 Position newPos;
997 float angle[4];
998 angle[0] = me->GetAngle(ownerPos);
999 angle[1] = me->GetAngle(ownerPos) - static_cast<float>(M_PI/2);
1000 angle[2] = me->GetAngle(ownerPos) - static_cast<float>(-M_PI/2);
1001 angle[3] = me->GetAngle(ownerPos) - static_cast<float>(M_PI);
1002
1003 _meteorList.clear();
1004 for (uint8 i = 0; i < 4; i++)
1005 {
1006 angle[i] = Position::NormalizeOrientation(angle[i]);
1007 me->SetOrientation(angle[i]);
1008 me->GetNearPosition(newPos, 10.0f, 0.0f); // Exact distance
1009 if (Creature* meteor = me->SummonCreature(NPC_METEOR_STRIKE_NORTH + i, newPos, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 30000))
1010 _meteorList.push_back(meteor);
1011 }
1012 }
1013 }
1014
1015 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
1017 private:
1019 std::list<Creature*> _meteorList;
1020 };
1021
1023 {
1025 }
1026};
1027
1029{
1030 public:
1031 npc_meteor_strike() : CreatureScript("npc_meteor_strike") { }
1032
1034 {
1036 _instance(creature->GetInstanceScript())
1037 {
1038 _range = 5.0f;
1039 _spawnCount = 0;
1040
1041 SetCombatMovement(false);
1042 }
1043
1045 {
1046 if (action == ACTION_METEOR_STRIKE_BURN)
1047 {
1049 me->setActive(true);
1050 _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, 500);
1051 }
1052 }
1053
1054 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1055 {
1056 // Let Halion Controller count as summoner.
1058 controller->AI()->JustSummoned(me);
1059 }
1060
1062 {
1063 if (_spawnCount > 5)
1064 return;
1065
1066 _events.Update(diff);
1067
1068 if (_events.ExecuteEvent() == EVENT_SPAWN_METEOR_FLAME)
1069 {
1070 Position pos;
1071 me->GetNearPosition(pos, _range, 0.0f);
1072
1073 if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 25000))
1074 {
1076 controller->AI()->JustSummoned(flame);
1077
1078 flame->CastSpell(flame, SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
1079 ++_spawnCount;
1080 }
1081 _range += 5.0f;
1082 _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, 800);
1083 }
1084 }
1085
1086 private:
1089 float _range;
1091 };
1092
1094 {
1096 }
1097};
1098
1100{
1101 public:
1102 npc_combustion_consumption() : CreatureScript("npc_combustion_consumption") { }
1103
1105 {
1107 _instance(creature->GetInstanceScript()), _summonerGuid(0)
1108 {
1109 SetCombatMovement(false);
1110
1111 switch (me->GetEntry())
1112 {
1113 case NPC_COMBUSTION:
1116 me->SetPhaseMask(0x01, true);
1117 break;
1118 case NPC_CONSUMPTION:
1121 me->SetPhaseMask(0x20, true);
1122 break;
1123 default: // Should never happen
1124 _explosionSpell = 0;
1125 _damageSpell = 0;
1126 break;
1127 }
1128
1129 if (IsHeroic())
1130 me->SetPhaseMask(0x01 | 0x20, true);
1131 }
1132
1134 {
1135 // Let Halion Controller count as summoner
1137 controller->AI()->JustSummoned(me);
1138
1139 _summonerGuid = summoner->GetGUID();
1140 }
1141
1142 void SetData(uint32 type, uint32 stackAmount) OVERRIDE
1143 {
1145
1146 if (type != DATA_STACKS_DISPELLED || !_damageSpell || !_explosionSpell || !summoner)
1147 return;
1148
1149 me->CastCustomSpell(SPELL_SCALE_AURA, SPELLVALUE_AURA_STACK, stackAmount, me);
1151
1152 int32 damage = 1200 + (stackAmount * 1290); // Needs more researches.
1153 summoner->CastCustomSpell(_explosionSpell, SPELLVALUE_BASE_POINT0, damage, summoner);
1154 }
1155
1156 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
1157
1158 private:
1163 };
1164
1166 {
1168 }
1169};
1170
1172{
1173 public:
1174 npc_living_inferno() : CreatureScript("npc_living_inferno") { }
1175
1177 {
1178 npc_living_infernoAI(Creature* creature) : ScriptedAI(creature) { }
1179
1180 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1181 {
1182 me->SetInCombatWithZone();
1183 me->CastSpell(me, SPELL_BLAZING_AURA, true);
1184
1185 if (InstanceScript* instance = me->GetInstanceScript())
1186 if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION_CONTROLLER)))
1187 controller->AI()->JustSummoned(me);
1188 }
1189
1190 void JustDied(Unit* /*killer*/) OVERRIDE
1191 {
1192 me->DespawnOrUnsummon(1);
1193 }
1194 };
1195
1197 {
1199 }
1200};
1201
1204{
1205 public:
1206 npc_living_ember() : CreatureScript("npc_living_ember") { }
1207
1209 {
1210 npc_living_emberAI(Creature* creature) : ScriptedAI(creature) { }
1211
1213 {
1214 _hasEnraged = false;
1215 }
1216
1218 {
1219 _enrageTimer = 20000;
1220 _hasEnraged = false;
1221 }
1222
1223 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
1224 {
1225 if (InstanceScript* instance = me->GetInstanceScript())
1226 if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION_CONTROLLER)))
1227 controller->AI()->JustSummoned(me);
1228 }
1229
1230 void JustDied(Unit* /*killer*/) OVERRIDE
1231 {
1232 me->DespawnOrUnsummon(1);
1233 }
1234
1236 {
1237 if (!UpdateVictim() || me->HasUnitState(UNIT_STATE_CASTING))
1238 return;
1239
1240 if (!_hasEnraged && _enrageTimer <= diff)
1241 {
1242 _hasEnraged = true;
1244 }
1245 else _enrageTimer -= diff;
1246
1248 }
1249
1250 private:
1253 };
1254
1256 {
1257 return GetRubySanctumAI<npc_living_emberAI>(creature);
1258 }
1259};
1260
1262{
1263 public:
1264 go_twilight_portal() : GameObjectScript("go_twilight_portal") { }
1265
1267 {
1269 _instance(gameobject->GetInstanceScript()), _deleted(false)
1270 {
1271 switch (gameobject->GetEntry())
1272 {
1273 case GO_HALION_PORTAL_EXIT:
1274 gameobject->SetPhaseMask(0x20, true);
1275 _spellId = gameobject->GetGOInfo()->goober.spellId;
1276 break;
1277 case GO_HALION_PORTAL_1:
1278 case GO_HALION_PORTAL_2: // Not used, not seen in sniffs. Just in case.
1279 gameobject->SetPhaseMask(0x1, true);
1281 _spellId = SPELL_TWILIGHT_REALM;
1282 break;
1283 default:
1284 _spellId = 0;
1285 break;
1286 }
1287 }
1288
1290 {
1291 if (_spellId != 0)
1292 player->CastSpell(player, _spellId, true);
1293 return true;
1294 }
1295
1296 void UpdateAI(uint32 /*diff*/) OVERRIDE
1297 {
1298 if (_instance->GetBossState(DATA_HALION) == IN_PROGRESS)
1299 return;
1300
1301 if (!_deleted)
1302 {
1303 _deleted = true;
1304 go->Delete();
1305 }
1306 }
1307
1308 private:
1312 };
1313
1315 {
1316 return GetRubySanctumAI<go_twilight_portalAI>(gameobject);
1317 }
1318};
1319
1321{
1322 public:
1323 spell_halion_meteor_strike_marker() : SpellScriptLoader("spell_halion_meteor_strike_marker") { }
1324
1326 {
1328
1329 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1330 {
1331 if (!GetCaster())
1332 return;
1333
1334 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
1335 if (Creature* creCaster = GetCaster()->ToCreature())
1336 creCaster->AI()->DoAction(ACTION_METEOR_STRIKE_AOE);
1337 }
1338
1343 };
1344
1349};
1350
1352{
1353 public:
1354 spell_halion_combustion_consumption(char const* scriptName, uint32 spell) : SpellScriptLoader(scriptName), _spellID(spell) { }
1355
1357 {
1359
1360 public:
1362
1363 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
1364 {
1365 if (!sSpellMgr->GetSpellInfo(_markSpell))
1366 return false;
1367 return true;
1368 }
1369
1370 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1371 {
1372 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
1373 return;
1374
1375 if (GetTarget()->HasAura(_markSpell))
1377 }
1378
1379 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1380 {
1382 }
1383
1384 void AddMarkStack(AuraEffect const* /*aurEff*/)
1385 {
1387 }
1388
1395
1397 };
1398
1403
1404 private:
1406};
1407
1409{
1410 public:
1411 spell_halion_marks(char const* scriptName, uint32 summonSpell, uint32 removeSpell) : SpellScriptLoader(scriptName),
1412 _summonSpell(summonSpell), _removeSpell(removeSpell) { }
1413
1415 {
1417
1418 public:
1420 _summonSpellId(summonSpell), _removeSpellId(removeSpell) { }
1421
1422 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
1423 {
1424 if (!sSpellMgr->GetSpellInfo(_summonSpellId))
1425 return false;
1426 return true;
1427 }
1428
1430 void BeforeDispel(DispelInfo* dispelData)
1431 {
1432 // Prevent any stack from being removed at this point.
1433 dispelData->SetRemovedCharges(0);
1434
1435 if (Unit* dispelledUnit = GetUnitOwner())
1436 if (dispelledUnit->HasAura(_removeSpellId))
1437 dispelledUnit->RemoveAurasDueToSpell(_removeSpellId, 0, 0, AURA_REMOVE_BY_EXPIRE);
1438 }
1439
1440 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1441 {
1442 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
1443 return;
1444
1445 // Stacks marker
1447 }
1448
1454
1457 };
1458
1463
1464 private:
1467};
1468
1470{
1471 public:
1472 spell_halion_damage_aoe_summon() : SpellScriptLoader("spell_halion_damage_aoe_summon") { }
1473
1475 {
1477
1479 {
1480 PreventHitDefaultEffect(effIndex);
1481 Unit* caster = GetCaster();
1482 uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue);
1483 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetSpellInfo()->Effects[effIndex].MiscValueB));
1484 uint32 duration = uint32(GetSpellInfo()->GetDuration());
1485
1486 Position pos;
1487 caster->GetPosition(&pos);
1488 if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id))
1489 if (summon->IsAIEnabled)
1490 summon->AI()->SetData(DATA_STACKS_DISPELLED, GetSpellValue()->EffectBasePoints[EFFECT_1]);
1491 }
1492
1497 };
1498
1503};
1504
1506{
1507 public:
1508 spell_halion_twilight_realm_handlers(const char* scriptName, uint32 beforeHitSpell, bool isApplyHandler) : SpellScriptLoader(scriptName),
1509 _beforeHitSpell(beforeHitSpell), _isApplyHandler(isApplyHandler)
1510 { }
1511
1513 {
1515
1516 public:
1518 _isApply(isApplyHandler), _beforeHitSpellId(beforeHitSpell)
1519 { }
1520
1521 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
1522 {
1523 if (!sSpellMgr->GetSpellInfo(_beforeHitSpellId))
1524 return false;
1525 return true;
1526 }
1527
1528 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1529 {
1531 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
1532 instance->SendEncounterUnit(ENCOUNTER_FRAME_UNK7);
1533 }
1534
1535 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
1536 {
1537 Unit* target = GetTarget();
1538 if (!target)
1539 return;
1540
1542 if (InstanceScript* instance = target->GetInstanceScript())
1543 instance->SendEncounterUnit(ENCOUNTER_FRAME_UNK7);
1544 }
1545
1556
1559 };
1560
1565
1566 private:
1569};
1570
1572{
1573 public:
1574 spell_halion_clear_debuffs() : SpellScriptLoader("spell_halion_clear_debuffs") { }
1575
1577 {
1579
1580 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
1581 {
1582 if (!sSpellMgr->GetSpellInfo(SPELL_CLEAR_DEBUFFS))
1583 return false;
1584 if (!sSpellMgr->GetSpellInfo(SPELL_TWILIGHT_REALM))
1585 return false;
1586 return true;
1587 }
1588
1590 {
1591 if (GetHitUnit()->HasAura(GetSpellInfo()->Effects[effIndex].CalcValue()))
1592 GetHitUnit()->RemoveAurasDueToSpell(GetSpellInfo()->Effects[effIndex].CalcValue());
1593 }
1594
1599 };
1600
1605};
1606
1608{
1609 public:
1610 TwilightCutterSelector(Unit* caster, Unit* target) : _caster(caster), _channelTarget(target) { }
1611
1613 {
1614 return !unit->IsInBetween(_caster, _channelTarget, 4.0f);
1615 }
1616
1617 private:
1620};
1621
1623{
1624 public:
1625 spell_halion_twilight_cutter() : SpellScriptLoader("spell_halion_twilight_cutter") { }
1626
1628 {
1630
1631 void RemoveNotBetween(std::list<WorldObject*>& unitList)
1632 {
1633 if (unitList.empty())
1634 return;
1635
1636 Unit* caster = GetCaster();
1637 if (Unit* channelTarget = ObjectAccessor::GetUnit(*caster, caster->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)))
1638 {
1639 unitList.remove_if(TwilightCutterSelector(caster, channelTarget));
1640 return;
1641 }
1642
1643 // In case cutter caster werent found for some reason
1644 unitList.clear();
1645 }
1646
1651 };
1652
1657};
1658
1686
1721
1723{
1724 new boss_halion();
1726
1729 new npc_meteor_strike();
1731 new npc_orb_carrier();
1732 new npc_living_inferno();
1733 new npc_living_ember();
1734
1735 new go_twilight_portal();
1736
1738 new spell_halion_combustion_consumption("spell_halion_soul_consumption", SPELL_MARK_OF_CONSUMPTION);
1739 new spell_halion_combustion_consumption("spell_halion_fiery_combustion", SPELL_MARK_OF_COMBUSTION);
1740 new spell_halion_marks("spell_halion_mark_of_combustion", SPELL_FIERY_COMBUSTION_SUMMON, SPELL_FIERY_COMBUSTION);
1741 new spell_halion_marks("spell_halion_mark_of_consumption", SPELL_SOUL_CONSUMPTION_SUMMON, SPELL_SOUL_CONSUMPTION);
1743 new spell_halion_twilight_realm_handlers("spell_halion_leave_twilight_realm", SPELL_SOUL_CONSUMPTION, false);
1744 new spell_halion_twilight_realm_handlers("spell_halion_enter_twilight_realm", SPELL_FIERY_COMBUSTION, true);
1749}
Actions
@ IN_MILLISECONDS
Definition Common.h:125
@ MINUTE
Definition Common.h:119
#define M_PI
Definition Common.h:192
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
#define ASSERT
Definition Errors.h:29
@ IN_PROGRESS
@ FAIL
@ ENCOUNTER_FRAME_UNK7
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
#define CAST_AI(a, b)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SUMMON
@ SPELL_EFFECT_SUMMON_OBJECT_WILD
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PHASE
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
#define sSpellMgr
Definition SpellMgr.h:744
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define SpellHitFn(F)
#define AuraDispelFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
@ SPELLVALUE_AURA_STACK
Definition Unit.h:119
@ SPELLVALUE_BASE_POINT1
Definition Unit.h:115
@ SPELLVALUE_BASE_POINT0
Definition Unit.h:114
@ AURA_REMOVE_BY_DEATH
Definition Unit.h:411
@ AURA_REMOVE_BY_EXPIRE
Definition Unit.h:410
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition Unit.h:409
@ TRIGGERED_FULL_MASK
Will ignore most target checks (mostly DBC target checks).
Definition Unit.h:435
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_DEFENSIVE
Definition Unit.h:1157
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_CHANNEL_OBJECT
@ UNIT_FIELD_FLAGS
@ SPELL_CLEAVE
@ EVENT_CLEAVE
@ SAY_BERSERK
@ SAY_INTRO
@ PHASE_INTRO
#define SAY_DEATH
#define SAY_AGGRO
#define SAY_KILL
#define SPELL_BERSERK
@ ACTION_METEOR_STRIKE_AOE
@ ACTION_MONITOR_CORPOREALITY
@ ACTION_METEOR_STRIKE_BURN
@ ACTION_SHOOT
@ DATA_TWILIGHT_DAMAGE_TAKEN
@ DATA_MATERIAL_DAMAGE_TAKEN
@ DATA_FIGHT_PHASE
@ DATA_EVADE_METHOD
@ DATA_STACKS_DISPELLED
@ SPELL_COSMETIC_FIRE_PILLAR
@ SPELL_CLEAVE
@ SPELL_METEOR_STRIKE_COUNTDOWN
@ SPELL_FIERY_COMBUSTION_SUMMON
@ SPELL_METEOR_STRIKE_FIRE_AURA_1
@ SPELL_TWILIGHT_PHASING
@ SPELL_DUSK_SHROUD
@ SPELL_SUMMON_TWILIGHT_PORTAL
@ SPELL_MARK_OF_COMBUSTION
@ SPELL_METEOR_STRIKE_AOE_DAMAGE
@ SPELL_DARK_BREATH
@ SPELL_TWILIGHT_DIVISION
@ SPELL_FLAME_BREATH
@ SPELL_TWILIGHT_CUTTER
@ SPELL_LEAVE_TWILIGHT_REALM
@ SPELL_TWILIGHT_PRECISION
@ SPELL_CLEAR_DEBUFFS
@ SPELL_COPY_DAMAGE
@ SPELL_SOUL_CONSUMPTION_SUMMON
@ SPELL_SOUL_CONSUMPTION
@ SPELL_TAIL_LASH
@ SPELL_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_FIERY_EXPLOSION
@ SPELL_SCALE_AURA
@ SPELL_CONSUMPTION_DAMAGE_AURA
@ SPELL_TWILIGHT_REALM
@ SPELL_FIERY_COMBUSTION
@ SPELL_BIRTH_NO_VISUAL
@ SPELL_METEOR_STRIKE_FIRE_AURA_2
@ PHASE_ONE
@ PHASE_INTRO
@ PHASE_THREE
@ PHASE_TWO
boss_halion::boss_halionAI HalionAI
uint8 const MAX_CORPOREALITY_STATE
CorporealityEntry const _corporealityReference[MAX_CORPOREALITY_STATE]
@ SAY_DEATH
@ EMOTE_WARN_LASER
@ SAY_AGGRO
@ SAY_SPHERE_PULSE
@ SAY_PHASE_TWO
@ SAY_KILL
@ EMOTE_CORPOREALITY_TOT
@ SAY_PHASE_THREE
@ EMOTE_CORPOREALITY_PIP
@ SAY_REGENERATE
@ SAY_METEOR_STRIKE
@ EMOTE_CORPOREALITY_POT
@ EMOTE_CORPOREALITY_TIT
@ SAY_INTRO
void AddSC_boss_halion()
Position const HalionSpawnPos
npc_halion_controller::npc_halion_controllerAI controllerAI
CorporealityEvent
@ CORPOREALITY_TWILIGHT_MENDING
@ CORPOREALITY_DECREASE
@ CORPOREALITY_INCREASE
@ CORPOREALITY_NONE
@ EVENT_SHADOW_PULSARS_SHOOT
@ EVENT_TWILIGHT_MENDING
@ EVENT_SPAWN_METEOR_FLAME
@ EVENT_START_INTRO
@ EVENT_ACTIVATE_FIREWALL
@ EVENT_TRIGGER_BERSERK
@ EVENT_FIERY_COMBUSTION
@ EVENT_INTRO_PROGRESS_1
@ EVENT_INTRO_PROGRESS_2
@ EVENT_TAIL_LASH
@ EVENT_CHECK_CORPOREALITY
@ EVENT_BREATH
@ EVENT_SOUL_CONSUMPTION
@ EVENT_CLEAVE
@ EVENT_INTRO_PROGRESS_3
@ EVENT_METEOR_STRIKE
OrbCarrierSeats
@ SEAT_NORTH
@ SEAT_WEST
@ SEAT_SOUTH
@ SEAT_EAST
@ SPELL_TAIL_LASH
@ SPELL_FLAME_BREATH
Aura * GetBase() const
uint8 GetStackAmount() const
Definition SpellAuras.h:133
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
uint64 GetCasterGUID() const
Unit * GetCaster() const
Unit * GetTarget() const
HookList< AuraDispelHandler > OnDispel
Unit * GetUnitOwner() const
InstanceScript *const instance
void _JustReachedHome()
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
virtual void JustSummoned(Creature *)
Definition CreatureAI.h:98
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
void SetRemovedCharges(uint8 amount)
Definition Unit.h:852
GameObject *const go
GameObjectAI(GameObject *g)
GameObjectScript(const char *name)
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=NULL, uint32 duration=0, Unit *summoner=NULL, uint32 spellId=0, uint32 vehId=0)
Definition Object.cpp:2564
static Creature * GetCreature(WorldObject const &u, uint64 guid)
static GameObject * GetGameObject(WorldObject const &u, uint64 guid)
static Unit * GetUnit(WorldObject const &, uint64 guid)
TypeID GetTypeId() const
Definition Object.h:131
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
uint32 GetEntry() const
Definition Object.h:125
uint64 GetUInt64Value(uint16 index) const
Definition Object.cpp:331
Creature * ToCreature()
Definition Object.h:207
WorldLocation const * GetExplTargetDest()
void SetExplTargetDest(WorldLocation &loc)
SpellInfo const * GetSpellInfo()
HookList< HitHandler > OnHit
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
WorldLocation * GetHitDest()
HookList< EffectHandler > OnEffectLaunch
SpellValue const * GetSpellValue()
Unit * GetCaster()
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
SpellScriptLoader(const char *name)
bool operator()(WorldObject *unit)
TwilightCutterSelector(Unit *caster, Unit *target)
virtual void SetData(uint32, uint32)
Definition UnitAI.h:128
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition UnitAI.cpp:66
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
void DoCastAOE(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:176
Definition Unit.h:1367
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Aura * AddAura(uint32 spellId, Unit *target)
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
uint32 GetHealth() const
Definition Unit.h:1600
void CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
Vehicle * GetVehicleKit() const
Definition Unit.h:2739
Unit * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
Definition Vehicle.cpp:306
Map * GetMap() const
Definition Object.h:740
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
bool IsInBetween(WorldObject const *obj1, WorldObject const *obj2, float size=0) const
Definition Object.cpp:1920
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
GameObjectAI * GetAI(GameObject *gameobject) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Need sniff data.
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
PrepareSpellScript(spell_halion_clear_debuffs_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
spell_halion_combustion_consumption(char const *scriptName, uint32 spell)
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
void BeforeDispel(DispelInfo *dispelData)
We were purged. Force removed stacks to zero and trigger the appropriated remove handler.
void OnRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
spell_halion_marks_AuraScript(uint32 summonSpell, uint32 removeSpell)
PrepareAuraScript(spell_halion_marks_AuraScript)
spell_halion_marks(char const *scriptName, uint32 summonSpell, uint32 removeSpell)
AuraScript * GetAuraScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
PrepareSpellScript(spell_halion_twilight_cutter_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
spell_halion_twilight_realm_handlers(const char *scriptName, uint32 beforeHitSpell, bool isApplyHandler)
AuraScript * GetAuraScript() const OVERRIDE
@ NPC_METEOR_STRIKE_NORTH
@ NPC_HALION
@ NPC_TWILIGHT_HALION
@ NPC_CONSUMPTION
@ NPC_METEOR_STRIKE_FLAME
@ NPC_COMBUSTION
@ ACTION_INTRO_HALION
@ WORLDSTATE_CORPOREALITY_TOGGLE
@ WORLDSTATE_CORPOREALITY_MATERIAL
@ WORLDSTATE_CORPOREALITY_TWILIGHT
CreatureAI * GetRubySanctumAI(Creature *creature)
@ DATA_HALION_CONTROLLER
@ DATA_TWILIGHT_FLAME_RING
@ DATA_BURNING_TREE_1
@ DATA_BURNING_TREE_2
@ DATA_BURNING_TREE_3
@ DATA_BURNING_TREE_4
@ DATA_ORB_CARRIER
@ DATA_TWILIGHT_HALION
@ DATA_FLAME_RING
@ DATA_HALION
@ DATA_ORB_ROTATION_FOCUS
uint32 materialRealmSpell
uint32 twilightRealmSpell
static float NormalizeOrientation(float o)
Definition Object.h:427
float GetPositionZ() const
Definition Object.h:330
float m_positionY
Definition Object.h:288
float GetPositionX() const
Definition Object.h:328
void GetPosition(float &x, float &y) const
Definition Object.h:333
float GetPositionY() const
Definition Object.h:329
void RelocateOffset(Position const &offset)
Definition Object.cpp:1841
bool IsHeroic() const
void SetCombatMovement(bool allowMovement)
Creature * me
ScriptedAI(Creature *creature)
void JustDied(Unit *) OVERRIDE
boss_halionAI(Creature *creature)
void SetData(uint32 index, uint32 value) OVERRIDE
void EnterEvadeMode() OVERRIDE
void EnterCombat(Unit *who) OVERRIDE
void DamageTaken(Unit *attacker, uint32 &damage) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void ExecuteEvent(uint32 eventId) OVERRIDE
Position const * GetMeteorStrikePosition() const
void DamageTaken(Unit *attacker, uint32 &damage) OVERRIDE
void ExecuteEvent(uint32 eventId) OVERRIDE
void SpellHit(Unit *who, SpellInfo const *spell) OVERRIDE
void ExecuteEvent(uint32 eventId) OVERRIDE
void Reset() OVERRIDE
void JustReachedHome() OVERRIDE
void EnterCombat(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
generic_halionAI(Creature *creature, uint32 bossId)
void SetData(uint32 index, uint32 dataValue) OVERRIDE
void SpellHit(Unit *, SpellInfo const *spellInfo) OVERRIDE
go_twilight_portalAI(GameObject *gameobject)
bool GossipHello(Player *player) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void SetData(uint32 type, uint32 stackAmount) OVERRIDE
uint32 GetSpell(uint8 pctValue, bool isTwilight=false) const
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void RemoveCorporeality(Creature *who, bool isTwilight=false)
void SetData(uint32 id, uint32 value) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void DoAction(int32 action) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void DoAction(int32 action) OVERRIDE
npc_orb_carrierAI(Creature *creature)
void TriggerCutter(Unit *caster, Unit *target)
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================