TrinityCore
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
zone_the_wandering_isle.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 "CellImpl.h"
19#include "Containers.h"
20#include "CreatureAI.h"
21#include "CreatureAIImpl.h" // for RAND()
22#include "GameObject.h"
23#include "GameObjectAI.h"
24#include "GridNotifiersImpl.h"
25#include "MotionMaster.h"
26#include "ObjectAccessor.h"
27#include "PhasingHandler.h"
28#include "Player.h"
29#include "ScriptMgr.h"
30#include "ScriptedCreature.h"
31#include "SpellScript.h"
32#include "TaskScheduler.h"
33#include "TemporarySummon.h"
34
36{
38
40
42
44
49};
50
52 { 1465.3872f, 3283.8604f, 137.69096f },
53 { 1431.401f, 3264.001f, 136.02579f },
54 { 1397.2067f, 3276.5618f, 133.84508f },
55 { 1441.566f, 3232.8013f, 135.01802f },
56 { 1403.632f, 3229.1094f, 132.14877f },
57 { 1347.1927f, 3286.5842f, 131.94803f },
58 { 1365.1865f, 3338.9502f, 128.57233f },
59 { 1349.6024f, 3315.0574f, 130.97443f },
60 { 1335.4618f, 3344.019f, 130.42047f },
61 { 1360.1198f, 3378.02f, 127.34183f },
62 { 1435.8524f, 3355.6423f, 173.77744f },
63 { 1432.7031f, 3385.1572f, 184.4187f },
64 { 1452.6094f, 3373.3315f, 187.0402f },
65 { 1426.7778f, 3364.7517f, 184.39569f },
66 { 1450.3646f, 3361.264f, 184.42484f },
67};
68
69Emote constexpr TraineeEmotes[5] =
70{
76};
77
78// 54586 - Huojin Trainee
79// 65470 - Huojin Trainee
80// 54587 - Tushui Trainee
81// 65471 - Tushui Trainee
83{
84 npc_tushui_huojin_trainee(Creature* creature) : ScriptedAI(creature), _defeated(false) { }
85
87 {
89 me->HandleEmoteCommand(emote);
90 return emote;
91 }
92
93 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
94 {
95 if (me->HealthBelowPctDamaged(20, damage))
96 {
97 damage = 0;
98 if (_defeated)
99 return;
100
101 _defeated = true;
102 if (attacker)
103 {
104 if (Player* player = attacker->ToPlayer())
105 player->KilledMonsterCredit(QUEST_29524_KILLCREDIT);
106 }
107
109 me->SetImmuneToPC(true);
110 me->CombatStop();
111
112 _scheduler.Schedule(1s, [this](TaskContext /*task*/)
113 {
115 });
116
117 _scheduler.Schedule(3s, [this](TaskContext /*task*/)
118 {
119 Position currentPosition;
120 float currentDist = 1000.0f;
121 for (Position const& pos : TraineeEndpoints)
122 {
123 float dist = pos.GetExactDist(me);
124 if (dist >= currentDist)
125 continue;
126
127 currentPosition = pos;
128 currentDist = dist;
129 }
130 me->GetMotionMaster()->MovePoint(POINT_DESPAWN, currentPosition);
131 });
132 }
133 }
134
135 void MovementInform(uint32 type, uint32 id) override
136 {
137 if (type != POINT_MOTION_TYPE)
138 return;
139
140 if (id != POINT_DESPAWN)
141 return;
142
144 }
145
146 void JustEngagedWith(Unit* /*attacker*/) override
147 {
148 _scheduler.Schedule(4s, [this](TaskContext task)
149 {
150 if (me->GetVictim())
152
153 task.Repeat(8s);
154 });
155 }
156
157 void UpdateAI(uint32 diff) override
158 {
159 _scheduler.Update(diff);
160
161 if (!UpdateVictim())
162 return;
163 }
164
165 void EnterEvadeMode(EvadeReason why) override
166 {
167 if (!_defeated)
169 }
170
171protected:
174};
175
177{
179};
180
182{
183public:
184 HuojinTraineePartnerSearch(Creature* partner) : _partner(partner), _minDist(10.0f) { }
185
186 bool operator()(Creature const* target)
187 {
189 return false;
190 if (target == _partner)
191 return false;
192 if (target->IsInCombat())
193 return false;
194 if (target->IsInEvadeMode())
195 return false;
196 if (target->isDead())
197 return false;
198
199 float dist = target->GetDistance(_partner);
200 if (dist >= _minDist)
201 return false;
202
203 _minDist = dist;
204 return true;
205 }
206
207private:
209 float _minDist;
210};
211
212// 54586 - Huojin Trainee
213// 65470 - Huojin Trainee
215{
217
218 void JustEngagedWith(Unit* attacker) override
219 {
222
224 if (!partner)
225 return;
226
227 if (partner->AI())
229 }
230
231 void DoAction(int32 action) override
232 {
233 if (action == ACTION_PARTNER_ENTERED_COMBAT)
234 {
236
238 _scheduler.Schedule(1s, [this](TaskContext /*task*/ )
239 {
241 });
242 }
243 }
244
246 {
247 _partnerGuid = guid;
250
251 _scheduler.Schedule(1s, [this](TaskContext /*task*/)
252 {
254 });
255
256 _scheduler.Schedule(4s, [this](TaskContext task)
257 {
259 task.Repeat(4s);
260 });
261 }
262
264 {
265 Creature* partner = nullptr;
268 Cell::VisitGridObjects(me, searcher, 10.0f);
269 return partner;
270 }
271
273 {
274 _partnerGuid = partnerGuid;
275 _scheduler.Schedule(1s, [this, partnerGuid](TaskContext /*task*/)
276 {
277 BeginSparring(partnerGuid);
278 });
279 }
280
282 {
283 Creature* partner = GetNewPartner();
284
285 if (!partner)
286 return;
287
288 BeginSparring(partner->GetGUID());
290 {
291 if (npc_huojin_trainee* ai = CAST_AI(npc_huojin_trainee, partner->GetAI()))
292 ai->BeginSparringDelayed(me->GetGUID());
293 }
294 }
295
296 void JustReachedHome() override
297 {
299 }
300
301 void JustAppeared() override
302 {
303 // partner is already assigned, sparring start is delayed
306 }
307private:
309};
310
312{
313public:
314 TushuiTraineeSearch(Creature* leader, float maxDist) : _leader(leader), _maxDist(maxDist) { }
315
316 bool operator()(Creature const* target) const
317 {
319 return false;
320 if (target->IsInCombat())
321 return false;
322 if (target->IsInEvadeMode())
323 return false;
324 if (target->GetDistance(_leader) >= _maxDist)
325 return false;
326 if (target->isDead())
327 return false;
328
329 return true;
330 }
331
332private:
334 float _maxDist;
335};
336
338{
339 std::list<Creature*> traineeList;
340 TushuiTraineeSearch check(leader, 10.0f);
341 Trinity::CreatureListSearcher<TushuiTraineeSearch> searcher(leader, traineeList, check);
342 Cell::VisitGridObjects(leader, searcher, 10.0f);
343
344 for (Creature* trainee : traineeList)
345 trainee->HandleEmoteCommand(emote);
346}
347
348// 54587 - Tushui Trainee
349// 65471 - Tushui Trainee
351{
353
355 {
356 _scheduler.Schedule(1s, [this](TaskContext task)
357 {
358 Emote emote = PlayRandomEmote();
360 task.Repeat(6s);
361 });
362 }
363
364 void JustReachedHome() override
365 {
367 }
368
369 void JustAppeared() override
370 {
372 }
373
374 void JustEngagedWith(Unit* attacker) override
375 {
378 }
379};
380
381// 61411 - Instructor Zhi
383{
384 npc_instructor_zhi(Creature* creature) : ScriptedAI(creature) { }
385
386 void JustAppeared() override
387 {
388 _scheduler.Schedule(6s, [this](TaskContext task)
389 {
391 me->HandleEmoteCommand(emote);
392
393 task.Schedule(1s, [this, emote](TaskContext /*task*/)
394 {
396 });
397 task.Repeat(6s);
398 });
399 }
400
401 void UpdateAI(uint32 diff) override
402 {
403 _scheduler.Update(diff);
404 }
405
406private:
408};
409
410// 210986 - Edict of Temperance
412{
414
415 bool OnGossipHello(Player* /*player*/) override
416 {
417 me->DespawnOrUnsummon(1ms);
418 return false;
419 }
420};
421
423{
424 // Spells
431 SPELL_DIZZY = 108959,
435
436 // Texts
439
440 // Movement
442
443 // Events
449
450// 54611 - Jaomin Ro
452{
454
455 void JustEngagedWith(Unit* /*who*/) override
456 {
458 }
459
460 void JustReachedHome() override
461 {
464 }
465
466 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
467 {
468 if (spellInfo->Id == SPELL_CSA_AREATRIGGER_DUMMY && target->GetTypeId() == TYPEID_PLAYER && !me->IsInCombat())
469 {
470 Talk(SAY_INTRO, target);
471 me->SetOrientation(1.67690026f);
474 }
475 }
476
477 void UpdateAI(uint32 diff) override
478 {
479 if (!UpdateVictim())
480 return;
481
482 _events.Update(diff);
483
485 return;
486
487 switch (_events.ExecuteEvent())
488 {
490 {
492 DoCast(spellId);
494 break;
495 }
496 case EVENT_HEAL:
497 {
499 me->SetUninteractible(false);
500 break;
501 }
502 case EVENT_MOVE_HOME:
503 {
505 break;
506 }
507 default:
508 break;
509 }
510 }
511
512 void OnHealthDepleted(Unit* attacker, bool /*isKill*/) override
513 {
515 me->AttackStop();
518 _events.Reset();
519 me->SetUninteractible(true);
523 Talk(SAY_DEFEATED, attacker);
524
527 }
528
529private:
531};
532
533// 57750 - Jaomin Ro (Hawk)
535{
537
538 void JustAppeared() override
539 {
541 me->SetSpeedRate(MOVE_RUN, 2.5f);
542 }
543
544 void IsSummonedBy(WorldObject* summonerWO) override
545 {
546 Unit* summoner = summonerWO->ToUnit();
547 if (!summoner)
548 return;
549 Unit* victim = summoner->GetVictim();
550 if (!victim)
551 return;
552
554 _scheduler.Schedule(1s, [this, orientation = me->GetAbsoluteAngle(victim) - me->GetOrientation()](TaskContext /*context*/)
555 {
556 me->GetMotionMaster()->MovePoint(POINT_RANDOM_DEST, me->GetFirstCollisionPosition(40.0f, orientation));
557 });
558 }
559
560 void UpdateAI(uint32 diff) override
561 {
562 _scheduler.Update(diff);
563 }
564
565 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
566 {
567 if (spellInfo->Id == SPELL_HAWK_DIVING_TO_EARTH_DMG && target->GetTypeId() == TYPEID_PLAYER)
568 {
571 }
572 }
573
574 void MovementInform(uint32 type, uint32 pointId) override
575 {
576 if (type != POINT_MOTION_TYPE)
577 return;
578
579 switch (pointId)
580 {
582 {
585 break;
586 }
587 default:
588 break;
589 }
590 }
591
592private:
594};
595
596// 108583 - Force Summoner to Ride Vehicle
598{
599 void HandleScript(SpellEffIndex /*effIndex*/) const
600 {
602 }
603
604 void Register() override
605 {
607 }
608};
609
610// 108582 - Ride Drake
612{
613 void OnRemoveVehicle(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
614 {
615 if (Unit* caster = GetCaster())
616 caster->CastSpell(caster, SPELL_DIZZY, TRIGGERED_FULL_MASK);
617 }
618
619 void Register() override
620 {
622 }
623};
624
625// Quest 29419 - The Missing Driver
627{
628 // Spells
632
633 // Texts
638
641
642 // Waypoint
643 PATH_MOVE_RUN = 5650300,
644 PATH_MOVE_WALK = 5650301,
645
649
651
653
654 // Quests
657
658constexpr Position amberleafPos[5] =
659{
660 { 1410.2014f, 3598.6494f, 89.59319f },
661 { 1456.201f, 3568.265f, 88.39075f },
662 { 1383.158f, 3595.447f, 90.3155f },
663 { 1367.333f, 3594.927f, 88.89806f },
664 { 1350.278f, 3588.938f, 89.17908f }
665};
666
667// 6958 - Areatrigger
669{
670 public:
671 at_min_dimwind_captured() : AreaTriggerScript("at_min_dimwind_captured") { }
672
673 bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
674 {
676 {
677 Creature* minDimwind = player->FindNearestCreatureWithOptions(20.0f, { .StringId = "npc_min_dimwind" });
678
679 if (!minDimwind)
680 return false;
681
684 PhasingHandler::OnConditionChange(player); // phase 630 is added when kill credit but immediately is removed to be added again when Min Dimwind reaches final waypoint
685 }
686
687 return false;
688 }
689};
690
691// 56503 - Min Dimwind (Summon)
693{
695
696 void IsSummonedBy(WorldObject* summoner) override
697 {
698 if (!summoner->IsPlayer())
699 return;
700
701 Creature* amberleafScamp1 = me->FindNearestCreatureWithOptions(20.0f, { .StringId = "npc_amberleaf_scamp_1" });
702 Creature* amberleafScamp2 = me->FindNearestCreatureWithOptions(20.0f, { .StringId = "npc_amberleaf_scamp_2" });
703 Creature* amberleafScamp3 = me->FindNearestCreatureWithOptions(20.0f, { .StringId = "npc_amberleaf_scamp_3" });
704 Creature* amberleafScamp5 = me->FindNearestCreatureWithOptions(20.0f, { .StringId = "npc_amberleaf_scamp_5" });
705
706 if (!amberleafScamp1 || !amberleafScamp2 || !amberleafScamp3 || !amberleafScamp5)
707 return;
708
709 amberleafScamp1->AI()->Talk(SAY_AMBERLEAF_SCAMP_0);
710 amberleafScamp1->GetMotionMaster()->MovePoint(0, amberleafPos[0]);
711
712 amberleafScamp2->GetMotionMaster()->MovePoint(0, amberleafPos[1]);
713
714 amberleafScamp3->GetMotionMaster()->MovePoint(0, amberleafPos[2]);
715
716 amberleafScamp5->GetMotionMaster()->MovePoint(0, amberleafPos[4]);
717
718 _scheduler.Schedule(2s, [this](TaskContext /*task*/)
719 {
720 Creature* amberleafScamp4 = me->FindNearestCreatureWithOptions(20.0f, { .StringId = "npc_amberleaf_scamp_4" });
721
722 if (!amberleafScamp4)
723 return;
724
725 amberleafScamp4->AI()->Talk(SAY_AMBERLEAF_SCAMP_1);
726 amberleafScamp4->GetMotionMaster()->MovePoint(0, amberleafPos[3]);
727 });
728
729 _scheduler.Schedule(5s, [this](TaskContext task)
730 {
731 Unit* summoner = me->ToTempSummon()->GetSummonerUnit();
732
733 if (!summoner)
734 return;
735
736 me->SetFacingToObject(summoner);
737 Talk(SAY_MIN_DIMWIND_TEXT_0, summoner);
738
739 task.Schedule(4s, [this](TaskContext task)
740 {
742
743 task.Schedule(4s, [this](TaskContext /*task*/)
744 {
745 me->GetMotionMaster()->MovePath(PATH_MOVE_RUN, false);
746 });
747 });
748 });
749 }
750
751 void WaypointReached(uint32 waypointId, uint32 pathId) override
752 {
753 if (pathId == PATH_MOVE_RUN)
754 {
755 switch (waypointId)
756 {
757 case WAYPOINT_TALK_0:
758 case WAYPOINT_TALK_1:
759 {
761 break;
762 }
764 {
767 break;
768 }
769 }
770 }
771 else if (pathId == PATH_MOVE_WALK)
772 {
773 if (waypointId == WAYPOINT_DESPAWN)
774 {
775 me->SetFacingTo(0.575958f);
777
778 _scheduler.Schedule(1s, [this](TaskContext /*task*/)
779 {
780 if (me->IsSummon())
781 {
782 Unit* summoner = me->ToTempSummon()->GetSummonerUnit();
783
784 if (!summoner)
785 return;
786
787 summoner->RemoveAurasDueToSpell(SPELL_SUMMON_CART_DRIVER);
788 PhasingHandler::OnConditionChange(summoner);
789 }
790 });
791 }
792 }
793 }
794
795 void UpdateAI(uint32 diff) override
796 {
797 _scheduler.Update(diff);
798 }
799
800private:
802};
803
804// 54130 - Amberleaf Scamp
806{
808
809 void MovementInform(uint32 type, uint32 id) override
810 {
811 if (type == POINT_MOTION_TYPE && id == POINT_MOVE_RANDOM && !me->IsInCombat())
812 {
813 me->GetMotionMaster()->MoveRandom(10.0f);
814
815 _scheduler.Schedule(10s, [this](TaskContext /*task*/)
816 {
817 if (!me->IsInCombat())
819 });
820 }
821 }
822
823 void JustReachedHome() override
824 {
826 }
827
828 void UpdateAI(uint32 diff) override
829 {
830 _scheduler.Update(diff);
831 }
832
833private:
835};
836
837// Quest 29414 - The Way of the Tushui
839{
840 // Texts
842
843 // Waypoints
847
848constexpr Position aysaJumpPos[3] =
849{
850 { 1196.72f, 3492.85f, 90.9836f },
851 { 1192.29f, 3478.69f, 108.788f },
852 { 1197.99f, 3460.63f, 103.04f }
853};
854
855// 59652 - Aysa Cloudsinger (summon)
857{
859
860 void IsSummonedBy(WorldObject* summoner) override
861 {
862 if (!summoner->IsPlayer())
863 return;
864
865 Talk(SAY_GO_CAVE, summoner);
866
867 _scheduler.Schedule(3s, [this](TaskContext task)
868 {
869 me->GetMotionMaster()->MoveJumpWithGravity(aysaJumpPos[0], 12.0f, 17.4735f);
870
871 task.Schedule(1700ms, [this](TaskContext task)
872 {
873 me->GetMotionMaster()->MoveJumpWithGravity(aysaJumpPos[1], 12.0f, 10.7163f);
874
875 task.Schedule(2s, [this](TaskContext /*task*/)
876 {
877 me->GetMotionMaster()->MoveJumpWithGravity(aysaJumpPos[2], 12.0f, 14.6923f, POINT_JUMP);
878 });
879 });
880 });
881 }
882
883 void MovementInform(uint32 type, uint32 pointId) override
884 {
885 if (type != EFFECT_MOTION_TYPE)
886 return;
887
888 if (pointId == POINT_JUMP)
890 }
891
892 void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
893 {
894 if (pathId == PATH_CAVE_OF_MEDITATION)
896 }
897
898 void UpdateAI(uint32 diff) override
899 {
900 _scheduler.Update(diff);
901 }
902
903private:
905};
906
908{
909 // Quest
911
912 // Spells
918
919 // Actions
923
924 // Events
926
927 // Texts
931
932// 59642 - Aysa Cloudsinger (Cave of Meditation)
934{
936
937 void DoAction(int32 action) override
938 {
939 switch (action)
940 {
942 {
943 _finishEvent = false;
945 break;
946 }
948 {
950 break;
951 }
953 {
954 if (_finishEvent)
955 return;
956
957 Creature* aysa = me->FindNearestCreatureWithOptions(40.0f, { .StringId = "npc_aysa_after_quest_29414", .IgnorePhases = true });
958
959 if (!aysa)
960 return;
961
963 _finishEvent = true;
964 break;
965 }
966 default:
967 break;
968 }
969 }
970
971 void UpdateAI(uint32 diff) override
972 {
973 events.Update(diff);
974
975 while (uint32 eventId = events.ExecuteEvent())
976 {
977 switch (eventId)
978 {
980 {
982 events.Repeat(11s);
983 break;
984 }
985 default:
986 break;
987 }
988 }
989 }
990
991private:
994};
995
997{
998 // Waypoint
999 PATH_MASTER_LI = 5485600,
1000
1001 // Texts
1010
1011 // Spells
1014
1015// 54856 - Master Li Fei (Summon)
1017{
1019
1021 {
1022 if (me->IsSummon())
1023 {
1024 Unit* summoner = me->ToTempSummon()->GetSummonerUnit();
1025
1026 if (!summoner)
1027 return;
1028
1029 me->SetFacingToObject(summoner);
1030 }
1031 }
1032
1033 void IsSummonedBy(WorldObject* summoner) override
1034 {
1035 if (!summoner->IsPlayer())
1036 return;
1037
1039
1040 Seconds delay = 23s;
1041
1042 _scheduler.Schedule(delay, [this](TaskContext)
1043 {
1044 FaceToPlayer();
1045 });
1046
1047 delay += 2s;
1048
1049 _scheduler.Schedule(delay, [this](TaskContext)
1050 {
1052 });
1053
1054 delay += 10s;
1055
1056 _scheduler.Schedule(delay, [this](TaskContext)
1057 {
1059 });
1060
1061 delay += 12s;
1062
1063 _scheduler.Schedule(delay, [this](TaskContext)
1064 {
1066 });
1067
1068 delay += 11s;
1069
1070 _scheduler.Schedule(delay, [this](TaskContext)
1071 {
1072 FaceToPlayer();
1074 });
1075
1076 delay += 11s;
1077
1078 _scheduler.Schedule(delay, [this](TaskContext)
1079 {
1081 });
1082
1083 delay += 9s;
1084
1085 _scheduler.Schedule(delay, [this](TaskContext)
1086 {
1087 FaceToPlayer();
1088 });
1089
1090 delay += 2s;
1091
1092 _scheduler.Schedule(delay, [this](TaskContext)
1093 {
1095 });
1096
1097 delay += 6s;
1098
1099 _scheduler.Schedule(delay, [this](TaskContext)
1100 {
1101 Creature* aysa = me->FindNearestCreatureWithOptions(40.0f, { .StringId = "npc_aysa_quest_29414" });
1102
1103 if (!aysa)
1104 return;
1105
1109 me->DespawnOrUnsummon(200ms);
1110 });
1111 }
1112
1113 void UpdateAI(uint32 diff) override
1114 {
1115 _scheduler.Update(diff);
1116 }
1117
1118private:
1120};
1121
1122// 7756 - Areatrigger
1124{
1125public:
1126 at_cave_of_meditation() : AreaTriggerScript("at_cave_of_meditation") { }
1127
1128 bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
1129 {
1131 {
1132 if (!player->HasAura(SPELL_MEDITATION_TIMER_BAR))
1134
1135 return true;
1136 }
1137 return false;
1138 }
1139
1140 bool OnExit(Player* player, AreaTriggerEntry const* /*trigger*/) override
1141 {
1143 return true;
1144 }
1145};
1146
1147// 7645 - Areatrigger
1149{
1150public:
1151 at_inside_of_cave_of_meditation() : AreaTriggerScript("at_inside_of_cave_of_meditation") { }
1152
1153 bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
1154 {
1156 {
1157 if (!player->HasAura(SPELL_SUMMON_MASTER_LI_FEI))
1158 {
1159 Creature* aysa = player->FindNearestCreatureWithOptions(40.0f, { .StringId = "npc_aysa_quest_29414" });
1160
1161 if (!aysa)
1162 return false;
1163
1164 aysa->AI()->Talk(SAY_AYSA_HELP, player);
1167 }
1168
1169 return true;
1170 }
1171 return false;
1172 }
1173
1174 bool OnExit(Player* player, AreaTriggerEntry const* /*trigger*/) override
1175 {
1177 {
1178 if (Creature* aysa = player->FindNearestCreatureWithOptions(40.0f, { .StringId = "npc_aysa_quest_29414", .IgnorePhases = true }))
1179 aysa->AI()->DoAction(ACTION_FINISH_EVENT);
1180 }
1181
1182 return true;
1183 }
1184};
1185
1186// 116421 - Meditation Timer Bar
1188{
1189 void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
1190 {
1191 if (Unit* target = GetTarget())
1192 {
1193 target->ModifyPower(POWER_ALTERNATE_POWER, 1);
1194
1195 if (target->GetPowerPct(POWER_ALTERNATE_POWER) == 100)
1196 {
1199 Remove();
1200 }
1201 }
1202 }
1203
1204 void Register() override
1205 {
1207 }
1208};
1209
1211{
1214
1215// 114684 - Flame Spout
1217{
1218 bool Validate(SpellInfo const* /*spellInfo*/) override
1219 {
1221 }
1222
1223 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1224 {
1226 }
1227
1228 void Register() override
1229 {
1231 }
1232};
1233
1235{
1248
1253
1257}
First const & RAND(First const &first, Second const &second, Rest const &... rest)
int32_t int32
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:148
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:28
@ POINT_MOTION_TYPE
@ EFFECT_MOTION_TYPE
@ TYPEID_PLAYER
Definition: ObjectGuid.h:43
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:150
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:148
#define RegisterCreatureAI(ai_name)
Definition: ScriptMgr.h:1373
#define RegisterGameObjectAI(ai_name)
Definition: ScriptMgr.h:1391
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1364
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
Emote
@ EMOTE_ONESHOT_MONKOFFENSE_ATTACKUNARMEDOFF
@ EMOTE_ONESHOT_MONKOFFENSE_PARRYUNARMED
@ EMOTE_STATE_READY_UNARMED
@ EMOTE_ONESHOT_PALMSTRIKE
@ EMOTE_ONESHOT_BOW
@ EMOTE_STATE_MONKOFFENSE_READYUNARMED
@ EMOTE_ONESHOT_MONKOFFENSE_SPECIALUNARMED
@ EMOTE_ONESHOT_NONE
@ EMOTE_ONESHOT_MONKOFFENSE_ATTACKUNARMED
@ SPELL_EFFECT_SCRIPT_EFFECT
@ POWER_ALTERNATE_POWER
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_CONTROL_VEHICLE
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:277
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:896
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2171
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2165
EvadeReason
Definition: UnitAICommon.h:30
#define CAST_AI(a, b)
Definition: UnitAI.h:29
@ MOVE_RUN
Definition: UnitDefines.h:118
@ REACT_PASSIVE
Definition: UnitDefines.h:540
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:42
DamageEffectType
Definition: UnitDefines.h:154
@ UNIT_FLAG_NON_ATTACKABLE_2
Definition: UnitDefines.h:183
@ UNIT_STATE_CASTING
Definition: Unit.h:274
@ UNIT_STATE_STUNNED
Definition: Unit.h:262
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2164
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2170
Unit * GetCaster() const
Unit * GetTarget() const
HookList< EffectApplyHandler > OnEffectRemove
Definition: SpellScript.h:2160
void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:218
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:244
Creature *const me
Definition: CreatureAI.h:61
void SetImmuneToPC(bool apply) override
Definition: Creature.h:184
void SetReactState(ReactStates st)
Definition: Creature.h:174
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2420
void InitializeReactState()
Definition: Creature.cpp:1303
bool IsInEvadeMode() const
Definition: Creature.h:217
CreatureAI * AI() const
Definition: Creature.h:228
uint32 ExecuteEvent()
Definition: EventMap.cpp:77
void Update(uint32 time)
Definition: EventMap.h:61
void Repeat(Milliseconds time)
Definition: EventMap.cpp:67
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:40
void CancelEvent(uint32 eventId)
Definition: EventMap.cpp:135
void Reset()
Definition: EventMap.cpp:25
GameObject *const me
Definition: GameObjectAI.h:50
GameObjectAI(GameObject *go, uint32 scriptId={}) noexcept
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forceRespawnTime=0s)
HuojinTraineePartnerSearch(Creature *partner)
bool operator()(Creature const *target)
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< 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< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void MoveTargetedHome()
void MoveRandom(float wanderDistance=0.0f, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_DEFAULT, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void InitializeDefault()
bool IsPlayer() const
Definition: Object.h:248
static Unit * ToUnit(Object *o)
Definition: Object.h:261
TypeID GetTypeId() const
Definition: Object.h:209
uint32 GetEntry() const
Definition: Object.h:197
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:195
static Player * ToPlayer(Object *o)
Definition: Object.h:249
static bool OnConditionChange(WorldObject *object, bool updateVisibility=true)
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: Player.cpp:15961
uint32 const Id
Definition: SpellInfo.h:323
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:170
Unit * GetCaster() const
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:894
TaskContext & Schedule(TaskScheduler::duration_t time, TaskScheduler::task_handler_t task)
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update(success_t const &callback=nullptr)
Unit * GetSummonerUnit() const
TushuiTraineeSearch(Creature *leader, float maxDist)
bool operator()(Creature const *target) const
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:160
virtual void DoAction(int32 param)
Definition: UnitAI.h:73
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:632
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition: Unit.cpp:5939
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3775
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10505
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3173
MotionMaster * GetMotionMaster()
Definition: Unit.h:1703
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:13092
bool IsAlive() const
Definition: Unit.h:1177
TempSummon * ToTempSummon()
Definition: Unit.h:1808
UnitAI * GetAI() const
Definition: Unit.h:665
void SetUninteractible(bool apply)
Definition: Unit.cpp:8372
void SetEmoteState(Emote emote)
Definition: Unit.h:862
bool IsSummon() const
Definition: Unit.h:746
Unit * GetVictim() const
Definition: Unit.h:723
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition: Unit.cpp:8750
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:13074
bool HasUnitState(const uint32 f) const
Definition: Unit.h:740
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4751
void RemoveAllAuras()
Definition: Unit.cpp:4329
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition: Unit.cpp:1629
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition: Unit.h:790
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:843
bool AttackStop()
Definition: Unit.cpp:5893
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3921
bool IsInCombat() const
Definition: Unit.h:1054
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:844
bool isDead() const
Definition: Unit.h:1179
Creature * FindNearestCreatureWithOptions(float range, FindCreatureOptions const &options) const
Definition: Object.cpp:2249
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2990
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1139
bool OnExit(Player *player, AreaTriggerEntry const *) override
bool OnTrigger(Player *player, AreaTriggerEntry const *) override
bool OnTrigger(Player *player, AreaTriggerEntry const *) override
bool OnExit(Player *player, AreaTriggerEntry const *) override
bool OnTrigger(Player *player, AreaTriggerEntry const *) override
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void HandleEffectPeriodic(AuraEffect const *)
void OnRemoveVehicle(AuraEffect const *, AuraEffectHandleModes) const
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition: Containers.h:110
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:179
constexpr void SetOrientation(float orientation)
Definition: Position.h:81
float GetExactDist(float x, float y, float z) const
Definition: Position.h:128
float GetAbsoluteAngle(float x, float y) const
Definition: Position.h:135
constexpr float GetOrientation() const
Definition: Position.h:89
ScriptedAI(Creature *creature, uint32 scriptId=0) noexcept
bool OnGossipHello(Player *) override
void UpdateAI(uint32 diff) override
void MovementInform(uint32 type, uint32 id) override
npc_aysa_cloudsinger_summon(Creature *creature)
void IsSummonedBy(WorldObject *summoner) override
void MovementInform(uint32 type, uint32 pointId) override
void WaypointPathEnded(uint32, uint32 pathId) override
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *attacker) override
npc_huojin_trainee(Creature *creature)
void BeginSparring(ObjectGuid guid)
void DoAction(int32 action) override
Creature * GetNewPartner() const
void BeginSparringDelayed(ObjectGuid partnerGuid)
npc_instructor_zhi(Creature *creature)
void UpdateAI(uint32 diff) override
void IsSummonedBy(WorldObject *summonerWO) override
void MovementInform(uint32 type, uint32 pointId) override
void UpdateAI(uint32 diff) override
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void JustEngagedWith(Unit *) override
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void UpdateAI(uint32 diff) override
void JustReachedHome() override
void OnHealthDepleted(Unit *attacker, bool) override
npc_master_li_fei_summon(Creature *creature)
void IsSummonedBy(WorldObject *summoner) override
void UpdateAI(uint32 diff) override
void WaypointReached(uint32 waypointId, uint32 pathId) override
void UpdateAI(uint32 diff) override
void IsSummonedBy(WorldObject *summoner) override
void EnterEvadeMode(EvadeReason why) override
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *) override
void MovementInform(uint32 type, uint32 id) override
void DamageTaken(Unit *attacker, uint32 &damage, DamageEffectType, SpellInfo const *) override
npc_tushui_huojin_trainee(Creature *creature)
void JustEngagedWith(Unit *attacker) override
npc_tushui_leading_trainee(Creature *creature)
Emote constexpr TraineeEmotes[5]
@ SPELL_BLACKOUT_KICK
@ QUEST_29524_KILLCREDIT
@ NPC_TUSHUI_TRAINEE_FEMALE
@ NPC_HUOJIN_TRAINEE_FEMALE
@ NPC_HUOJIN_TRAINEE_MALE
@ NPC_TUSHUI_TRAINEE_MALE
constexpr Position amberleafPos[5]
@ ACTION_FINISH_MEDITATION
@ SPELL_AYSA_CAVE_OF_SCROLLS_COMP
@ SAY_AYSA_FINISH_MEDITATION
@ QUEST_THE_WAY_OF_THE_TUSHUI
@ SPELL_MEDITATION_TIMER_BAR
@ SPELL_SUMMON_AMBERLEAF_TROUBLEMAKER
@ SPELL_CAVE_OF_SCROLLS_CREDIT
@ SPELL_SUMMON_MASTER_LI_FEI
@ EVENT_SUMMON_AMBERLEAF
@ ACTION_START_MEDITATION
void HandleEmoteNearbyTushuiTrainees(Creature *leader, Emote emote)
@ SPELL_UPDATE_PHASE_SHIFT_DEMON_CREATOR
void AddSC_zone_the_wandering_isle()
constexpr Position aysaJumpPos[3]
@ SAY_MIN_DIMWIND_TEXT_3
@ SAY_MIN_DIMWIND_TEXT_1
@ SPELL_SERVERSIDE_DRIVER_CREDIT
@ SAY_MIN_DIMWIND_TEXT_2
@ SAY_AMBERLEAF_SCAMP_1
@ QUEST_THE_MISSING_DRIVER
@ SAY_AMBERLEAF_SCAMP_0
@ SAY_MIN_DIMWIND_TEXT_0
@ SPELL_SUMMON_CART_DRIVER
@ SPELL_FORCE_SUMMON_CART_DRIVER
@ SPELL_SERVERSIDE_KILL_CREDIT
@ SPELL_FORCE_SUMMONER_TO_RIDE
@ SPELL_HAWK_DIVING_TO_EARTH_DMG
@ SPELL_HAWK_DIVING_TO_EARTH
@ SPELL_CSA_AREATRIGGER_DUMMY
@ SPELL_BABY_ELEPHANT_TAKES_A_BATH
@ SPELL_EJECT_ALL_PASSENGERS
@ SPELL_FLAME_SPOUT_VISUAL
@ ACTION_PARTNER_ENTERED_COMBAT
Position const TraineeEndpoints[]
@ PATH_CAVE_OF_MEDITATION