Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
zone_blades_edge_mountains.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: Blades_Edge_Mountains
8SD%Complete: 90
9SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10821, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete)
10SDCategory: Blade's Edge Mountains
11EndScriptData */
12
13/* ContentData
14npc_bladespire_ogre
15npc_nether_drake
16npc_daranelle
17npc_overseer_nuaar
18npc_saikkal_the_elder
19go_legion_obelisk
20go_thunderspike
21EndContentData */
22
23#include "ScriptMgr.h"
24#include "ScriptedCreature.h"
25#include "ScriptedGossip.h"
26#include "GridNotifiers.h"
27#include "GridNotifiersImpl.h"
28#include "Cell.h"
29#include "CellImpl.h"
30
31//Support for quest: You're Fired! (10821)
33
34#define LEGION_OBELISK_ONE 185193
35#define LEGION_OBELISK_TWO 185195
36#define LEGION_OBELISK_THREE 185196
37#define LEGION_OBELISK_FOUR 185197
38#define LEGION_OBELISK_FIVE 185198
39
40/*######
41## npc_bladespire_ogre
42######*/
43
46{
47public:
48 npc_bladespire_ogre() : CreatureScript("npc_bladespire_ogre") { }
49
51 {
52 return new npc_bladespire_ogreAI(creature);
53 }
54
56 {
57 npc_bladespire_ogreAI(Creature* creature) : ScriptedAI(creature) { }
58
59 void Reset() OVERRIDE { }
60
61 void UpdateAI(uint32 /*uiDiff*/) OVERRIDE
62 {
63 if (!UpdateVictim())
64 return;
65
67 }
68 };
69};
70
71/*######
72## npc_nether_drake
73######*/
74
76{
77 //Used by 20021, 21817, 21820, 21821, 21823 but not existing in database
83
84 ENTRY_WHELP = 20021,
85 ENTRY_PROTO = 21821,
86 ENTRY_ADOLE = 21817,
87 ENTRY_MATUR = 21820,
88 ENTRY_NIHIL = 21823,
89
91
95};
96
98{
99public:
100 npc_nether_drake() : CreatureScript("npc_nether_drake") { }
101
103 {
104 return new npc_nether_drakeAI(creature);
105 }
106
108 {
109 npc_nether_drakeAI(Creature* creature) : ScriptedAI(creature) { }
110
114
118
120 {
121 IsNihil = false;
122 NihilSpeech_Timer = 3000;
124
125 ArcaneBlast_Timer = 7500;
126 ManaBurn_Timer = 10000;
128 }
129
130 void EnterCombat(Unit* /*who*/) OVERRIDE { }
131
133
134 {
136 return;
137
139 }
140
141 //in case Creature was not summoned (not expected)
143 {
144 if (type != POINT_MOTION_TYPE)
145 return;
146
147 if (id == 0)
148 {
149 me->setDeathState(DeathState::JUST_DIED);
150 me->RemoveCorpse();
151 me->SetHealth(0);
152 }
153 }
154
155 void SpellHit(Unit* caster, const SpellInfo* spell) OVERRIDE
156 {
157 if (spell->Id == SPELL_T_PHASE_MODULATOR && caster->GetTypeId() == TypeID::TYPEID_PLAYER)
158 {
159 const uint32 entry_list[4] = {ENTRY_PROTO, ENTRY_ADOLE, ENTRY_MATUR, ENTRY_NIHIL};
160 int cid = rand()%(4-1);
161
162 if (entry_list[cid] == me->GetEntry())
163 ++cid;
164
165 //we are nihil, so say before transform
166 if (me->GetEntry() == ENTRY_NIHIL)
167 {
170 IsNihil = false;
171 }
172
173 if (me->UpdateEntry(entry_list[cid]))
174 {
175 if (entry_list[cid] == ENTRY_NIHIL)
176 {
179 IsNihil = true;
180 }else
181 AttackStart(caster);
182 }
183 }
184 }
185
187 {
188 if (IsNihil)
189 {
190 if (NihilSpeech_Timer <= diff)
191 {
192 switch (NihilSpeech_Phase)
193 {
194 case 0:
197 break;
198 case 1:
201 break;
202 case 2:
205 break;
206 case 3:
209 break;
210 case 4:
212 //take off to location above
213 me->GetMotionMaster()->MovePoint(0, me->GetPositionX()+50.0f, me->GetPositionY(), me->GetPositionZ()+50.0f);
215 break;
216 }
217 NihilSpeech_Timer = 5000;
218 } else NihilSpeech_Timer -=diff;
219
220 //anything below here is not interesting for Nihil, so skip it
221 return;
222 }
223
224 if (!UpdateVictim())
225 return;
226
227 if (IntangiblePresence_Timer <= diff)
228 {
230 IntangiblePresence_Timer = 15000+rand()%15000;
231 } else IntangiblePresence_Timer -= diff;
232
233 if (ManaBurn_Timer <= diff)
234 {
235 Unit* target = me->GetVictim();
236 if (target && target->getPowerType() == POWER_MANA)
237 DoCast(target, SPELL_MANA_BURN);
238 ManaBurn_Timer = 8000+rand()%8000;
239 } else ManaBurn_Timer -= diff;
240
241 if (ArcaneBlast_Timer <= diff)
242 {
244 ArcaneBlast_Timer = 2500+rand()%5000;
245 } else ArcaneBlast_Timer -= diff;
246
248 }
249 };
250};
251
252/*######
253## npc_daranelle
254######*/
255
261
263{
264public:
265 npc_daranelle() : CreatureScript("npc_daranelle") { }
266
268 {
269 return new npc_daranelleAI(creature);
270 }
271
273 {
274 npc_daranelleAI(Creature* creature) : ScriptedAI(creature) { }
275
276 void Reset() OVERRIDE { }
277
278 void EnterCombat(Unit* /*who*/) OVERRIDE { }
279
281
282 {
283 if (who->GetTypeId() == TypeID::TYPEID_PLAYER)
284 {
285 if (who->HasAura(SPELL_LASHHAN_CHANNEL) && me->IsWithinDistInMap(who, 10.0f))
286 {
289 DoCast(who, 37028, true);
290 }
291 }
292
294 }
295 };
296};
297
298/*######
299## npc_overseer_nuaar
300######*/
301
302#define GOSSIP_HELLO_ON "Overseer, I am here to negotiate on behalf of the Cenarion Expedition."
303
305{
306public:
307 npc_overseer_nuaar() : CreatureScript("npc_overseer_nuaar") { }
308
309 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
310 {
311 player->PlayerTalkClass->ClearMenus();
312 if (action == GOSSIP_ACTION_INFO_DEF+1)
313 {
314 player->SEND_GOSSIP_MENU(10533, creature->GetGUID());
315 player->AreaExploredOrEventHappens(10682);
316 }
317 return true;
318 }
319
320 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
321 {
322 if (player->GetQuestStatus(10682) == QUEST_STATUS_INCOMPLETE)
324
325 player->SEND_GOSSIP_MENU(10532, creature->GetGUID());
326
327 return true;
328 }
329};
330
331/*######
332## npc_saikkal_the_elder
333######*/
334
335#define GOSSIP_HELLO_STE "Yes... yes, it's me."
336#define GOSSIP_SELECT_STE "Yes elder. Tell me more of the book."
337
339{
340public:
341 npc_saikkal_the_elder() : CreatureScript("npc_saikkal_the_elder") { }
342
343 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
344 {
345 player->PlayerTalkClass->ClearMenus();
346 switch (action)
347 {
350 player->SEND_GOSSIP_MENU(10795, creature->GetGUID());
351 break;
353 player->TalkedToCreature(creature->GetEntry(), creature->GetGUID());
354 player->SEND_GOSSIP_MENU(10796, creature->GetGUID());
355 break;
356 }
357 return true;
358 }
359
360 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
361 {
362 if (player->GetQuestStatus(10980) == QUEST_STATUS_INCOMPLETE)
364
365 player->SEND_GOSSIP_MENU(10794, creature->GetGUID());
366
367 return true;
368 }
369};
370
371/*######
372## go_legion_obelisk
373######*/
374
376{
377public:
378 go_legion_obelisk() : GameObjectScript("go_legion_obelisk") { }
379
381 {
382 if (player->GetQuestStatus(10821) == QUEST_STATUS_INCOMPLETE)
383 {
384 switch (go->GetEntry())
385 {
387 obelisk_one = true;
388 break;
390 obelisk_two = true;
391 break;
393 obelisk_three = true;
394 break;
396 obelisk_four = true;
397 break;
399 obelisk_five = true;
400 break;
401 }
402
403 if (obelisk_one == true && obelisk_two == true && obelisk_three == true && obelisk_four == true && obelisk_five == true)
404 {
405 go->SummonCreature(19963, 2943.40f, 4778.20f, 284.49f, 0.94f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000);
406 //reset global var
407 obelisk_one = false;
408 obelisk_two = false;
409 obelisk_three = false;
410 obelisk_four = false;
411 obelisk_five = false;
412 }
413 }
414
415 return true;
416 }
417};
418
419/*######
420## npc_bloodmaul_brutebane
421######*/
422
431
433{
434public:
435 npc_bloodmaul_brutebane() : CreatureScript("npc_bloodmaul_brutebane") { }
436
438 {
439 return new npc_bloodmaul_brutebaneAI(creature);
440 }
441
443 {
445 {
446 if (Creature* Ogre = me->FindNearestCreature(NPC_OGRE_BRUTE, 50, true))
447 {
448 Ogre->SetReactState(REACT_DEFENSIVE);
449 Ogre->GetMotionMaster()->MovePoint(1, me->GetPositionX()-1, me->GetPositionY()+1, me->GetPositionZ());
450 }
451 }
452
454
456 {
457 OgreGUID = 0;
458 }
459
460 void UpdateAI(uint32 /*uiDiff*/) OVERRIDE { }
461 };
462};
463
464/*######
465## npc_ogre_brute
466######*/
467
469{
470public:
471 npc_ogre_brute() : CreatureScript("npc_ogre_brute") { }
472
474 {
475 return new npc_ogre_bruteAI(creature);
476 }
477
479 {
480 npc_ogre_bruteAI(Creature* creature) : ScriptedAI(creature) { }
481
483
485 {
486 PlayerGUID = 0;
487 }
488
490 {
491 if (!who || (!who->IsAlive()))
492 return;
493
494 if (me->IsWithinDistInMap(who, 50.0f))
495 {
496 if (who->GetTypeId() == TypeID::TYPEID_PLAYER)
497 if (who->ToPlayer()->GetQuestStatus(QUEST_GETTING_THE_BLADESPIRE_TANKED) == QUEST_STATUS_INCOMPLETE
498 || who->ToPlayer()->GetQuestStatus(QUEST_BLADESPIRE_KEGGER) == QUEST_STATUS_INCOMPLETE)
499 PlayerGUID = who->GetGUID();
500 }
501 }
502
504 {
505 if (id == 1)
506 {
507 if (GameObject* Keg = me->FindNearestGameObject(GO_KEG, 20))
508 Keg->Delete();
509
510 me->HandleEmoteCommand(7);
511 me->SetReactState(REACT_AGGRESSIVE);
512 me->GetMotionMaster()->MoveTargetedHome();
513
515 Creature* Credit = me->FindNearestCreature(NPC_QUEST_CREDIT, 50, true);
516 if (player && Credit)
517 player->KilledMonster(Credit->GetCreatureTemplate(), Credit->GetGUID());
518 }
519 }
520
521 void UpdateAI(uint32 /*diff*/) OVERRIDE
522 {
523 if (!UpdateVictim())
524 return;
526 }
527 };
528};
529
530/*######
531## go_thunderspike
532######*/
533
539
541{
542 public:
543 go_thunderspike() : GameObjectScript("go_thunderspike") { }
544
546 {
547 if (player->GetQuestStatus(QUEST_THUNDERSPIKE) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_GOR_GRIMGUT, 25.0f, true))
548 if (Creature* gorGrimgut = go->SummonCreature(NPC_GOR_GRIMGUT, -2413.4f, 6914.48f, 25.01f, 3.67f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000))
549 gorGrimgut->AI()->AttackStart(player);
550
551 return true;
552 }
553};
554
601
616
625
627{
628 public:
629 npc_simon_bunny() : CreatureScript("npc_simon_bunny") { }
630
632 {
633 npc_simon_bunnyAI(Creature* creature) : ScriptedAI(creature) { }
634
635 bool large;
646
648 {
649 _events.Update(diff);
650
651 switch (_events.ExecuteEvent())
652 {
654 if (!CheckPlayer())
655 ResetNode();
656 else
657 _events.ScheduleEvent(EVENT_SIMON_PERIODIC_PLAYER_CHECK, 2000);
658 break;
660 SetUpPreGame();
661 _events.CancelEvent(EVENT_SIMON_GAME_TICK);
662 _events.ScheduleEvent(EVENT_SIMON_PLAY_SEQUENCE, 1000);
663 break;
665 if (!playableSequence.empty())
666 {
668 _events.ScheduleEvent(EVENT_SIMON_PLAY_SEQUENCE, 1500);
669 }
670 else
671 {
672 listening = true;
674 playerSequence.clear();
676 gameTicks = 0;
677 _events.ScheduleEvent(EVENT_SIMON_GAME_TICK, 3000);
678 }
679 break;
682
683 if (gameTicks > gameLevel)
684 _events.ScheduleEvent(EVENT_SIMON_TOO_LONG_TIME, 500);
685 else
686 _events.ScheduleEvent(EVENT_SIMON_GAME_TICK, 3000);
687 gameTicks++;
688 break;
690 PrepareClusters(true);
691 break;
694 break;
697 break;
698 }
699 }
700
702 {
703 switch (action)
704 {
706 listening = false;
709 _events.CancelEventGroup(0);
710 if (gameLevel == 10)
711 ResetNode();
712 else
713 _events.ScheduleEvent(EVENT_SIMON_SETUP_PRE_GAME, 1000);
714 break;
716 gameLevel++;
718 break;
722 break;
723 }
724 }
725
726 // Called by color clusters script (go_simon_cluster) and used for knowing the button pressed by player
727 void SetData(uint32 type, uint32 /*data*/) OVERRIDE
728 {
729 if (!listening)
730 return;
731
732 uint8 pressedColor = SIMON_MAX_COLORS;
733
734 if (type == clusterIds[SIMON_RED])
735 pressedColor = SIMON_RED;
736 else if (type == clusterIds[SIMON_BLUE])
737 pressedColor = SIMON_BLUE;
738 else if (type == clusterIds[SIMON_GREEN])
739 pressedColor = SIMON_GREEN;
740 else if (type == clusterIds[SIMON_YELLOW])
741 pressedColor = SIMON_YELLOW;
742
743 PlayColor(pressedColor);
744 playerSequence.push_back(pressedColor);
745 _events.ScheduleEvent(EVENT_SIMON_RESET_CLUSTERS, 500);
747 }
748
749 // Used for getting involved player guid. Parameter id is used for defining if is a large(Monument) or small(Relic) node
751 {
752 me->SetCanFly(true);
753
754 large = (bool)id;
755 playerGUID = guid;
756 StartGame();
757 }
758
759 /*
760 Resets all variables and also find the ids of the four closests color clusters, since every simon
761 node have diferent ids for clusters this is absolutely NECESSARY.
762 */
764 {
765 listening = false;
766 gameLevel = 0;
767 fails = 0;
768 gameTicks = 0;
769 zCoordCorrection = large ? 8.0f : 2.75f;
770 searchDistance = large ? 13.0f : 5.0f;
771 colorSequence.clear();
772 playableSequence.clear();
773 playerSequence.clear();
774 me->SetObjectScale(large ? 2.0f : 1.0f);
775
776 std::list<WorldObject*> ClusterList;
779 me->VisitNearbyObject(searchDistance, searcher);
780
781 for (std::list<WorldObject*>::const_iterator i = ClusterList.begin(); i != ClusterList.end(); ++i)
782 {
783 if (GameObject* go = (*i)->ToGameObject())
784 {
785 // We are checking for displayid because all simon nodes have 4 clusters with different entries
786 if (large)
787 {
788 switch (go->GetGOInfo()->displayId)
789 {
791 clusterIds[SIMON_BLUE] = go->GetEntry();
792 break;
793
795 clusterIds[SIMON_RED] = go->GetEntry();
796 break;
797
799 clusterIds[SIMON_GREEN] = go->GetEntry();
800 break;
801
803 clusterIds[SIMON_YELLOW] = go->GetEntry();
804 break;
805 }
806 }
807 else
808 {
809 switch (go->GetGOInfo()->displayId)
810 {
812 clusterIds[SIMON_BLUE] = go->GetEntry();
813 break;
814
816 clusterIds[SIMON_RED] = go->GetEntry();
817 break;
818
820 clusterIds[SIMON_GREEN] = go->GetEntry();
821 break;
822
824 clusterIds[SIMON_YELLOW] = go->GetEntry();
825 break;
826 }
827 }
828 }
829 }
830
831 _events.Reset();
832 _events.ScheduleEvent(EVENT_SIMON_ROUND_FINISHED, 1000);
833 _events.ScheduleEvent(EVENT_SIMON_PERIODIC_PLAYER_CHECK, 2000);
834
835 if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance))
837 }
838
839 // Called when despawning the bunny. Sets all the node GOs to their default states.
841 {
843
844 for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
845 if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance))
847
848 for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++)
849 if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance))
850 auraGo->RemoveFromWorld();
851
852 if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance))
854
855 me->DespawnOrUnsummon(1000);
856 }
857
858 /*
859 Called on every button click of player. Adds the clicked color to the player created sequence and
860 checks if it corresponds to the AI created sequence. If so, incremente gameLevel and start a new
861 round, if not, give punishment and restart current level.
862 */
864 {
865 bool correct = true;
866 if (playerSequence.size() <= colorSequence.size())
867 for (std::list<uint8>::const_iterator i = playerSequence.begin(), j = colorSequence.begin(); i != playerSequence.end(); ++i, ++j)
868 if ((*i) != (*j))
869 correct = false;
870
871 if (correct && (playerSequence.size() == colorSequence.size()))
873 else if (!correct)
875 }
876
877 /*
878 Generates a random sequence of colors depending on the gameLevel. We also copy this sequence to
879 the playableSequence wich will be used when playing the sequence to the player.
880 */
882 {
883 colorSequence.clear();
884 for (uint8 i = 0; i <= gameLevel; i++)
886
887 for (std::list<uint8>::const_iterator i = colorSequence.begin(); i != colorSequence.end(); ++i)
888 playableSequence.push_back(*i);
889 }
890
891
892 // Remove any existant glowing auras over clusters and set clusters ready for interating with them.
893 void PrepareClusters(bool clustersOnly = false)
894 {
895 for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
896 if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance))
898
899 if (clustersOnly)
900 return;
901
902 for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++)
903 if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance))
904 auraGo->RemoveFromWorld();
905 }
906
907 /*
908 Called when AI is playing the sequence for player. We cast the visual spell and then remove the
909 casted color from the casting sequence.
910 */
912 {
913 PlayColor(*playableSequence.begin());
914 playableSequence.erase(playableSequence.begin());
915 }
916
917 // Casts a spell and plays a sound depending on parameter color.
918 void PlayColor(uint8 color)
919 {
920 switch (color)
921 {
922 case SIMON_BLUE:
925 break;
926 case SIMON_GREEN:
929 break;
930 case SIMON_RED:
933 break;
934 case SIMON_YELLOW:
937 break;
938 }
939 }
940
941 /*
942 Creates the transparent glowing auras on every cluster of this node.
943 After calling this function bunny is teleported to the center of the node.
944 */
946 {
947 for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
948 {
949 if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], 2.0f*searchDistance))
950 {
952
953 // break since we don't need glowing auras for large clusters
954 if (large)
955 break;
956
957 float x, y, z, o;
958 cluster->GetPosition(x, y, z, o);
959 me->NearTeleportTo(x, y, z, o);
960
961 uint32 preGameSpellId;
962 if (cluster->GetEntry() == clusterIds[SIMON_RED])
963 preGameSpellId = SPELL_PRE_GAME_RED;
964 else if (cluster->GetEntry() == clusterIds[SIMON_BLUE])
965 preGameSpellId = SPELL_PRE_GAME_BLUE;
966 else if (cluster->GetEntry() == clusterIds[SIMON_GREEN])
967 preGameSpellId = SPELL_PRE_GAME_GREEN;
968 else if (cluster->GetEntry() == clusterIds[SIMON_YELLOW])
969 preGameSpellId = SPELL_PRE_GAME_YELLOW;
970 else break;
971
972 me->CastSpell(cluster, preGameSpellId, true);
973 }
974 }
975
976 if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance))
977 {
978 float x, y, z, o;
979 relic->GetPosition(x, y, z, o);
980 me->NearTeleportTo(x, y, z + zCoordCorrection, o);
981 }
982
984 }
985
986 // Handles the spell rewards. The spells also have the QuestCompleteEffect, so quests credits are working.
988 {
989 uint32 rewSpell = 0;
990 switch (level)
991 {
992 case 6:
993 if (large)
995 else
996 rewSpell = SPELL_REWARD_BUFF_1;
997 break;
998 case 8:
999 rewSpell = SPELL_REWARD_BUFF_2;
1000 break;
1001 case 10:
1002 rewSpell = SPELL_REWARD_BUFF_3;
1003 break;
1004 }
1005
1006 if (rewSpell)
1008 DoCast(player, rewSpell, true);
1009 }
1010
1011 /*
1012 Depending on the number of failed pushes for player the damage of the spell scales, so we first
1013 cast the spell on the target that hits for 50 and shows the visual and then forces the player
1014 to cast the damaging spell on it self with the modified basepoints.
1015 4 fails = death.
1016 On large nodes punishment and reward are the same, summoning the Apexis Guardian.
1017 */
1019 {
1020 if (large)
1021 {
1023 if (Creature* guardian = me->SummonCreature(NPC_APEXIS_GUARDIAN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() - zCoordCorrection, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000))
1024 guardian->AI()->AttackStart(player);
1025
1026 ResetNode();
1027 }
1028 else
1029 {
1030 fails++;
1031
1033 DoCast(player, SPELL_BAD_PRESS_TRIGGER, true);
1034
1035 if (fails >= 4)
1036 ResetNode();
1037 }
1038 }
1039
1040 void SpellHitTarget(Unit* target, const SpellInfo* spell) OVERRIDE
1041 {
1042 // Cast SPELL_BAD_PRESS_DAMAGE with scaled basepoints when the visual hits the target.
1043 // Need Fix: When SPELL_BAD_PRESS_TRIGGER hits target it triggers spell SPELL_BAD_PRESS_DAMAGE by itself
1044 // so player gets damage equal to calculated damage dbc basepoints for SPELL_BAD_PRESS_DAMAGE (~50)
1045 if (spell->Id == SPELL_BAD_PRESS_TRIGGER)
1046 {
1047 int32 bp = (int32)((float)(fails)*0.33f*target->GetMaxHealth());
1048 target->CastCustomSpell(target, SPELL_BAD_PRESS_DAMAGE, &bp, NULL, NULL, true);
1049 }
1050 }
1051
1052 // Checks if player has already die or has get too far from the current node
1054 {
1056 {
1057 if (player->isDead())
1058 return false;
1059 if (player->GetDistance2d(me) >= 2.0f*searchDistance)
1060 {
1062 return false;
1063 }
1064 }
1065 else
1066 return false;
1067
1068 return true;
1069 }
1070 };
1071
1073 {
1074 return new npc_simon_bunnyAI(creature);
1075 }
1076};
1077
1079{
1080 public:
1081 go_simon_cluster() : GameObjectScript("go_simon_cluster") { }
1082
1084 {
1085 if (Creature* bunny = go->FindNearestCreature(NPC_SIMON_BUNNY, 12.0f, true))
1086 bunny->AI()->SetData(go->GetEntry(), 0);
1087
1088 player->CastSpell(player, go->GetGOInfo()->goober.spellId, true);
1089 go->AddUse();
1090 return true;
1091 }
1092};
1093
1103
1105{
1106 public:
1107 go_apexis_relic() : GameObjectScript("go_apexis_relic") { }
1108
1110 {
1111 player->PrepareGossipMenu(go, go->GetGOInfo()->questgiver.gossipID);
1112 player->SendPreparedGossip(go);
1113 return true;
1114 }
1115
1116 bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 /*action*/) OVERRIDE
1117 {
1118 player->CLOSE_GOSSIP_MENU();
1119
1120 bool large = (go->GetEntry() == GO_APEXIS_MONUMENT);
1121 if (player->HasItemCount(ITEM_APEXIS_SHARD, large ? 35 : 1))
1122 {
1123 player->CastSpell(player, large ? SPELL_TAKE_REAGENTS_GROUP : SPELL_TAKE_REAGENTS_SOLO, false);
1124
1125 if (Creature* bunny = player->SummonCreature(NPC_SIMON_BUNNY, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()))
1126 bunny->AI()->SetGUID(player->GetGUID(), large);
1127 }
1128
1129 return true;
1130 }
1131};
1132
1134{
1135 new npc_bladespire_ogre();
1136 new npc_nether_drake();
1137 new npc_daranelle();
1138 new npc_overseer_nuaar();
1140 new go_legion_obelisk();
1142 new npc_ogre_brute();
1143 new go_thunderspike();
1144 new npc_simon_bunny();
1145 new go_simon_cluster();
1146 new go_apexis_relic();
1147}
const T & RAND(const T &v1, const T &v2)
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ POWER_MANA
@ GO_FLAG_NOT_SELECTABLE
@ JUST_DIED
Definition Unit.h:504
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FIELD_FLAGS
@ GAMEOBJECT_FIELD_FLAGS
@ SPELL_ARCANE_BLAST
@ SPELL_INTANGIBLE_PRESENCE
virtual void MoveInLineOfSight(Unit *)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:524
CreatureScript(const char *name)
GameObjectScript(const char *name)
static Player * GetPlayer(WorldObject const &, uint64 guid)
uint64 GetGUID() const
Definition Object.h:119
GameObject * ToGameObject()
Definition Object.h:213
void KilledMonster(CreatureTemplate const *cInfo, uint64 guid)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
Powers getPowerType() const
Definition Unit.h:1651
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2801
TempSummon * SummonCreature(uint32 id, Position const &pos, TempSummonType spwtype=TempSummonType::TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0) const
Definition Object.cpp:2703
bool OnGossipSelect(Player *player, GameObject *go, uint32, uint32) OVERRIDE
bool OnGossipHello(Player *player, GameObject *go) OVERRIDE
bool OnGossipHello(Player *player, GameObject *go) OVERRIDE
bool OnGossipHello(Player *player, GameObject *go) OVERRIDE
bool OnGossipHello(Player *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
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ SPELL_MANA_BURN
Creature * me
ScriptedAI(Creature *creature)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void AttackStart(Unit *) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void MovementInform(uint32 type, uint32 id) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHit(Unit *caster, const SpellInfo *spell) OVERRIDE
void MovementInform(uint32, uint32 id) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHitTarget(Unit *target, const SpellInfo *spell) OVERRIDE
void SetGUID(uint64 guid, int32 id) OVERRIDE
void SetData(uint32 type, uint32) OVERRIDE
#define GOSSIP_HELLO_ON
#define LEGION_OBELISK_FOUR
#define GOSSIP_SELECT_STE
#define LEGION_OBELISK_FIVE
void AddSC_blades_edge_mountains()
#define GOSSIP_HELLO_STE
#define LEGION_OBELISK_THREE
#define LEGION_OBELISK_TWO
@ EVENT_SIMON_PERIODIC_PLAYER_CHECK
@ ACTION_SIMON_CORRECT_FULL_SEQUENCE
@ GO_BLUE_CLUSTER_DISPLAY_LARGE
@ GO_GREEN_CLUSTER_DISPLAY_LARGE
@ SPELL_VISUAL_START_PLAYER_LEVEL
@ GO_YELLOW_CLUSTER_DISPLAY_LARGE
@ QUEST_GETTING_THE_BLADESPIRE_TANKED
#define LEGION_OBELISK_ONE