Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
violet_hold.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"
9#include "ScriptedEscortAI.h"
10#include "violet_hold.h"
11#include "Player.h"
12#include "SpellAuras.h"
13#include "SpellAuraEffects.h"
14#include "SpellScript.h"
15
16#define GOSSIP_START_EVENT "Get your people to safety, we'll keep the Blue Dragonflight's forces at bay."
17#define GOSSIP_ITEM_1 "Activate the crystals when we get in trouble, right"
18#define GOSSIP_I_WANT_IN "I'm not fighting, so send me in now!"
19#define SPAWN_TIME 20000
20
36
45
55
67
73
79
87
93
99
105
110
117
119{
121};
122
123float FirstPortalWPs [6][3] =
124{
125 {1877.670288f, 842.280273f, 43.333591f},
126 {1877.338867f, 834.615356f, 38.762287f},
127 {1872.161011f, 823.854309f, 38.645401f},
128 {1864.860474f, 815.787170f, 38.784843f},
129 {1858.953735f, 810.048950f, 44.008759f},
130 {1843.707153f, 805.807739f, 44.135197f}
131 //{1825.736084f, 807.305847f, 44.363785f}
132};
133
135{
136 {1902.561401f, 853.334656f, 47.106117f},
137 {1895.486084f, 855.376404f, 44.334591f},
138 {1882.805176f, 854.993286f, 43.333591f},
139 {1877.670288f, 842.280273f, 43.333591f},
140 {1877.338867f, 834.615356f, 38.762287f},
141 {1872.161011f, 823.854309f, 38.645401f},
142 {1864.860474f, 815.787170f, 38.784843f},
143 {1858.953735f, 810.048950f, 44.008759f},
144 {1843.707153f, 805.807739f, 44.135197f}
145 //{1825.736084f, 807.305847f, 44.363785f}
146};
147
149{
150 {1929.392212f, 837.614990f, 47.136166f},
151 {1928.290649f, 824.750427f, 45.474411f},
152 {1915.544922f, 826.919373f, 38.642811f},
153 {1900.933960f, 818.855652f, 38.801647f},
154 {1886.810547f, 813.536621f, 38.490490f},
155 {1869.079712f, 808.701538f, 38.689003f},
156 {1860.843384f, 806.645020f, 44.008789f},
157 {1843.707153f, 805.807739f, 44.135197f}
158 //{1825.736084f, 807.305847f, 44.363785f}
159};
160
161float ThirdPortalWPs [8][3] =
162{
163 {1934.049438f, 815.778503f, 52.408699f},
164 {1928.290649f, 824.750427f, 45.474411f},
165 {1915.544922f, 826.919373f, 38.642811f},
166 {1900.933960f, 818.855652f, 38.801647f},
167 {1886.810547f, 813.536621f, 38.490490f},
168 {1869.079712f, 808.701538f, 38.689003f},
169 {1860.843384f, 806.645020f, 44.008789f},
170 {1843.707153f, 805.807739f, 44.135197f}
171 //{1825.736084f, 807.305847f, 44.363785f}
172};
173
174float FourthPortalWPs [9][3] =
175{
176 {1921.658447f, 761.657043f, 50.866741f},
177 {1910.559814f, 755.780457f, 47.701447f},
178 {1896.664673f, 752.920898f, 47.667004f},
179 {1887.398804f, 763.633240f, 47.666851f},
180 {1879.020386f, 775.396973f, 38.705990f},
181 {1872.439087f, 782.568604f, 38.808292f},
182 {1863.573364f, 791.173584f, 38.743660f},
183 {1857.811890f, 796.765564f, 43.950329f},
184 {1845.577759f, 800.681152f, 44.104248f}
185 //{1827.100342f, 801.605957f, 44.363358f}
186};
187
188float FifthPortalWPs [6][3] =
189{
190 {1887.398804f, 763.633240f, 47.666851f},
191 {1879.020386f, 775.396973f, 38.705990f},
192 {1872.439087f, 782.568604f, 38.808292f},
193 {1863.573364f, 791.173584f, 38.743660f},
194 {1857.811890f, 796.765564f, 43.950329f},
195 {1845.577759f, 800.681152f, 44.104248f}
196 //{1827.100342f, 801.605957f, 44.363358f}
197};
198
199float SixthPoralWPs [4][3] =
200{
201 {1888.861084f, 805.074768f, 38.375790f},
202 {1869.793823f, 804.135804f, 38.647018f},
203 {1861.541504f, 804.149780f, 43.968292f},
204 {1843.567017f, 804.288208f, 44.139091f}
205 //{1826.889648f, 803.929993f, 44.363239f}
206};
207
208const float SaboteurFinalPos1[3][3] =
209{
210 {1892.502319f, 777.410767f, 38.630402f},
211 {1891.165161f, 762.969421f, 47.666920f},
212 {1893.168091f, 740.919189f, 47.666920f}
213};
214const float SaboteurFinalPos2[3][3] =
215{
216 {1882.242676f, 834.818726f, 38.646786f},
217 {1879.220825f, 842.224854f, 43.333641f},
218 {1873.842896f, 863.892456f, 43.333641f}
219};
220const float SaboteurFinalPos3[2][3] =
221{
222 {1904.298340f, 792.400391f, 38.646782f},
223 {1935.716919f, 758.437073f, 30.627895f}
224};
225const float SaboteurFinalPos4[3] =
226{
227 1855.006104f, 760.641724f, 38.655266f
228};
229const float SaboteurFinalPos5[3] =
230{
231 1906.667358f, 841.705566f, 38.637894f
232};
233const float SaboteurFinalPos6[5][3] =
234{
235 {1911.437012f, 821.289246f, 38.684128f},
236 {1920.734009f, 822.978027f, 41.525414f},
237 {1928.262939f, 830.836609f, 44.668266f},
238 {1929.338989f, 837.593933f, 47.137596f},
239 {1931.063354f, 848.468445f, 47.190434f}
240 };
241
242const Position MovePosition = {1806.955566f, 803.851807f, 44.363323f, 0.0f};
243const Position playerTeleportPosition = {1830.531006f, 803.939758f, 44.340508f, 6.281611f};
244const Position sinclariOutsidePosition = {1817.315674f, 804.060608f, 44.363998f, 0.0f};
245
247{
248public:
249 npc_sinclari_vh() : CreatureScript("npc_sinclari_vh") { }
250
251 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
252 {
253 player->PlayerTalkClass->ClearMenus();
254 switch (action)
255 {
257 player->CLOSE_GOSSIP_MENU();
258 CAST_AI(npc_sinclari_vh::npc_sinclariAI, (creature->AI()))->uiPhase = 1;
259 if (InstanceScript* instance = creature->GetInstanceScript())
260 instance->SetData(DATA_MAIN_EVENT_PHASE, SPECIAL);
261 break;
263 player->SEND_GOSSIP_MENU(13854, creature->GetGUID());
264 break;
266 player->NearTeleportTo(playerTeleportPosition.GetPositionX(), playerTeleportPosition.GetPositionY(), playerTeleportPosition.GetPositionZ(), playerTeleportPosition.GetOrientation(), true);
267 player->CLOSE_GOSSIP_MENU();
268 break;
269 }
270 return true;
271 }
272
273 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
274 {
275 if (InstanceScript* instance = creature->GetInstanceScript())
276 {
277 switch (instance->GetData(DATA_MAIN_EVENT_PHASE))
278 {
279 case NOT_STARTED:
280 case FAIL: // Allow to start event if not started or wiped
283 player->SEND_GOSSIP_MENU(13853, creature->GetGUID());
284 break;
285 case IN_PROGRESS: // Allow to teleport inside if event is in progress
287 player->SEND_GOSSIP_MENU(13853, creature->GetGUID());
288 break;
289 default:
290 player->SEND_GOSSIP_MENU(13910, creature->GetGUID());
291 }
292 }
293 return true;
294 }
295
297 {
298 npc_sinclariAI(Creature* creature) : ScriptedAI(creature)
299 {
300 instance = creature->GetInstanceScript();
301 uiPhase = 0;
302 uiTimer = 0;
303 }
304
306 {
307 uiPhase = 0;
308 uiTimer = 0;
309
310 me->SetReactState(REACT_AGGRESSIVE);
311
312 std::list<Creature*> GuardList;
313 me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
314 if (!GuardList.empty())
315 {
316 for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
317 {
318 if (Creature* pGuard = *itr)
319 {
320 pGuard->DisappearAndDie();
321 pGuard->Respawn();
322 pGuard->SetVisible(true);
323 pGuard->SetReactState(REACT_AGGRESSIVE);
324 }
325 }
326 }
327 }
328
330 {
331 ScriptedAI::UpdateAI(uiDiff);
332
333 if (uiPhase)
334 {
335 if (uiTimer <= uiDiff)
336 {
337 switch (uiPhase)
338 {
339 case 1:
341 uiTimer = 4000;
342 uiPhase = 2;
343 break;
344 case 2:
345 {
346 std::list<Creature*> GuardList;
347 me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
348 if (!GuardList.empty())
349 for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
350 {
351 if (Creature* pGuard = *itr)
352 {
353 pGuard->SetWalk(false);
354 pGuard->GetMotionMaster()->MovePoint(0, MovePosition);
355 }
356 }
357 uiTimer = 6000;
358 uiPhase = 3;
359 break;
360 }
361 case 3:
362 {
363 std::list<Creature*> GuardList;
364 me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
365 if (!GuardList.empty())
366 for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
367 {
368 if (Creature* pGuard = *itr)
369 {
370 pGuard->SetVisible(false);
371 pGuard->SetReactState(REACT_PASSIVE);
372 }
373 }
374 uiTimer = 2000;
375 uiPhase = 4;
376 break;
377 }
378 case 4:
379 me->GetMotionMaster()->MovePoint(0, sinclariOutsidePosition);
380 uiTimer = 4000;
381 uiPhase = 5;
382 break;
383 case 5:
384 if (instance)
386 me->SetReactState(REACT_PASSIVE);
387 uiTimer = 0;
388 uiPhase = 0;
389 break;
390 }
391 }
392 else uiTimer -= uiDiff;
393 }
394
395 if (!UpdateVictim())
396 return;
397
399 }
400 public:
402 private:
405 };
406
408 {
409 return new npc_sinclariAI(creature);
410 }
411};
412
414{
415public:
416 npc_azure_saboteur() : CreatureScript("npc_azure_saboteur") { }
417
419 {
421 {
422 instance = creature->GetInstanceScript();
423 bHasGotMovingPoints = false;
424 uiBoss = 0;
425 Reset();
426 }
427
429 {
430 if (instance && !uiBoss)
431 uiBoss = instance->GetData(DATA_WAVE_COUNT) == 6 ? instance->GetData(DATA_FIRST_BOSS) : instance->GetData(DATA_SECOND_BOSS);
432 me->SetReactState(REACT_PASSIVE);
435 }
436
438 {
439 switch (uiBoss)
440 {
441 case 1:
442 if (waypointId == 2)
444 break;
445 case 2:
446 if (waypointId == 2)
448 break;
449 case 3:
450 if (waypointId == 1)
452 break;
453 case 4:
454 if (waypointId == 0)
456 break;
457 case 5:
458 if (waypointId == 0)
460 break;
461 case 6:
462 if (waypointId == 4)
464 break;
465 }
466 }
467
469 {
471 me->CastStop();
472
474
476 {
477 bHasGotMovingPoints = true;
478 switch (uiBoss)
479 {
480 case 1:
481 for (int i=0;i<3;i++)
483 me->SetHomePosition(SaboteurFinalPos1[2][0], SaboteurFinalPos1[2][1], SaboteurFinalPos1[2][2], 4.762346f);
484 break;
485 case 2:
486 for (int i=0;i<3;i++)
488 me->SetHomePosition(SaboteurFinalPos2[2][0], SaboteurFinalPos2[2][1], SaboteurFinalPos2[2][2], 1.862674f);
489 break;
490 case 3:
491 for (int i=0;i<2;i++)
493 me->SetHomePosition(SaboteurFinalPos3[1][0], SaboteurFinalPos3[1][1], SaboteurFinalPos3[1][2], 5.500638f);
494 break;
495 case 4:
497 me->SetHomePosition(SaboteurFinalPos4[0], SaboteurFinalPos4[1], SaboteurFinalPos4[2], 3.991108f);
498 break;
499 case 5:
501 me->SetHomePosition(SaboteurFinalPos5[0], SaboteurFinalPos5[1], SaboteurFinalPos5[2], 1.100841f);
502 break;
503 case 6:
504 for (int i=0;i<5;i++)
506 me->SetHomePosition(SaboteurFinalPos6[4][0], SaboteurFinalPos6[4][1], SaboteurFinalPos6[4][2], 0.983031f);
507 break;
508 }
509
510 SetDespawnAtEnd(false);
511 Start(true, true);
512 }
513 }
514
516 {
517 me->CastSpell(me, SABOTEUR_SHIELD_DISRUPTION, false);
518 me->DisappearAndDie();
519 Creature* pSaboPort = Unit::GetCreature((*me), instance->GetData64(DATA_SABOTEUR_PORTAL));
520 if (pSaboPort)
521 pSaboPort->DisappearAndDie();
523 }
524 private:
528 };
529
531 {
532 return new npc_azure_saboteurAI(creature);
533 }
534};
535
537{
538public:
539 npc_teleportation_portal_vh() : CreatureScript("npc_teleportation_portal_vh") { }
540
542 {
544 {
545 instance = creature->GetInstanceScript();
546 uiTypeOfMobsPortal = std::rand() % 1; // 0 - elite mobs 1 - portal guardian or portal keeper with regular mobs
548 uiSpawnTimer = 0;
549 }
550
552 {
553 uiSpawnTimer = 10000;
555 }
556
557 void EnterCombat(Unit* /*who*/) OVERRIDE { }
558
559 void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
560
561
563 {
564 if (!instance) //Massive usage of instance, global check
565 return;
566
567 if (instance->GetData(DATA_REMOVE_NPC) == 1)
568 {
569 me->DespawnOrUnsummon();
570 instance->SetData(DATA_REMOVE_NPC, 0);
571 }
572
573 uint8 uiWaveCount = instance->GetData(DATA_WAVE_COUNT);
574 if ((uiWaveCount == 6) || (uiWaveCount == 12)) //Don't spawn mobs on boss encounters
575 return;
576
577 switch (uiTypeOfMobsPortal)
578 {
579 // spawn elite mobs and then set portals visibility to make it look like it dissapeard
580 case 0:
582 {
583 if (uiSpawnTimer <= diff)
584 {
586 uint8 k = uiWaveCount < 12 ? 2 : 3;
587 for (uint8 i = 0; i < k; ++i)
588 {
591 }
592 me->SetVisible(false);
593 } else uiSpawnTimer -= diff;
594 }
595 else
596 {
597 // if all spawned elites have died kill portal
598 if (listOfMobs.empty())
599 {
600 me->Kill(me, false);
601 me->RemoveCorpse();
602 }
603 }
604 break;
605 // spawn portal guardian or portal keeper with regular mobs
606 case 1:
607 if (uiSpawnTimer <= diff)
608 {
610 {
611 uint8 k = instance->GetData(DATA_WAVE_COUNT) < 12 ? 3 : 4;
612 for (uint8 i = 0; i < k; ++i)
613 {
616 }
617 }
618 else
619 {
622 if (Creature* pPortalKeeper = DoSummon(entry, me, 2.0f, 0, TempSummonType::TEMPSUMMON_DEAD_DESPAWN))
623 me->CastSpell(pPortalKeeper, SPELL_PORTAL_CHANNEL, false);
624 }
626 } else uiSpawnTimer -= diff;
627
628 if (bPortalGuardianOrKeeperOrEliteSpawn && !me->IsNonMeleeSpellCasted(false))
629 {
630 me->Kill(me, false);
631 me->RemoveCorpse();
632 }
633 break;
634 }
635 }
636
637 void JustDied(Unit* /*killer*/) OVERRIDE
638 {
639 if (instance)
640 instance->SetData(DATA_WAVE_COUNT, instance->GetData(DATA_WAVE_COUNT)+1);
641 }
642
644 {
645 listOfMobs.Summon(summoned);
646 if (instance)
647 instance->SetData64(DATA_ADD_TRASH_MOB, summoned->GetGUID());
648 }
649
650 void SummonedCreatureDies(Creature* summoned, Unit* /*killer*/) OVERRIDE
651 {
652 listOfMobs.Despawn(summoned);
653 if (instance)
654 instance->SetData64(DATA_DEL_TRASH_MOB, summoned->GetGUID());
655 }
656 private:
661
663 };
664
666 {
667 return new npc_teleportation_portalAI(creature);
668 }
669};
670
672{
674 {
675 instance = creature->GetInstanceScript();
676 bHasGotMovingPoints = false;
678 if (instance)
681 Reset();
682 }
683
685 {
686 switch (portalLocationID)
687 {
688 case 0:
689 if (waypointId == 5)
691 break;
692 case 1:
693 if ((waypointId == 8 && secondPortalRouteID == 0) || (waypointId == 7 && secondPortalRouteID == 1))
695 break;
696 case 2:
697 if (waypointId == 7)
699 break;
700 case 3:
701 if (waypointId == 8)
703 break;
704 case 4:
705 if (waypointId == 5)
707 break;
708 case 5:
709 if (waypointId == 3)
711 break;
712 }
713 }
714
716 {
718 me->CastStop();
719
721 {
722 bHasGotMovingPoints = true;
723 switch (portalLocationID)
724 {
725 case 0:
726 for (int i=0;i<6;i++)
727 AddWaypoint(i, FirstPortalWPs[i][0] + (std::rand() % 1 + -1), FirstPortalWPs[i][1] + (std::rand() % 1 + -1), FirstPortalWPs[i][2] + (std::rand() % 1 + -1), 0);
728 me->SetHomePosition(FirstPortalWPs[5][0], FirstPortalWPs[5][1], FirstPortalWPs[5][2], 3.149439f);
729 break;
730 case 1:
731 secondPortalRouteID = std::rand() % 1;
732 switch (secondPortalRouteID)
733 {
734 case 0:
735 for (int i=0;i<9;i++)
736 AddWaypoint(i, SecondPortalFirstWPs[i][0] + (std::rand() % 1 + -1), SecondPortalFirstWPs[i][1] + (std::rand() % 1 + -1), SecondPortalFirstWPs[i][2], 0);
737 me->SetHomePosition(SecondPortalFirstWPs[8][0] + (std::rand() % 1 + -1), SecondPortalFirstWPs[8][1] + (std::rand() % 1 + -1), SecondPortalFirstWPs[8][2] + (std::rand() % 1 + -1), 3.149439f);
738 break;
739 case 1:
740 for (int i=0;i<8;i++)
741 AddWaypoint(i, SecondPortalSecondWPs[i][0] + (std::rand() % 1 + -1), SecondPortalSecondWPs[i][1] + (std::rand() % 1 + -1), SecondPortalSecondWPs[i][2], 0);
742 me->SetHomePosition(SecondPortalSecondWPs[7][0], SecondPortalSecondWPs[7][1], SecondPortalSecondWPs[7][2], 3.149439f);
743 break;
744 }
745 break;
746 case 2:
747 for (int i=0;i<8;i++)
748 AddWaypoint(i, ThirdPortalWPs[i][0] + (std::rand() % 1 + -1), ThirdPortalWPs[i][1] + (std::rand() % 1 + -1), ThirdPortalWPs[i][2], 0);
749 me->SetHomePosition(ThirdPortalWPs[7][0], ThirdPortalWPs[7][1], ThirdPortalWPs[7][2], 3.149439f);
750 break;
751 case 3:
752 for (int i=0;i<9;i++)
753 AddWaypoint(i, FourthPortalWPs[i][0] + (std::rand() % 1 + -1), FourthPortalWPs[i][1] + (std::rand() % 1 + -1), FourthPortalWPs[i][2], 0);
754 me->SetHomePosition(FourthPortalWPs[8][0], FourthPortalWPs[8][1], FourthPortalWPs[8][2], 3.149439f);
755 break;
756 case 4:
757 for (int i=0;i<6;i++)
758 AddWaypoint(i, FifthPortalWPs[i][0] + (std::rand() % 1 + -1), FifthPortalWPs[i][1] + (std::rand() % 1 + -1), FifthPortalWPs[i][2], 0);
759 me->SetHomePosition(FifthPortalWPs[5][0], FifthPortalWPs[5][1], FifthPortalWPs[5][2], 3.149439f);
760 break;
761 case 5:
762 for (int i=0;i<4;i++)
763 AddWaypoint(i, SixthPoralWPs[i][0] + (std::rand() % 1 + -1), SixthPoralWPs[i][1] + (std::rand() % 1 + -1), SixthPoralWPs[i][2], 0);
764 me->SetHomePosition(SixthPoralWPs[3][0], SixthPoralWPs[3][1], SixthPoralWPs[3][2], 3.149439f);
765 break;
766 }
767 SetDespawnAtEnd(false);
768 Start(true, true);
769 }
770 }
771
772 void JustDied(Unit* /*killer*/) OVERRIDE
773 {
774 if (instance)
776 }
777
779 {
780 me->SetReactState(REACT_PASSIVE);
782 if (instance)
784 }
785public:
787private:
791};
792
794{
795public:
796 npc_azure_invader() : CreatureScript("npc_azure_invader") { }
797
799 {
801 {
802 instance = creature->GetInstanceScript();
803 uiCleaveTimer = 0;
804 uiImpaleTimer = 0;
807 }
808
810 {
811 uiCleaveTimer = 5000;
812 uiImpaleTimer = 4000;
813 uiBrutalStrikeTimer = 5000;
814 uiSunderArmorTimer = 4000;
815 }
816
818 {
821
822 if (!UpdateVictim())
823 return;
824
825 if (me->GetEntry() == CREATURE_AZURE_INVADER_1)
826 {
827 if (uiCleaveTimer <= diff)
828 {
830 uiCleaveTimer = 5000;
831 } else uiCleaveTimer -= diff;
832
833 if (uiImpaleTimer <= diff)
834 {
835 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
836 if (target)
837 DoCast(target, SPELL_IMPALE);
838 uiImpaleTimer = 4000;
839 } else uiImpaleTimer -= diff;
840 }
841
842 if (me->GetEntry() == CREATURE_AZURE_INVADER_2)
843 {
844 if (uiBrutalStrikeTimer <= diff)
845 {
847 uiBrutalStrikeTimer = 5000;
848 } else uiBrutalStrikeTimer -= diff;
849
850 if (uiSunderArmorTimer <= diff)
851 {
853 uiSunderArmorTimer = std::rand() % 10000 + 8000;
854 } else uiSunderArmorTimer -= diff;
855
857 }
858
860 }
861 private:
866 };
867
869 {
870 return new npc_azure_invaderAI(creature);
871 }
872};
873
875{
876public:
877 npc_azure_binder() : CreatureScript("npc_azure_binder") { }
878
880 {
882 {
883 instance = creature->GetInstanceScript();
888 }
889
891 {
894 uiFrostNovaTimer = 5000;
895 uiFrostboltTimer = 4000;
896 }
897
899 {
902
903 if (!UpdateVictim())
904 return;
905
906 if (me->GetEntry() == CREATURE_AZURE_BINDER_1)
907 {
908 if (uiArcaneExplosionTimer <= diff)
909 {
912 } else uiArcaneExplosionTimer -= diff;
913
914 if (uiArcainBarrageTimer <= diff)
915 {
916 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
917 if (target)
920 } else uiArcainBarrageTimer -= diff;
921 }
922
923 if (me->GetEntry() == CREATURE_AZURE_BINDER_2)
924 {
925 if (uiFrostNovaTimer <= diff)
926 {
928 uiFrostNovaTimer = 5000;
929 } else uiFrostNovaTimer -= diff;
930
931 if (uiFrostboltTimer <= diff)
932 {
933 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
934 if (target)
936 uiFrostboltTimer = 6000;
937 } else uiFrostboltTimer -= diff;
938 }
939
941 }
942 private:
947 };
948
950 {
951 return new npc_azure_binderAI(creature);
952 }
953};
954
956{
957public:
958 npc_azure_mage_slayer() : CreatureScript("npc_azure_mage_slayer") { }
959
961 {
963 {
964 instance = creature->GetInstanceScript();
967 }
968
970 {
972 uiSpellLockTimer = 5000;
973 }
974
976 {
979
980 if (!UpdateVictim())
981 return;
982
983 if (me->GetEntry() == CREATURE_AZURE_MAGE_SLAYER_1)
984 {
985 if (uiArcaneEmpowermentTimer <= diff)
986 {
989 } else uiArcaneEmpowermentTimer -= diff;
990 }
991
992 if (me->GetEntry() == CREATURE_AZURE_MAGE_SLAYER_2)
993 {
994 if (uiSpellLockTimer <= diff)
995 {
996 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
997 if (target)
998 DoCast(target, SPELL_SPELL_LOCK);
999 uiSpellLockTimer = 9000;
1000 } else uiSpellLockTimer -= diff;
1001 }
1002
1004 }
1005 private:
1008 };
1009
1011 {
1012 return new npc_azure_mage_slayerAI(creature);
1013 }
1014};
1015
1017{
1018public:
1019 npc_azure_raider() : CreatureScript("npc_azure_raider") { }
1020
1022 {
1024 {
1025 instance = creature->GetInstanceScript();
1028 }
1029
1031 {
1032 uiConcussionBlowTimer = 5000;
1034 }
1035
1037 {
1040
1041 if (!UpdateVictim())
1042 return;
1043
1044 if (uiConcussionBlowTimer <= diff)
1045 {
1047 uiConcussionBlowTimer = 5000;
1048 } else uiConcussionBlowTimer -= diff;
1049
1050 if (uiMagicReflectionTimer <= diff)
1051 {
1053 uiMagicReflectionTimer = std::rand() % 15000 + 10000;
1054 } else uiMagicReflectionTimer -= diff;
1055
1057 }
1058 private:
1061 };
1062
1064 {
1065 return new npc_azure_raiderAI(creature);
1066 }
1067};
1068
1070{
1071public:
1072 npc_azure_stalker() : CreatureScript("npc_azure_stalker") { }
1073
1075 {
1077 {
1078 instance = creature->GetInstanceScript();
1079 _backstabTimer = 0;
1081 _tacticalBlinkCast = false;
1082 }
1083
1085 {
1086 _backstabTimer = 1300;
1087 _tacticalBlinkTimer = 8000;
1088 _tacticalBlinkCast =false;
1089 }
1090
1092 {
1095
1096 if (!UpdateVictim())
1097 return;
1098
1099 if (!_tacticalBlinkCast)
1100 {
1101 if (_tacticalBlinkTimer <= diff)
1102 {
1103 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true);
1104 if (target)
1106 _tacticalBlinkTimer = 6000;
1107 _tacticalBlinkCast = true;
1108 } else _tacticalBlinkTimer -= diff;
1109 }
1110 else
1111 {
1112 if (_backstabTimer <= diff)
1113 {
1114 Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 10, true);
1115 DoCast(target, SPELL_BACKSTAB);
1116 _tacticalBlinkCast = false;
1117 _backstabTimer =1300;
1118 } else _backstabTimer -= diff;
1119 }
1120
1122 }
1123 private:
1127 };
1128
1130 {
1131 return new npc_azure_stalkerAI(creature);
1132 }
1133};
1134
1136{
1137public:
1138 npc_azure_spellbreaker() : CreatureScript("npc_azure_spellbreaker") { }
1139
1141 {
1143 {
1144 instance = creature->GetInstanceScript();
1146 uiSlowTimer = 0;
1149 }
1150
1152 {
1153 uiArcaneBlastTimer = 5000;
1154 uiSlowTimer = 4000;
1155 uiChainsOfIceTimer = 5000;
1156 uiConeOfColdTimer = 4000;
1157 }
1158
1160 {
1163
1164 if (!UpdateVictim())
1165 return;
1166
1167 if (me->GetEntry() == CREATURE_AZURE_SPELLBREAKER_1)
1168 {
1169 if (uiArcaneBlastTimer <= diff)
1170 {
1171 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
1172 if (target)
1174 uiArcaneBlastTimer = 6000;
1175 } else uiArcaneBlastTimer -= diff;
1176
1177 if (uiSlowTimer <= diff)
1178 {
1179 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
1180 if (target)
1181 DoCast(target, SPELL_SLOW);
1182 uiSlowTimer = 5000;
1183 } else uiSlowTimer -= diff;
1184 }
1185
1186 if (me->GetEntry() == CREATURE_AZURE_SPELLBREAKER_2)
1187 {
1188 if (uiChainsOfIceTimer <= diff)
1189 {
1190 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
1191 if (target)
1192 DoCast(target, SPELL_CHAINS_OF_ICE);
1193 uiChainsOfIceTimer = 7000;
1194 } else uiChainsOfIceTimer -= diff;
1195
1196 if (uiConeOfColdTimer <= diff)
1197 {
1199 uiConeOfColdTimer = 5000;
1200 } else uiConeOfColdTimer -= diff;
1201 }
1202
1204 }
1205 private:
1210 };
1211
1213 {
1214 return new npc_azure_spellbreakerAI(creature);
1215 }
1216};
1217
1219{
1220public:
1221 npc_azure_captain() : CreatureScript("npc_azure_captain") { }
1222
1224 {
1226 {
1227 instance = creature->GetInstanceScript();
1229 uiWhirlwindTimer = 0;
1230 }
1231
1233 {
1234 uiMortalStrikeTimer = 5000;
1235 uiWhirlwindTimer = 8000;
1236 }
1237
1239 {
1242
1243 if (!UpdateVictim())
1244 return;
1245
1246 if (uiMortalStrikeTimer <= diff)
1247 {
1249 uiMortalStrikeTimer = 5000;
1250 } else uiMortalStrikeTimer -= diff;
1251
1252 if (uiWhirlwindTimer <= diff)
1253 {
1255 uiWhirlwindTimer = 8000;
1256 } else uiWhirlwindTimer -= diff;
1257
1259 }
1260 private:
1263 };
1264
1266 {
1267 return new npc_azure_captainAI(creature);
1268 }
1269};
1270
1272{
1273public:
1274 npc_azure_sorceror() : CreatureScript("npc_azure_sorceror") { }
1275
1277 {
1285
1292
1294 {
1297
1298 if (!UpdateVictim())
1299 return;
1300
1301 if (uiArcaneStreamTimer <= diff)
1302 {
1303 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
1304 if (target)
1306 uiArcaneStreamTimer = (std::rand() % 5000)+5000;
1308 } else uiArcaneStreamTimer -= diff;
1309
1311 {
1313 uiManaDetonationTimer = std::rand() % 6000 + 2000;
1314 } else uiManaDetonationTimer -= diff;
1315
1317 }
1318 private:
1322 };
1323
1325 {
1326 return new npc_azure_sorcerorAI(creature);
1327 }
1328};
1329
1330
1332{
1333public:
1334 npc_violet_hold_arcane_sphere() : CreatureScript("npc_violet_hold_arcane_sphere") { }
1335
1337 {
1339 {
1340 DespawnTimer = 0;
1341 }
1342
1344 {
1345 DespawnTimer = 3000;
1346
1347 me->SetDisableGravity(true);
1349 }
1350
1351 void EnterCombat(Unit * /*who*/) OVERRIDE { }
1352
1354 {
1355 if (DespawnTimer <= diff)
1356 me->Kill(me);
1357 else
1358 DespawnTimer -= diff;
1359 }
1360 private:
1362 };
1363
1365 {
1366 return new npc_violet_hold_arcane_sphereAI(creature);
1367 }
1368};
1369
1371{
1372public:
1373 go_activation_crystal() : GameObjectScript("go_activation_crystal") { }
1374
1375 bool OnGossipHello(Player * /*player*/, GameObject* go) OVERRIDE
1376 {
1377 go->EventInform(EVENT_ACTIVATE_CRYSTAL);
1378 return false;
1379 }
1380};
1381
1383{
1384 new npc_sinclari_vh();
1386 new npc_azure_invader();
1388 new npc_azure_binder();
1390 new npc_azure_captain();
1391 new npc_azure_sorceror();
1392 new npc_azure_raider();
1393 new npc_azure_stalker();
1394 new npc_azure_saboteur();
1397}
const T & RAND(const T &v1, const T &v2)
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ IN_PROGRESS
@ FAIL
@ SPECIAL
@ NOT_STARTED
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:74
#define CAST_AI(a, b)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ 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
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ SELECT_TARGET_NEAREST
Definition UnitAI.h:26
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ SPELL_CLEAVE
@ SPELL_FROST_NOVA
@ SPELL_FROSTBOLT
@ SPELL_ARCANE_EXPLOSION
@ SPELL_CONE_OF_COLD
@ H_SPELL_ARCANE_BLAST
@ SPELL_ARCANE_BLAST
@ SPELL_ARCANE_BARRAGE
@ SPELL_ARCANE_SPHERE_PASSIVE
@ SPELL_MORTAL_STRIKE
@ SPELL_MANA_DETONATION
@ SPELL_MAGIC_REFLECTION
@ H_SPELL_IMPALE
Creature * DoSummon(uint32 entry, Position const &pos, uint32 despawnTime=30000, TempSummonType summonType=TempSummonType::TEMPSUMMON_CORPSE_TIMED_DESPAWN)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
void DisappearAndDie()
Definition Creature.cpp:206
CreatureScript(const char *name)
GameObjectScript(const char *name)
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
Definition Unit.h:1367
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
bool OnGossipHello(Player *, GameObject *go) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
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 OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ DATA_WAVE_COUNT
@ SABOTEUR_SHIELD_EFFECT
@ SABOTEUR_SHIELD_DISRUPTION
@ SPELL_TACTICAL_BLINK
void Reset() OVERRIDE
Creature * me
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
ScriptedAI(Creature *creature)
const T & DUNGEON_MODE(const T &normal5, const T &heroic5) const
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void WaypointReached(uint32 waypointId) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
npc_escortAI(Creature *creature)
void SetDespawnAtEnd(bool despawn)
void Start(bool isActiveAttacker=true, bool run=false, uint64 playerGUID=0, Quest const *quest=NULL, bool instantRespawn=false, bool canLoopPath=false, bool resetWaypoints=true)
void AddWaypoint(uint32 id, float x, float y, float z, uint32 waitTime=0)
npc_sinclariAI(Creature *creature)
void UpdateAI(uint32 uiDiff) OVERRIDE
== Triggered Actions Requested ==================
void SummonedCreatureDies(Creature *summoned, Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JustDied(Unit *) OVERRIDE
InstanceScript * instance
void WaypointReached(uint32 waypointId) OVERRIDE
violet_hold_trashAI(Creature *creature)
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
const float SaboteurFinalPos3[2][3]
float FourthPortalWPs[9][3]
void AddSC_violet_hold()
const Position playerTeleportPosition
float ThirdPortalWPs[8][3]
AzureSorcerorSpells
@ SPELL_ARCANE_STREAM
@ H_SPELL_MANA_DETONATION
@ H_SPELL_ARCANE_STREAM
@ SPELL_MANA_DETONATION
float FifthPortalWPs[6][3]
AzureSellbreakerSpells
@ H_SPELL_ARCANE_BLAST
@ SPELL_SLOW
@ SPELL_CONE_OF_COLD
@ H_SPELL_CONE_OF_COLD
@ SPELL_CHAINS_OF_ICE
@ SPELL_ARCANE_BLAST
Sinclari
@ SAY_SINCLARI_1
float SecondPortalFirstWPs[9][3]
AzureRaiderSpells
@ SPELL_CONCUSSION_BLOW
@ SPELL_MAGIC_REFLECTION
const Position sinclariOutsidePosition
#define GOSSIP_ITEM_1
@ SPELL_ARCANE_SPHERE_PASSIVE
@ SPELL_PORTAL_CHANNEL
@ SPELL_CRYSTAL_ACTIVATION
float SixthPoralWPs[4][3]
const float SaboteurFinalPos2[3][3]
@ SABOTEUR_SHIELD_DISRUPTION
AzureStalkerSpells
@ SPELL_BACKSTAB
@ SPELL_TACTICAL_BLINK
TrashDoorSpell
@ SPELL_DESTROY_DOOR_SEAL
#define GOSSIP_START_EVENT
const float SaboteurFinalPos1[3][3]
#define SPAWN_TIME
AzureMageSlayerSpells
@ SPELL_SPELL_LOCK
@ SPELL_ARCANE_EMPOWERMENT
AzureBinderSpells
@ SPELL_FROSTBOLT
@ SPELL_ARCANE_BARRAGE
@ H_SPELL_ARCANE_BARRAGE
@ H_SPELL_FROSTBOLT
@ SPELL_ARCANE_EXPLOSION
@ H_SPELL_ARCANE_EXPLOSION
@ SPELL_FROST_NOVA
@ H_SPELL_FROST_NOVA
float SecondPortalSecondWPs[8][3]
const float SaboteurFinalPos4[3]
const float SaboteurFinalPos5[3]
AzureInvaderSpells
@ SPELL_CLEAVE
@ SPELL_SUNDER_ARMOR
@ SPELL_BRUTAL_STRIKE
@ SPELL_IMPALE
const Position MovePosition
PortalCreatures
@ CREATURE_AZURE_MAGE_SLAYER_1
@ CREATURE_AZURE_SORCEROR
@ CREATURE_AZURE_INVADER_2
@ CREATURE_AZURE_STALKER
@ CREATURE_AZURE_MAGE_SLAYER_2
@ CREATURE_AZURE_BINDER_2
@ CREATURE_AZURE_SPELLBREAKER_2
@ CREATURE_AZURE_INVADER_1
@ CREATURE_AZURE_BINDER_1
@ CREATURE_AZURE_RAIDER
@ CREATURE_AZURE_SPELLBREAKER_1
@ CREATURE_AZURE_CAPTAIN
const float SaboteurFinalPos6[5][3]
AzureCaptainSpells
@ SPELL_MORTAL_STRIKE
@ SPELL_WHIRLWIND_OF_STEEL
#define GOSSIP_I_WANT_IN
float FirstPortalWPs[6][3]
@ NPC_VIOLET_HOLD_GUARD
Definition violet_hold.h:83
@ CREATURE_PORTAL_KEEPER
Definition violet_hold.h:72
@ CREATURE_PORTAL_GUARDIAN
Definition violet_hold.h:71
@ DATA_ADD_TRASH_MOB
Definition violet_hold.h:52
@ DATA_DEL_TRASH_MOB
Definition violet_hold.h:53
@ DATA_SABOTEUR_PORTAL
Definition violet_hold.h:51
@ DATA_SECOND_BOSS
Definition violet_hold.h:23
@ DATA_NPC_PRESENCE_AT_DOOR_ADD
Definition violet_hold.h:19
@ DATA_FIRST_BOSS
Definition violet_hold.h:22
@ DATA_PORTAL_LOCATION
Definition violet_hold.h:16
@ DATA_REMOVE_NPC
Definition violet_hold.h:15
@ DATA_START_BOSS_ENCOUNTER
Definition violet_hold.h:21
@ DATA_MAIN_EVENT_PHASE
Definition violet_hold.h:25
@ DATA_NPC_PRESENCE_AT_DOOR_REMOVE
Definition violet_hold.h:20
@ EVENT_ACTIVATE_CRYSTAL
Definition violet_hold.h:96
Position const MovePosition