Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_razorscale.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
7
8#include "ScriptMgr.h"
9#include "ScriptedCreature.h"
10#include "ScriptedGossip.h"
11#include "SpellScript.h"
12#include "ulduar.h"
13#include "SpellInfo.h"
14#include "Player.h"
15
16enum Says
17{
18 // Expedition Commander
22
23 // Expedition Engineer
26 SAY_TURRETS = 2, // unused
27
28 // Razorscale Controller
30
31 // Razorscale
34};
35
65
76
78{
79 // Dark Rune Watcher
82 // Dark Rune Guardian
84 // Dark Rune Sentinel
88};
89
98
105
125
126#define GROUND_Z 391.517f
127#define GOSSIP_ITEM_1 "Activate Harpoons!"
128
130{
131 DATA_QUICK_SHAVE = 29192921, // 2919, 2921 are achievement IDs
133};
134
136{
137 { 590.442f, -130.550f, GROUND_Z, 4.789f },
138 { 574.850f, -133.687f, GROUND_Z, 4.252f },
139 { 606.567f, -143.369f, GROUND_Z, 4.434f },
140 { 560.609f, -142.967f, GROUND_Z, 5.074f },
141};
142
144{
145 { 600.75f, -104.850f, GROUND_Z, 0 },
146 { 596.38f, -110.262f, GROUND_Z, 0 },
147 { 566.47f, -103.633f, GROUND_Z, 0 },
148 { 570.41f, -108.791f, GROUND_Z, 0 },
149};
150
152{
153 { 614.975f, -155.138f, GROUND_Z, 4.154f },
154 { 609.814f, -204.968f, GROUND_Z, 5.385f },
155 { 563.531f, -201.557f, GROUND_Z, 4.108f },
156 { 560.231f, -153.677f, GROUND_Z, 5.403f },
157};
158
160{
161 { 571.901f, -136.554f, GROUND_Z, 0 },
162 { 589.450f, -134.888f, GROUND_Z, 0 },
163 { 559.119f, -140.505f, GROUND_Z, 0 },
164 { 606.229f, -136.721f, GROUND_Z, 0 },
165};
166
167const Position RazorFlight = { 588.050f, -251.191f, 470.536f, 1.498f };
168const Position RazorGround = { 586.966f, -175.534f, GROUND_Z, 4.682f };
169const Position PosEngSpawn = { 591.951f, -95.9680f, GROUND_Z, 0.000f };
170
172{
173 public:
174 boss_razorscale_controller() : CreatureScript("boss_razorscale_controller") { }
175
177 {
179 {
180 me->SetDisplayId(me->GetCreatureTemplate()->Modelid2);
181 }
182
184 {
185 _Reset();
186 me->SetReactState(REACT_PASSIVE);
187 }
188
189 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
190 {
191 switch (spell->Id)
192 {
193 case SPELL_FLAMED:
195 Harpoon1->RemoveFromWorld();
197 Harpoon2->RemoveFromWorld();
199 Harpoon3->RemoveFromWorld();
201 Harpoon4->RemoveFromWorld();
202 me->AI()->DoAction(ACTION_HARPOON_BUILD);
203 me->AI()->DoAction(ACTION_PLACE_BROKEN_HARPOON);
204 break;
210 break;
211 }
212 }
213
214 void JustDied(Unit* /*killer*/) OVERRIDE
215 {
216 _JustDied();
217 }
218
220 {
221 if (instance->GetBossState(BOSS_RAZORSCALE) != IN_PROGRESS)
222 return;
223
224 switch (action)
225 {
227 events.ScheduleEvent(EVENT_BUILD_HARPOON_1, 50000);
228 if (me->GetMap()->GetSpawnMode() == DIFFICULTY_25MAN_NORMAL)
229 events.ScheduleEvent(EVENT_BUILD_HARPOON_3, 90000);
230 break;
232 for (uint8 n = 0; n < RAID_MODE(2, 4); n++)
233 me->SummonGameObject(GO_RAZOR_BROKEN_HARPOON, PosHarpoon[n].GetPositionX(), PosHarpoon[n].GetPositionY(), PosHarpoon[n].GetPositionZ(), 2.286f, 0, 0, 0, 0, 180000);
234 break;
235 }
236 }
237
239 {
240 events.Update(Diff);
241
242 while (uint32 eventId = events.ExecuteEvent())
243 {
244 switch (eventId)
245 {
248 if (GameObject* Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_1, PosHarpoon[0].GetPositionX(), PosHarpoon[0].GetPositionY(), PosHarpoon[0].GetPositionZ(), 4.790f, 0.0f, 0.0f, 0.0f, 0.0f, uint32(me->GetRespawnTime())))
249 {
250 if (GameObject* BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) //only nearest broken harpoon
251 BrokenHarpoon->RemoveFromWorld();
252 events.ScheduleEvent(EVENT_BUILD_HARPOON_2, 20000);
253 events.CancelEvent(EVENT_BUILD_HARPOON_1);
254 }
255 return;
258 if (GameObject* Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_2, PosHarpoon[1].GetPositionX(), PosHarpoon[1].GetPositionY(), PosHarpoon[1].GetPositionZ(), 4.659f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
259 {
260 if (GameObject* BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
261 BrokenHarpoon->RemoveFromWorld();
262 events.CancelEvent(EVENT_BUILD_HARPOON_2);
263 }
264 return;
267 if (GameObject* Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_3, PosHarpoon[2].GetPositionX(), PosHarpoon[2].GetPositionY(), PosHarpoon[2].GetPositionZ(), 5.382f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
268 {
269 if (GameObject* BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
270 BrokenHarpoon->RemoveFromWorld();
271 events.ScheduleEvent(EVENT_BUILD_HARPOON_4, 20000);
272 events.CancelEvent(EVENT_BUILD_HARPOON_3);
273 }
274 return;
277 if (GameObject* Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_4, PosHarpoon[3].GetPositionX(), PosHarpoon[3].GetPositionY(), PosHarpoon[3].GetPositionZ(), 4.266f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
278 {
279 if (GameObject* BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
280 BrokenHarpoon->RemoveFromWorld();
281 events.CancelEvent(EVENT_BUILD_HARPOON_4);
282 }
283 return;
284 }
285 }
286 }
287 };
288
290 {
291 return new boss_razorscale_controllerAI(creature);
292 }
293};
294
296{
297 public:
298 go_razorscale_harpoon() : GameObjectScript("go_razorscale_harpoon") { }
299
301 {
302 InstanceScript* instance = go->GetInstanceScript();
303 if (ObjectAccessor::GetCreature(*go, instance ? instance->GetData64(BOSS_RAZORSCALE) : 0))
305 return false;
306 }
307};
308
310{
311 public:
312 boss_razorscale() : CreatureScript("boss_razorscale") { }
313
314 struct boss_razorscaleAI : public BossAI
315 {
317 {
318 // Do not let Razorscale be affected by Battle Shout buff
319 me->ApplySpellImmune(0, IMMUNITY_ID, (SPELL_BATTLE_SHOUT), true);
320 }
321
323
329
331 {
332 _Reset();
333 me->SetCanFly(true);
335 me->SetReactState(REACT_PASSIVE);
336 PermaGround = false;
337 HarpoonCounter = 0;
339 commander->AI()->DoAction(ACTION_COMMANDER_RESET);
340 }
341
342 void EnterCombat(Unit* /*who*/) OVERRIDE
343 {
344 _EnterCombat();
346 controller->AI()->DoAction(ACTION_HARPOON_BUILD);
347 me->SetSpeed(MOVE_FLIGHT, 3.0f, true);
348 me->SetReactState(REACT_PASSIVE);
350 events.SetPhase(PHASE_GROUND);
351 FlyCount = 0;
352 EnrageTimer = 600000;
353 Enraged = false;
354 events.ScheduleEvent(EVENT_FLIGHT, 0, 0, PHASE_GROUND);
355 }
356
357 void JustDied(Unit* /*killer*/) OVERRIDE
358 {
359 _JustDied();
361 controller->AI()->Reset();
362 }
363
364 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
365 {
366 if (spell->Id == SPELL_HARPOON_TRIGGER)
368 }
369
371 {
372 if (type == EFFECT_MOTION_TYPE && id == 1)
373 {
375 events.SetPhase(PHASE_GROUND);
376 events.ScheduleEvent(EVENT_LAND, 0, 0, PHASE_GROUND);
377 }
378 }
379
381 {
382 if (type == DATA_QUICK_SHAVE)
383 if (FlyCount <= 2)
384 return 1;
385
386 return 0;
387 }
388
390 {
391 if (!UpdateVictim())
392 return;
393
394 events.Update(Diff);
395
396 if (HealthBelowPct(50) && !PermaGround)
398
399 if (EnrageTimer <= Diff && !Enraged)
400 {
402 Enraged = true;
403 }
404 else
405 EnrageTimer -= Diff;
406
407 if (HarpoonCounter == RAID_MODE(2, 4))
408 {
409 HarpoonCounter = 0;
410 me->GetMotionMaster()->MoveLand(1, RazorGround);
411 }
412
413 if (phase == PHASE_GROUND)
414 {
415 while (uint32 eventId = events.ExecuteEvent())
416 {
417 switch (eventId)
418 {
419 case EVENT_FLIGHT:
421 events.SetPhase(PHASE_FLIGHT);
422 me->SetCanFly(true);
424 me->SetReactState(REACT_PASSIVE);
425 me->AttackStop();
426 me->GetMotionMaster()->MoveTakeoff(0, RazorFlight);
427 events.ScheduleEvent(EVENT_FIREBALL, 7000, 0, PHASE_FLIGHT);
428 events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT);
429 events.ScheduleEvent(EVENT_SUMMON, 5000, 0, PHASE_FLIGHT);
430 ++FlyCount;
431 return;
432 case EVENT_LAND:
433 me->SetCanFly(false);
437 commander->AI()->DoAction(ACTION_GROUND_PHASE);
438 events.ScheduleEvent(EVENT_BREATH, 30000, 0, PHASE_GROUND);
439 events.ScheduleEvent(EVENT_BUFFET, 33000, 0, PHASE_GROUND);
440 events.ScheduleEvent(EVENT_FLIGHT, 35000, 0, PHASE_GROUND);
441 return;
442 case EVENT_BREATH:
444 me->RemoveAllAuras();
445 me->SetReactState(REACT_AGGRESSIVE);
448 events.CancelEvent(EVENT_BREATH);
449 return;
450 case EVENT_BUFFET:
453 controller->CastSpell(controller, SPELL_FLAMED, true);
454 events.CancelEvent(EVENT_BUFFET);
455 return;
456 }
457 }
458 }
460 {
461 while (uint32 eventId = events.ExecuteEvent())
462 {
463 switch (eventId)
464 {
465 case EVENT_FLAME:
467 events.ScheduleEvent(EVENT_FLAME, 10000, 0, PHASE_PERMAGROUND);
468 return;
469 case EVENT_BREATH:
472 events.ScheduleEvent(EVENT_BREATH, 20000, 0, PHASE_PERMAGROUND);
473 return;
474 case EVENT_FIREBALL:
475 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true))
476 DoCast(target, SPELL_FIREBALL);
477 events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_PERMAGROUND);
478 return;
479 case EVENT_DEVOURING:
480 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true))
482 events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_PERMAGROUND);
483 return;
484 case EVENT_BUFFET:
486 events.CancelEvent(EVENT_BUFFET);
487 return;
488 case EVENT_FUSE:
490 events.ScheduleEvent(EVENT_FUSE, 10000, 0, PHASE_PERMAGROUND);
491 return;
492 }
493 }
494
496 }
497 else
498 {
499 if (uint32 eventId = events.ExecuteEvent())
500 {
501 switch (eventId)
502 {
503 case EVENT_FIREBALL:
504 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true))
505 DoCast(target, SPELL_FIREBALL);
506 events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_FLIGHT);
507 return;
508 case EVENT_DEVOURING:
509 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true))
510 me->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), SPELL_DEVOURING_FLAME, true);
511 events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT);
512 return;
513 case EVENT_SUMMON:
515 events.ScheduleEvent(EVENT_SUMMON, 45000, 0, PHASE_FLIGHT);
516 return;
517 }
518 }
519 }
520 }
521
523 {
526 events.SetPhase(PHASE_PERMAGROUND);
527 me->SetCanFly(false);
529 me->SetReactState(REACT_AGGRESSIVE);
530 me->RemoveAurasDueToSpell(SPELL_HARPOON_TRIGGER);
531 me->SetSpeed(MOVE_FLIGHT, 1.0f, true);
532 PermaGround = true;
534 events.ScheduleEvent(EVENT_FLAME, 15000, 0, PHASE_PERMAGROUND);
535 events.RescheduleEvent(EVENT_DEVOURING, 15000, 0, PHASE_PERMAGROUND);
536 events.RescheduleEvent(EVENT_BREATH, 20000, 0, PHASE_PERMAGROUND);
537 events.RescheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_PERMAGROUND);
538 events.RescheduleEvent(EVENT_DEVOURING, 6000, 0, PHASE_PERMAGROUND);
539 events.RescheduleEvent(EVENT_BUFFET, 2500, 0, PHASE_PERMAGROUND);
540 events.RescheduleEvent(EVENT_FUSE, 5000, 0, PHASE_PERMAGROUND);
541 }
542
544 {
545 // Adds will come in waves from mole machines. One mole can spawn a Dark Rune Watcher
546 // with 1-2 Guardians, or a lone Sentinel. Up to 4 mole machines can spawn adds at any given time.
547 uint8 random = std::rand() % 4 + 2;
548 for (uint8 n = 0; n < random; n++)
549 {
550 float x = float(std::rand() % 640 + 540); // Safe range is between 500 and 650
551 float y = float(std::rand() % -195 + -230); // Safe range is between -235 and -145
552 float z = GROUND_Z; // Ground level
553 me->SummonCreature(MOLE_MACHINE_TRIGGER, x, y, z, 0, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 15000);
554 }
555 }
556
558 {
559 switch (action)
560 {
563 me->SetReactState(REACT_AGGRESSIVE);
564 DoZoneInCombat(me, 150.0f);
565 break;
566 }
567 }
568 };
569
571 {
572 return GetUlduarAI<boss_razorscaleAI>(creature);
573 }
574};
575
577{
578 public:
579 npc_expedition_commander() : CreatureScript("npc_expedition_commander") { }
580
582 {
584 {
585 instance = me->GetInstanceScript();
586 Greet = false;
587 }
588
590 std::list<uint64> summons;
591
592 bool Greet;
597
599 {
601 Phase = 0;
602 Greet = false;
603 summons.clear();
604 }
605
607
608 {
609 if (!Greet && me->IsWithinDistInMap(who, 10.0f) && who->GetTypeId() == TypeID::TYPEID_PLAYER)
610 {
612 Greet = true;
613 }
614 }
615
617 {
618 summons.push_back(summoned->GetGUID());
619 }
620
622 {
623 switch (action)
624 {
627 break;
629 summons.clear();
631 break;
632 }
633 }
634
636 {
637 if (AttackStartTimer <= Diff)
638 {
639 switch (Phase)
640 {
641 case 1:
642 instance->SetBossState(BOSS_RAZORSCALE, IN_PROGRESS);
643 summons.clear();
644 AttackStartTimer = 1000;
645 Phase = 2;
646 break;
647 case 2:
648 for (uint8 n = 0; n < RAID_MODE(2, 4); n++)
649 {
651 Engineer[n]->SetWalk(false);
652 Engineer[n]->SetSpeed(MOVE_RUN, 0.5f);
653 Engineer[n]->SetHomePosition(PosEngRepair[n]);
654 Engineer[n]->GetMotionMaster()->MoveTargetedHome();
655 }
656 Engineer[0]->AI()->Talk(SAY_AGGRO_3);
657 Phase = 3;
658 AttackStartTimer = 14000;
659 break;
660 case 3:
661 for (uint8 n = 0; n < 4; n++)
662 {
664 Defender[n]->SetWalk(false);
665 Defender[n]->SetHomePosition(PosDefCombat[n]);
666 Defender[n]->GetMotionMaster()->MoveTargetedHome();
667 }
668 Phase = 4;
669 break;
670 case 4:
671 for (uint8 n = 0; n < RAID_MODE(2, 4); n++)
673 for (uint8 n = 0; n < 4; ++n)
676 AttackStartTimer = 16000;
677 Phase = 5;
678 break;
679 case 5:
680 if (Creature* Razorscale = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_RAZORSCALE) : 0))
681 {
682 Razorscale->AI()->DoAction(ACTION_EVENT_START);
683 me->SetInCombatWith(Razorscale);
684 }
685 Engineer[0]->AI()->Talk(SAY_AGGRO_1);
686 Phase = 6;
687 break;
688 }
689 }
690 else
691 AttackStartTimer -= Diff;
692 }
693 };
694
695 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
696 {
697 player->PlayerTalkClass->ClearMenus();
698 switch (action)
699 {
701 player->CLOSE_GOSSIP_MENU();
702 CAST_AI(npc_expedition_commanderAI, creature->AI())->Phase = 1;
703 break;
704 }
705 return true;
706 }
707
708 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
709 {
710 InstanceScript* instance = creature->GetInstanceScript();
711 if (instance && instance->GetBossState(BOSS_RAZORSCALE) == NOT_STARTED)
712 {
713 player->PrepareGossipMenu(creature);
714
716 player->SEND_GOSSIP_MENU(13853, creature->GetGUID());
717 }
718 else
719 player->SEND_GOSSIP_MENU(13910, creature->GetGUID());
720
721 return true;
722 }
723
725 {
726 return new npc_expedition_commanderAI(creature);
727 }
728};
729
731{
732 public:
733 npc_mole_machine_trigger() : CreatureScript("npc_mole_machine_trigger") { }
734
736 {
742
748
750 {
751 SummonGobTimer = 2000;
752 SummonNpcTimer = 6000;
753 DissapearTimer = 10000;
754 GobSummoned = false;
755 NpcSummoned = false;
756 }
757
759 {
760 if (!GobSummoned && SummonGobTimer <= Diff)
761 {
763 GobSummoned = true;
764 }
765 else
766 SummonGobTimer -= Diff;
767
768 if (!NpcSummoned && SummonNpcTimer <= Diff)
769 {
770 switch (std::rand() % 1)
771 {
772 case 0:
774 break;
775 case 1:
777 break;
778 }
779
782 NpcSummoned = true;
783 }
784 else
785 SummonNpcTimer -= Diff;
786
787 if (DissapearTimer <= Diff)
788 {
789 if (GameObject* molemachine = me->FindNearestGameObject(GO_MOLE_MACHINE, 1))
790 molemachine->Delete();
791
792 me->DisappearAndDie();
793 }
794 else
795 DissapearTimer -= Diff;
796 }
797
799 {
800 summoned->AI()->DoZoneInCombat();
801 }
802 };
803
805 {
806 return new npc_mole_machine_triggerAI(creature);
807 }
808};
809
811{
812 public:
813 npc_devouring_flame() : CreatureScript("npc_devouring_flame") { }
814
816 {
822
824 {
826 }
827 };
828
830 {
831 return new npc_devouring_flameAI(creature);
832 }
833};
834
836{
837 public:
838 npc_darkrune_watcher() : CreatureScript("npc_darkrune_watcher") { }
839
841 {
843
846
848 {
849 ChainTimer = std::rand() % 15000 + 10000;
850 LightTimer = std::rand() % 3000 + 1000;
851 }
852
854 {
855 if (!UpdateVictim())
856 return;
857
858 if (ChainTimer <= Diff)
859 {
861 ChainTimer = std::rand() % 15000 + 10000;
862 }
863 else
864 ChainTimer -= Diff;
865
866 if (LightTimer <= Diff)
867 {
869 LightTimer = std::rand() % 7000 + 5000;
870 }
871 else
872 LightTimer -= Diff;
873
875 }
876 };
877
879 {
880 return new npc_darkrune_watcherAI(creature);
881 }
882};
883
885{
886 public:
887 npc_darkrune_guardian() : CreatureScript("npc_darkrune_guardian") { }
888
890 {
892
894
896 {
897 StormTimer = std::rand() % 6000 + 3000;
898 killedByBreath = false;
899 }
900
902 {
903 return type == DATA_IRON_DWARF_MEDIUM_RARE ? killedByBreath : 0;
904 }
905
906 void SetData(uint32 type, uint32 value) OVERRIDE
907 {
908 if (type == DATA_IRON_DWARF_MEDIUM_RARE)
909 killedByBreath = value;
910 }
911
912
914 {
915 if (!UpdateVictim())
916 return;
917
918 if (StormTimer <= Diff)
919 {
921 StormTimer = std::rand() % 8000 + 4000;
922 }
923 else
924 StormTimer -= Diff;
925
927 }
928
929 private:
931 };
932
934 {
935 return new npc_darkrune_guardianAI(creature);
936 }
937};
938
940{
941 public:
942 npc_darkrune_sentinel() : CreatureScript("npc_darkrune_sentinel") { }
943
945 {
947
951
953 {
954 HeroicTimer = std::rand() % 8000 + 4000;
955 WhirlTimer = std::rand() % 25000 + 20000;
956 ShoutTimer = std::rand() % 30000 + 15000;
957 }
958
960 {
961 if (!UpdateVictim())
962 return;
963
964 if (HeroicTimer <= Diff)
965 {
967 HeroicTimer = std::rand() % 6000 + 4000;
968 }
969 else
970 HeroicTimer -= Diff;
971
972 if (WhirlTimer <= Diff)
973 {
975 WhirlTimer = std::rand() % 25000 + 20000;
976 }
977 else
978 WhirlTimer -= Diff;
979
980 if (ShoutTimer <= Diff)
981 {
983 ShoutTimer = std::rand() % 40000 + 30000;
984 }
985 else
986 ShoutTimer -= Diff;
987
989 }
990 };
991
993 {
994 return new npc_darkrune_sentinelAI(creature);
995 }
996};
997
999{
1000 public:
1001 spell_razorscale_devouring_flame() : SpellScriptLoader("spell_razorscale_devouring_flame") { }
1002
1004 {
1006
1008 {
1009 PreventHitDefaultEffect(effIndex);
1010 Unit* caster = GetCaster();
1011 uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue);
1012 WorldLocation const* summonLocation = GetExplTargetDest();
1013 if (!caster || !summonLocation)
1014 return;
1015
1016 caster->SummonCreature(entry, summonLocation->GetPositionX(), summonLocation->GetPositionY(), GROUND_Z, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 20000);
1017 }
1018
1023 };
1024
1029};
1030
1032{
1033 public:
1034 spell_razorscale_flame_breath() : SpellScriptLoader("spell_razorscale_flame_breath") { }
1035
1037 {
1039
1041 {
1042 Creature* target = GetHitCreature();
1043 if (!target || target->GetEntry() != NPC_DARK_RUNE_GUARDIAN)
1044 return;
1045
1046 if (GetHitDamage() >= int32(target->GetHealth()))
1047 target->AI()->SetData(DATA_IRON_DWARF_MEDIUM_RARE, 1);
1048 }
1049
1054 };
1055
1060};
1061
1063{
1064 public:
1065 achievement_iron_dwarf_medium_rare() : AchievementCriteriaScript("achievement_iron_dwarf_medium_rare")
1066 {
1067 }
1068
1069 bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
1070 {
1071 return target && target->IsAIEnabled && target->GetAI()->GetData(DATA_IRON_DWARF_MEDIUM_RARE);
1072 }
1073};
1074
1076{
1077 public:
1078 achievement_quick_shave() : AchievementCriteriaScript("achievement_quick_shave") { }
1079
1080 bool OnCheck(Player* /*source*/, Unit* target) OVERRIDE
1081 {
1082 if (target)
1083 if (Creature* razorscale = target->ToCreature())
1084 if (razorscale->AI()->GetData(DATA_QUICK_SHAVE))
1085 return true;
1086
1087 return false;
1088 }
1089};
1090
Actions
@ DIFFICULTY_25MAN_NORMAL
Definition DBCEnums.h:335
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
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ IN_PROGRESS
@ NOT_STARTED
@ EFFECT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Definition Object.h:73
#define CAST_AI(a, b)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
SpellEffIndex
@ EFFECT_0
@ EMOTE_STATE_READY2H
@ EMOTE_STATE_USE_STANDING
@ SPELL_EFFECT_SUMMON
@ IMMUNITY_ID
@ GO_FLAG_NOT_SELECTABLE
#define SpellEffectFn(F, I, N)
#define SpellHitFn(F)
@ UNIT_NPC_FLAG_GOSSIP
Definition Unit.h:687
@ MOVE_FLIGHT
Definition Unit.h:561
@ MOVE_RUN
Definition Unit.h:556
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_STUNNED
Definition Unit.h:643
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_PACIFIED
Definition Unit.h:642
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_FLAGS
@ UNIT_FIELD_NPC_EMOTESTATE
@ GAMEOBJECT_FIELD_FLAGS
@ SPELL_WHIRLWIND
@ SAY_INTRO
@ SPELL_FIREBALL
@ SPELL_WINGBUFFET
@ PHASE_FLIGHT
@ PHASE_GROUND
@ EVENT_FLIGHT
#define SPELL_BERSERK
@ EVENT_SUMMON
@ SPELL_LIGHTNING_BOLT
@ SPELL_FLAMEBREATH
Definition boss_gyth.cpp:14
@ EVENT_BREATH
@ SPELL_HEROIC_STRIKE
@ EMOTE_BREATH
@ EVENT_GROUND
Definition boss_noth.cpp:56
@ EVENT_BERSERK
@ EVENT_FIREBALL
const Position PosEngRepair[4]
const Position PosDefSpawn[4]
const Position RazorFlight
@ SAY_AGGRO_2
@ EMOTE_HARPOON
@ EMOTE_BREATH
@ SAY_AGGRO_3
@ EMOTE_PERMA
@ SAY_GROUND_PHASE
@ SAY_AGGRO_1
@ SAY_TURRETS
@ SAY_INTRO
@ ACTION_PLACE_BROKEN_HARPOON
@ ACTION_HARPOON_BUILD
@ ACTION_COMMANDER_RESET
@ ACTION_EVENT_START
@ ACTION_GROUND_PHASE
@ DATA_IRON_DWARF_MEDIUM_RARE
@ DATA_QUICK_SHAVE
#define GOSSIP_ITEM_1
@ SPELL_SUMMON_IRON_DWARVE_GUARDIAN
@ SPELL_FUSEARMOR
@ SPELL_SUMMON_MOLE_MACHINE
@ SPELL_SUMMON_IRON_DWARVES_2
@ SPELL_HARPOON_SHOT_1
@ SPELL_DEVOURING_FLAME_TRIGGER
@ SPELL_FLAMEBREATH
@ SPELL_SUMMON_IRON_DWARVE_WATCHER
@ SPELL_FLAMED
@ SPELL_FIREBALL
@ SPELL_DEVOURING_FLAME_DAMAGE
@ SPELL_HARPOON_SHOT_3
@ SPELL_FLAMEBUFFET
@ SPELL_SUMMON_IRON_DWARVES
@ SPELL_HARPOON_SHOT_4
@ SPELL_BERSERK
@ SPELL_FLAME_GROUND
@ SPELL_DEVOURING_FLAME
@ SPELL_STUN
@ SPELL_HARPOON_TRIGGER
@ SPELL_WINGBUFFET
@ SPELL_HARPOON_SHOT_2
@ PHASE_PERMAGROUND
@ PHASE_FLIGHT
@ PHASE_GROUND
const Position PosHarpoon[4]
const Position PosEngSpawn
void AddSC_boss_razorscale()
@ NPC_COMMANDER
@ NPC_DARK_RUNE_SENTINEL
@ NPC_DARK_RUNE_GUARDIAN
@ NPC_DEFENDER
@ MOLE_MACHINE_TRIGGER
@ NPC_ENGINEER
@ NPC_DARK_RUNE_WATCHER
const Position RazorGround
const Position PosDefCombat[4]
DarkRuneSpells
@ SPELL_STORMSTRIKE
@ SPELL_BATTLE_SHOUT
@ SPELL_LIGHTNING_BOLT
@ SPELL_HEROIC_STRIKE
@ SPELL_CHAIN_LIGHTNING
@ SPELL_WHIRLWIND
#define GROUND_Z
@ EVENT_BUILD_HARPOON_2
@ EVENT_DEVOURING
@ EVENT_FIREBALL
@ EVENT_FUSE
@ EVENT_BUILD_HARPOON_3
@ EVENT_FLAME
@ EVENT_BUILD_HARPOON_4
@ EVENT_FLIGHT
@ EVENT_BUILD_HARPOON_1
@ EVENT_BREATH
@ EVENT_BUFFET
@ EVENT_SUMMON
@ EVENT_LAND
@ EVENT_LAND
@ SPELL_CHAIN_LIGHTNING
AchievementCriteriaScript(const char *name)
InstanceScript *const instance
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
GameObjectScript(const char *name)
EncounterState GetBossState(uint32 id) const
static Creature * GetCreature(WorldObject const &u, uint64 guid)
static GameObject * GetGameObject(WorldObject const &u, uint64 guid)
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
Creature * GetHitCreature()
WorldLocation const * GetExplTargetDest()
SpellInfo const * GetSpellInfo()
HookList< HitHandler > OnHit
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetCaster()
int32 GetHitDamage()
SpellScriptLoader(const char *name)
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
uint32 GetHealth() const
Definition Unit.h:1600
GameObject * FindNearestGameObject(uint32 entry, float range) const
Definition Object.cpp:2810
TempSummon * SummonCreature(uint32 id, Position const &pos, TempSummonType spwtype=TempSummonType::TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0) const
Definition Object.cpp:2703
virtual uint64 GetData64(uint32) const
Definition ZoneScript.h:32
bool OnCheck(Player *, Unit *target) OVERRIDE
bool OnCheck(Player *, Unit *target) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnGossipHello(Player *, GameObject *go) 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
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
void SetCombatMovement(bool allowMovement)
Creature * me
bool HealthBelowPct(uint32 pct) const
const T & RAID_MODE(const T &normal10, const T &normal25) const
ScriptedAI(Creature *creature)
void UpdateAI(uint32 Diff) OVERRIDE
== Triggered Actions Requested ==================
uint32 GetData(uint32 type) const OVERRIDE
void DoAction(int32 action) OVERRIDE
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void MovementInform(uint32 type, uint32 id) OVERRIDE
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void UpdateAI(uint32 Diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 Diff) OVERRIDE
== Triggered Actions Requested ==================
void SetData(uint32 type, uint32 value) OVERRIDE
uint32 GetData(uint32 type) const OVERRIDE
void UpdateAI(uint32 Diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 Diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 Diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 Diff) OVERRIDE
== Triggered Actions Requested ==================
@ BOSS_RAZORSCALE
Definition ulduar.h:22
@ DATA_RAZORSCALE_CONTROL
Definition ulduar.h:267
@ DATA_EXPEDITION_COMMANDER
Definition ulduar.h:266
@ GO_RAZOR_HARPOON_4
Definition ulduar.h:166
@ GO_RAZOR_BROKEN_HARPOON
Definition ulduar.h:167
@ GO_RAZOR_HARPOON_3
Definition ulduar.h:165
@ GO_RAZOR_HARPOON_2
Definition ulduar.h:164
@ GO_RAZOR_HARPOON_1
Definition ulduar.h:163
@ GO_MOLE_MACHINE
Definition ulduar.h:162
AI * GetUlduarAI(T *obj)
Definition ulduar.h:336