TrinityCore
Loading...
Searching...
No Matches
zone_storm_peaks.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#include "ScriptMgr.h"
19#include "CombatAI.h"
20#include "DB2Stores.h"
21#include "GameObject.h"
22#include "MotionMaster.h"
23#include "ObjectAccessor.h"
24#include "ObjectMgr.h"
25#include "Player.h"
26#include "ScriptedEscortAI.h"
27#include "ScriptedGossip.h"
28#include "SpellAuraEffects.h"
29#include "SpellScript.h"
30#include "TemporarySummon.h"
31#include "Vehicle.h"
32#include "WorldSession.h"
33
34/*######
35## npc_brunnhildar_prisoner
36######*/
37
46
48{
50 {
51 Initialize();
52 }
53
55 {
56 freed = false;
57 }
58
59 bool freed;
60
61 void Reset() override
62 {
63 Initialize();
65 }
66
67 void JustAppeared() override
68 {
69 Reset();
70 }
71
72 void UpdateAI(uint32 /*diff*/) override
73 {
74 if (!freed)
75 return;
76
77 if (!me->GetVehicle())
79 }
80
81 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
82 {
83 Unit* unitCaster = caster->ToUnit();
84 if (!unitCaster)
85 return;
86
87 if (spellInfo->Id != SPELL_ICE_LANCE)
88 return;
89
90 if (unitCaster->GetVehicleKit()->GetAvailableSeatCount() != 0)
91 {
93 me->CastSpell(unitCaster, SPELL_RIDE_DRAKE, true);
95 freed = true;
96 }
97 }
98};
99
100// 55048 - Free Brunnhildar Prisoner
118
119/*######
120## npc_freed_protodrake
121######*/
122
138
140{
141 npc_freed_protodrake(Creature* creature) : VehicleAI(creature) { }
142
144
145 void Reset() override
146 {
148 }
149
150 void MovementInform(uint32 type, uint32 id) override
151 {
152 if (type != WAYPOINT_MOTION_TYPE)
153 return;
154
155 if (id == 15)
156 // drake reached village
158 }
159
160 void UpdateAI(uint32 diff) override
161 {
163 events.Update(diff);
164
165 switch (events.ExecuteEvent())
166 {
167 case EVENT_CHECK_AREA:
169 {
170 if (Vehicle* vehicle = me->GetVehicleKit())
171 if (Unit* passenger = vehicle->GetPassenger(0))
172 {
173 Talk(TEXT_EMOTE, passenger);
174 me->GetMotionMaster()->MovePath(NPC_DRAKE << 3, false);
175 }
176 }
177 else
179 break;
181 if (Vehicle* vehicle = me->GetVehicleKit())
182 if (Unit* player = vehicle->GetPassenger(0))
183 if (player->GetTypeId() == TYPEID_PLAYER)
184 {
185 // for each prisoner on drake, give credit
186 for (uint8 i = 1; i < 4; ++i)
187 if (Unit* prisoner = me->GetVehicleKit()->GetPassenger(i))
188 {
189 if (prisoner->GetTypeId() != TYPEID_UNIT)
190 return;
191 prisoner->CastSpell(player, SPELL_KILL_CREDIT_PRISONER, true);
192 prisoner->CastSpell(prisoner, SPELL_SUMMON_LIBERATED, true);
193 prisoner->ExitVehicle();
194 }
196 player->ExitVehicle();
197 }
198 break;
199 }
200 }
201};
202
203static constexpr uint32 PATH_ESCORT_ICEFANG = 236818;
204
205struct npc_icefang : public EscortAI
206{
207 npc_icefang(Creature* creature) : EscortAI(creature) { }
208
209 void AttackStart(Unit* /*who*/) override { }
210 void JustEngagedWith(Unit* /*who*/) override { }
211 void EnterEvadeMode(EvadeReason /*why*/) override { }
212
213 void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override
214 {
215 if (who->GetTypeId() == TYPEID_PLAYER)
216 {
217 if (apply)
218 {
220 Start(false, who->GetGUID());
221 }
222 }
223 }
224
225 void JustDied(Unit* /*killer*/) override { }
226 void OnCharmed(bool /*isNew*/) override { }
227
228 void UpdateAI(uint32 diff) override
229 {
230 EscortAI::UpdateAI(diff);
231
232 if (!UpdateVictim())
233 return;
234 }
235};
236
238{
241
243{
244public:
246
247 void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) override
248 {
249 if (apply)
250 return;
251
254 }
255
256 void UpdateAI(uint32 diff) override
257 {
260 Vehicle* _vehicleKit = me->GetVehicleKit();
261 if (_accessoryRespawnTimer && _accessoryRespawnTimer <= diff && _vehicleKit)
262 {
263 _vehicleKit->InstallAllAccessories(true);
265 }
266 else
268 }
269
270private:
272};
273
274/*#####
275# npc_brann_bronzebeard for Quest 13285 "Forging the Keystone"
276#####*/
277
311
313{
315 {
316 objectCounter = 0;
317 }
318
319 void Reset() override
320 {
321 for (ObjectGuid& guid : objectGUID)
322 guid.Clear();
323
326 objectCounter = 0;
327 }
328
329 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
330 {
331 CloseGossipMenuFor(player);
332 playerGUID = player->GetGUID();
334 return false;
335 }
336
337 void UpdateAI(uint32 diff) override
338 {
339 events.Update(diff);
340
341 while (uint32 eventId = events.ExecuteEvent())
342 {
343 switch (eventId)
344 {
345 case EVENT_SCRIPT_1:
347 Talk(SAY_BRANN_1, player);
349 if (Creature* voice = me->SummonCreature(NPC_A_DISTANT_VOICE, 7863.43f, -1396.585f, 1538.076f, 2.949606f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 49s))
350 voiceGUID = voice->GetGUID();
352 break;
353 case EVENT_SCRIPT_2:
354 me->SetWalk(true);
355 me->GetMotionMaster()->MovePoint(0, 7861.488f, -1396.376f, 1534.059f, false);
357 break;
358 case EVENT_SCRIPT_3:
361 break;
362 case EVENT_SCRIPT_4:
365 {
366 voice->CastSpell(voice, SPELL_RESURRECTION);
368 voice->AI()->Talk(SAY_VOICE_1, player);
369 }
370 if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_1, 7860.273f, -1383.622f, 1538.302f, -1.658062f, QuaternionData(0.f, 0.f, -0.737277f, 0.6755905f), 0s))
371 objectGUID[objectCounter++] = go->GetGUID();
373 break;
374 case EVENT_SCRIPT_5:
377 voice->AI()->Talk(SAY_VOICE_2, player);
378 if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_2, 7875.67f, -1387.266f, 1538.323f, -2.373644f, QuaternionData(0.f, 0.f, -0.9271832f, 0.3746083f), 0s))
379 objectGUID[objectCounter++] = go->GetGUID();
381 break;
382 case EVENT_SCRIPT_6:
385 voice->AI()->Talk(SAY_VOICE_3, player);
386 if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_3, 7879.212f, -1401.175f, 1538.279f, 2.967041f, QuaternionData(0.f, 0.f, 0.9961939f, 0.08716504f), 0s))
387 objectGUID[objectCounter++] = go->GetGUID();
389 break;
390 case EVENT_SCRIPT_7:
393 voice->AI()->Talk(SAY_VOICE_4, player);
394 if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_4, 7868.944f, -1411.18f, 1538.213f, 2.111848f, QuaternionData(0.f, 0.f, 0.8703556f, 0.4924237f), 0s))
395 objectGUID[objectCounter++] = go->GetGUID();
397 break;
398 case EVENT_SCRIPT_8:
401 voice->AI()->Talk(SAY_VOICE_5, player);
402 if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_5, 7855.11f, -1406.839f, 1538.42f, 1.151916f, QuaternionData(0.f, 0.f, 0.5446386f, 0.8386708f), 0s))
403 objectGUID[objectCounter] = go->GetGUID();
405 break;
406 case EVENT_SCRIPT_9:
408 voice->CastSpell(voice, SPELL_RESURRECTION);
410 break;
411 case EVENT_SCRIPT_10:
413 {
414 Talk(SAY_BRANN_2, player);
415 player->KilledMonsterCredit(me->GetEntry());
416 }
418 break;
419 case EVENT_SCRIPT_11:
420 me->SetFacingTo(2.932153f);
422 Talk(SAY_BRANN_3, player);
423
424 for (uint8 i = 0; i < 5; ++i)
426 go->Delete();
427
429 break;
430 case EVENT_SCRIPT_12:
432 me->SetWalk(false);
433 me->GetMotionMaster()->MovePoint(0, 7799.908f, -1413.561f, 1534.829f, false);
435 break;
436 case EVENT_SCRIPT_13:
438 break;
439 }
440 }
441 }
442
443private:
449};
450
451/*#####
452# Quest 13003 Thrusting Hodir's Spear
453#####*/
454
509
517
519{
520 npc_wild_wyrm(Creature* creature) : VehicleAI(creature)
521 {
522 Initialize();
523 }
524
530
532 {
534 for (uint8 i = 0; i < ControllableSpellsCount; ++i)
536 }
537
538 void Reset() override
539 {
540 Initialize();
541
544
546
547 me->SetImmuneToPC(false);
548 me->SetCanMelee(true);
549 }
550
551 void DoAction(int32 action) override
552 {
554 if (!player)
555 return;
556
557 switch (action)
558 {
560 Talk(SAY_SWIPE, player);
561 break;
563 Talk(SAY_DODGED, player);
564 break;
566 Talk(SAY_GRIP_WARN, player);
567 break;
568 case ACTION_GRIP_LOST:
571 break;
573 Talk(SAY_STRIKE_MISS, player);
574 break;
575 default:
576 break;
577 }
578 }
579
580 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
581 {
582 if (!_playerGuid.IsEmpty() || spellInfo->Id != SPELL_SPEAR_OF_HODIR)
583 return;
584
585 _playerGuid = caster->GetGUID();
587 me->SetImmuneToPC(true);
588 me->SetCanMelee(false);
589
591 }
592
593 void MovementInform(uint32 type, uint32 id) override
594 {
595 if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
596 return;
597
598 switch (id)
599 {
601 {
603 if (!player)
604 return;
605
608 break;
609 }
610 case POINT_FALL:
612 me->KillSelf();
613 break;
614 default:
615 break;
616 }
617 }
618
619 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
620 {
621 if (damage >= me->GetHealth())
622 {
623 damage = me->GetHealth() - 1;
624
625 if (_phase == PHASE_DEAD)
626 return;
627
630 .Async([this]
631 {
633
635 player->VehicleSpellInitialize();
636
639
642
644
646 });
647 }
648 }
649
650 void PassengerBoarded(Unit* passenger, int8 seatId, bool apply) override
651 {
652 if (!apply || passenger->GetGUID() != _playerGuid)
653 return;
654
655 if (seatId != SEAT_INITIAL)
656 return;
657
658 me->CastSpell(nullptr, SPELL_GRIP, CastSpellExtraArgs().AddSpellMod(SPELLVALUE_AURA_STACK, 50));
660
661 _scheduler.Async([this]
662 {
663 me->GetMotionMaster()->MovePath(PATH_WILD_WYRM, true);
664 })
665 .Schedule(Milliseconds(500), [this](TaskContext& context)
666 {
667 if (_phase == PHASE_MOUTH)
668 return;
669
670 if (me->HealthBelowPct(25))
671 {
672 _phase = PHASE_MOUTH;
673 context.Async([this]
674 {
675 InitSpellsForPhase();
676 DoCastAOE(SPELL_LOW_HEALTH_TRIGGER, true);
677 me->RemoveAurasDueToSpell(SPELL_CLAW_SWIPE_PERIODIC);
678 me->RemoveAurasDueToSpell(SPELL_GRIP);
679
680 if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGuid))
681 Talk(SAY_PHASE_2, player);
682
683 DoCastAOE(SPELL_EJECT_PASSENGER_1, true);
684 DoCastAOE(SPELL_JAWS_OF_DEATH_PERIODIC);
685 DoCastAOE(SPELL_FLY_STATE_VISUAL);
686 });
687 return;
688 }
689
690 context.Repeat();
691 });
692 }
693
694 bool EvadeCheck() const
695 {
696 Player* player = ObjectAccessor::GetPlayer(*me, _playerGuid);
697 if (!player)
698 return false;
699
700 switch (_phase)
701 {
702 case PHASE_INITIAL:
703 case PHASE_MOUTH:
704 if (!player->IsAlive())
705 return false;
706 break;
707 case PHASE_DEAD:
708 break;
709 default:
710 ABORT();
711 break;
712 }
713
714 return true;
715 }
716
717 void UpdateAI(uint32 diff) override
718 {
719 if (!_playerGuid)
720 {
721 UpdateVictim();
722 return;
723 }
724
725 if (_playerCheckTimer <= diff)
726 {
727 if (!EvadeCheck())
728 EnterEvadeMode(EvadeReason::NoHostiles);
729
730 _playerCheckTimer = 1 * IN_MILLISECONDS;
731 }
732 else
733 _playerCheckTimer -= diff;
734
735 _scheduler.Update(diff);
736 }
737
738private:
743};
744
745/*#####
746# Quest 13010 Krolmir, Hammer of Storms
747#####*/
748
782
784{
786 {
787 pathEnd = false;
788 }
789
790 void Reset() override
791 {
793 pathEnd = false;
794 }
795
796 void OnCharmed(bool /*apply*/) override { }
797
798 void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) override
799 {
800 if (apply)
801 {
802 playerGUID = who->GetGUID();
803 Talk(SAY_HOLD_ON, who);
805 me->SetImmuneToNPC(true);
807 }
808 }
809
810 void MovementInform(uint32 type, uint32 id) override
811 {
812 if (type != WAYPOINT_MOTION_TYPE)
813 return;
814
815 if (pathEnd)
816 {
817 if (id == 4)
818 {
819
820 }
821 }
822 else
823 {
824 if (id == 19)
825 {
826 pathEnd = true;
827 me->SetFacingTo(0.418879f);
832
833 }
834 }
835 }
836
837 void UpdateAI(uint32 diff) override
838 {
839 if (!pathEnd)
840 return;
841
842 events.Update(diff);
843
844 while (uint32 eventId = events.ExecuteEvent())
845 {
846 switch (eventId)
847 {
848 case EVENT_KROLMIR_1:
851 break;
852 }
853 }
854 }
855
856private:
860
861};
862
863// 61319 - Jokkum Scriptcast
865{
866 bool Validate(SpellInfo const* /*spellInfo*/) override
867 {
869 }
870
871 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
872 {
873 if (Unit* target = GetTarget())
874 target->CastSpell(target, SPELL_JOKKUM_SUMMON, true);
875 }
876
881};
882
883// 56650 - Player Cast Veranus Summon
885{
886 bool Validate(SpellInfo const* /*spellInfo*/) override
887 {
889 }
890
891 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
892 {
893 if (Unit* target = GetTarget())
894 target->CastSpell(target, SPELL_SUMMON_VERANUS_AND_THORIM, true);
895 }
896
901};
902
904{
905 SPELL_DESPAWN_RIFT = 61665
907
908// 56763 - Close Rift
910{
911 bool Validate(SpellInfo const* /*spell*/) override
912 {
914 }
915
916 void HandlePeriodic(AuraEffect const* /* aurEff */)
917 {
918 if (++_counter == 5)
919 GetTarget()->CastSpell(nullptr, SPELL_DESPAWN_RIFT, true);
920 }
921
926
927private:
929};
930
931// 56689 - Grip
932class spell_grip : public AuraScript
933{
934 void DummyTick(AuraEffect const* /*aurEff*/)
935 {
936 ++_tickNumber;
937
938 // each 15 ticks stack reduction increases by 2 (increases by 1 at each 7th and 15th tick)
939 // except for the first 15 ticks that remove 1 stack each
940 uint32 const period = ((_tickNumber - 1) % 15) + 1;
941 uint32 const sequence = (_tickNumber - 1) / 15;
942
943 uint32 stacksToRemove;
944 if (sequence == 0)
945 stacksToRemove = 1;
946 else
947 {
948 stacksToRemove = sequence * 2;
949 if (period > 7)
950 ++stacksToRemove;
951 }
952
953 // while we could do ModStackAmount(-stacksToRemove), this is how it's done in sniffs :)
954 for (uint32 i = 0; i < stacksToRemove; ++i)
956
957 if (GetStackAmount() < 15 && !_warning)
958 {
959 _warning = true;
961 }
962 else if (GetStackAmount() > 30)
963 _warning = false;
964 }
965
966 void HandleDrop(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
967 {
968 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
969 return;
970
972 }
973
980
981 // tick number in the AuraEffect gets reset each time we stack the aura, so keep track of it locally
983
984 bool _warning = false;
985};
986
987// 60533 - Grab On
989{
990 void HandleScript(SpellEffIndex /*effIndex*/)
991 {
992 if (Aura* grip = GetCaster()->GetAura(SPELL_GRIP, GetCaster()->GetGUID()))
993 grip->ModStackAmount(GetEffectValueAsInt(), AURA_REMOVE_BY_DEFAULT, false);
994 }
995
1000};
1001
1002// 56690 - Thrust Spear
1003// 60586 - Mighty Spear Thrust
1004template <int8 StacksToLose>
1006{
1007 void HandleScript(SpellEffIndex /*effIndex*/)
1008 {
1009 if (Aura* grip = GetCaster()->GetAura(SPELL_GRIP))
1010 grip->ModStackAmount(-StacksToLose, AURA_REMOVE_BY_EXPIRE);
1011 }
1012
1017};
1018
1019// 60596 - Low Health Trigger
1021{
1022 bool Validate(SpellInfo const* spellInfo) override
1023 {
1024 return ValidateSpellInfo({ static_cast<uint32>(spellInfo->GetEffect(EFFECT_0).CalcValueAsInt()) });
1025 }
1026
1027 void HandleScript(SpellEffIndex /*effIndex*/)
1028 {
1029 GetHitUnit()->CastSpell(nullptr, GetEffectValueAsInt(), true);
1030 }
1031
1036};
1037
1038// 60776 - Claw Swipe
1039// 60864 - Jaws of Death
1052
1053// 56705 - Claw Swipe
1055{
1056 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1057 {
1059 }
1060
1061 void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1062 {
1063 if (Vehicle* vehicle = GetTarget()->GetVehicleKit())
1064 {
1065 if (Unit* player = vehicle->GetPassenger(SEAT_INITIAL))
1066 {
1067 if (player->HasAura(SPELL_DODGE_CLAWS))
1068 {
1070 return;
1071 }
1072 }
1073 }
1074
1075 GetTarget()->CastSpell(nullptr, aurEff->GetAmountAsInt(), false);
1076 }
1077
1083};
1084
1085// 60587 - Fatal Strike
1087{
1088 bool Validate(SpellInfo const* /*spellInfo*/) override
1089 {
1091 }
1092
1093 void HandleDummy(SpellEffIndex /*effIndex*/)
1094 {
1095 SpellEffectValue chance = 0;
1096 if (AuraEffect const* aurEff = GetCaster()->GetAuraEffect(SPELL_PRY_JAWS_OPEN, EFFECT_0))
1097 chance = aurEff->GetAmount();
1098
1099 if (!roll_chance(chance))
1100 {
1102 return;
1103 }
1104
1106 }
1107
1112};
1113
1114// 56672 - Player Mount Wyrm
1116{
1117 bool Validate(SpellInfo const* /*spellInfo*/) override
1118 {
1120 }
1121
1122 void HandleDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1123 {
1124 GetTarget()->CastSpell(nullptr, SPELL_FIGHT_WYRM, true);
1125 }
1126
1131};
1132
1133/*######
1134## Quest 12987: Mounting Hodir's Helm
1135######*/
1136
1143
1144// 56278 - Read Pronouncement
1146{
1147 bool Validate(SpellInfo const* /*spellInfo*/) override
1148 {
1149 return sBroadcastTextStore.HasRecord(TEXT_PRONOUNCEMENT_1) &&
1151 sObjectMgr->GetCreatureTemplate(NPC_HODIRS_HELM_KC);
1152 }
1153
1154 void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1155 {
1156 if (Player* target = GetTarget()->ToPlayer())
1157 {
1158 target->Unit::Whisper(TEXT_PRONOUNCEMENT_1, target, true);
1159 target->KilledMonsterCredit(NPC_HODIRS_HELM_KC);
1160 target->Unit::Whisper(TEXT_PRONOUNCEMENT_2, target, true);
1161 }
1162 }
1163
1168};
1169
1170/*######
1171## Quest 13011: Jormuttar is Soo Fat...
1172######*/
1173
1180
1181// 56565 - Bear Flank Master
1199
1200// 56569 - Bear Flank Fail
1202{
1203 bool Validate(SpellInfo const* /*spellInfo*/) override
1204 {
1205 return sBroadcastTextStore.HasRecord(TEXT_CARVE_FAIL);
1206 }
1207
1208 void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1209 {
1210 if (Player* target = GetTarget()->ToPlayer())
1211 target->Unit::Whisper(TEXT_CARVE_FAIL, target, true);
1212 }
1213
1218};
1219
1220/*######
1221## Quest 12828: Ample Inspiration
1222######*/
1223
1234
1235// 54581 - Mammoth Explosion Spell Spawner
1270
1271// 54892 - Unstable Explosive Detonation
1273{
1274 bool Validate(SpellInfo const* /*spellInfo*/) override
1275 {
1276 return sObjectMgr->GetItemTemplate(ITEM_EXPLOSIVE_DEVICE);
1277 }
1278
1279 void HandleScript(SpellEffIndex /*effIndex*/)
1280 {
1281 if (Player* caster = GetCaster()->ToPlayer())
1282 caster->DestroyItemCount(ITEM_EXPLOSIVE_DEVICE, 1, true);
1283 }
1284
1289};
1290
1291/*######
1292## Quest 12915: Mending Fences
1293######*/
1294
1299
1300// 55512 - Call of Earth
1302{
1303 bool Validate(SpellInfo const* /*spellInfo*/) override
1304 {
1306 }
1307
1308 void HandleScript(SpellEffIndex /*effIndex*/)
1309 {
1310 uint8 count = urand(2, 6);
1311 for (uint8 i = 0; i < count; i++)
1313 }
1314
1319};
1320
1321/*######
1322## Quest 12851: Bearly Hanging On
1323######*/
1324
1334
1335// 54798 - FLAMING Arrow Triggered Effect
1337{
1338 void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1339 {
1340 if (Unit* caster = GetCaster())
1341 {
1342 Unit* target = GetTarget();
1343 // Already in fire
1344 if (target->HasAura(SPELL_ABLAZE))
1345 return;
1346
1347 if (Player* player = caster->GetCharmerOrOwnerPlayerOrPlayerItself())
1348 {
1349 switch (target->GetEntry())
1350 {
1351 case NPC_FROSTWORG:
1352 target->CastSpell(player, SPELL_FROSTWORG_CREDIT, true);
1353 target->CastSpell(target, SPELL_IMMOLATION, true);
1354 target->CastSpell(target, SPELL_ABLAZE, true);
1355 break;
1356 case NPC_FROSTGIANT:
1357 target->CastSpell(player, SPELL_FROSTGIANT_CREDIT, true);
1358 target->CastSpell(target, SPELL_IMMOLATION, true);
1359 target->CastSpell(target, SPELL_ABLAZE, true);
1360 break;
1361 }
1362 }
1363 }
1364 }
1365
1370};
1371
1372/*######
1373## Quest 12920: Catching up with Brann
1374######*/
1375
1381
1382// 61122 - Contact Brann
1384{
1385 bool Validate(SpellInfo const* /*spellInfo*/) override
1386 {
1388 }
1389
1390 void HandleScript(SpellEffIndex /*effIndex*/)
1391 {
1392 Unit* caster = GetCaster();
1393 caster->CastSpell(caster, SPELL_DESPAWN_BRANN);
1394 caster->CastSpell(caster, SPELL_CONTACT_BRANN);
1395 }
1396
1401};
1402
1404{
1413
1420 RegisterSpellScriptWithArgs(spell_loosen_grip<15>, "spell_mighty_spear_thrust");
1434}
@ IN_MILLISECONDS
Definition Common.h:38
@ MINUTE
Definition Common.h:32
DB2Storage< BroadcastTextEntry > sBroadcastTextStore("BroadcastText.db2", &BroadcastTextLoadInfo::Instance)
uint8_t uint8
Definition Define.h:156
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
#define ABORT
Definition Errors.h:79
#define ASSERT
Definition Errors.h:72
@ WAYPOINT_MOTION_TYPE
@ POINT_MOTION_TYPE
@ EFFECT_MOTION_TYPE
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
#define sObjectMgr
Definition ObjectMgr.h:1873
bool roll_chance(float chance, PseudoRandomDistributionState &state)
Definition Random.cpp:131
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:43
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1392
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
#define RegisterSpellScriptWithArgs(spell_script, script_name,...)
Definition ScriptMgr.h:1382
void CloseGossipMenuFor(Player *player)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ EMOTE_STATE_WORK_MINING
@ EMOTE_ONESHOT_NONE
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_DEFAULT
@ AURA_REMOVE_BY_EXPIRE
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_NONE
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELLVALUE_AURA_STACK
double SpellEffectValue
This is a double instead of float to be able to store full range of int32.
#define SpellEffectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectRemoveFn(F, I, N, M)
EvadeReason
@ UNIT_NPC_FLAG_GOSSIP
@ UNIT_NPC_FLAG_NONE
@ UNIT_NPC_FLAG_QUESTGIVER
DamageEffectType
int32 GetAmountAsInt() const
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
Unit * GetTarget() const
uint8 GetStackAmount() const
HookList< EffectApplyHandler > OnEffectApply
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void SetCanMelee(bool canMelee, bool fleeFromMelee=false)
void SetImmuneToPC(bool apply) override
Definition Creature.h:190
uint32 m_spells[MAX_CREATURE_SPELLS]
Definition Creature.h:332
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetImmuneToNPC(bool apply) override
Definition Creature.h:193
void DisappearAndDie()
Definition Creature.h:95
void Update(uint32 time)
Definition EventMap.h:77
EventId ExecuteEvent()
Definition EventMap.cpp:77
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:40
void MoveFall(uint32 id=0, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={}, Optional< MovementFadeObject > fadeObject={}, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MovePath(uint32 pathId, bool repeatable, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< std::pair< Milliseconds, Milliseconds > > waitTimeRangeAtPathEnd={}, Optional< float > wanderDistanceAtPathEnds={}, Optional< bool > followPathBackwardsFromEndToStart={}, Optional< bool > exactSplinePath={}, bool generatePath=true, Optional< MovementFadeObject > fadeObject={}, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
bool IsEmpty() const
Definition ObjectGuid.h:362
void Clear()
Definition ObjectGuid.h:329
uint32 GetEntry() const
Definition Object.h:89
Unit * ToUnit()
Definition Object.h:116
uint32 const Id
Definition SpellInfo.h:328
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:590
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Unit * GetCaster() const
void SetEffectValue(SpellEffectValue value)
SpellEffectValue GetEffectValue() const
int32 GetEffectValueAsInt() const
HookList< EffectHandler > OnEffectHit
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
HookList< EffectHandler > OnEffectLaunchTarget
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & CancelAll()
TaskScheduler & Async(std::function< void()> callable)
virtual void DoAction(int32 param)
Definition UnitAI.h:73
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:162
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:81
Definition Unit.h:647
Vehicle * GetVehicle() const
Definition Unit.h:1800
MotionMaster * GetMotionMaster()
Definition Unit.h:1750
bool IsAlive() const
Definition Unit.h:1205
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:1013
UnitAI * GetAI() const
Definition Unit.h:680
void SetEmoteState(Emote emote)
Definition Unit.h:880
uint64 GetHealth() const
Definition Unit.h:800
bool SetWalk(bool enable)
Definition Unit.cpp:13422
bool HealthBelowPct(float pct) const
Definition Unit.h:804
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13385
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4822
Vehicle * GetVehicleKit() const
Definition Unit.h:1798
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.h:951
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:1014
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
uint8 GetAvailableSeatCount() const
Gets the available seat count.
Definition Vehicle.cpp:712
Unit * GetPassenger(int8 seatId) const
Gets a passenger on specified seat.
Definition Vehicle.cpp:303
void InstallAllAccessories(bool evading)
Definition Vehicle.cpp:97
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
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:1403
GameObject * SummonGameObject(uint32 entry, Position const &pos, QuaternionData const &rot, Seconds respawnTime, GOSummonType summonType=GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)
Definition Object.cpp:1446
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Object.cpp:1626
uint32 GetAreaId() const
Definition Object.h:333
void PassengerBoarded(Unit *who, int8, bool apply) override
== Fields =======================================
npc_hyldsmeet_protodrake(Creature *creature)
void UpdateAI(uint32 diff) override
void OnRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
void OnApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void HandlePeriodic(AuraEffect const *)
void Register() override
bool Validate(SpellInfo const *) override
void HandleDummy(SpellEffIndex)
void Register() override
void HandleScript(SpellEffIndex)
void HandleDrop(AuraEffect const *, AuraEffectHandleModes)
void DummyTick(AuraEffect const *)
void Register() override
void OnApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void HandleScript(SpellEffIndex)
void Register() override
bool Validate(SpellInfo const *spellInfo) override
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
void HandleDummy(AuraEffect const *, AuraEffectHandleModes)
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleEffectApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void OnApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void OnApply(AuraEffect const *, AuraEffectHandleModes)
TC_GAME_API GameObject * GetGameObject(WorldObject const &u, ObjectGuid const &guid)
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void Start(bool isActiveAttacker=true, ObjectGuid playerGUID=ObjectGuid::Empty, Quest const *quest=nullptr, bool instantRespawn=false, bool canLoopPath=false)
void LoadPath(uint32 pathId)
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
Definition CombatAI.cpp:246
bool OnGossipSelect(Player *player, uint32, uint32) override
void UpdateAI(uint32 diff) override
npc_brann_bronzebeard_keystone(Creature *creature)
npc_brunnhildar_prisoner(Creature *creature)
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
void UpdateAI(uint32) override
void UpdateAI(uint32 diff) override
void MovementInform(uint32 type, uint32 id) override
npc_freed_protodrake(Creature *creature)
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
npc_icefang(Creature *creature)
void EnterEvadeMode(EvadeReason) override
void JustEngagedWith(Unit *) override
void JustDied(Unit *) override
void PassengerBoarded(Unit *who, int8, bool apply) override
== Fields =======================================
void OnCharmed(bool) override
void UpdateAI(uint32 diff) override
void MovementInform(uint32 type, uint32 id) override
npc_king_jokkum_vehicle(Creature *creature)
void UpdateAI(uint32 diff) override
void OnCharmed(bool) override
void PassengerBoarded(Unit *who, int8, bool apply) override
== Fields =======================================
bool EvadeCheck() const
void Reset() override
void PassengerBoarded(Unit *passenger, int8 seatId, bool apply) override
== Fields =======================================
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
npc_wild_wyrm(Creature *creature)
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
TaskScheduler _scheduler
void UpdateAI(uint32 diff) override
void MovementInform(uint32 type, uint32 id) override
void DoAction(int32 action) override
FreedProtoDrake
@ EVENT_CHECK_AREA
@ AREA_VALLEY_OF_ANCIENT_WINTERS
@ TEXT_EMOTE
@ SPELL_SUMMON_LIBERATED
@ NPC_DRAKE
@ SPELL_KILL_CREDIT_PRISONER
@ SPELL_KILL_CREDIT_DRAKE
@ EVENT_REACHED_HOME
@ SPELL_MAMMOTH_SUMMON_OBJECT_1
@ SPELL_SUMMON_MAIN_MAMMOTH_MEAT
@ ITEM_EXPLOSIVE_DEVICE
@ SPELL_MAMMOTH_SUMMON_OBJECT_2
@ SPELL_QUIET_SUICIDE
@ SPELL_MAMMOTH_SUMMON_OBJECT_3
uint8 const ControllableSpellsCount
BrunnhildarPrisoner
@ SPELL_FREE_PRISONER
@ SPELL_ICE_PRISON
@ SPELL_ICE_LANCE
@ SPELL_SHARD_IMPACT
@ SPELL_RIDE_DRAKE
@ PHASE_INITIAL
@ SEAT_INITIAL
@ POINT_START_FIGHT
@ PHASE_DEAD
@ SAY_DODGED
@ SPELL_MIGHTY_SPEAR_THRUST
@ SPELL_FLY_STATE_VISUAL
@ SPELL_FATAL_STRIKE
@ PHASE_MOUTH
@ SPELL_EJECT_PASSENGER_1
@ PHASE_MAX
@ SAY_STRIKE_MISS
@ SPELL_JAWS_OF_DEATH_PERIODIC
@ ACTION_GRIP_FAILING
@ SPELL_FALLING_DRAGON_FEIGN_DEATH
@ SPELL_CLAW_SWIPE_DAMAGE
@ ACTION_FATAL_STRIKE_MISS
@ SAY_PHASE_2
@ SPELL_GRIP
@ SPELL_DODGE_CLAWS
@ SPELL_CLAW_SWIPE_PERIODIC
@ ACTION_GRIP_LOST
@ ACTION_CLAW_SWIPE_DODGE
@ SPELL_THRUST_SPEAR
@ SAY_GRIP_WARN
@ ACTION_CLAW_SWIPE_WARN
@ SPELL_WYRM_KILL_CREDIT
@ SPELL_PLAYER_MOUNT_WYRM
@ PATH_WILD_WYRM
@ SPELL_SPEAR_OF_HODIR
@ SPELL_LOW_HEALTH_TRIGGER
@ SPELL_FIGHT_WYRM
@ SPELL_EJECT_ALL_PASSENGERS
@ POINT_FALL
@ SAY_SWIPE
@ SPELL_PRY_JAWS_OPEN
@ SPELL_FULL_HEAL_MANA
@ SPELL_FATAL_STRIKE_DAMAGE
@ SPELL_GRAB_ON
@ SEAT_MOUTH
@ SPELL_DESPAWN_RIFT
@ NPC_HYLDSMEET_DRAKERIDER
@ SPELL_IMMOLATION
@ SPELL_ABLAZE
@ SPELL_FROSTGIANT_CREDIT
@ SPELL_FROSTWORG_CREDIT
@ NPC_FROSTGIANT
@ NPC_FROSTWORG
BrannBronzebeard
@ EVENT_SCRIPT_8
@ EVENT_SCRIPT_7
@ NPC_A_DISTANT_VOICE
@ EVENT_SCRIPT_1
@ SAY_BRANN_3
@ OBJECT_TOL_SIGNAL_1
@ SAY_VOICE_1
@ OBJECT_TOL_SIGNAL_3
@ SPELL_RESURRECTION
@ SAY_VOICE_2
@ EVENT_SCRIPT_9
@ SAY_VOICE_5
@ EVENT_SCRIPT_13
@ EVENT_SCRIPT_5
@ SAY_BRANN_1
@ EVENT_SCRIPT_3
@ SAY_VOICE_3
@ OBJECT_TOL_SIGNAL_2
@ EVENT_SCRIPT_4
@ SAY_VOICE_4
@ EVENT_SCRIPT_10
@ EVENT_SCRIPT_11
@ EVENT_SCRIPT_2
@ EVENT_SCRIPT_6
@ SAY_BRANN_2
@ NPC_BRANN_BRONZEBEARD
@ OBJECT_TOL_SIGNAL_5
@ OBJECT_TOL_SIGNAL_4
@ EVENT_SCRIPT_12
CatchingUpWithBrann
@ SPELL_CONTACT_BRANN
@ SPELL_DESPAWN_BRANN
void AddSC_storm_peaks()
uint32 const WyrmControlSpells[PHASE_MAX][ControllableSpellsCount]
@ SPELL_SUMMON_EARTHEN
MountingHodirsHelm
@ TEXT_PRONOUNCEMENT_1
@ TEXT_PRONOUNCEMENT_2
@ NPC_HODIRS_HELM_KC
JokkumScriptcast
@ EVENT_KROLMIR_4
@ SPELL_SUMMON_VERANUS_AND_THORIM
@ EVENT_KROLMIR_2
@ NPC_KINGJOKKUM
@ SAY_JOKKUM_7
@ SAY_JOKKUM_2
@ EVENT_KROLMIR_8
@ EVENT_KROLMIR_7
@ SPELL_JOKKUM_SUMMON
@ SAY_HOLD_ON
@ NPC_THORIM
@ SAY_JOKKUM_8
@ SAY_JOKKUM_3
@ SAY_THORIM_2
@ SPELL_JOKKUM_KILL_CREDIT
@ SPELL_PLAYER_CAST_VERANUS_SUMMON
@ SAY_THORIM_4
@ SAY_THORIM_1
@ EVENT_KROLMIR_5
@ EVENT_KROLMIR_1
@ PATH_JOKKUM_END
@ SAY_THORIM_3
@ SAY_JOKKUM_4
@ EVENT_KROLMIR_3
@ EVENT_KROLMIR_9
@ SAY_JOKKUM_5
@ SAY_JOKKUM_1
@ PATH_JOKKUM
@ SAY_JOKKUM_6
@ EVENT_KROLMIR_6
static constexpr uint32 PATH_ESCORT_ICEFANG
JormuttarIsSooFat
@ SPELL_BEAR_FLANK_FAIL
@ TEXT_CARVE_FAIL
@ SPELL_CREATE_BEAR_FLANK