Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
bosses_opera.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: Bosses_Opera
8SD%Complete: 90
9SDComment: Oz, Hood, and RAJ event implemented. RAJ event requires more testing.
10SDCategory: Karazhan
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "ScriptedGossip.h"
16#include "karazhan.h"
17#include "Player.h"
18#include "SpellInfo.h"
19
20/***********************************/
21/*** OPERA WIZARD OF OZ EVENT *****/
22/*********************************/
47
49{
50 // Dorothee
52 SPELL_SCREAM = 31013,
54
55 // Tito
57
58 // Strawman
62
63 // Tinhead
64 SPELL_CLEAVE = 31043,
65 SPELL_RUST = 31086,
66
67 // Roar
68 SPELL_MANGLE = 31041,
69 SPELL_SHRED = 31042,
71
72 // Crone
74
75 // Cyclone
78};
79
81{
85};
86
87void SummonCroneIfReady(InstanceScript* instance, Creature* creature)
88{
89 instance->SetData(DATA_OPERA_OZ_DEATHCOUNT, SPECIAL); // Increment DeathCount
90
91 if (instance->GetData(DATA_OPERA_OZ_DEATHCOUNT) == 4)
92 {
93 if (Creature* pCrone = creature->SummonCreature(CREATURE_CRONE, -10891.96f, -1755.95f, creature->GetPositionZ(), 4.64f, TempSummonType::TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR*2*IN_MILLISECONDS))
94 {
95 if (creature->GetVictim())
96 pCrone->AI()->AttackStart(creature->GetVictim());
97 }
98 }
99};
100
102{
103public:
104 boss_dorothee() : CreatureScript("boss_dorothee") { }
105
107 {
108 return new boss_dorotheeAI(creature);
109 }
110
112 {
113 boss_dorotheeAI(Creature* creature) : ScriptedAI(creature)
114 {
115 instance = creature->GetInstanceScript();
116 }
117
119
121
125
128
130 {
131 AggroTimer = 500;
132
133 WaterBoltTimer = 5000;
134 FearTimer = 15000;
135 SummonTitoTimer = 47500;
136
137 SummonedTito = false;
138 TitoDied = false;
139 }
140
141 void EnterCombat(Unit* /*who*/) OVERRIDE
142 {
144 }
145
147 {
148 me->DespawnOrUnsummon();
149 }
150
151 void SummonTito();
152
153 void JustDied(Unit* /*killer*/) OVERRIDE
154 {
156
157 if (instance)
159 }
160
162 {
164 return;
165
167 }
168
170
171 {
173 return;
174
176 }
177
179 {
180 if (AggroTimer)
181 {
182 if (AggroTimer <= diff)
183 {
185 AggroTimer = 0;
186 } else AggroTimer -= diff;
187 }
188
189 if (!UpdateVictim())
190 return;
191
192 if (WaterBoltTimer <= diff)
193 {
195 WaterBoltTimer = TitoDied ? 1500 : 5000;
196 } else WaterBoltTimer -= diff;
197
198 if (FearTimer <= diff)
199 {
201 FearTimer = 30000;
202 } else FearTimer -= diff;
203
204 if (!SummonedTito)
205 {
206 if (SummonTitoTimer <= diff)
207 SummonTito();
208 else SummonTitoTimer -= diff;
209 }
210
212 }
213 };
214};
215
217{
218public:
219 npc_tito() : CreatureScript("npc_tito") { }
220
222 {
223 return new npc_titoAI(creature);
224 }
225
226 struct npc_titoAI : public ScriptedAI
227 {
228 npc_titoAI(Creature* creature) : ScriptedAI(creature) { }
229
232
234 {
235 DorotheeGUID = 0;
236 YipTimer = 10000;
237 }
238
239 void EnterCombat(Unit* /*who*/) OVERRIDE { }
240
241 void JustDied(Unit* /*killer*/) OVERRIDE
242 {
243 if (DorotheeGUID)
244 {
245 Creature* Dorothee = (Unit::GetCreature((*me), DorotheeGUID));
246 if (Dorothee && Dorothee->IsAlive())
247 {
248 CAST_AI(boss_dorothee::boss_dorotheeAI, Dorothee->AI())->TitoDied = true;
249 Talk(SAY_DOROTHEE_TITO_DEATH, Dorothee);
250 }
251 }
252 }
253
255 {
256 if (!UpdateVictim())
257 return;
258
259 if (YipTimer <= diff)
260 {
262 YipTimer = 10000;
263 } else YipTimer -= diff;
264
266 }
267 };
268};
269
271{
272 if (Creature* pTito = me->SummonCreature(CREATURE_TITO, 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
273 {
275 CAST_AI(npc_tito::npc_titoAI, pTito->AI())->DorotheeGUID = me->GetGUID();
276 pTito->AI()->AttackStart(me->GetVictim());
277 SummonedTito = true;
278 TitoDied = false;
279 }
280}
281
283{
284public:
285 boss_strawman() : CreatureScript("boss_strawman") { }
286
288 {
289 return new boss_strawmanAI(creature);
290 }
291
293 {
294 boss_strawmanAI(Creature* creature) : ScriptedAI(creature)
295 {
296 instance = creature->GetInstanceScript();
297 }
298
300
304
306 {
307 AggroTimer = 13000;
308 BrainBashTimer = 5000;
309 BrainWipeTimer = 7000;
310 }
311
313 {
315 return;
316
318 }
319
321
322 {
324 return;
325
327 }
328
329 void EnterCombat(Unit* /*who*/) OVERRIDE
330 {
332 }
333
335 {
336 me->DespawnOrUnsummon();
337 }
338
339 void SpellHit(Unit* /*caster*/, const SpellInfo* Spell) OVERRIDE
340 {
341 if ((Spell->SchoolMask == SPELL_SCHOOL_MASK_FIRE) && (!(rand()%10)))
342 {
343 /*
344 if (not direct damage(aoe, dot))
345 return;
346 */
347
349 }
350 }
351
352 void JustDied(Unit* /*killer*/) OVERRIDE
353 {
355
356 if (instance)
358 }
359
360 void KilledUnit(Unit* /*victim*/) OVERRIDE
361 {
363 }
364
366 {
367 if (AggroTimer)
368 {
369 if (AggroTimer <= diff)
370 {
372 AggroTimer = 0;
373 } else AggroTimer -= diff;
374 }
375
376 if (!UpdateVictim())
377 return;
378
379 if (BrainBashTimer <= diff)
380 {
382 BrainBashTimer = 15000;
383 } else BrainBashTimer -= diff;
384
385 if (BrainWipeTimer <= diff)
386 {
387 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
388 DoCast(target, SPELL_BRAIN_WIPE);
389 BrainWipeTimer = 20000;
390 } else BrainWipeTimer -= diff;
391
393 }
394 };
395};
396
398{
399public:
400 boss_tinhead() : CreatureScript("boss_tinhead") { }
401
403 {
404 return new boss_tinheadAI(creature);
405 }
406
408 {
409 boss_tinheadAI(Creature* creature) : ScriptedAI(creature)
410 {
411 instance = creature->GetInstanceScript();
412 }
413
415
419
421
423 {
424 AggroTimer = 15000;
425 CleaveTimer = 5000;
426 RustTimer = 30000;
427
428 RustCount = 0;
429 }
430
431 void EnterCombat(Unit* /*who*/) OVERRIDE
432 {
434 }
435
437 {
438 me->DespawnOrUnsummon();
439 }
440
442 {
444 return;
445
447 }
448
450
451 {
453 return;
454
456 }
457
458 void JustDied(Unit* /*killer*/) OVERRIDE
459 {
461
462 if (instance)
464 }
465
466 void KilledUnit(Unit* /*victim*/) OVERRIDE
467 {
469 }
470
472 {
473 if (AggroTimer)
474 {
475 if (AggroTimer <= diff)
476 {
478 AggroTimer = 0;
479 } else AggroTimer -= diff;
480 }
481
482 if (!UpdateVictim())
483 return;
484
485 if (CleaveTimer <= diff)
486 {
488 CleaveTimer = 5000;
489 } else CleaveTimer -= diff;
490
491 if (RustCount < 8)
492 {
493 if (RustTimer <= diff)
494 {
495 ++RustCount;
498 RustTimer = 6000;
499 } else RustTimer -= diff;
500 }
501
503 }
504 };
505};
506
508{
509public:
510 boss_roar() : CreatureScript("boss_roar") { }
511
513 {
514 return new boss_roarAI(creature);
515 }
516
517 struct boss_roarAI : public ScriptedAI
518 {
519 boss_roarAI(Creature* creature) : ScriptedAI(creature)
520 {
521 instance = creature->GetInstanceScript();
522 }
523
525
530
532 {
533 AggroTimer = 20000;
534 MangleTimer = 5000;
535 ShredTimer = 10000;
536 ScreamTimer = 15000;
537 }
538
540
541 {
543 return;
544
546 }
547
549 {
551 return;
552
554 }
555
556 void EnterCombat(Unit* /*who*/) OVERRIDE
557 {
559 }
560
562 {
563 me->DespawnOrUnsummon();
564 }
565
566 void JustDied(Unit* /*killer*/) OVERRIDE
567 {
569
570 if (instance)
572 }
573
574 void KilledUnit(Unit* /*victim*/) OVERRIDE
575 {
577 }
578
580 {
581 if (AggroTimer)
582 {
583 if (AggroTimer <= diff)
584 {
586 AggroTimer = 0;
587 } else AggroTimer -= diff;
588 }
589
590 if (!UpdateVictim())
591 return;
592
593 if (MangleTimer <= diff)
594 {
596 MangleTimer = std::rand() % 8000 + 5000;
597 } else MangleTimer -= diff;
598
599 if (ShredTimer <= diff)
600 {
602 ShredTimer = std::rand() % 15000 + 10000;
603 } else ShredTimer -= diff;
604
605 if (ScreamTimer <= diff)
606 {
608 ScreamTimer = std::rand() % 30000 + 20000;
609 } else ScreamTimer -= diff;
610
612 }
613 };
614};
615
617{
618public:
619 boss_crone() : CreatureScript("boss_crone") { }
620
622 {
623 return new boss_croneAI(creature);
624 }
625
626 struct boss_croneAI : public ScriptedAI
627 {
628 boss_croneAI(Creature* creature) : ScriptedAI(creature)
629 {
630 instance = creature->GetInstanceScript();
631 }
632
634
637
639 {
640 CycloneTimer = 30000;
641 ChainLightningTimer = 10000;
642 }
643
645 {
646 me->DespawnOrUnsummon();
647 }
648
649 void KilledUnit(Unit* /*victim*/) OVERRIDE
650 {
652 }
653
660
661 void JustDied(Unit* /*killer*/) OVERRIDE
662 {
664
665 if (instance)
666 {
667 instance->SetData(TYPE_OPERA, DONE);
668 instance->HandleGameObject(instance->GetData64(DATA_GO_STAGEDOORLEFT), true);
669 instance->HandleGameObject(instance->GetData64(DATA_GO_STAGEDOORRIGHT), true);
670
671 if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetData64(DATA_GO_SIDE_ENTRANCE_DOOR)))
672 pSideEntrance->RemoveFlag(GAMEOBJECT_FIELD_FLAGS, GO_FLAG_LOCKED);
673 }
674 }
675
677 {
678 if (!UpdateVictim())
679 return;
680
683
684 if (CycloneTimer <= diff)
685 {
686 if (Creature* Cyclone = DoSpawnCreature(CREATURE_CYCLONE, float(std::rand() % 9), float(std::rand() % 9), 0, 0, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 15000))
687 Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_VISUAL, true);
688 CycloneTimer = 30000;
689 } else CycloneTimer -= diff;
690
691 if (ChainLightningTimer <= diff)
692 {
694 ChainLightningTimer = 15000;
695 } else ChainLightningTimer -= diff;
696
698 }
699 };
700};
701
703{
704public:
705 npc_cyclone() : CreatureScript("npc_cyclone") { }
706
708 {
709 return new npc_cycloneAI(creature);
710 }
711
712 struct npc_cycloneAI : public ScriptedAI
713 {
714 npc_cycloneAI(Creature* creature) : ScriptedAI(creature) { }
715
717
719 {
720 MoveTimer = 1000;
721 }
722
723 void EnterCombat(Unit* /*who*/) OVERRIDE { }
724
726
727 {
728 }
729
731 {
732 if (!me->HasAura(SPELL_KNOCKBACK))
733 DoCast(me, SPELL_KNOCKBACK, true);
734
735 if (MoveTimer <= diff)
736 {
737 Position pos;
738 me->GetRandomNearPosition(pos, 10);
739 me->GetMotionMaster()->MovePoint(0, pos);
740 MoveTimer = std::rand() % 8000 + 5000;
741 } else MoveTimer -= diff;
742 }
743 };
744};
745
746/**************************************/
747/**** Opera Red Riding Hood Event* ***/
748/************************************/
762
763
764#define GOSSIP_GRANDMA "What phat lewtz you have grandmother?"
765
766
767
769{
770public:
771 npc_grandmother() : CreatureScript("npc_grandmother") { }
772
773 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
774 {
775 player->PlayerTalkClass->ClearMenus();
776 if (action == GOSSIP_ACTION_INFO_DEF)
777 {
779 pBigBadWolf->AI()->AttackStart(player);
780
781 creature->DespawnOrUnsummon();
782 }
783
784 return true;
785 }
786
787 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
788 {
790 player->SEND_GOSSIP_MENU(8990, creature->GetGUID());
791
792 return true;
793 }
794};
795
797{
798public:
799 boss_bigbadwolf() : CreatureScript("boss_bigbadwolf") { }
800
802 {
803 return new boss_bigbadwolfAI(creature);
804 }
805
807 {
808 boss_bigbadwolfAI(Creature* creature) : ScriptedAI(creature)
809 {
810 instance = creature->GetInstanceScript();
811 }
812
814
818
821
823
825 {
826 ChaseTimer = 30000;
827 FearTimer = std::rand() % 35000 + 25000;
828 SwipeTimer = 5000;
829
830 HoodGUID = 0;
831 TempThreat = 0;
832
833 IsChasing = false;
834 }
835
836 void EnterCombat(Unit* /*who*/) OVERRIDE
837 {
839 }
840
841 void KilledUnit(Unit* /*victim*/) OVERRIDE
842 {
844 }
845
847 {
848 me->DespawnOrUnsummon();
849 }
850
851 void JustDied(Unit* /*killer*/) OVERRIDE
852 {
854
855 if (instance)
856 {
857 instance->SetData(TYPE_OPERA, DONE);
858 instance->HandleGameObject(instance->GetData64(DATA_GO_STAGEDOORLEFT), true);
859 instance->HandleGameObject(instance->GetData64(DATA_GO_STAGEDOORRIGHT), true);
860
861 if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetData64(DATA_GO_SIDE_ENTRANCE_DOOR)))
862 pSideEntrance->RemoveFlag(GAMEOBJECT_FIELD_FLAGS, GO_FLAG_LOCKED);
863 }
864 }
865
867 {
868 if (!UpdateVictim())
869 return;
870
872
873 if (ChaseTimer <= diff)
874 {
875 if (!IsChasing)
876 {
877 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
878 {
881 TempThreat = DoGetThreat(target);
882 if (TempThreat)
883 DoModifyThreatPercent(target, -100);
884 HoodGUID = target->GetGUID();
885 me->AddThreat(target, 1000000.0f);
886 ChaseTimer = 20000;
887 IsChasing = true;
888 }
889 }
890 else
891 {
892 IsChasing = false;
893
894 if (Unit* target = Unit::GetUnit(*me, HoodGUID))
895 {
896 HoodGUID = 0;
897 if (DoGetThreat(target))
898 DoModifyThreatPercent(target, -100);
899 me->AddThreat(target, TempThreat);
900 TempThreat = 0;
901 }
902
903 ChaseTimer = 40000;
904 }
905 } else ChaseTimer -= diff;
906
907 if (IsChasing)
908 return;
909
910 if (FearTimer <= diff)
911 {
913 FearTimer = std::rand() % 35000 + 25000;
914 } else FearTimer -= diff;
915
916 if (SwipeTimer <= diff)
917 {
919 SwipeTimer = std::rand() % 30000 + 25000;
920 } else SwipeTimer -= diff;
921 }
922 };
923};
924
925/**********************************************/
926/******** Opera Romeo and Juliet Event* ******/
927/********************************************/
928
963
964
971
972void PretendToDie(Creature* creature)
973{
974 creature->InterruptNonMeleeSpells(true);
975 creature->RemoveAllAuras();
976 creature->SetHealth(0);
978 creature->GetMotionMaster()->MovementExpired(false);
979 creature->GetMotionMaster()->MoveIdle();
981}
982
983void Resurrect(Creature* target)
984{
986 target->SetFullHealth();
988 target->CastSpell(target, SPELL_RES_VISUAL, true);
989 if (target->GetVictim())
990 {
991 target->GetMotionMaster()->MoveChase(target->GetVictim());
992 target->AI()->AttackStart(target->GetVictim());
993 }
994 else
995 target->GetMotionMaster()->Initialize();
996}
997
999{
1000public:
1001 boss_julianne() : CreatureScript("boss_julianne") { }
1002
1004 {
1005 return new boss_julianneAI(creature);
1006 }
1007
1009 {
1010 boss_julianneAI(Creature* creature) : ScriptedAI(creature)
1011 {
1012 instance = creature->GetInstanceScript();
1013 EntryYellTimer = 1000;
1014 AggroYellTimer = 10000;
1015 IsFakingDeath = false;
1016 }
1017
1019
1022
1024
1026
1035
1039
1041 {
1042 RomuloGUID = 0;
1044
1045 BlindingPassionTimer = 30000;
1046 DevotionTimer = 15000;
1047 EternalAffectionTimer = 25000;
1049 SummonRomuloTimer = 10000;
1050 DrinkPoisonTimer = 0;
1052
1053 if (IsFakingDeath)
1054 {
1055 Resurrect(me);
1056 IsFakingDeath = false;
1057 }
1058
1059 SummonedRomulo = false;
1060 RomuloDead = false;
1061 }
1062
1063 void EnterCombat(Unit* /*who*/) OVERRIDE { }
1064
1066 {
1068 return;
1069
1071 }
1072
1074
1075 {
1077 return;
1078
1080 }
1081
1083 {
1084 me->DespawnOrUnsummon();
1085 }
1086
1087 void SpellHit(Unit* /*caster*/, const SpellInfo* Spell) OVERRIDE
1088 {
1089 if (Spell->Id == SPELL_DRINK_POISON)
1090 {
1092 DrinkPoisonTimer = 2500;
1093 }
1094 }
1095
1096 void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE;
1097
1098 void JustDied(Unit* /*killer*/) OVERRIDE
1099 {
1101
1102 if (instance)
1103 {
1104 instance->SetData(TYPE_OPERA, DONE);
1105 instance->HandleGameObject(instance->GetData64(DATA_GO_STAGEDOORLEFT), true);
1106 instance->HandleGameObject(instance->GetData64(DATA_GO_STAGEDOORRIGHT), true);
1107 if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetData64(DATA_GO_SIDE_ENTRANCE_DOOR)))
1108 pSideEntrance->RemoveFlag(GAMEOBJECT_FIELD_FLAGS, GO_FLAG_LOCKED);
1109 }
1110 }
1111
1112 void KilledUnit(Unit* /*victim*/) OVERRIDE
1113 {
1115 }
1116
1117 void UpdateAI(uint32 diff) OVERRIDE;
1118 };
1119};
1120
1122{
1123public:
1124 boss_romulo() : CreatureScript("boss_romulo") { }
1125
1127 {
1128 return new boss_romuloAI(creature);
1129 }
1130
1132 {
1133 boss_romuloAI(Creature* creature) : ScriptedAI(creature)
1134 {
1135 instance = creature->GetInstanceScript();
1136 EntryYellTimer = 8000;
1137 AggroYellTimer = 15000;
1138 }
1139
1141
1144
1152
1155
1157 {
1158 JulianneGUID = 0;
1160
1161 BackwardLungeTimer = 15000;
1162 DaringTimer = 20000;
1163 DeadlySwatheTimer = 25000;
1164 PoisonThrustTimer = 10000;
1165 ResurrectTimer = 10000;
1166
1167 IsFakingDeath = false;
1168 JulianneDead = false;
1169 }
1170
1172 {
1173 me->DespawnOrUnsummon();
1174 }
1175
1176 void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE
1177 {
1178 if (damage < me->GetHealth())
1179 return;
1180
1181 //anything below only used if incoming damage will kill
1182
1183 if (Phase == PHASE_ROMULO)
1184 {
1187 IsFakingDeath = true;
1188 Phase = PHASE_BOTH;
1189
1190 if (Creature* Julianne = (Unit::GetCreature((*me), JulianneGUID)))
1191 {
1192 CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->RomuloDead = true;
1193 CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->ResurrectSelfTimer = 10000;
1194 }
1195
1196 damage = 0;
1197 return;
1198 }
1199
1200 if (Phase == PHASE_BOTH)
1201 {
1202 if (JulianneDead)
1203 {
1204 if (Creature* Julianne = (Unit::GetCreature((*me), JulianneGUID)))
1205 {
1206 Julianne->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
1207 Julianne->GetMotionMaster()->Clear();
1208 Julianne->setDeathState(DeathState::JUST_DIED);
1209 Julianne->CombatStop(true);
1210 Julianne->DeleteThreatList();
1211 Julianne->SetUInt32Value(OBJECT_FIELD_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
1212 }
1213 return;
1214 }
1215
1216 if (Creature* Julianne = (Unit::GetCreature((*me), JulianneGUID)))
1217 {
1219 IsFakingDeath = true;
1220 CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->ResurrectTimer = 10000;
1221 CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->RomuloDead = true;
1222 damage = 0;
1223 return;
1224 }
1225 }
1226
1227 SF_LOG_ERROR("scripts", "boss_romuloAI: DamageTaken reach end of code, that should not happen.");
1228 }
1229
1231 {
1233 if (JulianneGUID)
1234 {
1235 Creature* Julianne = (Unit::GetCreature((*me), JulianneGUID));
1236 if (Julianne && Julianne->GetVictim())
1237 {
1238 me->AddThreat(Julianne->GetVictim(), 1.0f);
1239 AttackStart(Julianne->GetVictim());
1240 }
1241 }
1242 }
1243
1245
1246 {
1248 return;
1249
1251 }
1252
1253 void JustDied(Unit* /*killer*/) OVERRIDE
1254 {
1256
1257 if (instance)
1258 {
1259 instance->SetData(TYPE_OPERA, DONE);
1260 instance->HandleGameObject(instance->GetData64(DATA_GO_STAGEDOORLEFT), true);
1261 instance->HandleGameObject(instance->GetData64(DATA_GO_STAGEDOORRIGHT), true);
1262
1263 if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetData64(DATA_GO_SIDE_ENTRANCE_DOOR)))
1264 pSideEntrance->RemoveFlag(GAMEOBJECT_FIELD_FLAGS, GO_FLAG_LOCKED);
1265 }
1266 }
1267
1268 void KilledUnit(Unit* /*victim*/) OVERRIDE
1269 {
1271 }
1272
1274 {
1275 if (!UpdateVictim() || IsFakingDeath)
1276 return;
1277
1278 if (JulianneDead)
1279 {
1280 if (ResurrectTimer <= diff)
1281 {
1282 Creature* Julianne = (Unit::GetCreature((*me), JulianneGUID));
1283 if (Julianne && CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->IsFakingDeath)
1284 {
1286 Resurrect(Julianne);
1287 CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->IsFakingDeath = false;
1288 JulianneDead = false;
1289 ResurrectTimer = 10000;
1290 }
1291 } else ResurrectTimer -= diff;
1292 }
1293
1294 if (BackwardLungeTimer <= diff)
1295 {
1296 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);
1297 if (target && !me->HasInArc(M_PI, target))
1298 {
1300 BackwardLungeTimer = std::rand() % 30000 + 15000;
1301 }
1302 } else BackwardLungeTimer -= diff;
1303
1304 if (DaringTimer <= diff)
1305 {
1307 DaringTimer = std::rand() % 40000 + 20000;
1308 } else DaringTimer -= diff;
1309
1310 if (DeadlySwatheTimer <= diff)
1311 {
1312 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
1313 DoCast(target, SPELL_DEADLY_SWATHE);
1314 DeadlySwatheTimer = std::rand() % 25000 + 15000;
1315 } else DeadlySwatheTimer -= diff;
1316
1317 if (PoisonThrustTimer <= diff)
1318 {
1320 PoisonThrustTimer = std::rand() % 20000 + 10000;
1321 } else PoisonThrustTimer -= diff;
1322
1324 }
1325 };
1326};
1327
1329{
1330 if (EntryYellTimer)
1331 {
1332 if (EntryYellTimer <= diff)
1333 {
1335 EntryYellTimer = 0;
1336 } else EntryYellTimer -= diff;
1337 }
1338
1339 if (AggroYellTimer)
1340 {
1341 if (AggroYellTimer <= diff)
1342 {
1345 me->setFaction(16);
1346 AggroYellTimer = 0;
1347 } else AggroYellTimer -= diff;
1348 }
1349
1350 if (DrinkPoisonTimer)
1351 {
1352 //will do this 2secs after spell hit. this is time to display visual as expected
1353 if (DrinkPoisonTimer <= diff)
1354 {
1357 SummonRomuloTimer = 10000;
1358 DrinkPoisonTimer = 0;
1359 } else DrinkPoisonTimer -= diff;
1360 }
1361
1363 {
1364 if (SummonRomuloTimer <= diff)
1365 {
1367 {
1368 RomuloGUID = pRomulo->GetGUID();
1369 CAST_AI(boss_romulo::boss_romuloAI, pRomulo->AI())->JulianneGUID = me->GetGUID();
1370 CAST_AI(boss_romulo::boss_romuloAI, pRomulo->AI())->Phase = PHASE_ROMULO;
1371 DoZoneInCombat(pRomulo);
1372
1373 pRomulo->setFaction(16);
1374 }
1375 SummonedRomulo = true;
1376 } else SummonRomuloTimer -= diff;
1377 }
1378
1380 {
1381 if (ResurrectSelfTimer <= diff)
1382 {
1383 Resurrect(me);
1384 Phase = PHASE_BOTH;
1385 IsFakingDeath = false;
1386
1387 if (me->GetVictim())
1388 AttackStart(me->GetVictim());
1389
1391 ResurrectTimer = 1000;
1392 } else ResurrectSelfTimer -= diff;
1393 }
1394
1395 if (!UpdateVictim() || IsFakingDeath)
1396 return;
1397
1398 if (RomuloDead)
1399 {
1400 if (ResurrectTimer <= diff)
1401 {
1402 Creature* Romulo = (Unit::GetCreature((*me), RomuloGUID));
1403 if (Romulo && CAST_AI(boss_romulo::boss_romuloAI, Romulo->AI())->IsFakingDeath)
1404 {
1406 Resurrect(Romulo);
1407 CAST_AI(boss_romulo::boss_romuloAI, Romulo->AI())->IsFakingDeath = false;
1408 RomuloDead = false;
1409 ResurrectTimer = 10000;
1410 }
1411 } else ResurrectTimer -= diff;
1412 }
1413
1414 if (BlindingPassionTimer <= diff)
1415 {
1416 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
1418 BlindingPassionTimer = std::rand() % 45000 + 30000;
1419 } else BlindingPassionTimer -= diff;
1420
1421 if (DevotionTimer <= diff)
1422 {
1424 DevotionTimer = std::rand() % 45000 + 15000;
1425 } else DevotionTimer -= diff;
1426
1427 if (PowerfulAttractionTimer <= diff)
1428 {
1430 PowerfulAttractionTimer = std::rand() % 30000 + 5000;
1431 } else PowerfulAttractionTimer -= diff;
1432
1433 if (EternalAffectionTimer <= diff)
1434 {
1435 if (std::rand() % 1 && SummonedRomulo)
1436 {
1437 Creature* Romulo = (Unit::GetCreature((*me), RomuloGUID));
1438 if (Romulo && Romulo->IsAlive() && !RomuloDead)
1441
1442 EternalAffectionTimer = std::rand() % 60000 + 45000;
1443 } else EternalAffectionTimer -= diff;
1444
1446}
1447
1449{
1450 if (damage < me->GetHealth())
1451 return;
1452
1453 //anything below only used if incoming damage will kill
1454
1455 if (Phase == PHASE_JULIANNE)
1456 {
1457 damage = 0;
1458
1459 //this means already drinking, so return
1460 if (IsFakingDeath)
1461 return;
1462
1463 me->InterruptNonMeleeSpells(true);
1465
1466 IsFakingDeath = true;
1467 //IS THIS USEFULL? Creature* Julianne = (Unit::GetCreature((*me), JulianneGUID));
1468 return;
1469 }
1470
1471 if (Phase == PHASE_ROMULO)
1472 {
1473 SF_LOG_ERROR("scripts", "boss_julianneAI: cannot take damage in PHASE_ROMULO, why was i here?");
1474 damage = 0;
1475 return;
1476 }
1477
1478 if (Phase == PHASE_BOTH)
1479 {
1480 //if this is true then we have to kill romulo too
1481 if (RomuloDead)
1482 {
1483 if (Creature* Romulo = (Unit::GetCreature((*me), RomuloGUID)))
1484 {
1485 Romulo->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
1486 Romulo->GetMotionMaster()->Clear();
1487 Romulo->setDeathState(DeathState::JUST_DIED);
1488 Romulo->CombatStop(true);
1489 Romulo->DeleteThreatList();
1490 Romulo->SetUInt32Value(OBJECT_FIELD_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
1491 }
1492
1493 return;
1494 }
1495
1496 //if not already returned, then romulo is alive and we can pretend die
1497 if (Creature* Romulo = (Unit::GetCreature((*me), RomuloGUID)))
1498 {
1500 IsFakingDeath = true;
1501 CAST_AI(boss_romulo::boss_romuloAI, Romulo->AI())->ResurrectTimer = 10000;
1502 CAST_AI(boss_romulo::boss_romuloAI, Romulo->AI())->JulianneDead = true;
1503 damage = 0;
1504 return;
1505 }
1506 }
1507 SF_LOG_ERROR("scripts", "boss_julianneAI: DamageTaken reach end of code, that should not happen.");
1508}
1509
1511{
1512 new boss_dorothee();
1513 new boss_strawman();
1514 new boss_tinhead();
1515 new boss_roar();
1516 new boss_crone();
1517 new npc_tito();
1518 new npc_cyclone();
1519 new npc_grandmother();
1520 new boss_bigbadwolf();
1521 new boss_julianne();
1522 new boss_romulo();
1523}
@ IN_MILLISECONDS
Definition Common.h:125
@ HOUR
Definition Common.h:120
#define M_PI
Definition Common.h:192
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
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ DONE
@ SPECIAL
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
Definition Object.h:68
#define CAST_AI(a, b)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ UNIT_DYNFLAG_LOOTABLE
@ GO_FLAG_LOCKED
@ SPELL_SCHOOL_MASK_FIRE
@ JUST_DIED
Definition Unit.h:504
@ UNIT_STAND_STATE_DEAD
Definition Unit.h:169
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ OBJECT_FIELD_DYNAMIC_FLAGS
@ GAMEOBJECT_FIELD_FLAGS
Creatures
@ SPELL_CLEAVE
@ SPELL_WATERBOLT
@ SPELL_MANGLE
@ SAY_ROAR_DEATH
@ SAY_ROAR_AGGRO
@ SAY_DOROTHEE_TITO_DEATH
@ SAY_DOROTHEE_DEATH
@ SAY_STRAWMAN_DEATH
@ SAY_CRONE_SLAY
@ SAY_CRONE_DEATH
@ SAY_DOROTHEE_AGGRO
@ SAY_STRAWMAN_SLAY
@ SAY_TINHEAD_DEATH
@ SAY_TINHEAD_SLAY
@ SAY_TINHEAD_AGGRO
@ SAY_CRONE_AGGRO
@ EMOTE_RUST
@ SAY_DOROTHEE_SUMMON
@ SAY_STRAWMAN_AGGRO
@ SAY_ROAR_SLAY
@ CREATURE_TITO
@ CREATURE_CRONE
@ CREATURE_CYCLONE
JulianneRomulo
@ SAY_ROMULO_DEATH
@ SAY_ROMULO_AGGRO
@ SAY_ROMULO_SLAY
@ CREATURE_ROMULO
@ SAY_JULIANNE_DEATH02
@ SPELL_ETERNAL_AFFECTION
@ SPELL_UNDYING_LOVE
@ SPELL_DRINK_POISON
@ ROMULO_Y
@ SAY_JULIANNE_ENTER
@ SPELL_BLINDING_PASSION
@ SAY_JULIANNE_RESURRECT
@ SPELL_POWERFUL_ATTRACTION
@ SAY_JULIANNE_AGGRO
@ SAY_ROMULO_RESURRECT
@ ROMULO_X
@ SPELL_DEADLY_SWATHE
@ SPELL_DEVOTION
@ SAY_ROMULO_ENTER
@ SPELL_POISON_THRUST
@ SAY_JULIANNE_DEATH01
@ SPELL_BACKWARD_LUNGE
@ SPELL_DARING
@ SAY_JULIANNE_SLAY
@ SPELL_RES_VISUAL
RAJPhase
@ PHASE_BOTH
@ PHASE_JULIANNE
@ PHASE_ROMULO
@ SPELL_CLEAVE
@ SPELL_CYCLONE_VISUAL
@ SPELL_WATERBOLT
@ SPELL_SUMMONTITO
@ SPELL_KNOCKBACK
@ SPELL_MANGLE
@ SPELL_BRAIN_WIPE
@ SPELL_SCREAM
@ SPELL_SHRED
@ SPELL_RUST
@ SPELL_FRIGHTENED_SCREAM
@ SPELL_CHAIN_LIGHTNING
@ SPELL_BURNING_STRAW
@ SPELL_YIPPING
@ SPELL_BRAIN_BASH
RedRidingHood
@ SAY_WOLF_HOOD
@ CREATURE_BIG_BAD_WOLF
@ SPELL_WIDE_SWIPE
@ SAY_WOLF_SLAY
@ SAY_WOLF_AGGRO
@ SPELL_LITTLE_RED_RIDING_HOOD
@ SOUND_WOLF_DEATH
@ SPELL_TERRIFYING_HOWL
#define GOSSIP_GRANDMA
void AddSC_bosses_opera()
void Resurrect(Creature *target)
void PretendToDie(Creature *creature)
void SummonCroneIfReady(InstanceScript *instance, Creature *creature)
virtual void MoveInLineOfSight(Unit *)
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)
void MovementExpired(bool reset=true)
void MoveChase(Unit *target, float dist=0.0f, float angle=0.0f)
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
Definition Spell.h:289
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 SetFullHealth()
Definition Unit.h:1644
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:1433
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
bool IsAlive() const
Definition Unit.h:2032
void SetHealth(uint32 val)
Definition Unit.cpp:5162
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
Unit * GetVictim() const
Definition Unit.h:1468
void RemoveAllAuras()
void SetStandState(uint8 state)
Definition Unit.cpp:5902
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
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 uint32 GetData(uint32) const
Definition ZoneScript.h:36
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:37
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
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ DATA_GO_STAGEDOORRIGHT
Definition karazhan.h:32
@ DATA_GO_STAGEDOORLEFT
Definition karazhan.h:31
@ TYPE_OPERA
Definition karazhan.h:15
@ DATA_GO_SIDE_ENTRANCE_DOOR
Definition karazhan.h:42
@ DATA_OPERA_OZ_DEATHCOUNT
Definition karazhan.h:25
float GetPositionZ() const
Definition Object.h:330
Creature * me
float DoGetThreat(Unit *unit)
Creature * DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, TempSummonType type, uint32 despawntime)
ScriptedAI(Creature *creature)
void DoModifyThreatPercent(Unit *unit, int32 pct)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void AttackStart(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JustDied(Unit *) OVERRIDE
boss_croneAI(Creature *creature)
InstanceScript * instance
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void KilledUnit(Unit *) OVERRIDE
void JustReachedHome() OVERRIDE
void EnterCombat(Unit *) OVERRIDE
boss_dorotheeAI(Creature *creature)
void AttackStart(Unit *who) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void MoveInLineOfSight(Unit *who) OVERRIDE
void JustDied(Unit *) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
void MoveInLineOfSight(Unit *who) OVERRIDE
void SpellHit(Unit *, const SpellInfo *Spell) OVERRIDE
void AttackStart(Unit *who) OVERRIDE
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
boss_julianneAI(Creature *creature)
void KilledUnit(Unit *) OVERRIDE
void JustDied(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void KilledUnit(Unit *) OVERRIDE
void MoveInLineOfSight(Unit *who) OVERRIDE
void AttackStart(Unit *who) OVERRIDE
InstanceScript * instance
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
boss_roarAI(Creature *creature)
void EnterCombat(Unit *) OVERRIDE
void JustDied(Unit *) OVERRIDE
void JustReachedHome() OVERRIDE
void EnterCombat(Unit *) OVERRIDE
void MoveInLineOfSight(Unit *who) OVERRIDE
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
boss_romuloAI(Creature *creature)
void KilledUnit(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JustDied(Unit *) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
void SpellHit(Unit *, const SpellInfo *Spell) OVERRIDE
boss_strawmanAI(Creature *creature)
void AttackStart(Unit *who) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void MoveInLineOfSight(Unit *who) OVERRIDE
void JustDied(Unit *) OVERRIDE
void KilledUnit(Unit *) OVERRIDE
void MoveInLineOfSight(Unit *who) OVERRIDE
void JustDied(Unit *) OVERRIDE
void KilledUnit(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void AttackStart(Unit *who) OVERRIDE
boss_tinheadAI(Creature *creature)
void EnterCombat(Unit *) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
npc_cycloneAI(Creature *creature)
void MoveInLineOfSight(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void EnterCombat(Unit *) OVERRIDE
void JustDied(Unit *) OVERRIDE
npc_titoAI(Creature *creature)
void Reset() OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================