TrinityCore
Loading...
Searching...
No Matches
zone_blades_edge_mountains.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* ScriptData
19SDName: Blades_Edge_Mountains
20SD%Complete: 90
21SDComment: Quest support: 10503, 10504, 10594, 10609, 10821. Ogri'la->Skettis Flight.
22SDCategory: Blade's Edge Mountains
23EndScriptData */
24
25/* ContentData
26npc_nether_drake
27go_legion_obelisk
28EndContentData */
29
30#include "ScriptMgr.h"
31#include "CellImpl.h"
32#include "CreatureAIImpl.h"
33#include "DBCStores.h"
34#include "GameObjectAI.h"
35#include "GridNotifiersImpl.h"
36#include "MotionMaster.h"
37#include "ObjectAccessor.h"
38#include "ScriptedCreature.h"
39#include "ScriptedGossip.h"
40#include "SpellAuraEffects.h"
41#include "SpellAuras.h"
42#include "SpellInfo.h"
43#include "SpellScript.h"
44#include "TemporarySummon.h"
45
46/*######
47## npc_nether_drake
48######*/
49
51{
52 //Used by 20021, 21817, 21820, 21821, 21823 but not existing in database
58
59 ENTRY_WHELP = 20021,
60 ENTRY_PROTO = 21821,
61 ENTRY_ADOLE = 21817,
62 ENTRY_MATUR = 21820,
63 ENTRY_NIHIL = 21823,
64
66
70};
71
73{
74public:
75 npc_nether_drake() : CreatureScript("npc_nether_drake") { }
76
78 {
79 npc_nether_drakeAI(Creature* creature) : ScriptedAI(creature)
80 {
81 Initialize();
82 }
83
85 {
86 IsNihil = false;
87 NihilSpeech_Timer = 3000;
89
90 ArcaneBlast_Timer = 7500;
91 ManaBurn_Timer = 10000;
93 }
94
95 bool IsNihil;
98
102
103 void Reset() override
104 {
105 Initialize();
106 }
107
108 void JustEngagedWith(Unit* /*who*/) override { }
109
110 void MoveInLineOfSight(Unit* who) override
111
112 {
114 return;
115
117 }
118
119 //in case Creature was not summoned (not expected)
120 void MovementInform(uint32 type, uint32 id) override
121 {
122 if (type != POINT_MOTION_TYPE)
123 return;
124
125 if (id == 0)
126 me->DespawnOrUnsummon(1ms);
127 }
128
129 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
130 {
131 Player* playerCaster = caster->ToPlayer();
132 if (!playerCaster)
133 return;
134
135 if (spellInfo->Id == SPELL_T_PHASE_MODULATOR)
136 {
137 const uint32 entry_list[4] = {ENTRY_PROTO, ENTRY_ADOLE, ENTRY_MATUR, ENTRY_NIHIL};
138 int cid = rand32() % (4 - 1);
139
140 if (entry_list[cid] == me->GetEntry())
141 ++cid;
142
143 //we are nihil, so say before transform
144 if (me->GetEntry() == ENTRY_NIHIL)
145 {
148 IsNihil = false;
149 }
150
151 if (me->UpdateEntry(entry_list[cid]))
152 {
153 if (entry_list[cid] == ENTRY_NIHIL)
154 {
157 IsNihil = true;
158 }
159 else
160 AttackStart(playerCaster);
161 }
162 }
163 }
164
165 void UpdateAI(uint32 diff) override
166 {
167 if (IsNihil)
168 {
169 if (NihilSpeech_Timer <= diff)
170 {
171 switch (NihilSpeech_Phase)
172 {
173 case 0:
176 break;
177 case 1:
180 break;
181 case 2:
184 break;
185 case 3:
188 break;
189 case 4:
191 //take off to location above
194 break;
195 }
196 NihilSpeech_Timer = 5000;
197 } else NihilSpeech_Timer -=diff;
198
199 //anything below here is not interesting for Nihil, so skip it
200 return;
201 }
202
203 if (!UpdateVictim())
204 return;
205
206 if (IntangiblePresence_Timer <= diff)
207 {
209 IntangiblePresence_Timer = 15000 + rand32() % 15000;
210 } else IntangiblePresence_Timer -= diff;
211
212 if (ManaBurn_Timer <= diff)
213 {
214 Unit* target = me->GetVictim();
215 if (target && target->GetPowerType() == POWER_MANA)
216 DoCast(target, SPELL_MANA_BURN);
217 ManaBurn_Timer = 8000 + rand32() % 8000;
218 } else ManaBurn_Timer -= diff;
219
220 if (ArcaneBlast_Timer <= diff)
221 {
223 ArcaneBlast_Timer = 2500 + rand32() % 5000;
224 } else ArcaneBlast_Timer -= diff;
225
227 }
228 };
229
230 CreatureAI* GetAI(Creature* creature) const override
231 {
232 return new npc_nether_drakeAI(creature);
233 }
234};
235
236//Support for quest: You're Fired! (10821)
238
249
250/*######
251## go_legion_obelisk
252######*/
253
255{
256public:
257 go_legion_obelisk() : GameObjectScript("go_legion_obelisk") { }
258
260 {
262
263 bool OnGossipHello(Player* player) override
264 {
266 {
267 switch (me->GetEntry())
268 {
270 obelisk_one = true;
271 break;
273 obelisk_two = true;
274 break;
276 obelisk_three = true;
277 break;
279 obelisk_four = true;
280 break;
282 obelisk_five = true;
283 break;
284 }
285
286 if (obelisk_one == true && obelisk_two == true && obelisk_three == true && obelisk_four == true && obelisk_five == true)
287 {
288 me->SummonCreature(NPC_DOOMCRYER, 2943.40f, 4778.20f, 284.49f, 0.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 2min);
289 //reset global var
290 obelisk_one = false;
291 obelisk_two = false;
292 obelisk_three = false;
293 obelisk_four = false;
294 obelisk_five = false;
295 }
296 }
297
298 return true;
299 }
300 };
301
302 GameObjectAI* GetAI(GameObject* go) const override
303 {
304 return new go_legion_obeliskAI(go);
305 }
306};
307
354
369
378
380{
381 public:
382 npc_simon_bunny() : CreatureScript("npc_simon_bunny") { }
383
385 {
386 npc_simon_bunnyAI(Creature* creature) : ScriptedAI(creature)
387 {
388 large = false;
389 listening = false;
390 gameLevel = 0;
391 fails = 0;
392 gameTicks = 0;
393 memset(clusterIds, 0, sizeof(clusterIds));
394 zCoordCorrection = 0.f;
395 searchDistance = 0.f;
396 }
397
398 bool large;
409
463
464 void DoAction(int32 action) override
465 {
466 switch (action)
467 {
469 listening = false;
473 if (gameLevel == 10)
474 ResetNode();
475 else
477 break;
479 gameLevel++;
481 break;
485 break;
486 }
487 }
488
489 // Called by color clusters script (go_simon_cluster) and used for knowing the button pressed by player
490 void SetData(uint32 type, uint32 /*data*/) override
491 {
492 if (!listening)
493 return;
494
495 uint8 pressedColor = SIMON_MAX_COLORS;
496
497 if (type == clusterIds[SIMON_RED])
498 pressedColor = SIMON_RED;
499 else if (type == clusterIds[SIMON_BLUE])
500 pressedColor = SIMON_BLUE;
501 else if (type == clusterIds[SIMON_GREEN])
502 pressedColor = SIMON_GREEN;
503 else if (type == clusterIds[SIMON_YELLOW])
504 pressedColor = SIMON_YELLOW;
505
506 PlayColor(pressedColor);
507 playerSequence.push_back(pressedColor);
510 }
511
512 // Used for getting involved player guid. Parameter id is used for defining if is a large(Monument) or small(Relic) node
513 void SetGUID(ObjectGuid const& guid, int32 id) override
514 {
515 me->SetCanFly(true);
516
517 large = id != 0;
518 playerGUID = guid;
519 StartGame();
520 }
521
522 /*
523 Resets all variables and also find the ids of the four closests color clusters, since every simon
524 node have diferent ids for clusters this is absolutely NECESSARY.
525 */
527 {
528 listening = false;
529 gameLevel = 0;
530 fails = 0;
531 gameTicks = 0;
532 zCoordCorrection = large ? 8.0f : 2.75f;
533 searchDistance = large ? 13.0f : 5.0f;
534 colorSequence.clear();
535 playableSequence.clear();
536 playerSequence.clear();
537 me->SetObjectScale(large ? 2.0f : 1.0f);
538
539 std::list<WorldObject*> ClusterList;
543
544 for (std::list<WorldObject*>::const_iterator i = ClusterList.begin(); i != ClusterList.end(); ++i)
545 {
546 if (GameObject* go = (*i)->ToGameObject())
547 {
548 // We are checking for displayid because all simon nodes have 4 clusters with different entries
549 if (large)
550 {
551 switch (go->GetGOInfo()->displayId)
552 {
554 clusterIds[SIMON_BLUE] = go->GetEntry();
555 break;
556
558 clusterIds[SIMON_RED] = go->GetEntry();
559 break;
560
562 clusterIds[SIMON_GREEN] = go->GetEntry();
563 break;
564
566 clusterIds[SIMON_YELLOW] = go->GetEntry();
567 break;
568 }
569 }
570 else
571 {
572 switch (go->GetGOInfo()->displayId)
573 {
575 clusterIds[SIMON_BLUE] = go->GetEntry();
576 break;
577
579 clusterIds[SIMON_RED] = go->GetEntry();
580 break;
581
583 clusterIds[SIMON_GREEN] = go->GetEntry();
584 break;
585
587 clusterIds[SIMON_YELLOW] = go->GetEntry();
588 break;
589 }
590 }
591 }
592 }
593
594 _events.Reset();
597
599 relic->SetFlag(GO_FLAG_NOT_SELECTABLE);
600 }
601
602 // Called when despawning the bunny. Sets all the node GOs to their default states.
604 {
606
607 for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
608 if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance))
609 cluster->SetFlag(GO_FLAG_NOT_SELECTABLE);
610
611 for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++)
612 if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance))
613 auraGo->RemoveFromWorld();
614
616 relic->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
617
619 }
620
621 /*
622 Called on every button click of player. Adds the clicked color to the player created sequence and
623 checks if it corresponds to the AI created sequence. If so, incremente gameLevel and start a new
624 round, if not, give punishment and restart current level.
625 */
627 {
628 bool correct = true;
629 if (playerSequence.size() <= colorSequence.size())
630 for (std::list<uint8>::const_iterator i = playerSequence.begin(), j = colorSequence.begin(); i != playerSequence.end(); ++i, ++j)
631 if ((*i) != (*j))
632 correct = false;
633
634 if (correct && (playerSequence.size() == colorSequence.size()))
636 else if (!correct)
638 }
639
640 /*
641 Generates a random sequence of colors depending on the gameLevel. We also copy this sequence to
642 the playableSequence wich will be used when playing the sequence to the player.
643 */
645 {
646 colorSequence.clear();
647 for (uint8 i = 0; i <= gameLevel; i++)
649
650 for (std::list<uint8>::const_iterator i = colorSequence.begin(); i != colorSequence.end(); ++i)
651 playableSequence.push_back(*i);
652 }
653
654 // Remove any existant glowing auras over clusters and set clusters ready for interating with them.
655 void PrepareClusters(bool clustersOnly = false)
656 {
657 for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
658 if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance))
659 cluster->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
660
661 if (clustersOnly)
662 return;
663
664 for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++)
665 if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance))
666 auraGo->RemoveFromWorld();
667 }
668
669 /*
670 Called when AI is playing the sequence for player. We cast the visual spell and then remove the
671 cast color from the casting sequence.
672 */
674 {
675 PlayColor(*playableSequence.begin());
676 playableSequence.erase(playableSequence.begin());
677 }
678
679 // Casts a spell and plays a sound depending on parameter color.
680 void PlayColor(uint8 color)
681 {
682 switch (color)
683 {
684 case SIMON_BLUE:
687 break;
688 case SIMON_GREEN:
691 break;
692 case SIMON_RED:
695 break;
696 case SIMON_YELLOW:
699 break;
700 }
701 }
702
703 /*
704 Creates the transparent glowing auras on every cluster of this node.
705 After calling this function bunny is teleported to the center of the node.
706 */
708 {
709 for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++)
710 {
711 if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], 2.0f*searchDistance))
712 {
713 cluster->SetFlag(GO_FLAG_NOT_SELECTABLE);
714
715 // break since we don't need glowing auras for large clusters
716 if (large)
717 break;
718
719 float x, y, z, o;
720 cluster->GetPosition(x, y, z, o);
721 me->NearTeleportTo(x, y, z, o);
722
723 uint32 preGameSpellId;
724 if (cluster->GetEntry() == clusterIds[SIMON_RED])
725 preGameSpellId = SPELL_PRE_GAME_RED;
726 else if (cluster->GetEntry() == clusterIds[SIMON_BLUE])
727 preGameSpellId = SPELL_PRE_GAME_BLUE;
728 else if (cluster->GetEntry() == clusterIds[SIMON_GREEN])
729 preGameSpellId = SPELL_PRE_GAME_GREEN;
730 else if (cluster->GetEntry() == clusterIds[SIMON_YELLOW])
731 preGameSpellId = SPELL_PRE_GAME_YELLOW;
732 else break;
733
734 me->CastSpell(cluster, preGameSpellId, true);
735 }
736 }
737
739 {
740 float x, y, z, o;
741 relic->GetPosition(x, y, z, o);
742 me->NearTeleportTo(x, y, z + zCoordCorrection, o);
743 }
744
746 }
747
748 // Handles the spell rewards. The spells also have the QuestCompleteEffect, so quests credits are working.
750 {
751 uint32 rewSpell = 0;
752 switch (level)
753 {
754 case 6:
755 if (large)
757 else
758 rewSpell = SPELL_REWARD_BUFF_1;
759 break;
760 case 8:
761 rewSpell = SPELL_REWARD_BUFF_2;
762 break;
763 case 10:
764 rewSpell = SPELL_REWARD_BUFF_3;
765 break;
766 }
767
768 if (rewSpell)
770 DoCast(player, rewSpell, true);
771 }
772
773 /*
774 Depending on the number of failed pushes for player the damage of the spell scales, so we first
775 cast the spell on the target that hits for 50 and shows the visual and then forces the player
776 to cast the damaging spell on it self with the modified basepoints.
777 4 fails = death.
778 On large nodes punishment and reward are the same, summoning the Apexis Guardian.
779 */
781 {
782 if (large)
783 {
786 guardian->AI()->AttackStart(player);
787
788 ResetNode();
789 }
790 else
791 {
792 fails++;
793
795 DoCast(player, SPELL_BAD_PRESS_TRIGGER, true);
796
797 if (fails >= 4)
798 ResetNode();
799 }
800 }
801
802 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
803 {
804 Unit* unitTarget = target->ToUnit();
805 if (!unitTarget)
806 return;
807
808 // Cast SPELL_BAD_PRESS_DAMAGE with scaled basepoints when the visual hits the target.
809 // Need Fix: When SPELL_BAD_PRESS_TRIGGER hits target it triggers spell SPELL_BAD_PRESS_DAMAGE by itself
810 // so player gets damage equal to calculated damage dbc basepoints for SPELL_BAD_PRESS_DAMAGE (~50)
811 if (spellInfo->Id == SPELL_BAD_PRESS_TRIGGER)
812 {
813 int32 bp = (int32)((float)(fails) * 0.33f * unitTarget->GetMaxHealth());
815 }
816 }
817
818 // Checks if player has already die or has get too far from the current node
820 {
822 {
823 if (player->isDead())
824 return false;
825 if (player->GetDistance2d(me) >= 2.0f*searchDistance)
826 {
828 return false;
829 }
830 }
831 else
832 return false;
833
834 return true;
835 }
836 };
837
838 CreatureAI* GetAI(Creature* creature) const override
839 {
840 return new npc_simon_bunnyAI(creature);
841 }
842};
843
845{
846 public:
847 go_simon_cluster() : GameObjectScript("go_simon_cluster") { }
848
850 {
852
853 bool OnGossipHello(Player* player) override
854 {
855 if (Creature* bunny = me->FindNearestCreature(NPC_SIMON_BUNNY, 12.0f, true))
856 bunny->AI()->SetData(me->GetEntry(), 0);
857
858 player->CastSpell(player, me->GetGOInfo()->goober.spellId, true);
859 me->AddUse();
860 return true;
861 }
862 };
863
864 GameObjectAI* GetAI(GameObject* go) const override
865 {
866 return new go_simon_clusterAI(go);
867 }
868};
869
879
881{
882 public:
883 go_apexis_relic() : GameObjectScript("go_apexis_relic") { }
884
886 {
888
889 bool OnGossipHello(Player* player) override
890 {
892 player->SendPreparedGossip(me);
893 return true;
894 }
895
896 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
897 {
898 CloseGossipMenuFor(player);
899
900 bool large = (me->GetEntry() == GO_APEXIS_MONUMENT);
901 if (player->HasItemCount(ITEM_APEXIS_SHARD, large ? 35 : 1))
902 {
903 player->CastSpell(player, large ? SPELL_TAKE_REAGENTS_GROUP : SPELL_TAKE_REAGENTS_SOLO, false);
904
906 bunny->AI()->SetGUID(player->GetGUID(), large);
907 }
908
909 return true;
910 }
911 };
912
913 GameObjectAI* GetAI(GameObject* go) const override
914 {
915 return new go_apexis_relicAI(go);
916 }
917};
918
919/*######
920## npc_oscillating_frequency_scanner_master_bunny used for quest 10594 "Gauging the Resonant Frequency"
921######*/
922
930
932{
933public:
934 npc_oscillating_frequency_scanner_master_bunny() : CreatureScript("npc_oscillating_frequency_scanner_master_bunny") { }
935
937 {
939 {
940 timer = 500;
941 }
942
943 void Reset() override
944 {
947 else
948 {
949 // Spell 37392 does not exist in dbc, manually spawning
952 me->DespawnOrUnsummon(50s);
953 }
954
955 timer = 500;
956 }
957
958 void IsSummonedBy(WorldObject* summoner) override
959 {
960 if (summoner->IsPlayer())
961 playerGuid = summoner->GetGUID();
962 }
963
964 void UpdateAI(uint32 diff) override
965 {
966 if (timer <= diff)
967 {
970
971 timer = 3000;
972 }
973 else
974 timer -= diff;
975 }
976
977 private:
980 };
981
982 CreatureAI* GetAI(Creature* creature) const override
983 {
985 }
986};
987
988// 37408 - Oscillation Field
990{
991 public:
992 spell_oscillating_field() : SpellScriptLoader("spell_oscillating_field") { }
993
1010
1011 SpellScript* GetSpellScript() const override
1012 {
1014 }
1015};
1016
1017/*######
1018## Quest 10556: Scratches
1019######*/
1020
1025
1026// 37028 - Dispelling Analysis
1046
1047/*######
1048## Quest 10544: A Curse Upon Both of Your Clans!
1049######*/
1050
1055
1056// 32580 - Wicked Strong Fetish
1072
1087
1089{
1091 {
1092 // Neccessary hack to allow spell 38629 to hit the keg credit (visibility is checked against the summoner, not the caster)
1094 }
1095};
1096
1098{
1100
1101 void IsSummonedBy(WorldObject* summoner) override
1102 {
1103 summoner->CastSpell(me, SPELL_CHARM_REXXARS_RODENT, true);
1104 }
1105};
1106
1107// 38544 - Coax Marmot
1109{
1111
1112 void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1113 {
1114 // prevent loading the aura from db
1115 if (GetTarget()->GetCharmedGUID().IsEmpty())
1116 Remove();
1117 }
1118
1119 void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1120 {
1121 if (Creature* marmot = Object::ToCreature(GetTarget()->GetCharmed()))
1122 if (marmot->GetUInt32Value(UNIT_CREATED_BY_SPELL) == SPELL_COAX_MARMOT)
1123 marmot->DespawnOrUnsummon();
1124 }
1125
1131};
1132
1133// 38586 - [DND]Charm Rexxar's Rodent
1135{
1137
1138 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1139 {
1140 if (Unit* caster = GetCaster())
1141 caster->RemoveAurasDueToSpell(SPELL_COAX_MARMOT);
1142
1143 if (Creature* creature = GetTarget()->ToCreature())
1144 creature->DespawnOrUnsummon(1ms);
1145 }
1146
1151};
1152
1153// 38629 - Poison Keg
1155{
1157
1158 bool Validate(SpellInfo const* /*spellEntry*/) override
1159 {
1160 return ValidateSpellInfo(
1161 {
1165 });
1166 }
1167
1169 {
1170 if (Player* player = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself())
1171 {
1172 uint32 spellId = 0;
1173 switch (GetHitUnit()->GetEntry())
1174 {
1177 break;
1180 break;
1183 break;
1184 default:
1185 return;
1186 }
1187
1188 player->CastSpell(nullptr, spellId, true);
1189 }
1190 }
1191
1196};
1197
1198/*######
1199## Quest 11010: Bombing Run / 11102: Bombing Run / 11023: Bomb Them Again!
1200######*/
1201
1211
1212// 40109 - Knockdown Fel Cannon: The Bolt
1214{
1216
1217 bool Validate(SpellInfo const* /*spellInfo*/) override
1218 {
1220 }
1221
1222 void HandleDummy(SpellEffIndex /*effIndex*/)
1223 {
1225 }
1226
1231};
1232
1233// 40113 - Knockdown Fel Cannon: The Aggro Check Aura
1235{
1237
1238 void HandleTriggerSpell(AuraEffect const* /*aurEff*/)
1239 {
1240 if (Unit* target = GetTarget())
1241 // On trigger proccing
1242 target->CastSpell(target, SPELL_AGGRO_CHECK);
1243 }
1244
1249};
1250
1251// 40112 - Knockdown Fel Cannon: The Aggro Check
1253{
1255
1256 void HandleDummy(SpellEffIndex /*effIndex*/)
1257 {
1258 if (Player* playerTarget = GetHitPlayer())
1259 // Check if found player target is on fly mount or using flying form
1260 if (playerTarget->HasAuraType(SPELL_AURA_FLY) || playerTarget->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED))
1261 playerTarget->CastSpell(playerTarget, SPELL_FLAK_CANNON_TRIGGER, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE);
1262 }
1263
1268};
1269
1270// 40119 - Knockdown Fel Cannon: The Aggro Burst
1272{
1274
1275 void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
1276 {
1277 if (Unit* target = GetTarget())
1278 // On each tick cast Choose Loc to trigger summon
1279 target->CastSpell(target, SPELL_CHOOSE_LOC);
1280 }
1281
1286};
1287
1288// 40056 - Knockdown Fel Cannon: Choose Loc
1290{
1292
1293 void HandleDummy(SpellEffIndex /*effIndex*/)
1294 {
1295 Unit* caster = GetCaster();
1296 // Check for player that is in 65 y range
1297 std::vector<Player*> playerList;
1298 caster->GetPlayerListInGrid(playerList, 65.0f);
1299 for (Player* player : playerList)
1300 // Check if found player target is on fly mount or using flying form
1301 if (player->HasAuraType(SPELL_AURA_FLY) || player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED))
1302 // Summom Fel Cannon (bunny version) at found player
1303 caster->SummonCreature(NPC_FEL_CANNON2, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
1304 }
1305
1310};
1311
1312// 39844 - Skyguard Blasting Charge
1313// 40160 - Throw Bomb
1315{
1317
1319 {
1320 Unit* caster = GetCaster();
1321 // This spell will be cast only if caster has one of these auras
1324 return SPELL_CAST_OK;
1325 }
1326
1331};
1332
1342
1343// 40623 - Apexis Vibrations
1344// 40625 - Apexis Emanations
1345// 40626 - Apexis Enlightenment
1383
1384/*######
1385## Quest 10525: Vision Guide
1386######*/
1387
1389{
1390 SPELL_VISION_GUIDE = 36573
1392
1393// 36587 - Vision Guide
1395{
1397
1398 bool Validate(SpellInfo const* /*spellInfo*/) override
1399 {
1401 }
1402
1403 void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1404 {
1406 }
1407
1412};
1413
1414/*######
1415## Quest 10714: On Spirit's Wings
1416######*/
1417
1422
1423// 38173 - Summon Spirit
1425{
1427
1428 bool Validate(SpellInfo const* /*spellInfo*/) override
1429 {
1431 }
1432
1433 void HandleDummy(SpellEffIndex /*effIndex*/)
1434 {
1435 // This spell script requires sniff verification
1437 }
1438
1443};
1444
First const & RAND(First const &first, Second const &second, Rest const &... rest)
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ POINT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
@ TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:107
uint32 rand32()
Definition Random.cpp:70
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1139
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
Creature * GetClosestCreatureWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool alive=true)
void CloseGossipMenuFor(Player *player)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_APPLY_AURA
@ INVISIBILITY_UNK4
@ POWER_MANA
@ GO_FLAG_NOT_SELECTABLE
SpellCastResult
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
@ SPELL_CAST_OK
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_MOD_INVISIBILITY
@ SPELL_AURA_DUMMY
@ SPELL_AURA_FLY
@ SPELL_AURA_MOD_POSSESS
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Disallows proc events from triggered spell (default)
#define SpellCheckCastFn(F)
#define SpellEffectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectRemoveFn(F, I, N, M)
@ UNIT_FLAG_NON_ATTACKABLE
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_CREATED_BY_SPELL
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
Unit * GetTarget() const
void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
uint32 GetId() const
virtual void MoveInLineOfSight(Unit *)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
void SetObjectScale(float scale) override
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:540
void Update(uint32 time)
Definition EventMap.h:67
EventId ExecuteEvent()
Definition EventMap.cpp:73
void CancelEvent(EventId eventId)
Definition EventMap.cpp:151
void CancelEventGroup(GroupIndex group)
Definition EventMap.cpp:165
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
void AddFlag(FLAG_TYPE flag)
Definition Object.h:287
GameObject *const me
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:102
void AddUse()
Definition GameObject.h:214
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
bool IsPlayer() const
Definition Object.h:179
static Unit * ToUnit(Object *o)
Definition Object.h:192
static GameObject * ToGameObject(Object *o)
Definition Object.h:198
uint32 GetEntry() const
Definition Object.h:81
Creature * ToCreature()
Definition Object.h:188
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
static Player * ToPlayer(Object *o)
Definition Object.h:180
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition Player.cpp:9763
void SendPreparedGossip(WorldObject *source)
Definition Player.cpp:14052
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15642
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition Player.cpp:13886
uint32 Id
Definition SpellInfo.h:289
HookList< CheckCastHandler > OnCheckCast
Player * GetHitPlayer() const
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
Powers GetPowerType() const
Definition Unit.h:931
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:953
uint32 GetMaxHealth() const
Definition Unit.h:914
bool SetCanFly(bool enable, bool packetOnly=false)
Definition Unit.cpp:13374
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4542
void NearTeleportTo(Position const &pos, bool casting=false)
Definition Unit.cpp:12832
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Unit * GetVictim() const
Definition Unit.h:859
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
void GetPlayerListInGrid(Container &playerContainer, float maxSearchRange, bool alive=true) const
Definition Object.cpp:3173
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition Object.cpp:2121
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES > m_invisibilityDetect
Definition Object.h:442
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1992
GameObject * SummonGameObject(uint32 entry, Position const &pos, QuaternionData const &rot, Seconds respawnTime, GOSummonType summonType=GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)
Definition Object.cpp:2015
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2099
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
GameObjectAI * GetAI(GameObject *go) const override
GameObjectAI * GetAI(GameObject *go) const override
GameObjectAI * GetAI(GameObject *go) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
PrepareAuraScript(spell_bem_aggro_burst)
void HandleEffectPeriodic(AuraEffect const *)
PrepareAuraScript(spell_bem_aggro_check_aura)
void HandleTriggerSpell(AuraEffect const *)
PrepareSpellScript(spell_bem_aggro_check)
void AfterRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_bem_apexis_swiftness)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_bem_charm_rexxars_rodent)
PrepareSpellScript(spell_bem_check_fly_mount)
PrepareSpellScript(spell_bem_choose_loc)
void HandleEffectRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_bem_coax_marmot)
void HandleEffectApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_bem_dispelling_analysis)
PrepareSpellScript(spell_bem_kfc_the_bolt)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_bem_q10720_poison_keg)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_bem_summon_spirit)
bool Validate(SpellInfo const *) override
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_bem_vision_guide)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_bem_wicked_strong_fetish)
PrepareSpellScript(spell_oscillating_field_SpellScript)
SpellScript * GetSpellScript() const override
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
CastSpellExtraArgs & AddSpellBP0(int32 val)
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:192
struct GameObjectTemplate::@191::@202 goober
struct GameObjectTemplate::@191::@195 questgiver
float GetPositionZ() const
Definition Position.h:81
float GetOrientation() const
Definition Position.h:82
float GetPositionX() const
Definition Position.h:79
float GetPositionY() const
Definition Position.h:80
void AttackStart(Unit *) override
ScriptedAI(Creature *creature)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
bool OnGossipSelect(Player *player, uint32, uint32) override
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
void MovementInform(uint32 type, uint32 id) override
void IsSummonedBy(WorldObject *summoner) override
void SetData(uint32 type, uint32) override
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void SetGUID(ObjectGuid const &guid, int32 id) override
@ SPELL_SWIFTNESS_APEXIS_EMANATIONS
@ SPELL_SWIFTNESS_APEXIS_VIBRATIONS
@ SPELL_SWIFTNESS_APEXIS_ENLIGHTENMENT
void AddSC_blades_edge_mountains()
@ 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
@ SPELL_FERMENTED_SEED_BEER_CREDIT
@ NPC_FERMENTED_SEED_BEER_KEG_CREDIT
@ NPC_OSCILLATING_FREQUENCY_SCANNER_TOP_BUNNY
@ GO_OSCILLATING_FREQUENCY_SCANNER
@ QUEST_GAUGING_THE_RESONANT_FREQUENCY