TrinityCore
Loading...
Searching...
No Matches
boss_freya.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 "InstanceScript.h"
20#include "Map.h"
21#include "ObjectAccessor.h"
22#include "Player.h"
23#include "ScriptedCreature.h"
24#include "SpellAuras.h"
25#include "SpellScript.h"
26#include "TemporarySummon.h"
27#include "ulduar.h"
28
50
52{
53 // Freya
57 SPELL_ENRAGE = 47008,
65
66 // Stonebark
71
72 // Ironbranch
73 SPELL_IMPALE = 62310,
76
77 // Brightleaf
79 SPELL_FLUX = 62262,
83 SPELL_UNSTABLE_SUN_BEAM_SUMMON = 62207, // Trigger 62221
84
85 // Stack Removing of Attuned to Nature
89
90 // Achievement spells
93
94 // Wave summoning spells
98
99 // Detonating Lasher
102
103 // Ancient Water Spirit
106
107 // Storm Lasher
110
111 // Snaplasher
114
115 // Ancient Conservator
119 SPELL_SPORE_SUMMON_NW = 62582, // Not used, triggered by SPELL_SUMMON_PERIODIC
123
124 // Healthly Spore
126 SPELL_GROW = 62559,
128
129 // Eonar's Gift
133
134 // Nature Bomb
138
139 // Unstable Sun Beam
144 SPELL_FREYA_UNSTABLE_SUNBEAM = 62450, // Or maybe 62866?
145
146 // Sun Beam
149
150 // Attuned To Nature spells
155
173
178
206
208{
209 TIME_DIFFERENCE = 10000, // If difference between waveTime and WAVE_TIME is bigger then TIME_DIFFERENCE, schedule EVENT_WAVE in 10 seconds
213
214constexpr Seconds FREYA_WAVE_TIME = 60s; // Normal wave is one minute
215
217{
218 public:
219 npc_iron_roots() : CreatureScript("npc_iron_roots") { }
220
222 {
223 npc_iron_rootsAI(Creature* creature) : ScriptedAI(creature)
224 {
225 SetCombatMovement(false);
226
227 me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip
230 }
231
232 void IsSummonedBy(WorldObject* summonerWO) override
233 {
234 Player* summoner = summonerWO->ToPlayer();
235 if (!summoner)
236 return;
237 // Summoner is a player, who should have root aura on self
238 summonerGUID = summoner->GetGUID();
239 me->SetFacingToObject(summoner);
240 me->SetInCombatWith(summoner);
241 }
242
243 void JustDied(Unit* /*killer*/) override
244 {
246 {
247 target->RemoveAurasDueToSpell(SPELL_ROOTS_IRONBRANCH);
248 target->RemoveAurasDueToSpell(SPELL_ROOTS_FREYA);
249 }
250
252 }
253
254 private:
256 };
257
258 CreatureAI* GetAI(Creature* creature) const override
259 {
260 return GetUlduarAI<npc_iron_rootsAI>(creature);
261 }
262};
263
265{
266 public:
267 boss_freya() : CreatureScript("boss_freya") { }
268
269 struct boss_freyaAI : public BossAI
270 {
271 boss_freyaAI(Creature* creature) : BossAI(creature, DATA_FREYA)
272 {
273 _encounterFinished = false;
274 Initialize();
275 memset(elementalTimer, 0, sizeof(elementalTimer));
276 diffTimer = 0;
277 attunedToNature = 0;
278 }
279
281 {
282 trioWaveCount = 0;
284 waveCount = 0;
285 elderCount = 0;
286
287 for (uint8 i = 0; i < 3; ++i)
288 for (uint8 n = 0; n < 2; ++n)
289 ElementalGUID[i][n].Clear();
290 for (uint8 i = 0; i < 6; ++i)
291 for (uint8 n = 0; n < 2; ++n)
292 deforestation[i][n] = 0;
293 for (uint8 n = 0; n < 2; ++n)
294 {
295 checkElementalAlive[n] = true;
296 trioDefeated[n] = false;
297 }
298 for (uint8 n = 0; n < 3; ++n)
299 random[n] = false;
300 }
301
303
312
315 bool random[3];
317
318 void Reset() override
319 {
321 return;
322
323 _Reset();
324 Initialize();
325 }
326
327 void KilledUnit(Unit* who) override
328 {
329 if (who->GetTypeId() == TYPEID_PLAYER)
330 Talk(SAY_SLAY);
331 }
332
333 void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
334 {
335 if (damage >= me->GetHealth())
336 {
337 damage = 0;
338 JustDied(who);
339 }
340 }
341
342 void JustEngagedWith(Unit* who) override
343 {
346 Creature* Elder[3];
347 for (uint8 n = 0; n < 3; ++n)
348 {
350 if (Elder[n] && Elder[n]->IsAlive())
351 {
353 Elder[n]->CastSpell(me, SPELL_IRONBRANCH_ESSENCE, true);
355 Elder[n]->AI()->AttackStart(who);
356 AddThreat(who, 250.0f, Elder[n]);
357 ++elderCount;
358 }
359 }
360
361 if (Elder[0] && Elder[0]->IsAlive())
362 {
363 Elder[0]->CastSpell(me, SPELL_BRIGHTLEAF_ESSENCE, true);
365 }
366
367 if (Elder[1] && Elder[1]->IsAlive())
368 {
369 Elder[1]->CastSpell(me, SPELL_STONEBARK_ESSENCE, true);
371 }
372
373 if (Elder[2] && Elder[2]->IsAlive())
374 {
375 Elder[2]->CastSpell(me, SPELL_IRONBRANCH_ESSENCE, true);
377 }
378
379 if (elderCount == 0)
381 else
383
387
392 }
393
394 uint32 GetData(uint32 type) const override
395 {
396 switch (type)
397 {
399 return attunedToNature;
401 return elderCount;
402 }
403
404 return 0;
405 }
406
407 void UpdateAI(uint32 diff) override
408 {
409 if (!UpdateVictim())
410 return;
411
412 events.Update(diff);
413
415 return;
416
417 while (uint32 eventId = events.ExecuteEvent())
418 {
419 switch (eventId)
420 {
421 case EVENT_ENRAGE:
424 break;
425 case EVENT_SUNBEAM:
426 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
427 DoCast(target, SPELL_SUNBEAM);
429 break;
433 break;
435 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
438 break;
439 case EVENT_WAVE:
440 SpawnWave();
441 if (waveCount <= 6) // If set to 6 The Bombs appear during the Final Add wave
443 else
445 break;
446 case EVENT_EONAR_GIFT:
450 break;
453 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, true, -SPELL_ROOTS_FREYA))
454 target->CastSpell(target, SPELL_ROOTS_FREYA, true); // This must be cast by Target self
456 break;
461 break;
462 }
463
465 return;
466 }
467
470
471 // For achievement check
473 attunedToNature = aura->GetStackAmount();
474 else
475 attunedToNature = 0;
476
477 diffTimer += diff; // For getting time difference for Deforestation achievement
478
479 // Elementals must be killed within 12 seconds of each other, or they will all revive and heal
480 Creature* Elemental[3][2];
481 for (uint8 i = 0; i < 2; ++i)
482 {
483 if (checkElementalAlive[i])
484 elementalTimer[i] = 0;
485 else
486 {
487 elementalTimer[i] += diff;
488 for (uint8 k = 0; k < 3; ++k)
489 Elemental[k][i] = ObjectAccessor::GetCreature(*me, ElementalGUID[k][i]);
490 if (elementalTimer[i] > 12000)
491 {
492 if (!trioDefeated[i]) // Do *NOT* merge this bool with bool few lines below!
493 {
494 if (Elemental[0][i] && Elemental[1][i] && Elemental[2][i])
495 {
496 for (uint8 n = 0; n < 3; ++n)
497 {
498 if (Elemental[n][i]->IsAlive())
499 Elemental[n][i]->SetHealth(Elemental[n][i]->GetMaxHealth());
500 else
501 Elemental[n][i]->Respawn();
502 }
503 }
504 }
505 checkElementalAlive[i] = true;
506 }
507 else
508 {
509 if (!trioDefeated[i])
510 {
511 if (Elemental[0][i] && Elemental[1][i] && Elemental[2][i])
512 {
513 if (Elemental[0][i]->isDead() && Elemental[1][i]->isDead() && Elemental[2][i]->isDead())
514 {
515 for (uint8 n = 0; n < 3; ++n)
516 {
517 summons.Despawn(Elemental[n][i]);
518 Elemental[n][i]->DespawnOrUnsummon(5s);
519 trioDefeated[i] = true;
520 Elemental[n][i]->CastSpell(me, SPELL_REMOVE_10STACK, true);
521 }
522 }
523 }
524 }
525 }
526 }
527 }
528
530 }
531
532 // Check if all Trio NPCs are dead - achievement check
533 void LasherDead(uint32 type) // Type must be in format of a binary mask
534 {
535 uint8 n = 0;
536
537 // Handling received data
538 for (uint8 i = 0; i < 5; ++i) // We have created "instances" for keeping informations about last 6 death lashers - needed because of respawning
539 {
540 deforestation[i][0] = deforestation[(i + 1)][0]; // Time
541 deforestation[i][1] = deforestation[(i + 1)][1]; // Type
542 }
543 deforestation[5][0] = diffTimer;
544 deforestation[5][1] = type;
545
546 // Check for achievement completion
547 if (deforestation[0][1]) // Check for proper functionality of binary masks (overflow would not be problem)
548 {
549 for (uint8 i = 0; i < 6; ++i) // Count binary mask
550 {
551 n += deforestation[i][1];
552 }
553 if ((deforestation[5][0] - deforestation[0][0]) < 10000) // Time check
554 {
555 if (n == 14 && instance) // Binary mask check - verification of lasher types
556 {
558 }
559 }
560 }
561 }
562
563 // Random order of spawning waves
565 {
566 if (random[0] && random[1] && random[2])
567 for (uint8 n = 0; n < 3; ++n)
568 random[n] = false;
569
570 uint8 randomId = urand(0, 2);
571
572 while (random[randomId])
573 randomId = urand(0, 2);
574
575 random[randomId] = true;
576 return randomId;
577 }
578
580 {
581 switch (GetWaveId())
582 {
583 case 0:
585 for (uint8 n = 0; n < 10; ++n)
587 break;
588 case 1:
592 break;
593 case 2:
596 break;
597 }
599 waveCount++;
600 }
601
602 void JustDied(Unit* /*killer*/) override
603 {
605 return;
606
607 _encounterFinished = true;
608
610 const uint32 summonSpell[2][4] =
611 {
612 /* 0Elder, 1Elder, 2Elder, 3Elder */
613 /* 10N */ {62950, 62952, 62953, 62954},
614 /* 25N */ {62955, 62956, 62957, 62958}
615 };
616
617 me->CastSpell(nullptr, summonSpell[me->GetMap()->GetDifficulty()][elderCount], true);
618
620
624 me->AttackStop();
626 me->DespawnOrUnsummon(7500ms);
628 _JustDied();
629
630 for (uint8 n = 0; n < 3; ++n)
631 {
633 if (Elder && Elder->IsAlive())
634 {
635 Elder->RemoveAllAuras();
636 Elder->AttackStop();
637 Elder->CombatStop(true);
640 }
641 }
642 }
643
644 void JustSummoned(Creature* summoned) override
645 {
646 switch (summoned->GetEntry())
647 {
648 case NPC_SNAPLASHER:
650 case NPC_STORM_LASHER:
652 summons.Summon(summoned);
654 if (trioWaveController > 2)
656 break;
659 default:
660 summons.Summon(summoned);
661 break;
662 }
663
664 // Need to have it there, or summoned units would do nothing untill attacked
665 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250.0f, true))
666 {
667 summoned->AI()->AttackStart(target);
668 AddThreat(target, 250.0f, summoned);
669 DoZoneInCombat(summoned);
670 }
671 }
672
673 void SummonedCreatureDies(Creature* summoned, Unit* who) override
674 {
675 switch (summoned->GetEntry())
676 {
678 summoned->CastSpell(me, SPELL_REMOVE_2STACK, true);
679 summoned->CastSpell(who, SPELL_DETONATE, true);
680 summoned->DespawnOrUnsummon(5s);
681 summons.Despawn(summoned);
682 break;
684 summoned->CastSpell(me, SPELL_REMOVE_25STACK, true);
685 summoned->DespawnOrUnsummon(5s);
686 summons.Despawn(summoned);
687 break;
688 }
689 }
690 };
691
692 CreatureAI* GetAI(Creature* creature) const override
693 {
694 return GetUlduarAI<boss_freyaAI>(creature);
695 }
696};
697
699{
700 public:
701 boss_elder_brightleaf() : CreatureScript("boss_elder_brightleaf") { }
702
704 {
706 {
707 }
708
718
719 void KilledUnit(Unit* who) override
720 {
721 if (who->GetTypeId() == TYPEID_PLAYER)
723 }
724
725 void JustDied(Unit* /*killer*/) override
726 {
727 _JustDied();
729 }
730
731 void JustEngagedWith(Unit* who) override
732 {
736 }
737
738 void UpdateAI(uint32 diff) override
739 {
741 return;
742
743 events.Update(diff);
744
746 return;
747
748 while (uint32 eventId = events.ExecuteEvent())
749 {
750 switch (eventId)
751 {
755 break;
757 {
758 uint8 stackAmount = 0;
759 if (Aura* aura = me->GetAura(SPELL_FLUX_AURA))
760 stackAmount = aura->GetStackAmount();
762 args.AddSpellMod(SPELLVALUE_MAX_TARGETS, stackAmount);
765 break;
766 }
767 case EVENT_FLUX:
770 if (Aura* Flux = me->GetAura(SPELL_FLUX_AURA))
771 Flux->SetStackAmount(urand(1, 8));
773 break;
774 }
775
777 return;
778 }
779
781 }
782
783 void DoAction(int32 action) override
784 {
785 switch (action)
786 {
788 me->DespawnOrUnsummon(10s);
789 _JustDied();
790 break;
791 }
792 }
793 };
794
795 CreatureAI* GetAI(Creature* creature) const override
796 {
797 return GetUlduarAI<boss_elder_brightleafAI>(creature);
798 }
799};
800
802{
803 public:
804 boss_elder_stonebark() : CreatureScript("boss_elder_stonebark") { }
805
807 {
809 {
810 }
811
812 void Reset() override
813 {
814 _Reset();
819 events.ScheduleEvent(EVENT_BARK, 37500ms, 40s);
820 }
821
822 void KilledUnit(Unit* who) override
823 {
824 if (who->GetTypeId() == TYPEID_PLAYER)
826 }
827
828 void JustDied(Unit* /*killer*/) override
829 {
830 _JustDied();
832 }
833
834 void JustEngagedWith(Unit* who) override
835 {
839 }
840
841 void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
842 {
843 if (!who || who == me)
844 return;
845
848 {
850 args.AddSpellBP0(damage);
851 who->CastSpell(who, SPELL_PETRIFIED_BARK_DMG, args);
852 damage = 0;
853 }
854 }
855
856 void UpdateAI(uint32 diff) override
857 {
859 return;
860
861 events.Update(diff);
862
864 return;
865
866 while (uint32 eventId = events.ExecuteEvent())
867 {
868 switch (eventId)
869 {
870 case EVENT_BARK:
873 break;
874 case EVENT_FISTS:
877 break;
878 case EVENT_TREMOR:
882 break;
883 }
884
886 return;
887 }
888
890 }
891
892 void DoAction(int32 action) override
893 {
894 switch (action)
895 {
897 me->DespawnOrUnsummon(10s);
898 _JustDied();
899 break;
900 }
901 }
902 };
903
904 CreatureAI* GetAI(Creature* creature) const override
905 {
906 return GetUlduarAI<boss_elder_stonebarkAI>(creature);
907 }
908};
909
911{
912 public:
913 boss_elder_ironbranch() : CreatureScript("boss_elder_ironbranch") { }
914
916 {
918 {
919 }
920
930
931 void KilledUnit(Unit* who) override
932 {
933 if (who->GetTypeId() == TYPEID_PLAYER)
935 }
936
937 void JustDied(Unit* /*killer*/) override
938 {
939 _JustDied();
941 }
942
943 void JustEngagedWith(Unit* who) override
944 {
948 }
949
950 void UpdateAI(uint32 diff) override
951 {
953 return;
954
955 events.Update(diff);
956
958 return;
959
960 while (uint32 eventId = events.ExecuteEvent())
961 {
962 switch (eventId)
963 {
964 case EVENT_IMPALE:
967 break;
968 case EVENT_IRON_ROOTS:
969 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, true, -SPELL_ROOTS_IRONBRANCH))
970 target->CastSpell(target, SPELL_ROOTS_IRONBRANCH, true);
972 break;
976 break;
977 }
978
980 return;
981 }
982
984 }
985
986 void DoAction(int32 action) override
987 {
988 switch (action)
989 {
991 me->DespawnOrUnsummon(10s);
992 _JustDied();
993 break;
994 }
995 }
996 };
997
998 CreatureAI* GetAI(Creature* creature) const override
999 {
1000 return GetUlduarAI<boss_elder_ironbranchAI>(creature);
1001 }
1002};
1003
1005{
1006 public:
1007 npc_detonating_lasher() : CreatureScript("npc_detonating_lasher") { }
1008
1010 {
1012 {
1013 Initialize();
1015 }
1016
1018 {
1019 lashTimer = 5000;
1020 changeTargetTimer = 7500;
1021 }
1022
1023 void Reset() override
1024 {
1025 Initialize();
1026 }
1027
1028 void UpdateAI(uint32 diff) override
1029 {
1030 if (!UpdateVictim())
1031 return;
1032
1033 if (lashTimer <= diff)
1034 {
1036 lashTimer = urand(5000, 10000);
1037 }
1038 else
1039 lashTimer -= diff;
1040
1041 if (changeTargetTimer <= diff)
1042 {
1043 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
1044 {
1045 // Switching to other target - modify aggro of new target by 20% from current target's aggro
1046 AddThreat(target, GetThreat(me->GetVictim()) * 1.2f);
1047 AttackStart(target);
1048 }
1049 changeTargetTimer = urand(5000, 10000);
1050 }
1051 else
1052 changeTargetTimer -= diff;
1053
1055 }
1056
1057 private:
1060 };
1061
1062 CreatureAI* GetAI(Creature* creature) const override
1063 {
1064 return GetUlduarAI<npc_detonating_lasherAI>(creature);
1065 }
1066};
1067
1069{
1070 public:
1071 npc_ancient_water_spirit() : CreatureScript("npc_ancient_water_spirit") { }
1072
1074 {
1076 {
1077 Initialize();
1079 if (Creature* freya = instance->GetCreature(DATA_FREYA))
1080 waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount;
1081 else
1082 waveCount = 0;
1083 }
1084
1086 {
1087 tidalWaveTimer = 10000;
1088 }
1089
1090 void Reset() override
1091 {
1092 Initialize();
1093 }
1094
1095 void UpdateAI(uint32 diff) override
1096 {
1097 if (!UpdateVictim())
1098 return;
1099
1100 if (tidalWaveTimer <= diff)
1101 {
1102 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
1103 {
1104 DoCast(target, SPELL_TIDAL_WAVE);
1105 DoCast(target, SPELL_TIDAL_WAVE_EFFECT, true);
1106 }
1107 tidalWaveTimer = urand(12000, 25000);
1108 }
1109 else
1110 tidalWaveTimer -= diff;
1111
1113 }
1114
1115 void JustDied(Unit* /*killer*/) override
1116 {
1117 if (Creature* freya = instance->GetCreature(DATA_FREYA))
1118 {
1119 ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false;
1120 ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(1);
1121 }
1122 }
1123
1124 private:
1128 };
1129
1130 CreatureAI* GetAI(Creature* creature) const override
1131 {
1132 return GetUlduarAI<npc_ancient_water_spiritAI>(creature);
1133 }
1134};
1135
1137{
1138 public:
1139 npc_storm_lasher() : CreatureScript("npc_storm_lasher") { }
1140
1142 {
1144 {
1145 Initialize();
1147 if (Creature* freya = instance->GetCreature(DATA_FREYA))
1148 waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount;
1149 else
1150 waveCount = 0;
1151 }
1152
1154 {
1155 lightningLashTimer = 10000;
1156 stormboltTimer = 5000;
1157 }
1158
1159 void Reset() override
1160 {
1161 Initialize();
1162 }
1163
1164 void UpdateAI(uint32 diff) override
1165 {
1166 if (!UpdateVictim())
1167 return;
1168
1169 if (lightningLashTimer <= diff)
1170 {
1172 lightningLashTimer = urand(7000, 14000);
1173 }
1174 else
1175 lightningLashTimer -= diff;
1176
1177 if (stormboltTimer <= diff)
1178 {
1179 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
1180 DoCast(target, SPELL_STORMBOLT);
1181 stormboltTimer = urand(8000, 12000);
1182 }
1183 else
1184 stormboltTimer -= diff;
1185
1187 }
1188
1189 void JustDied(Unit* /*killer*/) override
1190 {
1191 if (Creature* freya = instance->GetCreature(DATA_FREYA))
1192 {
1193 ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false;
1194 ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(2);
1195 }
1196 }
1197
1198 private:
1203 };
1204
1205 CreatureAI* GetAI(Creature* creature) const override
1206 {
1207 return GetUlduarAI<npc_storm_lasherAI>(creature);
1208 }
1209};
1210
1212{
1213 public:
1214 npc_snaplasher() : CreatureScript("npc_snaplasher") { }
1215
1217 {
1218 npc_snaplasherAI(Creature* creature) : ScriptedAI(creature)
1219 {
1221 if (Creature* freya = instance->GetCreature(DATA_FREYA))
1222 waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount;
1223 else
1224 waveCount = 0;
1225 }
1226
1227 void UpdateAI(uint32 /*diff*/) override
1228 {
1229 if (!UpdateVictim())
1230 return;
1231
1232 if (!me->HasAura(SPELL_BARK_AURA))
1234
1236 }
1237
1238 void JustDied(Unit* /*killer*/) override
1239 {
1240 if (Creature* freya = instance->GetCreature(DATA_FREYA))
1241 {
1242 ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false;
1243 ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(4);
1244 }
1245 }
1246
1247 private:
1250 };
1251
1252 CreatureAI* GetAI(Creature* creature) const override
1253 {
1254 return GetUlduarAI<npc_snaplasherAI>(creature);
1255 }
1256};
1257
1259{
1260 public:
1261 npc_ancient_conservator() : CreatureScript("npc_ancient_conservator") { }
1262
1264 {
1266 {
1267 Initialize();
1268 }
1269
1271 {
1272 natureFuryTimer = 7500;
1273 healthySporeTimer = 3500;
1274 }
1275
1276 void Reset() override
1277 {
1278 Initialize();
1280 }
1281
1282 void SummonHealthySpores(uint8 sporesCount)
1283 {
1284 for (uint8 n = 0; n < sporesCount; ++n)
1285 {
1290 }
1291 }
1292
1293 void JustEngagedWith(Unit* who) override
1294 {
1295 DoCast(who, SPELL_CONSERVATOR_GRIP, true);
1296 }
1297
1298 void UpdateAI(uint32 diff) override
1299 {
1300 if (!UpdateVictim())
1301 return;
1302
1303 if (healthySporeTimer <= diff)
1304 {
1306 healthySporeTimer = urand(15000, 17500);
1307 }
1308 else
1309 healthySporeTimer -= diff;
1310
1311 if (natureFuryTimer <= diff)
1312 {
1313 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, true, -SPELL_NATURE_FURY))
1314 DoCast(target, SPELL_NATURE_FURY);
1316 natureFuryTimer = 5000;
1317 }
1318 else
1319 natureFuryTimer -= diff;
1320
1322 }
1323
1324 private:
1327 };
1328
1329 CreatureAI* GetAI(Creature* creature) const override
1330 {
1331 return GetUlduarAI<npc_ancient_conservatorAI>(creature);
1332 }
1333};
1334
1336{
1337 public:
1338 npc_sun_beam() : CreatureScript("npc_sun_beam") { }
1339
1350
1351 CreatureAI* GetAI(Creature* creature) const override
1352 {
1353 return GetUlduarAI<npc_sun_beamAI>(creature);
1354 }
1355};
1356
1358{
1359 public:
1360 npc_healthy_spore() : CreatureScript("npc_healthy_spore") { }
1361
1363 {
1375
1376 void UpdateAI(uint32 diff) override
1377 {
1378 if (lifeTimer <= diff)
1379 {
1381 me->DespawnOrUnsummon(2200ms);
1382 lifeTimer = urand(22000, 30000);
1383 }
1384 else
1385 lifeTimer -= diff;
1386 }
1387
1388 private:
1390 };
1391
1392 CreatureAI* GetAI(Creature* creature) const override
1393 {
1394 return GetUlduarAI<npc_healthy_sporeAI>(creature);
1395 }
1396};
1397
1399{
1400 public:
1401 npc_eonars_gift() : CreatureScript("npc_eonars_gift") { }
1402
1404 {
1406 {
1407 SetCombatMovement(false);
1408
1409 lifeBindersGiftTimer = 12000;
1411 DoCast(me, SPELL_PHEROMONES, true);
1413 }
1414
1415 void UpdateAI(uint32 diff) override
1416 {
1417 if (lifeBindersGiftTimer <= diff)
1418 {
1421 me->DespawnOrUnsummon(2500ms);
1422 lifeBindersGiftTimer = 12000;
1423 }
1424 else
1425 lifeBindersGiftTimer -= diff;
1426 }
1427
1428 private:
1430 };
1431
1432 CreatureAI* GetAI(Creature* creature) const override
1433 {
1434 return GetUlduarAI<npc_eonars_giftAI>(creature);
1435 }
1436};
1437
1439{
1440 public:
1441 npc_nature_bomb() : CreatureScript("npc_nature_bomb") { }
1442
1444 {
1446 {
1447 SetCombatMovement(false);
1448
1449 bombTimer = urand(8000, 10000);
1451 }
1452
1453 void UpdateAI(uint32 diff) override
1454 {
1455 if (bombTimer <= diff)
1456 {
1458 {
1460 me->RemoveGameObject(go, true);
1462 }
1463
1464 bombTimer = 10000;
1465 }
1466 else
1467 bombTimer -= diff;
1468 }
1469
1470 private:
1472 };
1473
1474 CreatureAI* GetAI(Creature* creature) const override
1475 {
1476 return GetUlduarAI<npc_nature_bombAI>(creature);
1477 }
1478};
1479
1481{
1482 public:
1483 npc_unstable_sun_beam() : CreatureScript("npc_unstable_sun_beam") { }
1484
1486 {
1488 {
1489 SetCombatMovement(false);
1490
1491 despawnTimer = urand(7000, 12000);
1496 }
1497
1498 void UpdateAI(uint32 diff) override
1499 {
1500 if (despawnTimer <= diff)
1501 {
1504 }
1505 else
1506 despawnTimer -= diff;
1507 }
1508
1509 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
1510 {
1511 Unit* unitTarget = target->ToUnit();
1512 if (!unitTarget)
1513 return;
1514
1515 if (spellInfo->Id == SPELL_UNSTABLE_ENERGY)
1516 {
1519 }
1520 }
1521
1522 private:
1525 };
1526
1527 CreatureAI* GetAI(Creature* creature) const override
1528 {
1529 return GetUlduarAI<npc_unstable_sun_beamAI>(creature);
1530 }
1531};
1532
1533// 62521 - Attuned to Nature 25 Dose Reduction
1534// 62524 - Attuned to Nature 2 Dose Reduction
1535// 62525 - Attuned to Nature 10 Dose Reduction
1537{
1538 public:
1539 spell_freya_attuned_to_nature_dose_reduction() : SpellScriptLoader("spell_freya_attuned_to_nature_dose_reduction") { }
1540
1542 {
1544
1545 void HandleScript(SpellEffIndex /*effIndex*/)
1546 {
1547 Unit* target = GetHitUnit();
1548
1549 switch (GetSpellInfo()->Id)
1550 {
1552 if (target->HasAura(GetEffectValue()))
1553 for (uint8 n = 0; n < 2; ++n)
1555 break;
1557 if (target->HasAura(GetEffectValue()))
1558 for (uint8 n = 0; n < 10; ++n)
1560 break;
1562 if (target->HasAura(GetEffectValue()))
1563 for (uint8 n = 0; n < 25; ++n)
1565 break;
1566 default:
1567 break;
1568 }
1569 }
1570
1575 };
1576
1581};
1582
1583// 65158 - Strengthened Iron Roots Summon Effect
1584// 65160 - Iron Roots Summon Effect
1586{
1587 public:
1588 spell_freya_iron_roots() : SpellScriptLoader("spell_freya_iron_roots") { }
1589
1591 {
1593
1595 {
1596 PreventHitDefaultEffect(effIndex);
1597 uint32 entry = uint32(GetEffectInfo().MiscValue);
1598
1599 Position pos = GetCaster()->GetPosition();
1600 // Not good at all, but this prevents having roots in a different position then player
1601 if (Creature* Roots = GetCaster()->SummonCreature(entry, pos))
1602 GetCaster()->NearTeleportTo(Roots->GetPositionX(), Roots->GetPositionY(), Roots->GetPositionZ(), GetCaster()->GetOrientation());
1603 }
1604
1609 };
1610
1611 SpellScript* GetSpellScript() const override
1612 {
1614 }
1615};
1616
1618{
1619 public:
1620 achievement_getting_back_to_nature() : AchievementCriteriaScript("achievement_getting_back_to_nature") { }
1621
1622 bool OnCheck(Player* /*player*/, Unit* target) override
1623 {
1624 return target && target->GetAI()->GetData(DATA_GETTING_BACK_TO_NATURE) >= 25;
1625 }
1626};
1627
1629{
1630 public:
1631 achievement_knock_on_wood() : AchievementCriteriaScript("achievement_knock_on_wood") { }
1632
1633 bool OnCheck(Player* /*player*/, Unit* target) override
1634 {
1635 return target && target->GetAI()->GetData(DATA_KNOCK_ON_WOOD) >= 1;
1636 }
1637};
1638
1640{
1641 public:
1642 achievement_knock_knock_on_wood() : AchievementCriteriaScript("achievement_knock_knock_on_wood") { }
1643
1644 bool OnCheck(Player* /*player*/, Unit* target) override
1645 {
1646 return target && target->GetAI()->GetData(DATA_KNOCK_ON_WOOD) >= 2;
1647 }
1648};
1649
1651{
1652 public:
1653 achievement_knock_knock_knock_on_wood() : AchievementCriteriaScript("achievement_knock_knock_knock_on_wood") { }
1654
1655 bool OnCheck(Player* /*player*/, Unit* target) override
1656 {
1657 return target && target->GetAI()->GetData(DATA_KNOCK_ON_WOOD) == 3;
1658 }
1659};
1660
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
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
SpellEffIndex
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SUMMON
@ IMMUNITY_STATE
@ IMMUNITY_ID
@ LOOT_MODE_DEFAULT
@ FACTION_FRIENDLY
@ FACTION_MONSTER
@ SPELL_AURA_MOD_TAUNT
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ SPELLVALUE_AURA_STACK
@ SPELLVALUE_MAX_TARGETS
#define SpellEffectFn(F, I, N)
#define ENSURE_AI(a, b)
Definition UnitAI.h:28
@ REACT_PASSIVE
@ UNIT_FLAG_NON_ATTACKABLE
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
@ TIME_DIFFERENCE
@ DATA_KNOCK_ON_WOOD
@ DATA_GETTING_BACK_TO_NATURE
void AddSC_boss_freya()
FreyaYells
@ SAY_DEATH
@ SAY_SUMMON_CONSERVATOR
@ SAY_AGGRO_WITH_ELDER
@ SAY_ELDER_AGGRO
@ EMOTE_IRON_ROOTS
@ SAY_ELDER_DEATH
@ SAY_AGGRO
@ SAY_SUMMON_TRIO
@ SAY_SUMMON_LASHERS
@ SAY_ELDER_SLAY
@ EMOTE_ALLIES_OF_NATURE
@ SAY_SLAY
@ EMOTE_GROUND_TREMOR
@ EMOTE_LIFEBINDERS_GIFT
@ SAY_BERSERK
constexpr Seconds FREYA_WAVE_TIME
FreyaEvents
@ EVENT_THORN_SWARM
@ EVENT_IRON_ROOTS
@ EVENT_EONAR_GIFT
@ EVENT_ENRAGE
@ EVENT_GROUND_TREMOR
@ EVENT_UNSTABLE_ENERGY
@ EVENT_SOLAR_FLARE
@ EVENT_STRENGTHENED_IRON_ROOTS
@ EVENT_TREMOR
@ EVENT_FLUX
@ EVENT_FISTS
@ EVENT_BARK
@ EVENT_SUNBEAM
@ EVENT_WAVE
@ EVENT_UNSTABLE_SUN_BEAM
@ EVENT_IMPALE
@ EVENT_NATURE_BOMB
FreyaSpells
@ SPELL_FISTS_OF_STONE
@ SPELL_SUMMON_ANCIENT_CONSERVATOR
@ SPELL_ATTUNED_TO_NATURE_10_DOSE_REDUCTION
@ SPELL_DETONATE
@ SPELL_REMOVE_25STACK
@ SPELL_SUNBEAM
@ SPELL_HEALTHY_SPORE_VISUAL
@ SPELL_UNSTABLE_SUN_BEAM_TRIGGERED
@ SPELL_IRONBRANCH_ESSENCE
@ SPELL_DEFORESTATION_CREDIT
@ SPELL_FREYA_UNSTABLE_ENERGY_VISUAL
@ SPELL_SOLAR_FLARE
@ SPELL_ENRAGE
@ SPELL_EONAR_VISUAL
@ SPELL_OBJECT_BOMB
@ SPELL_POTENT_PHEROMONES
@ SPELL_SPORE_SUMMON_NE
@ SPELL_ROOTS_IRONBRANCH
@ SPELL_DRAINED_OF_POWER
@ SPELL_BRIGHTLEAF_ESSENCE
@ SPELL_FLUX_PLUS
@ SPELL_SUMMON_PERIODIC
@ SPELL_UNSTABLE_SUN_BEAM
@ SPELL_LIGHTNING_LASH
@ SPELL_BARK_AURA
@ SPELL_UNSTABLE_ENERGY
@ SPELL_UNSTABLE_SUN_BEAM_SUMMON
@ SPELL_SUMMON_EONAR_GIFT
@ SPELL_SPORE_SUMMON_SE
@ SPELL_SPORE_SUMMON_NW
@ SPELL_PHEROMONES
@ SPELL_THORN_SWARM
@ SPELL_SUMMON_NATURE_BOMB
@ SPELL_PETRIFIED_BARK_DMG
@ SPELL_STORMBOLT
@ SPELL_NATURE_BOMB
@ SPELL_ATTUNED_TO_NATURE_25_DOSE_REDUCTION
@ SPELL_NATURE_FURY
@ SPELL_HARDENED_BARK
@ SPELL_SPORE_SUMMON_SW
@ SPELL_PHOTOSYNTHESIS
@ SPELL_LIFEBINDERS_GIFT
@ SPELL_TIDAL_WAVE_EFFECT
@ SPELL_ROOTS_FREYA
@ SPELL_PETRIFIED_BARK
@ SPELL_GROUND_TREMOR
@ SPELL_FLUX_MINUS
@ SPELL_TIDAL_WAVE
@ SPELL_FREYA_UNSTABLE_ENERGY
@ SPELL_FLAME_LASH
@ SPELL_FREYA_GROUND_TREMOR
@ SPELL_SUMMON_LASHERS
@ SPELL_FREYA_UNSTABLE_SUNBEAM
@ SPELL_KNOCK_ON_WOOD_CREDIT
@ SPELL_REMOVE_2STACK
@ SPELL_FLUX_AURA
@ SPELL_CONSERVATOR_GRIP
@ SPELL_STONEBARK_ESSENCE
@ SPELL_REMOVE_10STACK
@ SPELL_ATTUNED_TO_NATURE_2_DOSE_REDUCTION
@ SPELL_SUMMON_TRIO
@ SPELL_TOUCH_OF_EONAR
@ SPELL_GROW
@ SPELL_IMPALE
@ SPELL_FLUX
@ SPELL_ATTUNED_TO_NATURE
FreyaNpcs
@ NPC_STRENGTHENED_IRON_ROOTS
@ NPC_IRON_ROOTS
@ OBJECT_NATURE_BOMB
@ NPC_SUN_BEAM
@ NPC_ANCIENT_WATER_SPIRIT
@ NPC_EONARS_GIFT
@ NPC_STORM_LASHER
@ NPC_DETONATING_LASHER
@ NPC_NATURE_BOMB
@ NPC_HEALTHY_SPORE
@ NPC_UNSTABLE_SUN_BEAM
@ NPC_ANCIENT_CONSERVATOR
@ NPC_SNAPLASHER
FreyaActions
@ ACTION_ELDER_FREYA_KILLED
void SetStackAmount(uint8 num)
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
SummonList summons
EventMap events
void DoZoneInCombat(Creature *creature=nullptr)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void EngagementOver()
void RemoveLootMode(uint16 lootMode)
Definition Creature.h:226
void Respawn(bool force=false)
void SetImmuneToPC(bool apply) override
Definition Creature.h:129
void SetReactState(ReactStates st)
Definition Creature.h:119
void RemoveFromWorld() override
Definition Creature.cpp:300
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureAI * AI() const
Definition Creature.h:154
void DisappearAndDie()
Definition Creature.h:73
void Update(uint32 time)
Definition EventMap.h:67
EventId ExecuteEvent()
Definition EventMap.cpp:73
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void DoCastSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
Creature * GetCreature(uint32 type)
virtual ObjectGuid GetGuidData(uint32 type) const override
Difficulty GetDifficulty() const
Definition Map.h:412
static Unit * ToUnit(Object *o)
Definition Object.h:192
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
static Player * ToPlayer(Object *o)
Definition Object.h:180
uint32 Id
Definition SpellInfo.h:289
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
int32 GetEffectValue() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
SpellInfo const * GetSpellInfo() const
void Despawn(Creature const *summon)
void Summon(Creature const *summon)
virtual void DoAction(int32)
Definition UnitAI.h:154
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
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
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:30
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:5111
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4439
void SetInCombatWith(Unit *enemy, bool addSecondUnitSuppressed=false)
Definition Unit.h:1146
void SetFaction(uint32 faction) override
Definition Unit.h:974
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:11964
bool IsAlive() const
Definition Unit.h:1234
void SetHealth(uint32 val)
Definition Unit.cpp:9361
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
UnitAI * GetAI() const
Definition Unit.h:800
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13259
uint32 GetHealth() const
Definition Unit.h:913
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3800
void NearTeleportTo(Position const &pos, bool casting=false)
Definition Unit.cpp:12832
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
Definition Unit.cpp:8142
void RemoveAllAttackers()
Definition Unit.cpp:5736
void RemoveAllAuras()
Definition Unit.cpp:4157
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:5691
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
bool AttackStop()
Definition Unit.cpp:5645
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition Object.cpp:2121
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
bool OnCheck(Player *, Unit *target) override
bool OnCheck(Player *, Unit *target) override
bool OnCheck(Player *, Unit *target) override
bool OnCheck(Player *, Unit *target) override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
SpellScript * GetSpellScript() const override
PrepareSpellScript(spell_freya_iron_roots_SpellScript)
SpellScript * GetSpellScript() const override
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
CastSpellExtraArgs & AddSpellBP0(int32 val)
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
void GetPosition(float &x, float &y) const
Definition Position.h:84
void AttackStart(Unit *) override
void SetCombatMovement(bool allowMovement)
float GetThreat(Unit const *victim, Unit const *who=nullptr)
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
void DamageTaken(Unit *who, uint32 &damage, DamageEffectType, SpellInfo const *) override
void DamageTaken(Unit *who, uint32 &damage, DamageEffectType, SpellInfo const *) override
void LasherDead(uint32 type)
boss_freyaAI(Creature *creature)
ObjectGuid ElementalGUID[3][2]
uint32 GetData(uint32 type) const override
void JustSummoned(Creature *summoned) override
void JustEngagedWith(Unit *who) override
void JustDied(Unit *) override
void SummonedCreatureDies(Creature *summoned, Unit *who) override
void KilledUnit(Unit *who) override
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
npc_eonars_giftAI(Creature *creature)
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
void IsSummonedBy(WorldObject *summonerWO) override
npc_iron_rootsAI(Creature *creature)
void UpdateAI(uint32 diff) override
npc_nature_bombAI(Creature *creature)
void UpdateAI(uint32) override
void JustDied(Unit *) override
npc_snaplasherAI(Creature *creature)
void UpdateAI(uint32 diff) override
npc_sun_beamAI(Creature *creature)
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
@ DATA_STONEBARK
Definition ulduar.h:52
@ DATA_BRIGHTLEAF
Definition ulduar.h:50
@ DATA_IRONBRANCH
Definition ulduar.h:51
@ DATA_FREYA
Definition ulduar.h:45