Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_cthun.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/* ScriptData
7SDName: Boss_Cthun
8SD%Complete: 95
9SDComment: Darkglare tracking issue
10SDCategory: Temple of Ahn'Qiraj
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "temple_of_ahnqiraj.h"
16#include "Player.h"
17
18/*
19 * This is a 2 phases events. Here follows an explanation of the main events and transition between phases and sub-phases.
20 *
21 * The first phase is the EYE phase: the Eye of C'Thun is active and C'thun is not active.
22 * During this phase, the "Eye of C'Thun" alternates between 2 sub-phases:
23 * - PHASE_EYE_GREEN_BEAM:
24 * 50 sec phase during which the Eye mainly casts its Green Beam every 3 sec.
25 * - PHASE_EYE_RED_BEAM:
26 * 35 sec phase during which the Eye casts its red beam every sec.
27 * This EYE phase ends when the "Eye of C'Thun" is killed. Then starts the CTHUN phase.
28 *
29 * The second phase is the CTHUN phase. The Eye of C'Thun is not active and C'Thun is active.
30 * This phase starts with the transformation of the Eye into C'Thun (PHASE_CTHUN_TRANSITION).
31 * After the transformation, C'Thun alternates between 2 sub-phases:
32 * - PHASE_CTHUN_STOMACH:
33 * - C'Thun is almost insensible to all damage (99% damage reduction).
34 * - It spawns 2 tentacles in its stomach.
35 * - C'Thun swallows players.
36 * - This sub-phase ends when the 2 tentacles are killed. Swallowed players are regurgitate.
37 *
38 * - PHASE_CTHUN_WEAK:
39 * - weakened C'Thun takes normal damage.
40 * - This sub-phase ends after 45 secs.
41 *
42 * This CTHUN phase ends when C'Thun is killed
43 *
44 * Note:
45 * - the current phase is stored in the instance data to be easily shared between the eye and cthun.
46 */
47
49{
51
52 // Main Phase 1 - EYE
55
56 // Main Phase 2 - CTHUN
60
62};
63
65{
66 // ***** Main Phase 1 ********
67 //Eye Spells
71 SPELL_RED_COLORATION = 22518, //Probably not the right spell but looks similar
72
73 //Eye Tentacles Spells
75
76 //Claw Tentacles Spells
79
80 // ***** Main Phase 2 ******
81 //Body spells
82 //SPELL_CARAPACE_CTHUN = 26156 //Was removed from client dbcs
84 SPELL_PURPLE_COLORATION = 22581, //Probably not the right spell but looks similar
85
86 //Eye Tentacles Spells
87 //SAME AS PHASE1
88
89 //Giant Claw Tentacles
91
92 //Also casts Hamstring
94
95 //Giant Eye Tentacles
96 //CHAIN CASTS "SPELL_GREEN_BEAM"
97
98 //Stomach Spells
102};
103
108
110{
111 //Text emote
113
114 // ****** Out of Combat ******
115 // Random Wispers - No txt only sound
116 // The random sound is chosen by the client.
118};
119
120//Stomach Teleport positions
121#define STOMACH_X -8562.0f
122#define STOMACH_Y 2037.0f
123#define STOMACH_Z -70.0f
124#define STOMACH_O 5.05f
125
126//Flesh tentacle positions
128{
129 { -8571.0f, 1990.0f, -98.0f, 1.22f},
130 { -8525.0f, 1994.0f, -98.0f, 2.12f},
131};
132
133//Kick out position
134const Position KickPos = { -8545.0f, 1984.0f, -96.0f, 0.0f};
135
137{
138public:
139 boss_eye_of_cthun() : CreatureScript("boss_eye_of_cthun") { }
140
142 {
143 return new eye_of_cthunAI(creature);
144 }
145
147 {
148 eye_of_cthunAI(Creature* creature) : ScriptedAI(creature)
149 {
150 instance = creature->GetInstanceScript();
151 if (!instance)
152 SF_LOG_ERROR("scripts", "No Instance eye_of_cthunAI");
153
154 SetCombatMovement(false);
155 }
156
158
159 //Global variables
161
162 //Eye beam phase
166
167 //Dark Glare phase
172
174 {
175 //Phase information
176 PhaseTimer = 50000; //First dark glare in 50 seconds
177
178 //Eye beam phase 50 seconds
179 BeamTimer = 3000;
180 EyeTentacleTimer = 45000; //Always spawns 5 seconds before Dark Beam
181 ClawTentacleTimer = 12500; //4 per Eye beam phase (unsure if they spawn during Dark beam)
182
183 //Dark Beam phase 35 seconds (each tick = 1 second, 35 ticks)
184 DarkGlareTick = 0;
185 DarkGlareTickTimer = 1000;
186 DarkGlareAngle = 0;
187 ClockWise = false;
188
189 //Reset flags
190 me->RemoveAurasDueToSpell(SPELL_RED_COLORATION);
191 me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
193 me->SetVisible(true);
194
195 //Reset Phase
196 if (instance)
198
199 //to avoid having a following void zone
200 Creature* pPortal= me->FindNearestCreature(NPC_CTHUN_PORTAL, 10);
201 if (pPortal)
203 }
204
205 void EnterCombat(Unit* /*who*/) OVERRIDE
206 {
208 if (instance)
210 }
211
212 void SpawnEyeTentacle(float x, float y)
213 {
215 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
216 if (Spawned->AI())
217 Spawned->AI()->AttackStart(target);
218 }
219
221 {
222 //Check if we have a target
223 if (!UpdateVictim())
224 return;
225
226 //No instance
227 if (!instance)
228 return;
229
230 uint32 currentPhase = instance->GetData(DATA_CTHUN_PHASE);
231 if (currentPhase == PHASE_EYE_GREEN_BEAM || currentPhase == PHASE_EYE_RED_BEAM)
232 {
233 // EyeTentacleTimer
234 if (EyeTentacleTimer <= diff)
235 {
236 //Spawn the 8 Eye Tentacles in the corret spots
237 SpawnEyeTentacle(0, 20); //south
238 SpawnEyeTentacle(10, 10); //south west
239 SpawnEyeTentacle(20, 0); //west
240 SpawnEyeTentacle(10, -10); //north west
241
242 SpawnEyeTentacle(0, -20); //north
243 SpawnEyeTentacle(-10, -10); //north east
244 SpawnEyeTentacle(-20, 0); // east
245 SpawnEyeTentacle(-10, 10); // south east
246
247 EyeTentacleTimer = 45000;
248 } else EyeTentacleTimer -= diff;
249 }
250
251 switch (currentPhase)
252 {
254 //BeamTimer
255 if (BeamTimer <= diff)
256 {
257 //SPELL_GREEN_BEAM
258 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
259 {
260 me->InterruptNonMeleeSpells(false);
261 DoCast(target, SPELL_GREEN_BEAM);
262
263 //Correctly update our target
264 me->SetTarget(target->GetGUID());
265 }
266
267 //Beam every 3 seconds
268 BeamTimer = 3000;
269 } else BeamTimer -= diff;
270
271 //ClawTentacleTimer
272 if (ClawTentacleTimer <= diff)
273 {
274 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
275 {
276 Creature* Spawned = NULL;
277
278 //Spawn claw tentacle on the random target
279 Spawned = me->SummonCreature(NPC_CLAW_TENTACLE, *target, TempSummonType::TEMPSUMMON_CORPSE_DESPAWN, 500);
280
281 if (Spawned && Spawned->AI())
282 Spawned->AI()->AttackStart(target);
283 }
284
285 //One claw tentacle every 12.5 seconds
286 ClawTentacleTimer = 12500;
287 } else ClawTentacleTimer -= diff;
288
289 //PhaseTimer
290 if (PhaseTimer <= diff)
291 {
292 //Switch to Dark Beam
294
295 me->InterruptNonMeleeSpells(false);
296 me->SetReactState(REACT_PASSIVE);
297
298 //Remove any target
299 me->SetTarget(0);
300
301 //Select random target for dark beam to start on
302 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
303 {
304 //Face our target
305 DarkGlareAngle = me->GetAngle(target);
306 DarkGlareTickTimer = 1000;
307 DarkGlareTick = 0;
308 ClockWise = RAND(true, false);
309 }
310
311 //Add red coloration to C'thun
313
314 //Freeze animation
316 me->SetOrientation(DarkGlareAngle);
317 me->StopMoving();
318
319 //Darkbeam for 35 seconds
320 PhaseTimer = 35000;
321 } else PhaseTimer -= diff;
322
323 break;
324
326 if (DarkGlareTick < 35)
327 {
328 if (DarkGlareTickTimer <= diff)
329 {
330 //Set angle and cast
331 if (ClockWise)
332 me->SetOrientation(DarkGlareAngle + DarkGlareTick * M_PI / 35);
333 else
334 me->SetOrientation(DarkGlareAngle - DarkGlareTick * M_PI / 35);
335
336 me->StopMoving();
337
338 //Actual dark glare cast, maybe something missing here?
339 DoCast(me, SPELL_DARK_GLARE, false);
340
341 //Increase tick
343
344 //1 second per tick
345 DarkGlareTickTimer = 1000;
346 } else DarkGlareTickTimer -= diff;
347 }
348
349 //PhaseTimer
350 if (PhaseTimer <= diff)
351 {
352 //Switch to Eye Beam
354
355 BeamTimer = 3000;
356 ClawTentacleTimer = 12500; //4 per Eye beam phase (unsure if they spawn during Dark beam)
357
358 me->InterruptNonMeleeSpells(false);
359
360 //Remove Red coloration from c'thun
361 me->RemoveAurasDueToSpell(SPELL_RED_COLORATION);
362 me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
363
364 //set it back to aggressive
365 me->SetReactState(REACT_AGGRESSIVE);
366
367 //Eye Beam for 50 seconds
368 PhaseTimer = 50000;
369 } else PhaseTimer -= diff;
370
371 break;
372
373 //Transition phase
375 //Remove any target
376 me->SetTarget(0);
377 me->SetHealth(0);
378 me->SetVisible(false);
379 break;
380
381 //Dead phase
382 case PHASE_CTHUN_DONE:
383 Creature* pPortal= me->FindNearestCreature(NPC_CTHUN_PORTAL, 10);
384 if (pPortal)
385 pPortal->DespawnOrUnsummon();
386
387 me->DespawnOrUnsummon();
388 break;
389 }
390 }
391
392 void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE
393 {
394 //No instance
395 if (!instance)
396 return;
397
398 switch (instance->GetData(DATA_CTHUN_PHASE))
399 {
402 //Only if it will kill
403 if (damage < me->GetHealth())
404 return;
405
406 //Fake death in phase 0 or 1 (green beam or dark glare phase)
407 me->InterruptNonMeleeSpells(false);
408
409 //Remove Red coloration from c'thun
410 me->RemoveAurasDueToSpell(SPELL_RED_COLORATION);
411
412 //Reset to normal emote state and prevent select and attack
414
415 //Remove Target field
416 me->SetTarget(0);
417
418 //Death animation/respawning;
420
421 me->SetHealth(0);
422 damage = 0;
423
424 me->InterruptNonMeleeSpells(true);
425 me->RemoveAllAuras();
426 break;
427
428 case PHASE_CTHUN_DONE:
429 //Allow death here
430 return;
431
432 default:
433 //Prevent death in these phases
434 damage = 0;
435 return;
436 }
437 }
438 };
439};
440
442{
443public:
444 boss_cthun() : CreatureScript("boss_cthun") { }
445
447 {
448 return new cthunAI(creature);
449 }
450
451 struct cthunAI : public ScriptedAI
452 {
453 cthunAI(Creature* creature) : ScriptedAI(creature)
454 {
455 SetCombatMovement(false);
456
457 instance = creature->GetInstanceScript();
458 if (!instance)
459 SF_LOG_ERROR("scripts", "No Instance eye_of_cthunAI");
460 }
461
463
464 //Out of combat whisper timer
466
467 //Global variables
469
470 //-------------------
471
472 //Phase transition
474
475 //Body Phase
484
485 //Stomach map, bool = true then in stomach
487
489 {
490 //One random wisper every 90 - 300 seconds
491 WisperTimer = 90000;
492
493 //Phase information
494 PhaseTimer = 10000; //Emerge in 10 seconds
495
496 //No hold player for transition
497 HoldPlayer = 0;
498
499 //Body Phase
500 EyeTentacleTimer = 30000;
502 GiantClawTentacleTimer = 15000; //15 seconds into body phase (1 min repeat)
503 GiantEyeTentacleTimer = 45000; //15 seconds into body phase (1 min repeat)
504 StomachAcidTimer = 4000; //Every 4 seconds
505 StomachEnterTimer = 10000; //Every 10 seconds
506 StomachEnterVisTimer = 0; //Always 3.5 seconds after Stomach Enter Timer
507 StomachEnterTarget = 0; //Target to be teleported to stomach
508
509 //Clear players in stomach and outside
510 Stomach_Map.clear();
511
512 //Reset flags
513 me->RemoveAurasDueToSpell(SPELL_TRANSFORM);
515 me->SetVisible(false);
516
517 if (instance)
519 }
520
521 void EnterCombat(Unit* /*who*/) OVERRIDE
522 {
524 }
525
526 void SpawnEyeTentacle(float x, float y)
527 {
528 Creature* Spawned;
530 if (Spawned && Spawned->AI())
531 if (Unit* target = SelectRandomNotStomach())
532 Spawned->AI()->AttackStart(target);
533 }
534
536 {
537 if (Stomach_Map.empty())
538 return NULL;
539
541
542 std::list<Unit*> temp;
543 std::list<Unit*>::const_iterator j;
544
545 //Get all players in map
546 while (i != Stomach_Map.end())
547 {
548 //Check for valid player
549 Unit* unit = Unit::GetUnit(*me, i->first);
550
551 //Only units out of stomach
552 if (unit && i->second == false)
553 temp.push_back(unit);
554
555 ++i;
556 }
557
558 if (temp.empty())
559 return NULL;
560
561 j = temp.begin();
562
563 //Get random but only if we have more than one unit on threat list
564 if (temp.size() > 1)
565 advance (j, rand() % (temp.size() - 1));
566
567 return (*j);
568 }
569
571 {
572 //Check if we have a target
573 if (!UpdateVictim())
574 {
575 //No target so we'll use this section to do our random wispers instance wide
576 //WisperTimer
577 if (WisperTimer <= diff)
578 {
579 Map* map = me->GetMap();
580 if (!map->IsRaid())
581 return;
582
583 //Play random sound to the zone
584 Map::PlayerList const &PlayerList = map->GetPlayers();
585
586 if (!PlayerList.isEmpty())
587 {
588 for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
589 {
590 if (Player* pPlr = itr->GetSource())
591 pPlr->PlayDirectSound(RANDOM_SOUND_WHISPER, pPlr);
592 }
593 }
594
595 //One random wisper every 90 - 300 seconds
596 WisperTimer = std::rand() % 300000 + 90000;
597 } else WisperTimer -= diff;
598
599 return;
600 }
601
602 me->SetTarget(0);
603
604 //No instance
605 if (!instance)
606 return;
607
608 uint32 currentPhase = instance->GetData(DATA_CTHUN_PHASE);
609 if (currentPhase == PHASE_CTHUN_STOMACH || currentPhase == PHASE_CTHUN_WEAK)
610 {
611 // EyeTentacleTimer
612 if (EyeTentacleTimer <= diff)
613 {
614 //Spawn the 8 Eye Tentacles in the corret spots
615 SpawnEyeTentacle(0, 20); //south
616 SpawnEyeTentacle(10, 10); //south west
617 SpawnEyeTentacle(20, 0); //west
618 SpawnEyeTentacle(10, -10); //north west
619
620 SpawnEyeTentacle(0, -20); //north
621 SpawnEyeTentacle(-10, -10); //north east
622 SpawnEyeTentacle(-20, 0); // east
623 SpawnEyeTentacle(-10, 10); // south east
624
625 EyeTentacleTimer = 30000; // every 30sec in phase 2
626 } else EyeTentacleTimer -= diff;
627 }
628
629 switch (currentPhase)
630 {
631 //Transition phase
633 //PhaseTimer
634 if (PhaseTimer <= diff)
635 {
636 //Switch
638
639 //Switch to c'thun model
640 me->InterruptNonMeleeSpells(false);
641 DoCast(me, SPELL_TRANSFORM, false);
642 me->SetFullHealth();
643
644 me->SetVisible(true);
646
647 //Emerging phase
648 //AttackStart(Unit::GetUnit(*me, HoldpPlayer));
650
651 //Place all units in threat list on outside of stomach
652 Stomach_Map.clear();
653
654 for (std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i)
655 Stomach_Map[(*i)->getUnitGuid()] = false; //Outside stomach
656
657 //Spawn 2 flesh tentacles
659
660 //Spawn flesh tentacle
661 for (uint8 i = 0; i < 2; i++)
662 {
664 if (!spawned)
666 }
667
668 PhaseTimer = 0;
669 } else PhaseTimer -= diff;
670
671 break;
672
673 //Body Phase
675 //Remove Target field
676 me->SetTarget(0);
677
678 //Weaken
679 if (FleshTentaclesKilled > 1)
680 {
682
684 PhaseTimer = 45000;
685
687
689
690 //Kick all players out of stomach
691 while (i != Stomach_Map.end())
692 {
693 //Check for valid player
694 Unit* unit = Unit::GetUnit(*me, i->first);
695
696 //Only move units in stomach
697 if (unit && i->second == true)
698 {
699 //Teleport each player out
700 DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6));
701
702 //Cast knockback on them
704
705 //Remove the acid debuff
707
708 i->second = false;
709 }
710 ++i;
711 }
712
713 return;
714 }
715
716 //Stomach acid
717 if (StomachAcidTimer <= diff)
718 {
719 //Apply aura to all players in stomach
721
722 while (i != Stomach_Map.end())
723 {
724 //Check for valid player
725 Unit* unit = Unit::GetUnit(*me, i->first);
726
727 //Only apply to units in stomach
728 if (unit && i->second == true)
729 {
730 //Cast digestive acid on them
731 DoCast(unit, SPELL_DIGESTIVE_ACID, true);
732
733 //Check if player should be kicked from stomach
734 if (unit->IsWithinDist3d(&KickPos, 15.0f))
735 {
736 //Teleport each player out
737 DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6));
738
739 //Cast knockback on them
741
742 //Remove the acid debuff
744
745 i->second = false;
746 }
747 }
748 ++i;
749 }
750
751 StomachAcidTimer = 4000;
752 } else StomachAcidTimer -= diff;
753
754 //Stomach Enter Timer
755 if (StomachEnterTimer <= diff)
756 {
757 if (Unit* target = SelectRandomNotStomach())
758 {
759 //Set target in stomach
760 Stomach_Map[target->GetGUID()] = true;
761 target->InterruptNonMeleeSpells(false);
762 target->CastSpell(target, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID());
763 StomachEnterTarget = target->GetGUID();
765 }
766
767 StomachEnterTimer = 13800;
768 } else StomachEnterTimer -= diff;
769
771 {
772 if (StomachEnterVisTimer <= diff)
773 {
774 //Check for valid player
776
777 if (unit)
778 {
780 }
781
784 } else StomachEnterVisTimer -= diff;
785 }
786
787 //GientClawTentacleTimer
788 if (GiantClawTentacleTimer <= diff)
789 {
790 if (Unit* target = SelectRandomNotStomach())
791 {
792 //Spawn claw tentacle on the random target
793 if (Creature* spawned = me->SummonCreature(NPC_GIANT_CLAW_TENTACLE, *target, TempSummonType::TEMPSUMMON_CORPSE_DESPAWN, 500))
794 if (spawned->AI())
795 spawned->AI()->AttackStart(target);
796 }
797
798 //One giant claw tentacle every minute
800 } else GiantClawTentacleTimer -= diff;
801
802 //GiantEyeTentacleTimer
803 if (GiantEyeTentacleTimer <= diff)
804 {
805 if (Unit* target = SelectRandomNotStomach())
806 {
807 //Spawn claw tentacle on the random target
808 if (Creature* spawned = me->SummonCreature(NPC_GIANT_EYE_TENTACLE, *target, TempSummonType::TEMPSUMMON_CORPSE_DESPAWN, 500))
809 if (spawned->AI())
810 spawned->AI()->AttackStart(target);
811 }
812
813 //One giant eye tentacle every minute
814 GiantEyeTentacleTimer = 60000;
815 } else GiantEyeTentacleTimer -= diff;
816
817 break;
818
819 //Weakened state
820 case PHASE_CTHUN_WEAK:
821 //PhaseTimer
822 if (PhaseTimer <= diff)
823 {
824 //Switch
826
827 //Remove purple coloration
828 me->RemoveAurasDueToSpell(SPELL_PURPLE_COLORATION);
829
830 //Spawn 2 flesh tentacles
832
833 //Spawn flesh tentacle
834 for (uint8 i = 0; i < 2; i++)
835 {
837 if (!spawned)
839 }
840
841 PhaseTimer = 0;
842 } else PhaseTimer -= diff;
843
844 break;
845 }
846 }
847
848 void JustDied(Unit* /*killer*/) OVERRIDE
849 {
850 if (instance)
852 }
853
854 void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE
855 {
856 //No instance
857 if (!instance)
858 return;
859
860 switch (instance->GetData(DATA_CTHUN_PHASE))
861 {
863 //Not weakened so reduce damage by 99%
864 damage /= 100;
865 if (damage == 0)
866 damage = 1;
867
868 //Prevent death in non-weakened state
869 if (damage >= me->GetHealth())
870 damage = 0;
871
872 return;
873
874 case PHASE_CTHUN_WEAK:
875 //Weakened - takes normal damage
876 return;
877
878 default:
879 damage = 0;
880 break;
881 }
882 }
883
885 {
886 switch (param)
887 {
890 break;
891 }
892 }
893 };
894};
895
897{
898public:
899 npc_eye_tentacle() : CreatureScript("npc_eye_tentacle") { }
900
902 {
903 return new eye_tentacleAI(creature);
904 }
905
907 {
908 eye_tentacleAI(Creature* creature) : ScriptedAI(creature)
909 {
911 {
912 pPortal->SetReactState(REACT_PASSIVE);
913 Portal = pPortal->GetGUID();
914 }
915
916 SetCombatMovement(false);
917 }
918
922
923 void JustDied(Unit* /*killer*/) OVERRIDE
924 {
925 if (Unit* p = Unit::GetUnit(*me, Portal))
926 p->Kill(p);
927 }
928
930 {
931 //Mind flay half a second after we spawn
932 MindflayTimer = 500;
933
934 //This prevents eyes from overlapping
935 KillSelfTimer = 35000;
936 }
937
938 void EnterCombat(Unit* /*who*/) OVERRIDE
939 {
941 }
942
944 {
945 //Check if we have a target
946 if (!UpdateVictim())
947 return;
948
949 //KillSelfTimer
950 if (KillSelfTimer <= diff)
951 {
952 me->Kill(me);
953 return;
954 } else KillSelfTimer -= diff;
955
956 //MindflayTimer
957 if (MindflayTimer <= diff)
958 {
960 if (target && !target->HasAura(SPELL_DIGESTIVE_ACID))
961 DoCast(target, SPELL_MIND_FLAY);
962
963 //Mindflay every 10 seconds
964 MindflayTimer = 10000;
965 } else MindflayTimer -= diff;
966 }
967 };
968};
969
971{
972public:
973 npc_claw_tentacle() : CreatureScript("npc_claw_tentacle") { }
974
976 {
977 return new claw_tentacleAI(creature);
978 }
979
981 {
982 claw_tentacleAI(Creature* creature) : ScriptedAI(creature)
983 {
984 SetCombatMovement(false);
985
987 {
988 pPortal->SetReactState(REACT_PASSIVE);
989 Portal = pPortal->GetGUID();
990 }
991 }
992
997
998 void JustDied(Unit* /*killer*/) OVERRIDE
999 {
1000 if (Unit* p = Unit::GetUnit(*me, Portal))
1001 p->Kill(p);
1002 }
1003
1005 {
1006 //First rupture should happen half a second after we spawn
1007 GroundRuptureTimer = 500;
1008 HamstringTimer = 2000;
1009 EvadeTimer = 5000;
1010 }
1011
1013 {
1015 }
1016
1018 {
1019 //Check if we have a target
1020 if (!UpdateVictim())
1021 return;
1022
1023 //EvadeTimer
1024 if (!me->IsWithinMeleeRange(me->GetVictim()))
1025 {
1026 if (EvadeTimer <= diff)
1027 {
1028 if (Unit* p = Unit::GetUnit(*me, Portal))
1029 p->Kill(p);
1030
1031 //Dissapear and reappear at new position
1032 me->SetVisible(false);
1033
1035 if (!target)
1036 {
1037 me->Kill(me);
1038 return;
1039 }
1040
1041 if (!target->HasAura(SPELL_DIGESTIVE_ACID))
1042 {
1043 me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
1044 if (Creature* pPortal = me->SummonCreature(NPC_SMALL_PORTAL, *me, TempSummonType::TEMPSUMMON_CORPSE_DESPAWN))
1045 {
1046 pPortal->SetReactState(REACT_PASSIVE);
1047 Portal = pPortal->GetGUID();
1048 }
1049
1050 GroundRuptureTimer = 500;
1051 HamstringTimer = 2000;
1052 EvadeTimer = 5000;
1053 AttackStart(target);
1054 }
1055
1056 me->SetVisible(true);
1057 } else EvadeTimer -= diff;
1058 }
1059
1060 //GroundRuptureTimer
1061 if (GroundRuptureTimer <= diff)
1062 {
1064 GroundRuptureTimer = 30000;
1065 } else GroundRuptureTimer -= diff;
1066
1067 //HamstringTimer
1068 if (HamstringTimer <= diff)
1069 {
1071 HamstringTimer = 5000;
1072 } else HamstringTimer -= diff;
1073
1075 }
1076 };
1077};
1078
1080{
1081public:
1082 npc_giant_claw_tentacle() : CreatureScript("npc_giant_claw_tentacle") { }
1083
1085 {
1086 return new giant_claw_tentacleAI(creature);
1087 }
1088
1090 {
1092 {
1093 SetCombatMovement(false);
1094
1095 if (Creature* pPortal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TempSummonType::TEMPSUMMON_CORPSE_DESPAWN))
1096 {
1097 pPortal->SetReactState(REACT_PASSIVE);
1098 Portal = pPortal->GetGUID();
1099 }
1100 }
1101
1107
1108 void JustDied(Unit* /*killer*/) OVERRIDE
1109 {
1110 if (Unit* p = Unit::GetUnit(*me, Portal))
1111 p->Kill(p);
1112 }
1113
1115 {
1116 //First rupture should happen half a second after we spawn
1117 GroundRuptureTimer = 500;
1118 HamstringTimer = 2000;
1119 ThrashTimer = 5000;
1120 EvadeTimer = 5000;
1121 }
1122
1124 {
1126 }
1127
1129 {
1130 //Check if we have a target
1131 if (!UpdateVictim())
1132 return;
1133
1134 //EvadeTimer
1135 if (!me->IsWithinMeleeRange(me->GetVictim()))
1136 {
1137 if (EvadeTimer <= diff)
1138 {
1139 if (Unit* p = Unit::GetUnit(*me, Portal))
1140 p->Kill(p);
1141
1142 //Dissapear and reappear at new position
1143 me->SetVisible(false);
1144
1146 if (!target)
1147 {
1148 me->Kill(me);
1149 return;
1150 }
1151
1152 if (!target->HasAura(SPELL_DIGESTIVE_ACID))
1153 {
1154 me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
1155 if (Creature* pPortal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TempSummonType::TEMPSUMMON_CORPSE_DESPAWN))
1156 {
1157 pPortal->SetReactState(REACT_PASSIVE);
1158 Portal = pPortal->GetGUID();
1159 }
1160
1161 GroundRuptureTimer = 500;
1162 HamstringTimer = 2000;
1163 ThrashTimer = 5000;
1164 EvadeTimer = 5000;
1165 AttackStart(target);
1166 }
1167 me->SetVisible(true);
1168 } else EvadeTimer -= diff;
1169 }
1170
1171 //GroundRuptureTimer
1172 if (GroundRuptureTimer <= diff)
1173 {
1175 GroundRuptureTimer = 30000;
1176 } else GroundRuptureTimer -= diff;
1177
1178 //ThrashTimer
1179 if (ThrashTimer <= diff)
1180 {
1182 ThrashTimer = 10000;
1183 } else ThrashTimer -= diff;
1184
1185 //HamstringTimer
1186 if (HamstringTimer <= diff)
1187 {
1189 HamstringTimer = 10000;
1190 } else HamstringTimer -= diff;
1191
1193 }
1194 };
1195};
1196
1198{
1199public:
1200 npc_giant_eye_tentacle() : CreatureScript("npc_giant_eye_tentacle") { }
1201
1203 {
1204 return new giant_eye_tentacleAI(creature);
1205 }
1206
1208 {
1210 {
1211 SetCombatMovement(false);
1212
1213 if (Creature* pPortal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TempSummonType::TEMPSUMMON_CORPSE_DESPAWN))
1214 {
1215 pPortal->SetReactState(REACT_PASSIVE);
1216 Portal = pPortal->GetGUID();
1217 }
1218 }
1219
1222
1223 void JustDied(Unit* /*killer*/) OVERRIDE
1224 {
1225 if (Unit* p = Unit::GetUnit(*me, Portal))
1226 p->Kill(p);
1227 }
1228
1230 {
1231 //Green Beam half a second after we spawn
1232 BeamTimer = 500;
1233 }
1234
1236 {
1238 }
1239
1241 {
1242 //Check if we have a target
1243 if (!UpdateVictim())
1244 return;
1245
1246 //BeamTimer
1247 if (BeamTimer <= diff)
1248 {
1250 if (target && !target->HasAura(SPELL_DIGESTIVE_ACID))
1251 DoCast(target, SPELL_GREEN_BEAM);
1252
1253 //Beam every 2 seconds
1254 BeamTimer = 2100;
1255 } else BeamTimer -= diff;
1256 }
1257 };
1258};
1259
1261{
1262public:
1263 npc_giant_flesh_tentacle() : CreatureScript("npc_giant_flesh_tentacle") { }
1264
1266 {
1267 return new flesh_tentacleAI(creature);
1268 }
1269
1271 {
1272 flesh_tentacleAI(Creature* creature) : ScriptedAI(creature)
1273 {
1274 SetCombatMovement(false);
1275 }
1276
1277 void JustDied(Unit* /*killer*/) OVERRIDE
1278 {
1279 if (TempSummon* summon = me->ToTempSummon())
1280 if (Unit* summoner = summon->GetSummoner())
1281 if (summoner->IsAIEnabled)
1282 summoner->GetAI()->DoAction(ACTION_FLESH_TENTACLE_KILLED);
1283 }
1284 };
1285};
1286
1287//GetAIs
1288
1290{
1291 new boss_eye_of_cthun();
1292 new boss_cthun();
1293 new npc_eye_tentacle();
1294 new npc_claw_tentacle();
1298}
Actions
#define M_PI
Definition Common.h:192
const T & RAND(const T &v1, const T &v2)
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 SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
@ TEMPSUMMON_CORPSE_DESPAWN
Definition Object.h:72
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
#define UNORDERED_MAP
@ UNIT_FIELD_FLAGS
#define STOMACH_X
@ ACTION_FLESH_TENTACLE_KILLED
@ RANDOM_SOUND_WHISPER
@ EMOTE_WEAKENED
#define STOMACH_O
@ SPELL_MOUTH_TENTACLE
@ SPELL_HAMSTRING
@ SPELL_FREEZE_ANIM
@ SPELL_RED_COLORATION
@ SPELL_TRANSFORM
@ SPELL_EXIT_STOMACH_KNOCKBACK
@ SPELL_GREEN_BEAM
@ SPELL_PURPLE_COLORATION
@ SPELL_DIGESTIVE_ACID
@ SPELL_MASSIVE_GROUND_RUPTURE
@ SPELL_THRASH
@ SPELL_MIND_FLAY
@ SPELL_GROUND_RUPTURE
@ SPELL_DARK_GLARE
@ PHASE_EYE_RED_BEAM
@ PHASE_CTHUN_TRANSITION
@ PHASE_NOT_STARTED
@ PHASE_CTHUN_DONE
@ PHASE_CTHUN_STOMACH
@ PHASE_EYE_GREEN_BEAM
@ PHASE_CTHUN_WEAK
#define STOMACH_Y
void AddSC_boss_cthun()
const Position FleshTentaclePos[2]
#define STOMACH_Z
const Position KickPos
@ SPELL_THRASH
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
void DespawnOrUnsummon(uint32 msTimeToDespawn=0)
void SetReactState(ReactStates st)
Definition Creature.h:460
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
bool isEmpty() const
Definition LinkedList.h:86
Definition Map.h:238
MapRefManager PlayerList
Definition Map.h:406
bool IsRaid() const
Definition Map.h:372
PlayerList const & GetPlayers() const
Definition Map.h:407
iterator end()
iterator begin()
LinkedListHead::Iterator< MapReference const > const_iterator
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
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:16
Definition Unit.h:1367
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1710
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
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
float GetPositionZ() const
Definition Object.h:330
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
void SetCombatMovement(bool allowMovement)
Creature * me
void DoTeleportPlayer(Unit *unit, float x, float y, float z, float o)
Creature * DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, TempSummonType type, uint32 despawntime)
ScriptedAI(Creature *creature)
void AttackStart(Unit *) OVERRIDE
UNORDERED_MAP< uint64, bool > Stomach_Map
cthunAI(Creature *creature)
void DoAction(int32 param) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void EnterCombat(Unit *) OVERRIDE
void JustDied(Unit *) OVERRIDE
InstanceScript * instance
void Reset() OVERRIDE
Unit * SelectRandomNotStomach()
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void SpawnEyeTentacle(float x, float y)
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
void SpawnEyeTentacle(float x, float y)
eye_of_cthunAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
claw_tentacleAI(Creature *creature)
void EnterCombat(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JustDied(Unit *) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
eye_tentacleAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
@ NPC_FLESH_TENTACLE
@ NPC_GIANT_PORTAL
@ NPC_GIANT_CLAW_TENTACLE
@ NPC_GIANT_EYE_TENTACLE
@ NPC_EYE_TENTACLE
@ NPC_SMALL_PORTAL
@ NPC_CTHUN_PORTAL
@ NPC_CLAW_TENTACLE
@ DATA_CTHUN_PHASE