Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
culling_of_stratholme.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "ScriptMgr.h"
7#include "ScriptedCreature.h"
8#include "ScriptedGossip.h"
10#include "ScriptedEscortAI.h"
11#include "PassiveAI.h"
12#include "Player.h"
13#include "SpellInfo.h"
14
15enum Says
16{
17 //Arthas
18 //First Act
29
30 //Second Act - City Streets
37
38 //Third Act - Town Hall
51
52 //Fourth Act - Fire Corridor
60
61 //Fifth Act - Mal'Ganis Fight
66
67 //Malganis
70
71 //Epoch
73
74 //Uther
81
82 //Jaina
85
86 //Cityman
88
89 //Crazyman
91
92 //Drakonian
95};
96
121
131
140
148
149// Locations for necromancers and add to spawn
151{
152 {
153 {NPC_ZOMBIE, 2164.698975f, 1255.392944f, 135.040878f, 0.490202f},
154 {NPC_ZOMBIE, 2183.501465f, 1263.079102f, 134.859055f, 3.169981f},
155 {NPC_GHOUL, 2177.512939f, 1247.313843f, 135.846695f, 1.696574f},
156 {NPC_GHOUL, 2171.991943f, 1246.615845f, 135.745026f, 1.696574f},
157 {0, 0, 0, 0, 0}
158 },
159 {
160 {NPC_GHOUL, 2254.434326f, 1163.427612f, 138.055038f, 2.077358f},
161 {NPC_GHOUL, 2254.703613f, 1158.867798f, 138.212234f, 2.345532f},
162 {NPC_GHOUL, 2257.615723f, 1162.310913f, 138.091202f, 2.077358f},
163 {NPC_NECROMANCER, 2258.258057f, 1157.250732f, 138.272873f, 2.387766f},
164 {0, 0, 0, 0, 0}
165 },
166 {
167 {NPC_STALKER, 2348.120117f, 1202.302490f, 130.491104f, 4.698538f},
168 {NPC_GHOUL, 2352.863525f, 1207.819092f, 130.424271f, 4.949865f},
169 {NPC_GHOUL, 2343.593750f, 1207.915039f, 130.781311f, 4.321547f},
170 {NPC_NECROMANCER, 2348.257324f, 1212.202515f, 130.670135f, 4.450352f},
171 {0, 0, 0, 0, 0}
172 },
173 {
174 {NPC_STALKER, 2139.825195f, 1356.277100f, 132.199615f, 5.820131f},
175 {NPC_GHOUL, 2137.073486f, 1362.464844f, 132.271637f, 5.820131f},
176 {NPC_GHOUL, 2134.075684f, 1354.148071f, 131.885864f, 5.820131f},
177 {NPC_NECROMANCER, 2133.302246f, 1358.907837f, 132.037689f, 5.820131f},
178 {0, 0, 0, 0, 0}
179 },
180 {
181 {NPC_NECROMANCER, 2264.013428f, 1174.055908f, 138.093094f, 2.860481f},
182 {NPC_GHOUL, 2264.207764f, 1170.892700f, 138.034973f, 2.860481f},
183 {NPC_GHOUL, 2266.948975f, 1176.898926f, 137.976929f, 2.860481f},
184 {NPC_STALKER, 2269.215576f, 1170.109253f, 137.742691f, 2.860481f},
185 {NPC_FIEND, 2273.106689f, 1176.101074f, 137.880508f, 2.860481f}
186 },
187 {
188 {NPC_GOLEM, 2349.701660f, 1188.436646f, 130.428864f, 3.908642f},
189 {NPC_GHOUL, 2349.909180f, 1194.582642f, 130.417816f, 3.577001f},
190 {NPC_EGHOUL, 2354.662598f, 1185.692017f, 130.552032f, 3.577001f},
191 {NPC_EGHOUL, 2354.716797f, 1191.614380f, 130.539810f, 3.577001f},
192 {0, 0, 0, 0, 0}
193 },
194 {
195 {NPC_CONSTRUCT, 2145.212891f, 1355.288086f, 132.288773f, 6.004838f},
196 {NPC_NECROMANCER, 2137.078613f, 1357.612671f, 132.173340f, 6.004838f},
197 {NPC_EGHOUL, 2139.402100f, 1352.541626f, 132.127518f, 5.812850f},
198 {NPC_EGHOUL, 2142.408447f, 1360.760620f, 132.321564f, 5.812850f},
199 {0, 0, 0, 0, 0}
200 },
201 {
202 {NPC_GHOUL, 2172.686279f, 1259.618164f, 134.391754f, 1.865499f},
203 {NPC_FIEND, 2177.649170f, 1256.061157f, 135.096512f, 1.849572f},
204 {NPC_CONSTRUCT, 2170.782959f, 1253.594849f, 134.973022f, 1.849572f},
205 {NPC_NECROMANCER, 2175.595703f, 1249.041992f, 135.603531f, 1.849572f},
206 {0, 0, 0, 0, 0}
207 }
208};
209
210// Locations for rifts to spawn and draconians to go
212{
213 {NPC_TIME_RIFT, 2431.790039f, 1190.670044f, 148.076004f, 0.187923f},
214 {NPC_INFINITE_ADVERSARY, 2433.857910f, 1185.612061f, 148.075974f, 4.566168f},
215 {NPC_INFINITE_ADVERSARY, 2437.577881f, 1188.241089f, 148.075974f, 0.196999f},
216 {NPC_INFINITE_AGENT, 2437.165527f, 1192.294922f, 148.075974f, 0.169247f},
217 {NPC_INFINITE_HUNTER, 2434.989990f, 1197.679565f, 148.075974f, 0.715971f},
218 {NPC_TIME_RIFT, 2403.954834f, 1178.815430f, 148.075943f, 4.966126f},
219 {NPC_INFINITE_AGENT, 2403.676758f, 1171.495850f, 148.075607f, 4.902797f},
220 {NPC_INFINITE_HUNTER, 2407.691162f, 1172.162720f, 148.075607f, 4.963010f},
221 {NPC_TIME_RIFT, 2414.217041f, 1133.446167f, 148.076050f, 1.706972f},
222 {NPC_INFINITE_ADVERSARY, 2416.024658f, 1139.456177f, 148.076431f, 1.752129f},
223 {NPC_INFINITE_HUNTER, 2410.866699f, 1139.680542f, 148.076431f, 1.752129f},
224 {NPC_TIME_RIFT, 2433.081543f, 1099.869751f, 148.076157f, 1.809509f},
225 {NPC_INFINITE_ADVERSARY, 2426.947998f, 1107.471680f, 148.076019f, 1.877580f},
226 {NPC_INFINITE_HUNTER, 2432.944580f, 1108.896362f, 148.208160f, 2.199241f},
227 {NPC_TIME_RIFT, 2444.077637f, 1114.366089f, 148.076157f, 3.049565f},
228 {NPC_INFINITE_ADVERSARY, 2438.190674f, 1118.368164f, 148.076172f, 3.139232f},
229 {NPC_INFINITE_AGENT, 2435.861328f, 1113.402954f, 148.169327f, 2.390271f},
230 {NPC_TIME_RIFT, 2463.131592f, 1115.391724f, 152.473129f, 3.409651f},
231 {NPC_EPOCH, 2451.809326f, 1112.901245f, 149.220459f, 3.363617f}
232};
233
234#define GOSSIP_ITEM_ARTHAS_0 "I'm ready to start Culling of Stratholme."
235#define GOSSIP_ITEM_ARTHAS_1 "Yes, my Prince. We're ready."
236#define GOSSIP_ITEM_ARTHAS_2 "We're only doing what is best for Loarderon your Highness."
237#define GOSSIP_ITEM_ARTHAS_3 "I'm ready."
238#define GOSSIP_ITEM_ARTHAS_4 "For Lordaeron!"
239#define GOSSIP_ITEM_ARTHAS_5 "I'm ready to battle the dreadlord, sire."
240
242{
243public:
244 npc_arthas() : CreatureScript("npc_arthas") { }
245
246 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
247 {
248 player->PlayerTalkClass->ClearMenus();
249 npc_arthasAI* ai = CAST_AI(npc_arthas::npc_arthasAI, creature->AI());
250
251 if (!ai)
252 return false;
253
254 switch (action)
255 {
257 ai->Start(true, true, player->GetGUID(), 0, false, false);
258 ai->SetDespawnAtEnd(false);
259 ai->bStepping = false;
260 ai->step = 1;
261 break;
263 ai->bStepping = true;
264 ai->step = 24;
265 break;
267 ai->SetHoldState(false);
268 ai->bStepping = false;
269 ai->step = 61;
270 break;
272 ai->SetHoldState(false);
273 break;
275 ai->bStepping = true;
276 ai->step = 84;
277 break;
279 ai->bStepping = true;
280 ai->step = 85;
281 break;
282 }
283 player->CLOSE_GOSSIP_MENU();
284 ai->SetDespawnAtFar(true);
285 creature->RemoveFlag(UNIT_FIELD_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
286 return true;
287 }
288
289 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
290 {
291 npc_arthasAI* ai = CAST_AI(npc_arthas::npc_arthasAI, creature->AI());
292
293 if (ai && ai->bStepping == false)
294 {
295 switch (ai->gossipStep)
296 {
297 case 0: //This one is a workaround since the very beggining of the script is wrong.
298 {
299 QuestStatus status = player->GetQuestStatus(13149);
300 if (status != QUEST_STATUS_COMPLETE && status != QUEST_STATUS_REWARDED)
301 return false;
303 player->SEND_GOSSIP_MENU(907, creature->GetGUID());
304 break;
305 }
306 case 1:
308 player->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_1, creature->GetGUID());
309 break;
310 case 2:
312 player->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_2, creature->GetGUID());
313 break;
314 case 3:
316 player->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_3, creature->GetGUID());
317 break;
318 case 4:
320 player->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_4, creature->GetGUID());
321 break;
322 case 5:
324 player->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_5, creature->GetGUID());
325 break;
326 default:
327 return false;
328 }
329 }
330 return true;
331 }
332
334 {
335 return new npc_arthasAI(creature);
336 }
337
339 {
340 npc_arthasAI(Creature* creature) : npc_escortAI(creature)
341 {
342 instance = creature->GetInstanceScript();
343 Reset();
344 }
345
347
355
362
367
369
371 {
372 utherGUID = 0;
373 jainaGUID = 0;
374
375 for (uint8 i = 0; i < 2; ++i)
376 citymenGUID[i] = 0;
377
378 for (uint8 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i)
379 waveGUID[i] = 0;
380
381 for (uint8 i = 0; i < ENCOUNTER_DRACONIAN_NUMBER; ++i)
383
384 stalkerGUID = 0;
385 bossGUID = 0;
386 epochGUID = 0;
387 malganisGUID = 0;
388 infiniteGUID = 0;
389
390 if (instance) {
392 switch (instance->GetData(DATA_ARTHAS_EVENT))
393 {
394 case NOT_STARTED:
395 bStepping = true;
396 step = 0;
399 gossipStep = 0;
400 break;
401 }
402 phaseTimer = 1000;
403 exorcismTimer = 7300;
404 wave = 0;
405 }
406 }
407
408 void EnterCombat(Unit* /*who*/) OVERRIDE
409 {
411 }
412
413 void JustDied(Unit* /*killer*/) OVERRIDE
414 {
415 if (instance)
417 }
418
419 void SpawnTimeRift(uint32 timeRiftID, uint64* guidVector)
420 {
421 me->SummonCreature((uint32)RiftAndSpawnsLocations[timeRiftID][0], RiftAndSpawnsLocations[timeRiftID][1], RiftAndSpawnsLocations[timeRiftID][2], RiftAndSpawnsLocations[timeRiftID][3], RiftAndSpawnsLocations[timeRiftID][4], TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 11000);
422
423 for (uint32 i = timeRiftID+1; i < ENCOUNTER_CHRONO_SPAWNS; ++i)
424 {
425 if ((uint32)RiftAndSpawnsLocations[i][0] == NPC_TIME_RIFT) break;
426 if (Creature* temp = me->SummonCreature((uint32)RiftAndSpawnsLocations[i][0], RiftAndSpawnsLocations[timeRiftID][1], RiftAndSpawnsLocations[timeRiftID][2], RiftAndSpawnsLocations[timeRiftID][3], RiftAndSpawnsLocations[timeRiftID][4], TempSummonType::TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000))
427 {
428 guidVector[i-timeRiftID-1] = temp->GetGUID();
430 temp->SetReactState(REACT_PASSIVE);
431 temp->GetMotionMaster()->MovePoint(0, RiftAndSpawnsLocations[i][1], RiftAndSpawnsLocations[i][2], RiftAndSpawnsLocations[i][3]);
433 epochGUID = temp->GetGUID();
434 }
435 }
436 }
437
438 void SpawnWaveGroup(uint32 waveID, uint64* guidVector)
439 {
440 for (uint32 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i)
441 {
442 if ((uint32)WavesLocations[waveID][i][0] == 0) break;
443 if (Creature* temp = me->SummonCreature((uint32)WavesLocations[waveID][i][0], WavesLocations[waveID][i][1], WavesLocations[waveID][i][2], WavesLocations[waveID][i][3], WavesLocations[waveID][i][4], TempSummonType::TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000))
444 {
445 guidVector[i] = temp->GetGUID();
446 }
447 }
448 }
449
450 void SetHoldState(bool bOnHold)
451 {
452 SetEscortPaused(bOnHold);
453 }
454
455 void JumpToNextStep(uint32 uiTimer)
456 {
457 phaseTimer = uiTimer;
458 ++step;
459 }
460
462 {
463 switch (waypointId)
464 {
465 case 0:
466 case 1:
467 case 3:
468 case 9:
469 case 10:
470 case 11:
471 case 22:
472 case 23:
473 case 26:
474 case 55:
475 case 56:
476 SetHoldState(true);
477 bStepping = true;
478 break;
479 case 7:
480 if (Unit* cityman0 = me->SummonCreature(NPC_CITY_MAN, 2091.977f, 1275.021f, 140.757f, 0.558f, TempSummonType::TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000))
481 citymenGUID[0] = cityman0->GetGUID();
482 if (Unit* cityman1 = me->SummonCreature(NPC_CITY_MAN2, 2093.514f, 1275.842f, 140.408f, 3.801f, TempSummonType::TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000))
483 citymenGUID[1] = cityman1->GetGUID();
484 break;
485 case 8:
486 gossipStep = 1;
488 SetHoldState(true);
489 break;
490 case 12:
491 SetRun(true);
493 if (Unit* disguised0 = me->SummonCreature(NPC_CITY_MAN3, 2398.14f, 1207.81f, 134.04f, 5.155249f, TempSummonType::TEMPSUMMON_DEAD_DESPAWN, 180000))
494 {
495 infiniteDraconianGUID[0] = disguised0->GetGUID();
496 if (Unit* disguised1 = me->SummonCreature(NPC_CITY_MAN4, 2403.22f, 1205.54f, 134.04f, 3.311264f, TempSummonType::TEMPSUMMON_DEAD_DESPAWN, 180000))
497 {
498 infiniteDraconianGUID[1] = disguised1->GetGUID();
499
500 if (Unit* disguised2 = me->SummonCreature(NPC_CITY_MAN, 2400.82f, 1201.69f, 134.01f, 1.534082f, TempSummonType::TEMPSUMMON_DEAD_DESPAWN, 180000))
501 {
502 infiniteDraconianGUID[2] = disguised2->GetGUID();
503 disguised0->SetTarget(infiniteDraconianGUID[1]);
504 disguised1->SetTarget(infiniteDraconianGUID[0]);
505 disguised2->SetTarget(infiniteDraconianGUID[1]);
506 }
507 }
508 }
509 break;
510 case 20:
511 gossipStep = 2;
513 SetRun(false);
514 SetHoldState(true);
515 break;
516 case 21:
518 break;
519 case 25:
520 SetRun(false);
523 break;
524 case 29:
525 SetRun(false);
529 SetHoldState(true);
530 bStepping = true;
531 break;
532 case 31:
533 SetRun(false);
537 SetHoldState(true);
538 bStepping = true;
539 break;
540 case 32:
542 break;
543 case 34:
545 break;
546 case 35:
548 break;
549 case 36:
550 if (instance)
551 if (GameObject* pGate = instance->instance->GetGameObject(instance->GetData64(DATA_SHKAF_GATE)))
552 pGate->SetGoState(GOState::GO_STATE_ACTIVE);
553 break;
554 case 45:
555 SetRun(true);
556 SetDespawnAtFar(false);
557 gossipStep = 4;
559 SetHoldState(true);
560 break;
561 case 47:
562 SetRun(false);
564 break;
565 case 48:
566 SetRun(true);
568 break;
569 case 53:
571 break;
572 case 54:
573 gossipStep = 5;
575 SetHoldState(true);
576 break;
577 }
578 }
579
581 {
583
585
586 if (bStepping)
587 {
588 if (phaseTimer <= diff)
589 {
590 switch (step)
591 {
592 //After reset
593 case 0:
594 {
596 if (!jaina)
597 jaina = me->SummonCreature(NPC_JAINA, 1895.48f, 1292.66f, 143.706f, 0.023475f, TempSummonType::TEMPSUMMON_DEAD_DESPAWN, 180000);
598 if (jaina)
599 jainaGUID = jaina->GetGUID();
600 bStepping = false;
602 break;
603 }
604 //After waypoint 0
605 case 1:
606 me->SetWalk(false);
607 if (Unit* uther = me->SummonCreature(NPC_UTHER, 1794.357f, 1272.183f, 140.558f, 1.37f, TempSummonType::TEMPSUMMON_DEAD_DESPAWN, 180000))
608 {
609 utherGUID = uther->GetGUID();
610 uther->SetWalk(false);
611 uther->GetMotionMaster()->MovePoint(0, 1897.018f, 1287.487f, 143.481f);
612 uther->SetTarget(me->GetGUID());
613 me->SetTarget(utherGUID);
614 }
615 JumpToNextStep(17000);
616 break;
617 case 2:
619 JumpToNextStep(2000);
620 break;
621 case 3:
622 if (Creature* uther = Unit::GetCreature(*me, utherGUID))
623 {
624 uther->AI()->Talk(SAY_PHASE102);
625 }
626 JumpToNextStep(8000);
627 break;
628 case 4:
629 SetEscortPaused(false);
630 bStepping = false;
631 SetRun(false);
634 break;
635 //After waypoint 1
636 case 5:
637 if (Creature* jaina = Unit::GetCreature(*me, jainaGUID))
638 jaina->SetTarget(me->GetGUID());
640 JumpToNextStep(10000);
641 break;
642 case 6:
643 if (Creature* uther = Unit::GetCreature(*me, utherGUID))
644 uther->AI()->Talk(SAY_PHASE105);
645 JumpToNextStep(1000);
646 break;
647 case 7:
649 JumpToNextStep(4000);
650 break;
651 case 8:
652 if (Creature* uther = Unit::GetCreature(*me, utherGUID))
653 uther->AI()->Talk(SAY_PHASE107);
654 JumpToNextStep(6000);
655 break;
656 case 9:
658 JumpToNextStep(4000);
659 break;
660 case 10:
661 if (Creature* uther = Unit::GetCreature(*me, utherGUID))
662 uther->AI()->Talk(SAY_PHASE109);
663 JumpToNextStep(8000);
664 break;
665 case 11:
667 JumpToNextStep(4000);
668 break;
669 case 12:
670 if (Creature* uther = Unit::GetCreature(*me, utherGUID))
671 uther->AI()->Talk(SAY_PHASE111);
672 JumpToNextStep(4000);
673 break;
674 case 13:
676 JumpToNextStep(11000);
677 break;
678 case 14:
679 if (Creature* jaina = Unit::GetCreature(*me, jainaGUID))
680 jaina->AI()->Talk(SAY_PHASE113);
681 JumpToNextStep(3000);
682 break;
683 case 15:
685 JumpToNextStep(9000);
686 break;
687 case 16:
688 if (Creature* uther = Unit::GetCreature(*me, utherGUID))
689 uther->AI()->Talk(SAY_PHASE115);
690 JumpToNextStep(4000);
691 break;
692 case 17:
693 if (Creature* uther = Unit::GetCreature(*me, utherGUID))
694 {
695 uther->SetWalk(true);
696 uther->GetMotionMaster()->MovePoint(0, 1794.357f, 1272.183f, 140.558f);
697 }
698 JumpToNextStep(1000);
699 break;
700 case 18:
701 if (Creature* jaina = Unit::GetCreature(*me, jainaGUID))
702 {
703 me->SetTarget(jainaGUID);
704 jaina->SetWalk(true);
705 jaina->GetMotionMaster()->MovePoint(0, 1794.357f, 1272.183f, 140.558f);
706 }
707 JumpToNextStep(1000);
708 break;
709 case 19:
711 JumpToNextStep(1000);
712 break;
713 case 20:
714 if (Creature* jaina = Unit::GetCreature(*me, jainaGUID))
715 jaina->AI()->Talk(SAY_PHASE117);
716 JumpToNextStep(3000);
717 break;
718 case 21:
719 SetEscortPaused(false);
720 bStepping = false;
721 me->SetTarget(0);
723 break;
724 //After waypoint 3
725 case 22:
727 me->SetTarget(jainaGUID);
728 JumpToNextStep(10000);
729 break;
730 case 23:
731 SetEscortPaused(false);
732 bStepping = false;
733 SetRun(true);
734
735 if (Creature* jaina = Unit::GetCreature(*me, jainaGUID))
736 jaina->DisappearAndDie();
737
738 if (Creature* uther = Unit::GetCreature(*me, utherGUID))
739 uther->DisappearAndDie();
740
741 me->SetTarget(0);
743 break;
744 //After Gossip 1 (waypoint 8)
745 case 24:
746 if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET, 2026.469f, 1287.088f, 143.596f, 1.37f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 14000))
747 {
748 stalkerGUID = pStalker->GetGUID();
749 me->SetTarget(stalkerGUID);
750 }
751 JumpToNextStep(1000);
752 break;
753 case 25:
755 JumpToNextStep(12000);
756 break;
757 case 26:
758 SetEscortPaused(false);
759 bStepping = false;
760 SetRun(false);
761 me->SetTarget(0);
763 break;
764 //After waypoint 9
765 case 27:
766 me->SetTarget(citymenGUID[0]);
767 if (Creature* cityman = Unit::GetCreature(*me, citymenGUID[0]))
768 {
769 cityman->SetTarget(me->GetGUID());
770 cityman->SetWalk(true);
771 cityman->GetMotionMaster()->MovePoint(0, 2088.625f, 1279.191f, 140.743f);
772 }
773 JumpToNextStep(2000);
774 break;
775 case 28:
776 if (Creature* cityman = Unit::GetCreature(*me, citymenGUID[0]))
777 cityman->AI()->Talk(SAY_PHASE202);
778 JumpToNextStep(4000);
779 break;
780 case 29:
781 SetEscortPaused(false);
782 bStepping = false;
785 break;
786 //After waypoint 10
787 case 30:
788 me->HandleEmoteCommand(37);
789 JumpToNextStep(1000);
790 break;
791 case 31:
792 SetEscortPaused(false);
793 bStepping = false;
794 if (Creature* cityman1 = Unit::GetCreature(*me, citymenGUID[1]))
795 {
796 cityman1->AI()->Talk(SAY_PHASE204);
797 cityman1->SetTarget(me->GetGUID());
798 if (Creature* cityman0 = Unit::GetCreature(*me, citymenGUID[0]))
799 cityman0->Kill(cityman0);
800 me->SetTarget(citymenGUID[1]);
801 }
803 break;
804 //After waypoint 11
805 case 32:
806 me->HandleEmoteCommand(37);
807 JumpToNextStep(1000);
808 break;
809 case 33:
810 if (Creature* cityman1 = Unit::GetCreature(*me, citymenGUID[1]))
811 cityman1->Kill(cityman1);
812 JumpToNextStep(1000);
813 break;
814 case 34:
815 if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET, 2081.447f, 1287.770f, 141.3241f, 1.37f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 10000))
816 {
817 stalkerGUID = pStalker->GetGUID();
818 me->SetTarget(stalkerGUID);
819 }
821 JumpToNextStep(3000);
822 break;
823 case 35:
824 if (Unit* pStalkerM = me->SummonCreature(NPC_INVIS_TARGET, 2117.349f, 1288.624f, 136.271f, 1.37f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 60000))
825 {
826 stalkerGUID = pStalkerM->GetGUID();
827 me->SetTarget(stalkerGUID);
828 }
829 JumpToNextStep(1000);
830 break;
831 case 36:
832 if (Creature* malganis = me->SummonCreature(NPC_MAL_GANIS, 2117.349f, 1288.624f, 136.271f, 1.37f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 60000))
833 {
834 if (Creature* pStalkerM = Unit::GetCreature(*me, stalkerGUID))
835 malganis->CastSpell(pStalkerM, 63793, false);
836
837 malganisGUID = malganis->GetGUID();
838 malganis->AI()->Talk(SAY_PHASE206);
839 malganis->SetTarget(me->GetGUID());
840 malganis->SetReactState(REACT_PASSIVE);
841 }
842 JumpToNextStep(11000);
843 break;
844 case 37:
845 if (Creature* malganis = Unit::GetCreature(*me, malganisGUID))
846 {
847 Creature* pZombie = GetClosestCreatureWithEntry(malganis, NPC_CITY_MAN, 100.0f);
848 if (!pZombie)
849 pZombie = GetClosestCreatureWithEntry(malganis, NPC_CITY_MAN2, 100.0f);
850 if (pZombie)
851 pZombie->UpdateEntry(NPC_ZOMBIE, 0);
852 else //There's no one else to transform
853 step++;
854 }
855 else
856 step++;
857 phaseTimer = 500;
858 break;
859 case 38:
860 if (Creature* malganis = Unit::GetCreature(*me, malganisGUID))
861 malganis->AI()->Talk(SAY_PHASE207);
862 JumpToNextStep(17000);
863 break;
864 case 39:
865 if (Creature* malganis = Unit::GetCreature(*me, malganisGUID))
866 malganis->SetVisible(false);
868 JumpToNextStep(7000);
869 break;
870 case 40:
871 if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET, 2081.447f, 1287.770f, 141.3241f, 1.37f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 10000))
872 {
873 stalkerGUID = pStalker->GetGUID();
874 me->SetTarget(stalkerGUID);
875 }
877
879 if (instance)
881
882 me->SetReactState(REACT_DEFENSIVE);
883 SetDespawnAtFar(false);
884 JumpToNextStep(5000);
885 break;
886 case 41: //Summon wave group
887 case 43:
888 case 45:
889 case 47:
890 case 51:
891 case 53:
892 case 55:
893 case 57:
894 if (instance->GetData(bossEvent) != DONE)
895 {
897 wave++;
898 }
899 JumpToNextStep(500);
900 break;
901 case 42: //Wait group to die
902 case 44:
903 case 46:
904 case 48:
905 case 52:
906 case 54:
907 case 56:
908 case 58:
909 if (instance->GetData(bossEvent) != DONE)
910 {
911 uint32 mobCounter = 0;
912 uint32 deadCounter = 0;
913 for (uint8 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i)
914 {
915 if (waveGUID[i] == 0)
916 break;
917 ++mobCounter;
918 Unit* temp = Unit::GetCreature(*me, waveGUID[i]);
919 if (!temp || temp->isDead())
920 ++deadCounter;
921 }
922
923 if (mobCounter <= deadCounter) //If group is dead
924 JumpToNextStep(1000);
925 else
926 phaseTimer = 1000;
927 }
928 else
929 JumpToNextStep(500);
930 break;
931 case 49: //Summon Boss
932 case 59:
933 if (instance->GetData(bossEvent) != DONE)
934 {
935 uint32 uiBossID = 0;
937 uiBossID = NPC_MEATHOOK;
938 else if (bossEvent == DATA_SALRAMM_EVENT)
939 uiBossID = NPC_SALRAMM;
940
941 if (Unit* pBoss = me->SummonCreature(uiBossID, 2232.19f, 1331.933f, 126.662f, 3.15f, TempSummonType::TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000))
942 {
943 bossGUID = pBoss->GetGUID();
944 pBoss->SetWalk(true);
945 pBoss->GetMotionMaster()->MovePoint(0, 2194.110f, 1332.00f, 130.00f);
946 }
947 }
948 JumpToNextStep(30000);
949 break;
950 case 50: //Wait Boss death
951 case 60:
952 if (instance)
953 {
954 if (instance->GetData(bossEvent) == DONE)
955 {
956 JumpToNextStep(1000);
959 else if (bossEvent == DATA_SALRAMM_EVENT)
960 {
961 SetHoldState(false);
962 bStepping = false;
964 }
965 }
966 else if (instance->GetData(bossEvent) == FAIL)
968 else
969 phaseTimer = 10000;
970 }
971 break;
972 //After Gossip 2 (waypoint 22)
973 case 61:
974 me->SetReactState(REACT_AGGRESSIVE);
975 if (Creature* disguised0 = Unit::GetCreature(*me, infiniteDraconianGUID[0]))
976 disguised0->SetTarget(me->GetGUID());
977 if (Creature* disguised1 = Unit::GetCreature(*me, infiniteDraconianGUID[1]))
978 disguised1->SetTarget(me->GetGUID());
979 if (Creature* disguised2 = Unit::GetCreature(*me, infiniteDraconianGUID[2]))
980 disguised2->SetTarget(me->GetGUID());
981 JumpToNextStep(1000);
982 break;
983 case 62:
984 if (Creature* disguised0 = Unit::GetCreature(*me, infiniteDraconianGUID[0]))
985 disguised0->AI()->Talk(SAY_PHASE302);
986 JumpToNextStep(7000);
987 break;
988 case 63:
990 SetHoldState(false);
991 bStepping = false;
993 break;
994 //After waypoint 23
995 case 64:
996 me->HandleEmoteCommand(54);
997 JumpToNextStep(1000);
998 break;
999 case 65:
1000 if (Creature* disguised0 = Unit::GetCreature(*me, infiniteDraconianGUID[0]))
1001 disguised0->HandleEmoteCommand(11);
1002 JumpToNextStep(1000);
1003 break;
1004 case 66:
1006 JumpToNextStep(2000);
1007 break;
1008 case 67:
1009 if (Creature* disguised0 = Unit::GetCreature(*me, infiniteDraconianGUID[0]))
1010 disguised0->AI()->Talk(SAY_PHASE305);
1011 JumpToNextStep(1000);
1012 break;
1013 case 68:
1014 if (Creature* disguised2 = Unit::GetCreature(*me, infiniteDraconianGUID[2]))
1015 {
1016 disguised2->UpdateEntry(NPC_INFINITE_HUNTER, 0);
1017 //Make them unattackable
1019 disguised2->SetReactState(REACT_PASSIVE);
1020 }
1021 JumpToNextStep(2000);
1022 break;
1023 case 69:
1024 if (Creature* disguised1 = Unit::GetCreature(*me, infiniteDraconianGUID[1]))
1025 {
1026 disguised1->UpdateEntry(NPC_INFINITE_AGENT, 0);
1027 //Make them unattackable
1029 disguised1->SetReactState(REACT_PASSIVE);
1030 }
1031 JumpToNextStep(2000);
1032 break;
1033 case 70:
1034 if (Creature* disguised0 = Unit::GetCreature(*me, infiniteDraconianGUID[0]))
1035 {
1036 disguised0->UpdateEntry(NPC_INFINITE_ADVERSARY, 0);
1037 //Make them unattackable
1039 disguised0->SetReactState(REACT_PASSIVE);
1040 }
1041 JumpToNextStep(2000);
1042 break;
1043 case 71:
1044 //After waypoint 26, 29, 31
1045 case 73:
1046 case 75:
1047 case 77:
1048 //Make cratures attackable
1049 for (uint32 i = 0; i< ENCOUNTER_DRACONIAN_NUMBER; ++i)
1051 {
1053 temp->SetReactState(REACT_AGGRESSIVE);
1054 }
1055 JumpToNextStep(5000);
1056 break;
1057 case 72:
1058 case 74:
1059 case 76:
1060 if (me->IsInCombat())
1061 phaseTimer = 1000;
1062 else
1063 {
1064 if (step == 72) Talk(SAY_PHASE308);
1065 if (step == 74) Talk(SAY_PHASE308);
1066 if (step == 76) Talk(SAY_PHASE310);
1067 SetHoldState(false);
1068 bStepping = false;
1069 SetRun(true);
1070 JumpToNextStep(2000);
1071 }
1072 break;
1073 case 78:
1074 if (me->IsInCombat())
1075 phaseTimer = 1000;
1076 else
1077 {
1079 JumpToNextStep(5000);
1080 }
1081 break;
1082 case 79:
1084 JumpToNextStep(1000);
1085 break;
1086 case 80:
1087 if (instance)
1088 if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
1089 {
1091 if (Creature* epoch = Unit::GetCreature(*me, epochGUID))
1092 epoch->AI()->Talk(SAY_PHASE314);
1093 me->SetTarget(epochGUID);
1094 }
1095 JumpToNextStep(18000);
1096 break;
1097 case 81:
1098 if (instance)
1099 if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
1101 JumpToNextStep(6000);
1102 break;
1103 case 82:
1104 if (instance)
1105 if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
1106 {
1107 if (Creature* epoch = Unit::GetCreature(*me, epochGUID))
1108 {
1109 //Make Epoch attackable
1111 epoch->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
1112 epoch->SetReactState(REACT_AGGRESSIVE);
1113 }
1114 }
1115 JumpToNextStep(1000);
1116 break;
1117 case 83:
1118 if (instance)
1119 {
1120 if (instance->GetData(DATA_EPOCH_EVENT) == DONE)
1121 {
1122 gossipStep = 3;
1124 bStepping = false;
1126 JumpToNextStep(15000);
1127 }
1128 else if (instance->GetData(DATA_EPOCH_EVENT) == FAIL)
1130 else
1131 phaseTimer = 10000;
1132 }
1133 break;
1134 //After Gossip 4
1135 case 84:
1137 SetHoldState(false);
1138 bStepping = false;
1139 break;
1140 //After Gossip 5
1141 case 85:
1143 if (Creature* malganis = me->SummonCreature(NPC_MAL_GANIS, 2296.665f, 1502.362f, 128.362f, 4.961f, TempSummonType::TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000))
1144 {
1145 malganisGUID = malganis->GetGUID();
1146 malganis->SetReactState(REACT_PASSIVE);
1147 }
1148 if (instance)
1149 if (GameObject* pGate = instance->instance->GetGameObject(instance->GetData64(DATA_MAL_GANIS_GATE_1)))
1150 pGate->SetGoState(GOState::GO_STATE_ACTIVE);
1151 SetHoldState(false);
1152 bStepping = false;
1153 JumpToNextStep(0);
1154 break;
1155 //After waypoint 55
1156 case 86:
1158 JumpToNextStep(6000);
1159 me->SetTarget(malganisGUID);
1160 break;
1161 case 87:
1162 if (Creature* malganis = Unit::GetCreature(*me, malganisGUID))
1163 {
1165 malganis->SetReactState(REACT_AGGRESSIVE);
1166 }
1167 JumpToNextStep(1000);
1168 break;
1169 case 88:
1170 if (instance)
1171 {
1172 if (instance->GetData(DATA_MAL_GANIS_EVENT) == DONE)
1173 {
1174 SetHoldState(false);
1175 JumpToNextStep(1000);
1176 }
1177 else if (instance->GetData(DATA_MAL_GANIS_EVENT) == FAIL)
1179 else
1180 phaseTimer = 10000;
1181 }
1182 break;
1183 //After waypoint 56
1184 case 89:
1185 SetRun(true);
1186 me->SetTarget(malganisGUID);
1188 JumpToNextStep(7000);
1189 break;
1190 case 90:
1191 if (instance)
1192 {
1193 instance->SetData(DATA_ARTHAS_EVENT, DONE); //Rewards: Achiev & Chest ;D
1194 me->SetTarget(instance->GetData64(DATA_MAL_GANIS_GATE_2)); //Look behind
1195 }
1197 bStepping = false;
1198 break;
1199 }
1200 } else phaseTimer -= diff;
1201 }
1202
1203 //Battling skills
1204 if (!me->GetVictim())
1205 return;
1206
1207 if (exorcismTimer < diff)
1208 {
1209 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
1210 DoCast(target, SPELL_EXORCISM_N);
1211 exorcismTimer = 7300;
1212 } else exorcismTimer -= diff;
1213
1214 if (HealthBelowPct(40))
1216 }
1217 };
1218};
1219
1221{
1222 public:
1223 npc_crate_helper() : CreatureScript("npc_create_helper_cot") { }
1224
1226 {
1228 {
1229 _marked = false;
1230 }
1231
1232 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
1233 {
1234 if (spell->Id == SPELL_ARCANE_DISRUPTION && !_marked)
1235 {
1236 _marked = true;
1237 if (InstanceScript* instance = me->GetInstanceScript())
1238 instance->SetData(DATA_CRATE_COUNT, instance->GetData(DATA_CRATE_COUNT) + 1);
1239 if (GameObject* crate = me->FindNearestGameObject(GO_SUSPICIOUS_CRATE, 5.0f))
1240 {
1241 crate->SummonGameObject(GO_PLAGUED_CRATE, crate->GetPositionX(), crate->GetPositionY(), crate->GetPositionZ(), crate->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, DAY);
1242 crate->Delete();
1243 }
1244 }
1245 }
1246
1247 private:
1249 };
1250
1252 {
1253 return new npc_crate_helperAI(creature);
1254 }
1255};
1256
1258{
1259 new npc_arthas();
1260 new npc_crate_helper();
1261}
@ DAY
Definition Common.h:121
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
@ GO_STATE_ACTIVE
Definition GameObject.h:576
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ IN_PROGRESS
@ FAIL
@ DONE
@ NOT_STARTED
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:74
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
Definition Object.h:68
QuestStatus
Definition QuestDef.h:85
@ QUEST_STATUS_REWARDED
Definition QuestDef.h:92
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:87
Creature * GetClosestCreatureWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool alive)
#define CAST_AI(a, b)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ UNIT_NPC_FLAG_GOSSIP
Definition Unit.h:687
@ REACT_DEFENSIVE
Definition Unit.h:1157
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_UNK_6
Definition Unit.h:631
@ UNIT_FLAG_IMMUNE_TO_NPC
Definition Unit.h:634
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ UNIT_FLAG_UNK_15
Definition Unit.h:640
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_FLAGS
@ SPELL_FEAR
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
Creature *const me
Definition CreatureAI.h:56
bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData *data=NULL)
Definition Creature.cpp:356
CreatureScript(const char *name)
NullCreatureAI(Creature *c)
Definition PassiveAI.cpp:12
uint64 GetGUID() const
Definition Object.h:119
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
Definition Unit.h:1367
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
bool isDead() const
Definition Unit.h:2040
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
#define GOSSIP_ITEM_ARTHAS_3
@ GOSSIP_MENU_ARTHAS_1
@ GOSSIP_MENU_ARTHAS_2
@ GOSSIP_MENU_ARTHAS_5
@ GOSSIP_MENU_ARTHAS_4
@ GOSSIP_MENU_ARTHAS_3
@ SPELL_ARCANE_DISRUPTION
@ NPC_INFINITE_ADVERSARY
@ NPC_INFINITE_HUNTER
@ ENCOUNTER_DRACONIAN_NUMBER
@ ENCOUNTER_WAVES_NUMBER
@ ENCOUNTER_WAVES_MAX_SPAWNS
@ ENCOUNTER_CHRONO_SPAWNS
#define GOSSIP_ITEM_ARTHAS_2
#define GOSSIP_ITEM_ARTHAS_0
#define GOSSIP_ITEM_ARTHAS_1
#define GOSSIP_ITEM_ARTHAS_5
#define GOSSIP_ITEM_ARTHAS_4
float WavesLocations[ENCOUNTER_WAVES_NUMBER][ENCOUNTER_WAVES_MAX_SPAWNS][5]
void AddSC_culling_of_stratholme()
float RiftAndSpawnsLocations[ENCOUNTER_CHRONO_SPAWNS][5]
@ GO_PLAGUED_CRATE
@ GO_SUSPICIOUS_CRATE
@ NPC_MAL_GANIS
@ DATA_MAL_GANIS_GATE_2
@ DATA_SHKAF_GATE
@ DATA_MAL_GANIS_GATE_1
@ DATA_MEATHOOK_EVENT
@ DATA_CRATE_COUNT
@ DATA_SALRAMM_EVENT
@ DATA_EPOCH_EVENT
@ DATA_ARTHAS_EVENT
@ DATA_MAL_GANIS_EVENT
Creature * me
bool HealthBelowPct(uint32 pct) const
void WaypointReached(uint32 waypointId) OVERRIDE
void SpawnTimeRift(uint32 timeRiftID, uint64 *guidVector)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JumpToNextStep(uint32 uiTimer)
uint64 infiniteDraconianGUID[ENCOUNTER_DRACONIAN_NUMBER]
uint64 waveGUID[ENCOUNTER_WAVES_MAX_SPAWNS]
void EnterCombat(Unit *) OVERRIDE
void SpawnWaveGroup(uint32 waveID, uint64 *guidVector)
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void EnterEvadeMode() OVERRIDE
void SetDespawnAtFar(bool despawn)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SetRun(bool on=true)
npc_escortAI(Creature *creature)
void SetDespawnAtEnd(bool despawn)
void SetEscortPaused(bool on)
void Start(bool isActiveAttacker=true, bool run=false, uint64 playerGUID=0, Quest const *quest=NULL, bool instantRespawn=false, bool canLoopPath=false, bool resetWaypoints=true)