TrinityCore
Loading...
Searching...
No Matches
npcs_special.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 "CellImpl.h"
20#include "CharmInfo.h"
21#include "CombatAI.h"
22#include "Containers.h"
23#include "CreatureTextMgr.h"
24#include "GameEventMgr.h"
25#include "GameObject.h"
26#include "GameObjectAI.h"
27#include "GridNotifiersImpl.h"
28#include "Log.h"
29#include "MotionMaster.h"
30#include "MoveSplineInit.h"
31#include "ObjectAccessor.h"
32#include "ObjectMgr.h"
33#include "PassiveAI.h"
34#include "Player.h"
35#include "QuestDef.h"
36#include "ScriptedEscortAI.h"
37#include "ScriptedGossip.h"
38#include "SpellAuras.h"
39#include "SpellHistory.h"
40#include "SpellInfo.h"
41#include "SpellMgr.h"
42#include "TemporarySummon.h"
43#include "Vehicle.h"
44
45/*########
46# npc_air_force_bots
47#########*/
48
50{
51 TRIPWIRE, // do not attack flying players, smaller range
52 ALARMBOT, // attack flying players, casts guard's mark
53
54 SPELL_GUARDS_MARK = 38067
55};
56
57float constexpr RANGE_TRIPWIRE = 15.0f;
58float constexpr RANGE_ALARMBOT = 100.0f;
59
66
68{
69 {2614, 15241, ALARMBOT}, // Air Force Alarm Bot (Alliance)
70 {2615, 15242, ALARMBOT}, // Air Force Alarm Bot (Horde)
71 {21974, 21976, ALARMBOT}, // Air Force Alarm Bot (Area 52)
72 {21993, 15242, ALARMBOT}, // Air Force Guard Post (Horde - Bat Rider)
73 {21996, 15241, ALARMBOT}, // Air Force Guard Post (Alliance - Gryphon)
74 {21997, 21976, ALARMBOT}, // Air Force Guard Post (Goblin - Area 52 - Zeppelin)
75 {21999, 15241, TRIPWIRE}, // Air Force Trip Wire - Rooftop (Alliance)
76 {22001, 15242, TRIPWIRE}, // Air Force Trip Wire - Rooftop (Horde)
77 {22002, 15242, TRIPWIRE}, // Air Force Trip Wire - Ground (Horde)
78 {22003, 15241, TRIPWIRE}, // Air Force Trip Wire - Ground (Alliance)
79 {22063, 21976, TRIPWIRE}, // Air Force Trip Wire - Rooftop (Goblin - Area 52)
80 {22065, 22064, ALARMBOT}, // Air Force Guard Post (Ethereal - Stormspire)
81 {22066, 22067, ALARMBOT}, // Air Force Guard Post (Scryer - Dragonhawk)
82 {22068, 22064, TRIPWIRE}, // Air Force Trip Wire - Rooftop (Ethereal - Stormspire)
83 {22069, 22064, ALARMBOT}, // Air Force Alarm Bot (Stormspire)
84 {22070, 22067, TRIPWIRE}, // Air Force Trip Wire - Rooftop (Scryer)
85 {22071, 22067, ALARMBOT}, // Air Force Alarm Bot (Scryer)
86 {22078, 22077, ALARMBOT}, // Air Force Alarm Bot (Aldor)
87 {22079, 22077, ALARMBOT}, // Air Force Guard Post (Aldor - Gryphon)
88 {22080, 22077, TRIPWIRE}, // Air Force Trip Wire - Rooftop (Aldor)
89 {22086, 22085, ALARMBOT}, // Air Force Alarm Bot (Sporeggar)
90 {22087, 22085, ALARMBOT}, // Air Force Guard Post (Sporeggar - Spore Bat)
91 {22088, 22085, TRIPWIRE}, // Air Force Trip Wire - Rooftop (Sporeggar)
92 {22090, 22089, ALARMBOT}, // Air Force Guard Post (Toshley's Station - Flying Machine)
93 {22124, 22122, ALARMBOT}, // Air Force Alarm Bot (Cenarion)
94 {22125, 22122, ALARMBOT}, // Air Force Guard Post (Cenarion - Stormcrow)
95 {22126, 22122, ALARMBOT} // Air Force Trip Wire - Rooftop (Cenarion Expedition)
96};
97
99{
100public:
101 npc_air_force_bots() : CreatureScript("npc_air_force_bots") { }
102
104 {
105 static AirForceSpawn const& FindSpawnFor(uint32 entry)
106 {
107 for (AirForceSpawn const& spawn : airforceSpawns)
108 {
109 if (spawn.myEntry == entry)
110 {
111 ASSERT_NODEBUGINFO(sObjectMgr->GetCreatureTemplate(spawn.otherEntry), "Invalid creature entry %u in 'npc_air_force_bots' script", spawn.otherEntry);
112 return spawn;
113 }
114 }
115 ASSERT_NODEBUGINFO(false, "Unhandled creature with entry %u is assigned 'npc_air_force_bots' script", entry);
116 }
117
119
121 {
123
124 if (!guard && (guard = me->SummonCreature(_spawn.otherEntry, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5min)))
125 _myGuard = guard->GetGUID();
126
127 return guard;
128 }
129
130 void UpdateAI(uint32 /*diff*/) override
131 {
132 if (_toAttack.empty())
133 return;
134
135 Creature* guard = GetOrSummonGuard();
136 if (!guard)
137 return;
138
139 // Keep the list of targets for later on when the guards will be alive
140 if (!guard->IsAlive())
141 return;
142
143 for (ObjectGuid guid : _toAttack)
144 {
145 Unit* target = ObjectAccessor::GetUnit(*me, guid);
146 if (!target)
147 continue;
148 if (guard->IsEngagedBy(target))
149 continue;
150
151 guard->EngageWithTarget(target);
152 if (_spawn.type == ALARMBOT)
153 guard->CastSpell(target, SPELL_GUARDS_MARK, true);
154 }
155
156 _toAttack.clear();
157 }
158
159 void MoveInLineOfSight(Unit* who) override
160 {
161 // guards are only spawned against players
162 if (who->GetTypeId() != TYPEID_PLAYER)
163 return;
164
165 // we're already scheduled to attack this player on our next tick, don't bother checking
166 if (_toAttack.find(who->GetGUID()) != _toAttack.end())
167 return;
168
169 // check if they're in range
171 return;
172
173 // check if they're hostile
174 if (!(me->IsHostileTo(who) || who->IsHostileTo(me)))
175 return;
176
177 // check if they're a valid attack target
178 if (!me->IsValidAttackTarget(who))
179 return;
180
181 if ((_spawn.type == TRIPWIRE) && who->IsFlying())
182 return;
183
184 _toAttack.insert(who->GetGUID());
185 }
186
187 private:
190 std::unordered_set<ObjectGuid> _toAttack;
191
192 };
193
194 CreatureAI* GetAI(Creature* creature) const override
195 {
196 return new npc_air_force_botsAI(creature);
197 }
198};
199
200/*########
201# npc_chicken_cluck
202#########*/
203
212
214{
215public:
216 npc_chicken_cluck() : CreatureScript("npc_chicken_cluck") { }
217
219 {
221 {
222 Initialize();
223 }
224
226 {
227 ResetFlagTimer = 120000;
228 }
229
231
232 void Reset() override
233 {
234 Initialize();
237 }
238
239 void JustEngagedWith(Unit* /*who*/) override { }
240
241 void UpdateAI(uint32 diff) override
242 {
243 // Reset flags after a certain time has passed so that the next player has to start the 'event' again
245 {
246 if (ResetFlagTimer <= diff)
247 {
249 return;
250 }
251 else
252 ResetFlagTimer -= diff;
253 }
254
255 UpdateVictim();
256 }
257
258 void ReceiveEmote(Player* player, uint32 emote) override
259 {
260 switch (emote)
261 {
263 if (player->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_NONE && rand32() % 30 == 1)
264 {
267 Talk(player->GetTeam() == HORDE ? EMOTE_HELLO_H : EMOTE_HELLO_A);
268 }
269 break;
270 case TEXT_EMOTE_CHEER:
272 {
276 }
277 break;
278 }
279 }
280
281 void OnQuestAccept(Player* /*player*/, Quest const* quest) override
282 {
283 if (quest->GetQuestId() == QUEST_CLUCK)
284 Reset();
285 }
286
287 void OnQuestReward(Player* /*player*/, Quest const* quest, LootItemType /*type*/, uint32 /*opt*/) override
288 {
289 if (quest->GetQuestId() == QUEST_CLUCK)
290 Reset();
291 }
292 };
293
294 CreatureAI* GetAI(Creature* creature) const override
295 {
296 return new npc_chicken_cluckAI(creature);
297 }
298};
299
300/*######
301## npc_dancing_flames
302######*/
303
310
312{
313 npc_dancing_flames(Creature* creature) : ScriptedAI(creature) { }
314
315 void Reset() override
316 {
320 float x, y, z;
321 me->GetPosition(x, y, z);
322 me->Relocate(x, y, z + 1.05f);
323 }
324
325 void UpdateAI(uint32 diff) override
326 {
327 _scheduler.Update(diff);
328 }
329
330 void ReceiveEmote(Player* player, uint32 emote) override
331 {
332 if (me->IsWithinLOS(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()) && me->IsWithinDistInMap(player, 30.0f))
333 {
334 // She responds to emotes not instantly but ~1500ms later
335 // If you first /bow, then /wave before dancing flames bow back, it doesnt bow at all and only does wave
336 // If you're performing emotes too fast, she will not respond to them
337 // Means she just replaces currently scheduled event with new after receiving new emote
339
340 switch (emote)
341 {
342 case TEXT_EMOTE_KISS:
343 _scheduler.Schedule(1500ms, [this](TaskContext const& /*context*/)
344 {
346 });
347 break;
348 case TEXT_EMOTE_WAVE:
349 _scheduler.Schedule(1500ms, [this](TaskContext const& /*context*/)
350 {
352 });
353 break;
354 case TEXT_EMOTE_BOW:
355 _scheduler.Schedule(1500ms, [this](TaskContext const& /*context*/)
356 {
358 });
359 break;
360 case TEXT_EMOTE_JOKE:
361 _scheduler.Schedule(1500ms, [this](TaskContext const& /*context*/)
362 {
364 });
365 break;
366 case TEXT_EMOTE_DANCE:
367 if (!player->HasAura(SPELL_FIERY_SEDUCTION))
368 {
369 DoCast(player, SPELL_FIERY_SEDUCTION, true);
371 }
372 break;
373 }
374 }
375 }
376
377private:
379};
380
381/*######
382## npc_torch_tossing_target_bunny_controller
383######*/
384
389
391{
392public:
393 npc_torch_tossing_target_bunny_controller() : CreatureScript("npc_torch_tossing_target_bunny_controller") { }
394
396 {
398
399 void Reset() override
400 {
401 _scheduler.Schedule(Seconds(2), [this](TaskContext& context)
402 {
404 _scheduler.Schedule(Seconds(3), [this](TaskContext const& /*context*/)
405 {
407 });
408 context.Repeat(Seconds(5));
409 });
410 }
411
412 void UpdateAI(uint32 diff) override
413 {
414 _scheduler.Update(diff);
415 }
416
417 private:
419 };
420
421 CreatureAI* GetAI(Creature* creature) const override
422 {
424 }
425};
426
427/*######
428## npc_midsummer_bunny_pole
429######*/
430
440
442{
443public:
444 npc_midsummer_bunny_pole() : CreatureScript("npc_midsummer_bunny_pole") { }
445
447 {
449 {
450 Initialize();
451 }
452
454 {
455 events.Reset();
456 running = false;
457 }
458
459 void Reset() override
460 {
461 Initialize();
462 }
463
464 void DoAction(int32 /*action*/) override
465 {
466 // Don't start event if it's already running.
467 if (running)
468 return;
469
470 running = true;
472 }
473
475 {
476 // Returns true if no nearby player has aura "Test Ribbon Pole Channel".
477 std::list<Player*> players;
480 Cell::VisitWorldObjects(me, searcher, 10.0f);
481
482 return players.empty();
483 }
484
485 void UpdateAI(uint32 diff) override
486 {
487 if (!running)
488 return;
489
490 events.Update(diff);
491
492 switch (events.ExecuteEvent())
493 {
495 {
496 if (checkNearbyPlayers())
497 {
498 Reset();
499 return;
500 }
501
503 me->CastSpell(go, SPELL_RED_FIRE_RING, true);
504
506 }
507 break;
509 {
510 if (checkNearbyPlayers())
511 {
512 Reset();
513 return;
514 }
515
518
520 }
521 break;
522 }
523 }
524
525 private:
528 };
529
530 CreatureAI* GetAI(Creature* creature) const override
531 {
532 return new npc_midsummer_bunny_poleAI(creature);
533 }
534};
535
536/*######
537## Triage quest
538######*/
539
549
551{
552 {-3757.38f, -4533.05f, 14.16f, 3.62f}, // Top-far-right bunk as seen from entrance
553 {-3754.36f, -4539.13f, 14.16f, 5.13f}, // Top-far-left bunk
554 {-3749.54f, -4540.25f, 14.28f, 3.34f}, // Far-right bunk
555 {-3742.10f, -4536.85f, 14.28f, 3.64f}, // Right bunk near entrance
556 {-3755.89f, -4529.07f, 14.05f, 0.57f}, // Far-left bunk
557 {-3749.51f, -4527.08f, 14.07f, 5.26f}, // Mid-left bunk
558 {-3746.37f, -4525.35f, 14.16f, 5.22f}, // Left bunk near entrance
559};
560
561//alliance run to where
562#define A_RUNTOX -3742.96f
563#define A_RUNTOY -4531.52f
564#define A_RUNTOZ 11.91f
565
567{
568 {-1013.75f, -3492.59f, 62.62f, 4.34f}, // Left, Behind
569 {-1017.72f, -3490.92f, 62.62f, 4.34f}, // Right, Behind
570 {-1015.77f, -3497.15f, 62.82f, 4.34f}, // Left, Mid
571 {-1019.51f, -3495.49f, 62.82f, 4.34f}, // Right, Mid
572 {-1017.25f, -3500.85f, 62.98f, 4.34f}, // Left, front
573 {-1020.95f, -3499.21f, 62.98f, 4.34f} // Right, Front
574};
575
576//horde run to where
577#define H_RUNTOX -1016.44f
578#define H_RUNTOY -3508.48f
579#define H_RUNTOZ 62.96f
580
582{
583 12938, // 12938 Injured Alliance Soldier
584 12936, // 12936 Badly injured Alliance Soldier
585 12937 // 12937 Critically injured Alliance Soldier
586};
587
589{
590 12923, //12923 Injured Soldier
591 12924, //12924 Badly injured Soldier
592 12925 //12925 Critically injured Soldier
593};
594
595/*######
596## npc_doctor (handles both Gustaf Vanhowzen and Gregory Victor)
597######*/
599{
600public:
601 npc_doctor() : CreatureScript("npc_doctor") { }
602
603 struct npc_doctorAI : public ScriptedAI
604 {
605 npc_doctorAI(Creature* creature) : ScriptedAI(creature)
606 {
607 Initialize();
608 }
609
611 {
613
614 SummonPatientTimer = 10000;
618
619 Patients.clear();
620 Coordinates.clear();
621
622 Event = false;
623 }
624
626
631
632 bool Event;
633
635 std::vector<Position const*> Coordinates;
636
637 void Reset() override
638 {
639 Initialize();
640 me->SetUninteractible(false);
641 }
642
643 void BeginEvent(Player* player)
644 {
645 PlayerGUID = player->GetGUID();
646
647 SummonPatientTimer = 10000;
651
652 switch (me->GetEntry())
653 {
654 case DOCTOR_ALLIANCE:
655 for (uint8 i = 0; i < ALLIANCE_COORDS; ++i)
656 Coordinates.push_back(&AllianceCoords[i]);
657 break;
658 case DOCTOR_HORDE:
659 for (uint8 i = 0; i < HORDE_COORDS; ++i)
660 Coordinates.push_back(&HordeCoords[i]);
661 break;
662 }
663
664 Event = true;
665 me->SetUninteractible(true);
666 }
667
668 void PatientDied(Position const* point)
669 {
671 if (player && ((player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)))
672 {
674
675 if (PatientDiedCount > 5 && Event)
676 {
677 if (player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
678 player->FailQuest(6624);
679 else if (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
680 player->FailQuest(6622);
681
682 Reset();
683 return;
684 }
685
686 Coordinates.push_back(point);
687 }
688 else
689 // If no player or player abandon quest in progress
690 Reset();
691 }
692
693 void PatientSaved(Creature* /*soldier*/, Player* player, Position const* point)
694 {
695 if (player && PlayerGUID == player->GetGUID())
696 {
697 if ((player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
698 {
700
701 if (PatientSavedCount == 15)
702 {
703 if (!Patients.empty())
704 {
705 for (GuidList::const_iterator itr = Patients.begin(); itr != Patients.end(); ++itr)
706 {
707 if (Creature* patient = ObjectAccessor::GetCreature(*me, *itr))
708 patient->setDeathState(JUST_DIED);
709 }
710 }
711
712 if (player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
713 player->AreaExploredOrEventHappens(6624);
714 else if (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
715 player->AreaExploredOrEventHappens(6622);
716
717 Reset();
718 return;
719 }
720
721 Coordinates.push_back(point);
722 }
723 }
724 }
725
726 void UpdateAI(uint32 diff) override;
727
728 void JustEngagedWith(Unit* /*who*/) override { }
729
730 void OnQuestAccept(Player* player, Quest const* quest) override
731 {
732 if ((quest->GetQuestId() == 6624) || (quest->GetQuestId() == 6622))
733 BeginEvent(player);
734 }
735 };
736
737 CreatureAI* GetAI(Creature* creature) const override
738 {
739 return new npc_doctorAI(creature);
740 }
741};
742
743/*#####
744## npc_injured_patient (handles all the patients, no matter Horde or Alliance)
745#####*/
746
748{
749public:
750 npc_injured_patient() : CreatureScript("npc_injured_patient") { }
751
753 {
755 {
756 Initialize();
757 }
758
760 {
762 Coord = nullptr;
763 }
764
767
768 void Reset() override
769 {
770 Initialize();
771
772 //no select
773 me->SetUninteractible(false);
774
775 //no regen health
777
778 //to make them lay with face down
780
781 uint32 mobId = me->GetEntry();
782
783 switch (mobId)
784 { //lower max health
785 case 12923:
786 case 12938: //Injured Soldier
788 break;
789 case 12924:
790 case 12936: //Badly injured Soldier
792 break;
793 case 12925:
794 case 12937: //Critically injured Soldier
796 break;
797 }
798 }
799
800 void JustEngagedWith(Unit* /*who*/) override { }
801
802 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
803 {
804 Player* player = caster->ToPlayer();
805 if (!player || !me->IsAlive() || spellInfo->Id != 20804)
806 return;
807
808 if (player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
809 if (!DoctorGUID.IsEmpty())
811 ENSURE_AI(npc_doctor::npc_doctorAI, doctor->AI())->PatientSaved(me, player, Coord);
812
813 //make uninteractible
814 me->SetUninteractible(true);
815
816 //regen health
818
819 //stand up
821
822 Talk(SAY_DOC);
823
824 uint32 mobId = me->GetEntry();
825 me->SetWalk(false);
826
827 switch (mobId)
828 {
829 case 12923:
830 case 12924:
831 case 12925:
833 break;
834 case 12936:
835 case 12937:
836 case 12938:
838 break;
839 }
840 }
841
842 void UpdateAI(uint32 /*diff*/) override
843 {
844 //lower HP on every world tick makes it a useful counter, not officlone though
845 if (me->IsAlive() && me->GetHealth() > 6)
846 me->ModifyHealth(-5);
847
848 if (me->IsAlive() && me->GetHealth() <= 6)
849 {
851 me->SetUninteractible(true);
854
855 if (!DoctorGUID.IsEmpty())
857 ENSURE_AI(npc_doctor::npc_doctorAI, doctor->AI())->PatientDied(Coord);
858 }
859 }
860 };
861
862 CreatureAI* GetAI(Creature* creature) const override
863 {
864 return new npc_injured_patientAI(creature);
865 }
866};
867
869{
870 if (Event && SummonPatientCount >= 20)
871 {
872 Reset();
873 return;
874 }
875
876 if (Event)
877 {
878 if (SummonPatientTimer <= diff)
879 {
880 if (Coordinates.empty())
881 return;
882
883 uint32 patientEntry = 0;
884
885 switch (me->GetEntry())
886 {
887 case DOCTOR_ALLIANCE:
888 patientEntry = AllianceSoldierId[rand32() % 3];
889 break;
890 case DOCTOR_HORDE:
891 patientEntry = HordeSoldierId[rand32() % 3];
892 break;
893 default:
894 TC_LOG_ERROR("scripts", "Invalid entry for Triage doctor. Please check your database");
895 return;
896 }
897
898 std::vector<Position const*>::iterator point = Coordinates.begin();
899 std::advance(point, urand(0, Coordinates.size() - 1));
900
901 if (Creature* Patient = me->SummonCreature(patientEntry, **point, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s))
902 {
903 Patients.push_back(Patient->GetGUID());
904 ENSURE_AI(npc_injured_patient::npc_injured_patientAI, Patient->AI())->DoctorGUID = me->GetGUID();
905 ENSURE_AI(npc_injured_patient::npc_injured_patientAI, Patient->AI())->Coord = *point;
906
907 Coordinates.erase(point);
908 }
909
910 SummonPatientTimer = 10000;
912 }
913 else
914 SummonPatientTimer -= diff;
915 }
916}
917
918/*######
919## npc_guardian
920######*/
921
926
928{
929public:
930 npc_guardian() : CreatureScript("npc_guardian") { }
931
933 {
934 npc_guardianAI(Creature* creature) : ScriptedAI(creature) { }
935
936 void Reset() override
937 {
938 me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
939 }
940
941 void JustEngagedWith(Unit* /*who*/) override
942 {
943 }
944
945 void UpdateAI(uint32 /*diff*/) override
946 {
947 if (!UpdateVictim())
948 return;
949
950 if (me->isAttackReady())
951 {
952 DoCastVictim(SPELL_DEATHTOUCH, true);
953 me->resetAttackTimer();
954 }
955 }
956 };
957
958 CreatureAI* GetAI(Creature* creature) const override
959 {
960 return new npc_guardianAI(creature);
961 }
962};
963
965{
966public:
967 npc_steam_tonk() : CreatureScript("npc_steam_tonk") { }
968
970 {
971 npc_steam_tonkAI(Creature* creature) : ScriptedAI(creature) { }
972
973 void Reset() override { }
974 void JustEngagedWith(Unit* /*who*/) override { }
975
976 void OnPossess(bool apply)
977 {
978 if (apply)
979 {
980 // Initialize the action bar without the melee attack command
981 me->InitCharmInfo();
982 me->GetCharmInfo()->InitEmptyActionBar(false);
983
984 me->SetReactState(REACT_PASSIVE);
985 }
986 else
987 me->SetReactState(REACT_AGGRESSIVE);
988 }
989 };
990
991 CreatureAI* GetAI(Creature* creature) const override
992 {
993 return new npc_steam_tonkAI(creature);
994 }
995};
996
998{
1036
1053
1091
1093{
1094 public:
1095 npc_tournament_mount() : CreatureScript("npc_tournament_mount") { }
1096
1098 {
1100 {
1101 _pennantSpellId = 0;
1102 }
1103
1104 void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override
1105 {
1106 Player* player = passenger->ToPlayer();
1107 if (!player)
1108 return;
1109
1110 if (apply)
1111 {
1112 _pennantSpellId = GetPennantSpellId(player);
1113 player->CastSpell(nullptr, _pennantSpellId, true);
1114 }
1115 else
1116 player->RemoveAurasDueToSpell(_pennantSpellId);
1117 }
1118
1119 private:
1121
1123 {
1124 switch (me->GetEntry())
1125 {
1128 {
1133 else
1135 }
1137 {
1142 else
1144 }
1146 {
1151 else
1153 }
1156 {
1161 else
1163 }
1165 {
1170 else
1172 }
1173 case NPC_EXODAR_ELEKK:
1174 {
1179 else
1181 }
1182 case NPC_IRONFORGE_RAM:
1183 {
1188 else
1190 }
1192 {
1197 else
1199 }
1200 case NPC_ORGRIMMAR_WOLF:
1201 {
1206 else
1208 }
1210 {
1215 else
1217 }
1219 {
1222 else if (player->HasAchieved(ACHIEVEMENT_ARGENT_VALOR))
1224 else
1226 }
1227 default:
1228 return 0;
1229 }
1230 }
1231 };
1232
1233 CreatureAI* GetAI(Creature* creature) const override
1234 {
1235 return new npc_tournament_mountAI(creature);
1236 }
1237};
1238
1239/*####
1240## npc_brewfest_reveler
1241####*/
1242
1247
1249{
1250 public:
1251 npc_brewfest_reveler() : CreatureScript("npc_brewfest_reveler") { }
1252
1254 {
1255 npc_brewfest_revelerAI(Creature* creature) : ScriptedAI(creature) { }
1256
1257 void ReceiveEmote(Player* player, uint32 emote) override
1258 {
1260 return;
1261
1262 if (emote == TEXT_EMOTE_DANCE)
1263 me->CastSpell(player, SPELL_BREWFEST_TOAST, false);
1264 }
1265 };
1266
1267 CreatureAI* GetAI(Creature* creature) const override
1268 {
1269 return new npc_brewfest_revelerAI(creature);
1270 }
1271};
1272
1273/*######
1274# npc_brewfest_reveler_2
1275######*/
1276
1285
1287{
1289 {
1290 NPC_BREWFEST_REVELER = 24484,
1291
1292 EVENT_FILL_LIST = 1,
1293 EVENT_FACE_TO = 2,
1295 EVENT_NEXT = 4
1297
1298 npc_brewfest_reveler_2(Creature* creature) : ScriptedAI(creature) { }
1299
1300 void Reset() override
1301 {
1302 _events.Reset();
1303 _events.ScheduleEvent(EVENT_FILL_LIST, 1s, 2s);
1304 }
1305
1306 // Copied from old script. I don't know if this is 100% correct.
1307 void ReceiveEmote(Player* player, uint32 emote) override
1308 {
1310 return;
1311
1312 if (emote == TEXT_EMOTE_DANCE)
1313 me->CastSpell(player, SPELL_BREWFEST_TOAST, false);
1314 }
1315
1316 void UpdateAI(uint32 diff) override
1317 {
1318 UpdateVictim();
1319
1320 _events.Update(diff);
1321
1322 while (uint32 eventId = _events.ExecuteEvent())
1323 {
1324 switch (eventId)
1325 {
1326 case EVENT_FILL_LIST:
1327 {
1328 std::list<Creature*> creatureList;
1329 GetCreatureListWithEntryInGrid(creatureList, me, NPC_BREWFEST_REVELER, 5.0f);
1330 for (Creature* creature : creatureList)
1331 if (creature != me)
1332 _revelerGuids.push_back(creature->GetGUID());
1333
1334 _events.ScheduleEvent(EVENT_FACE_TO, 1s, 2s);
1335 break;
1336 }
1337 case EVENT_FACE_TO:
1338 {
1339 // Turn to random brewfest reveler within set range
1340 if (!_revelerGuids.empty())
1342 me->SetFacingToObject(creature);
1343
1344 _events.ScheduleEvent(EVENT_EMOTE, 2s, 6s);
1345 break;
1346 }
1347 case EVENT_EMOTE:
1348 // Play random emote or dance
1349 if (roll_chance(50))
1350 {
1352 _events.ScheduleEvent(EVENT_NEXT, 4s, 6s);
1353 }
1354 else
1355 {
1356 me->SetEmoteState(EMOTE_STATE_DANCE);
1357 _events.ScheduleEvent(EVENT_NEXT, 8s, 12s);
1358 }
1359 break;
1360 case EVENT_NEXT:
1361 // If dancing stop before next random state
1362 if (me->GetEmoteState() == EMOTE_STATE_DANCE)
1363 me->SetEmoteState(EMOTE_ONESHOT_NONE);
1364
1365 // Random EVENT_EMOTE or EVENT_FACETO
1366 if (roll_chance(50))
1367 _events.ScheduleEvent(EVENT_FACE_TO, 1s);
1368 else
1369 _events.ScheduleEvent(EVENT_EMOTE, 1s);
1370 break;
1371 default:
1372 break;
1373 }
1374 }
1375 }
1376
1377private:
1380};
1381
1383{
1384 npc_training_dummy(Creature* creature) : NullCreatureAI(creature) { }
1385
1386 void JustEnteredCombat(Unit* who) override
1387 {
1388 _combatTimer[who->GetGUID()] = 5s;
1389 }
1390
1391 void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damageType, SpellInfo const* /*spellInfo = nullptr*/) override
1392 {
1393 damage = 0;
1394
1395 if (!attacker || damageType == DOT)
1396 return;
1397
1398 _combatTimer[attacker->GetGUID()] = 5s;
1399 }
1400
1401 void UpdateAI(uint32 diff) override
1402 {
1403 for (auto itr = _combatTimer.begin(); itr != _combatTimer.end();)
1404 {
1405 itr->second -= Milliseconds(diff);
1406 if (itr->second <= 0s)
1407 {
1408 // The attacker has not dealt any damage to the dummy for over 5 seconds. End combat.
1409 auto const& pveRefs = me->GetCombatManager().GetPvECombatRefs();
1410 auto it = pveRefs.find(itr->first);
1411 if (it != pveRefs.end())
1412 it->second->EndCombat();
1413
1414 itr = _combatTimer.erase(itr);
1415 }
1416 else
1417 ++itr;
1418 }
1419 }
1420private:
1421 std::unordered_map<ObjectGuid /*attackerGUID*/, Milliseconds /*combatTime*/> _combatTimer;
1422};
1423
1424/*######
1425# npc_wormhole
1426######*/
1427
1429{
1430 MENU_ID_WORMHOLE = 10668, // "This tear in the fabric of time and space looks ominous."
1431 NPC_TEXT_WORMHOLE = 14785, // (not 907 "What brings you to this part of the world, $n?")
1432 GOSSIP_OPTION_1 = 0, // "Borean Tundra"
1433 GOSSIP_OPTION_2 = 1, // "Howling Fjord"
1434 GOSSIP_OPTION_3 = 2, // "Sholazar Basin"
1435 GOSSIP_OPTION_4 = 3, // "Icecrown"
1436 GOSSIP_OPTION_5 = 4, // "Storm Peaks"
1437 GOSSIP_OPTION_6 = 5, // "Underground..."
1438
1442 SPELL_ICECROWN = 67836, // 3
1443 SPELL_STORM_PEAKS = 67837, // 4
1444 SPELL_UNDERGROUND = 68081 // 5
1446
1448{
1449 public:
1450 npc_wormhole() : CreatureScript("npc_wormhole") { }
1451
1453 {
1454 npc_wormholeAI(Creature* creature) : PassiveAI(creature)
1455 {
1456 Initialize();
1457 }
1458
1460 {
1461 _showUnderground = urand(0, 100) == 0; // Guessed value, it is really rare though
1462 }
1463
1464 void InitializeAI() override
1465 {
1466 Initialize();
1467 }
1468
1491
1492 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
1493 {
1494 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
1495 ClearGossipMenuFor(player);
1496
1497 switch (action)
1498 {
1499 case GOSSIP_ACTION_INFO_DEF + 1: // Borean Tundra
1500 CloseGossipMenuFor(player);
1501 DoCast(player, SPELL_BOREAN_TUNDRA, false);
1502 break;
1503 case GOSSIP_ACTION_INFO_DEF + 2: // Howling Fjord
1504 CloseGossipMenuFor(player);
1505 DoCast(player, SPELL_HOWLING_FJORD, false);
1506 break;
1507 case GOSSIP_ACTION_INFO_DEF + 3: // Sholazar Basin
1508 CloseGossipMenuFor(player);
1509 DoCast(player, SPELL_SHOLAZAR_BASIN, false);
1510 break;
1511 case GOSSIP_ACTION_INFO_DEF + 4: // Icecrown
1512 CloseGossipMenuFor(player);
1513 DoCast(player, SPELL_ICECROWN, false);
1514 break;
1515 case GOSSIP_ACTION_INFO_DEF + 5: // Storm peaks
1516 CloseGossipMenuFor(player);
1517 DoCast(player, SPELL_STORM_PEAKS, false);
1518 break;
1519 case GOSSIP_ACTION_INFO_DEF + 6: // Underground
1520 CloseGossipMenuFor(player);
1521 DoCast(player, SPELL_UNDERGROUND, false);
1522 break;
1523 }
1524
1525 return true;
1526 }
1527
1528 private:
1530 };
1531
1532 CreatureAI* GetAI(Creature* creature) const override
1533 {
1534 return new npc_wormholeAI(creature);
1535 }
1536};
1537
1538/*#####
1539# npc_spring_rabbit
1540#####*/
1541
1551
1553{
1554public:
1555 npc_spring_rabbit() : CreatureScript("npc_spring_rabbit") { }
1556
1557 CreatureAI* GetAI(Creature* creature) const override
1558 {
1559 return new npc_spring_rabbitAI(creature);
1560 }
1561
1563 {
1565 {
1566 Initialize();
1567 }
1568
1570 {
1571 inLove = false;
1572 rabbitGUID.Clear();
1573 jumpTimer = urand(5000, 10000);
1574 bunnyTimer = urand(10000, 20000);
1575 searchTimer = urand(5000, 10000);
1576 }
1577
1583
1584 void Reset() override
1585 {
1586 Initialize();
1587 if (Unit* owner = me->GetOwner())
1588 me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
1589 }
1590
1591 void JustEngagedWith(Unit* /*who*/) override { }
1592
1593 void DoAction(int32 /*param*/) override
1594 {
1595 inLove = true;
1596 if (Unit* owner = me->GetOwner())
1597 owner->CastSpell(owner, SPELL_SPRING_FLING, true);
1598 }
1599
1600 void UpdateAI(uint32 diff) override
1601 {
1602 if (inLove)
1603 {
1604 if (jumpTimer <= diff)
1605 {
1606 if (Unit* rabbit = ObjectAccessor::GetUnit(*me, rabbitGUID))
1607 DoCast(rabbit, SPELL_SPRING_RABBIT_JUMP);
1608 jumpTimer = urand(5000, 10000);
1609 } else jumpTimer -= diff;
1610
1611 if (bunnyTimer <= diff)
1612 {
1614 bunnyTimer = urand(20000, 40000);
1615 } else bunnyTimer -= diff;
1616 }
1617 else
1618 {
1619 if (searchTimer <= diff)
1620 {
1621 if (Creature* rabbit = me->FindNearestCreature(NPC_SPRING_RABBIT, 10.0f))
1622 {
1623 if (rabbit == me || rabbit->HasAura(SPELL_SPRING_RABBIT_IN_LOVE))
1624 return;
1625
1626 me->AddAura(SPELL_SPRING_RABBIT_IN_LOVE, me);
1627 DoAction(1);
1628 rabbit->AddAura(SPELL_SPRING_RABBIT_IN_LOVE, rabbit);
1629 rabbit->AI()->DoAction(1);
1630 rabbit->CastSpell(rabbit, SPELL_SPRING_RABBIT_JUMP, true);
1631 rabbitGUID = rabbit->GetGUID();
1632 }
1633 searchTimer = urand(5000, 10000);
1634 } else searchTimer -= diff;
1635 }
1636 }
1637 };
1638};
1639
1641{
1642private:
1643 enum
1644 {
1646
1648 };
1649
1650public:
1651 npc_imp_in_a_ball() : CreatureScript("npc_imp_in_a_ball") { }
1652
1654 {
1656 {
1657 summonerGUID.Clear();
1658 }
1659
1660 void IsSummonedBy(WorldObject* summoner) override
1661 {
1662 if (summoner->GetTypeId() == TYPEID_PLAYER)
1663 {
1664 summonerGUID = summoner->GetGUID();
1665 events.ScheduleEvent(EVENT_TALK, 3s);
1666 }
1667 }
1668
1669 void UpdateAI(uint32 diff) override
1670 {
1671 events.Update(diff);
1672
1673 if (events.ExecuteEvent() == EVENT_TALK)
1674 {
1675 if (Player* owner = ObjectAccessor::GetPlayer(*me, summonerGUID))
1676 {
1677 sCreatureTextMgr->SendChat(me, SAY_RANDOM, owner,
1679 }
1680 }
1681 }
1682
1683 private:
1686 };
1687
1688 CreatureAI* GetAI(Creature* creature) const override
1689 {
1690 return new npc_imp_in_a_ballAI(creature);
1691 }
1692};
1693
1708{
1709 public:
1710 npc_train_wrecker() : CreatureScript("npc_train_wrecker") { }
1711
1713 {
1714 npc_train_wreckerAI(Creature* creature) : NullCreatureAI(creature), _isSearching(true), _nextAction(0), _timer(1 * IN_MILLISECONDS) { }
1715
1717 {
1718 if (GameObject* target = ObjectAccessor::GetGameObject(*me, _target))
1719 return target;
1720 me->HandleEmoteCommand(EMOTE_ONESHOT_RUDE);
1721 me->DespawnOrUnsummon(3s);
1722 return nullptr;
1723 }
1724
1725 void UpdateAI(uint32 diff) override
1726 {
1727 if (_isSearching)
1728 {
1729 if (diff < _timer)
1730 _timer -= diff;
1731 else
1732 {
1733 if (GameObject* target = me->FindNearestGameObject(GO_TOY_TRAIN, 15.0f))
1734 {
1735 _isSearching = false;
1736 _target = target->GetGUID();
1737 me->GetMotionMaster()->MovePoint(MOVEID_CHASE, target->GetNearPosition(1.0f, target->GetAbsoluteAngle(me)),
1739 }
1740 else
1741 _timer = 3 * IN_MILLISECONDS;
1742 }
1743 }
1744 else
1745 {
1746 switch (_nextAction)
1747 {
1748 case EVENT_DO_JUMP:
1749 if (GameObject* target = VerifyTarget())
1750 me->GetMotionMaster()->MoveJump(MOVEID_JUMP, *target, 3.0f, 1.0f);
1751 _nextAction = 0;
1752 break;
1753 case EVENT_DO_WRECK:
1754 _nextAction = 0;
1755 if (GameObject* target = VerifyTarget())
1756 me->CastSpell(target, SPELL_WRECK_TRAIN, false);
1757 break;
1758 case EVENT_DO_DANCE:
1759 if (diff < _timer)
1760 {
1761 _timer -= diff;
1762 break;
1763 }
1764 me->SetEmoteState(EMOTE_STATE_DANCE);
1765 me->DespawnOrUnsummon(5s);
1766 _nextAction = 0;
1767 break;
1768 default:
1769 break;
1770 }
1771 }
1772 }
1773
1774 void MovementInform(uint32 /*type*/, uint32 id) override
1775 {
1776 if (id == MOVEID_CHASE)
1777 _nextAction = EVENT_DO_JUMP;
1778 else if (id == MOVEID_JUMP)
1779 _nextAction = EVENT_DO_WRECK;
1780 }
1781
1782 void SpellHitTarget(WorldObject*, SpellInfo const* spellInfo) override
1783 {
1784 if (spellInfo->Id == SPELL_WRECK_TRAIN)
1785 {
1786 me->UpdateEntry(NPC_EXULTING_WIND_UP_TRAIN_WRECKER);
1787 _timer = 4 * IN_MILLISECONDS;
1788 _nextAction = EVENT_DO_DANCE;
1789 }
1790 }
1791
1792 private:
1797 };
1798
1799 CreatureAI* GetAI(Creature* creature) const override
1800 {
1801 return new npc_train_wreckerAI(creature);
1802 }
1803};
1804
1805/*######
1806## npc_argent_squire/gruntling
1807######*/
1808
1831
1843
1845{
1847 ACHIEVEMENT_PONY_UP = 3736
1849
1855
1864
1866{
1867public:
1868 npc_argent_squire_gruntling() : CreatureScript("npc_argent_squire_gruntling") { }
1869
1871 {
1873 {
1874 }
1875
1876 void Reset() override
1877 {
1878 if (Player* owner = Object::ToPlayer(me->GetOwner()))
1879 {
1880 if (Aura* ownerTired = owner->GetAura(SPELL_TIRED_PLAYER))
1881 if (Aura* squireTired = me->AddAura(IsArgentSquire() ? SPELL_AURA_TIRED_S : SPELL_AURA_TIRED_G, me))
1882 squireTired->SetDuration(ownerTired->GetDuration());
1883
1884 if (owner->HasAchieved(ACHIEVEMENT_PONY_UP) && !me->HasAura(SPELL_AURA_TIRED_S) && !me->HasAura(SPELL_AURA_TIRED_G))
1885 {
1886 me->SetVendor(UNIT_NPC_FLAG_VENDOR, true);
1888 return;
1889 }
1890 }
1891
1892 me->SetVendor(UNIT_NPC_FLAG_VENDOR_MASK, false);
1893 me->RemoveNpcFlag(UNIT_NPC_FLAG_BANKER | UNIT_NPC_FLAG_MAILBOX);
1894 }
1895
1896 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
1897 {
1898 switch (gossipListId)
1899 {
1900 case GOSSIP_OPTION_BANK:
1901 {
1902 me->SetVendor(UNIT_NPC_FLAG_VENDOR_MASK, false);
1903 me->RemoveNpcFlag(UNIT_NPC_FLAG_MAILBOX);
1904 uint32 _bankAura = IsArgentSquire() ? SPELL_AURA_BANK_S : SPELL_AURA_BANK_G;
1905 if (!me->HasAura(_bankAura))
1906 DoCastSelf(_bankAura);
1907
1908 if (!player->HasAura(SPELL_TIRED_PLAYER))
1909 player->CastSpell(player, SPELL_TIRED_PLAYER, true);
1910 break;
1911 }
1912 case GOSSIP_OPTION_SHOP:
1913 {
1914 me->RemoveNpcFlag(UNIT_NPC_FLAG_BANKER | UNIT_NPC_FLAG_MAILBOX);
1915 uint32 _shopAura = IsArgentSquire() ? SPELL_AURA_SHOP_S : SPELL_AURA_SHOP_G;
1916 if (!me->HasAura(_shopAura))
1917 DoCastSelf(_shopAura);
1918
1919 if (!player->HasAura(SPELL_TIRED_PLAYER))
1920 player->CastSpell(player, SPELL_TIRED_PLAYER, true);
1921 break;
1922 }
1923 case GOSSIP_OPTION_MAIL:
1924 {
1925 me->SetVendor(UNIT_NPC_FLAG_VENDOR_MASK, false);
1926 me->RemoveNpcFlag(UNIT_NPC_FLAG_BANKER);
1927 uint32 _mailAura = IsArgentSquire() ? SPELL_AURA_POSTMAN_S : SPELL_AURA_POSTMAN_G;
1928 if (!me->HasAura(_mailAura))
1929 DoCastSelf(_mailAura);
1930
1931 if (!player->HasAura(SPELL_TIRED_PLAYER))
1932 player->CastSpell(player, SPELL_TIRED_PLAYER, true);
1933 break;
1934 }
1940 if (IsArgentSquire())
1941 DoCastSelf(bannerSpells[gossipListId - 3].spellSquire, true);
1942 else
1943 DoCastSelf(bannerSpells[gossipListId - 3].spellGruntling, true);
1944
1945 player->PlayerTalkClass->SendCloseGossip();
1946 break;
1947 default:
1948 break;
1949 }
1950
1951 return false;
1952 }
1953
1954 bool IsArgentSquire() const { return me->GetEntry() == NPC_ARGENT_SQUIRE; }
1955 };
1956
1957 CreatureAI* GetAI(Creature *creature) const override
1958 {
1959 return new npc_argent_squire_gruntlingAI(creature);
1960 }
1961};
1962
1983
1984typedef std::unordered_map<uint32 /*Entry*/, uint32 /*Spell*/> ChairSpells;
1993
1995{
1996 public:
1997 CastFoodSpell(Unit* owner, uint32 spellId) : _owner(owner), _spellId(spellId) { }
1998
1999 bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override
2000 {
2001 _owner->CastSpell(_owner, _spellId, true);
2002 return true;
2003 }
2004
2005 private:
2008};
2009
2011{
2012public:
2013 npc_bountiful_table() : CreatureScript("npc_bountiful_table") { }
2014
2016 {
2017 npc_bountiful_tableAI(Creature* creature) : PassiveAI(creature) { }
2018
2019 void PassengerBoarded(Unit* who, int8 seatId, bool /*apply*/) override
2020 {
2021 float x = 0.0f;
2022 float y = 0.0f;
2023 float z = 0.0f;
2024 float o = 0.0f;
2025
2026 switch (seatId)
2027 {
2028 case SEAT_TURKEY_CHAIR:
2029 x = 3.87f;
2030 y = 2.07f;
2031 o = 3.700098f;
2032 break;
2034 x = 3.87f;
2035 y = -2.07f;
2036 o = 2.460914f;
2037 break;
2039 x = -2.52f;
2040 break;
2042 x = -0.09f;
2043 y = -3.24f;
2044 o = 1.186824f;
2045 break;
2046 case SEAT_PIE_CHAIR:
2047 x = -0.18f;
2048 y = 3.24f;
2049 o = 5.009095f;
2050 break;
2051 case SEAT_FOOD_HOLDER:
2052 case SEAT_PLATE_HOLDER:
2053 if (Vehicle* holders = who->GetVehicleKit())
2054 holders->InstallAllAccessories(true);
2055 return;
2056 default:
2057 break;
2058 }
2059
2060 std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
2061 {
2062 init.DisableTransportPathTransformations();
2063 init.MoveTo(x, y, z, false);
2064 init.SetFacing(o);
2065 };
2067 who->m_Events.AddEvent(new CastFoodSpell(who, _chairSpells.at(who->GetEntry())), who->m_Events.CalculateTime(1s));
2068 if (Creature* creature = who->ToCreature())
2069 creature->SetDisplayFromModel(0);
2070 }
2071 };
2072
2073 CreatureAI* GetAI(Creature* creature) const override
2074 {
2075 return new npc_bountiful_tableAI(creature);
2076 }
2077};
2078
2080{
2081 SPELL_CONSUMPTION = 28874
2083
2085{
2086 npc_gen_void_zone(Creature* creature) : ScriptedAI(creature) { }
2087
2088 void InitializeAI() override
2089 {
2090 me->SetReactState(REACT_PASSIVE);
2091 }
2092
2093 void JustAppeared() override
2094 {
2095 _scheduler.Schedule(2s, [this](TaskContext const& /*task*/)
2096 {
2097 DoCastSelf(SPELL_CONSUMPTION);
2098 });
2099 }
2100
2101 void UpdateAI(uint32 diff) override
2102 {
2103 _scheduler.Update(diff);
2104 }
2105
2106private:
2108};
2109
@ IN_MILLISECONDS
Definition Common.h:38
#define sCreatureTextMgr
@ TEXT_RANGE_NORMAL
T GetEntry(std::unordered_map< uint32, T > const &map, CriteriaTreeEntry const *tree)
uint8_t uint8
Definition Define.h:156
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
#define ASSERT_NODEBUGINFO
Definition Errors.h:73
bool IsHolidayActive(HolidayIds id)
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:182
LootItemType
@ MOTION_PRIORITY_HIGHEST
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
std::list< ObjectGuid > GuidList
Definition ObjectGuid.h:433
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
std::vector< ObjectGuid > GuidVector
Definition ObjectGuid.h:434
#define sObjectMgr
Definition ObjectMgr.h:1873
#define PET_FOLLOW_ANGLE
Definition PetDefines.h:99
#define PET_FOLLOW_DIST
Definition PetDefines.h:98
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:146
@ QUEST_STATUS_NONE
Definition QuestDef.h:143
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:144
bool roll_chance(float chance, PseudoRandomDistributionState &state)
Definition Random.cpp:131
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:43
uint32 rand32()
Definition Random.cpp:71
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1392
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
void AddGossipItemFor(Player *player, GossipOptionNpc optionNpc, std::string text, uint32 sender, uint32 action)
void SendGossipMenuFor(Player *player, uint32 npcTextID, ObjectGuid const &guid)
void ClearGossipMenuFor(Player *player)
void InitGossipMenuFor(Player *player, uint32 menuId)
void CloseGossipMenuFor(Player *player)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ CLASS_DEATH_KNIGHT
@ LANG_ADDON
@ EMOTE_ONESHOT_LAUGH_NO_SHEATHE
@ EMOTE_ONESHOT_APPLAUD
@ EMOTE_ONESHOT_QUESTION
@ EMOTE_ONESHOT_SHY
@ EMOTE_ONESHOT_LAUGH
@ EMOTE_ONESHOT_BOW
@ EMOTE_ONESHOT_RUDE
@ EMOTE_STATE_DANCE
@ EMOTE_ONESHOT_EAT_NO_SHEATHE
@ EMOTE_ONESHOT_NONE
@ EMOTE_ONESHOT_SHOUT
@ EMOTE_ONESHOT_WAVE
@ EVENT_VEHICLE_BOARD
@ TEXT_EMOTE_BOW
@ TEXT_EMOTE_CHICKEN
@ TEXT_EMOTE_CHEER
@ TEXT_EMOTE_DANCE
@ TEXT_EMOTE_KISS
@ TEXT_EMOTE_WAVE
@ TEXT_EMOTE_JOKE
@ HORDE
@ FACTION_FRIENDLY
@ FACTION_PREY
@ HOLIDAY_BREWFEST
@ CHAT_MSG_MONSTER_WHISPER
@ CHAT_MSG_MONSTER_PARTY
#define ENSURE_AI(a, b)
Definition UnitAI.h:30
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_STAND_STATE_DEAD
Definition UnitDefines.h:49
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:42
constexpr NPCFlags UNIT_NPC_FLAG_VENDOR_MASK
@ UNIT_NPC_FLAG_BANKER
@ UNIT_NPC_FLAG_VENDOR
@ UNIT_NPC_FLAG_QUESTGIVER
@ UNIT_NPC_FLAG_MAILBOX
DamageEffectType
@ DOT
@ UNIT_FLAG3_FAKE_DEAD
@ UNIT_FLAG_NON_ATTACKABLE
@ UNIT_FLAG_IN_COMBAT
@ JUST_DIED
Definition Unit.h:267
@ SAY_RANDOM
@ EVENT_EMOTE
Definition boss_laj.cpp:48
@ SPELL_CONSUMPTION
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
bool Execute(uint64, uint32) override
CastFoodSpell(Unit *owner, uint32 spellId)
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void setDeathState(DeathState s) override
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 Reset()
Definition EventMap.cpp:25
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forceRespawnTime=0s)
void LaunchMoveSpline(std::function< void(Movement::MoveSplineInit &init)> &&initializer, uint32 id=0, MovementGeneratorPriority priority=MOTION_PRIORITY_NORMAL, MovementGeneratorType type=EFFECT_MOTION_TYPE, 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={})
bool IsEmpty() const
Definition ObjectGuid.h:362
void Clear()
Definition ObjectGuid.h:329
Player * ToPlayer()
Definition Object.h:126
uint32 GetEntry() const
Definition Object.h:89
Creature * ToCreature()
Definition Object.h:121
bool GetQuestRewardStatus(uint32 quest_id) const
Definition Player.cpp:15912
bool HasAchieved(uint32 achievementId) const
Definition Player.cpp:27516
void AreaExploredOrEventHappens(uint32 questId)
Definition Player.cpp:16519
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15929
void FailQuest(uint32 quest_id)
Definition Player.cpp:15314
std::unique_ptr< PlayerMenu > PlayerTalkClass
Definition Player.h:2556
Team GetTeam() const
Definition Player.h:2406
uint32 GetQuestId() const
Definition QuestDef.h:633
uint32 const Id
Definition SpellInfo.h:328
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update()
Update the scheduler to the current time.
WorldObject * GetSummoner() const
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:81
Definition Unit.h:647
void SetHealth(uint64 val)
Definition Unit.cpp:10041
uint64 CountPctFromMaxHealth(float pct) const
Definition Unit.h:809
void SetUnitFlag3(UnitFlags3 flags)
Definition Unit.h:871
int64 ModifyHealth(int64 val)
Definition Unit.cpp:8618
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition Unit.cpp:10804
uint8 GetClass() const
Definition Unit.h:776
void SetFaction(uint32 faction) override
Definition Unit.h:887
MotionMaster * GetMotionMaster()
Definition Unit.h:1750
bool IsAlive() const
Definition Unit.h:1205
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:1013
TempSummon * ToTempSummon()
Definition Unit.h:1844
void SetUninteractible(bool apply)
Definition Unit.cpp:8583
void SetEmoteState(Emote emote)
Definition Unit.h:880
uint64 GetHealth() const
Definition Unit.h:800
void SetNpcFlag(NPCFlags flags)
Definition Unit.h:1012
bool SetWalk(bool enable)
Definition Unit.cpp:13422
void EngageWithTarget(Unit *who)
Definition Unit.cpp:8513
bool HasNpcFlag(NPCFlags flags) const
Definition Unit.h:1011
bool IsEngagedBy(Unit const *who) const
Definition Unit.h:1050
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
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition Unit.cpp:1662
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:861
bool IsFlying() const
Definition Unit.h:1823
Vehicle * GetVehicleKit() const
Definition Unit.h:1798
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:862
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition Object.cpp:1544
bool IsWithinLOS(float x, float y, float z, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition Object.cpp:513
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2329
bool IsHostileTo(WorldObject const *target) const
Definition Object.cpp:2186
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
Unit * GetOwner() const
Definition Object.cpp:1603
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:1522
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:499
EventProcessor m_Events
Definition Object.h:561
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
@ EVENT_TALK
RibbonPoleData
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
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)
auto SelectRandomContainerElement(C const &container) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition Containers.h:110
ArgentPetGossipOptions
@ GOSSIP_OPTION_GNOMEREGAN_ORGRIMMAR_PENNANT
@ GOSSIP_OPTION_EXODAR_UNDERCITY_PENNANT
@ GOSSIP_OPTION_SHOP
@ GOSSIP_OPTION_STORMWIND_THUNDERBLUFF_PENNANT
@ GOSSIP_OPTION_DARNASSUS_SENJIN_PENNANT
@ GOSSIP_OPTION_MAIL
@ GOSSIP_OPTION_IRONFORGE_SILVERMOON_PENNANT
@ GOSSIP_OPTION_BANK
Position const HordeCoords[]
#define A_RUNTOX
TournamentQuestsAchievements
@ ACHIEVEMENT_CHAMPION_UNDERCITY
@ QUEST_VALIANT_OF_UNDERCITY
@ ACHIEVEMENT_CHAMPION_THUNDER_BLUFF
@ QUEST_A_VALIANT_OF_STORMWIND
@ QUEST_A_VALIANT_OF_GNOMEREGAN
@ ACHIEVEMENT_CHAMPION_IRONFORGE
@ ACHIEVEMENT_CHAMPION_DARNASSUS
@ QUEST_VALIANT_OF_STORMWIND
@ QUEST_VALIANT_OF_GNOMEREGAN
@ ACHIEVEMENT_CHAMPION_SILVERMOON
@ QUEST_VALIANT_OF_DARNASSUS
@ ACHIEVEMENT_CHAMPION_GNOMEREGAN
@ QUEST_VALIANT_OF_ORGRIMMAR
@ QUEST_VALIANT_OF_THUNDER_BLUFF
@ QUEST_VALIANT_OF_IRONFORGE
@ QUEST_VALIANT_OF_SILVERMOON
@ QUEST_A_VALIANT_OF_SILVERMOON
@ QUEST_VALIANT_OF_SEN_JIN
@ ACHIEVEMENT_CHAMPION_HORDE
@ QUEST_VALIANT_OF_THE_EXODAR
@ ACHIEVEMENT_CHAMPION_STORMWIND
@ QUEST_A_VALIANT_OF_DARNASSUS
@ ACHIEVEMENT_CHAMPION_ALLIANCE
@ ACHIEVEMENT_ARGENT_VALOR
@ QUEST_A_VALIANT_OF_ORGRIMMAR
@ ACHIEVEMENT_CHAMPION_SEN_JIN
@ QUEST_A_VALIANT_OF_UNDERCITY
@ QUEST_A_VALIANT_OF_THUNDER_BLUFF
@ QUEST_A_VALIANT_OF_SEN_JIN
@ QUEST_A_VALIANT_OF_IRONFORGE
@ ACHIEVEMENT_CHAMPION_ORGRIMMAR
@ QUEST_A_VALIANT_OF_THE_EXODAR
@ ACHIEVEMENT_CHAMPION_THE_EXODAR
@ SPELL_CONSUMPTION
float constexpr RANGE_ALARMBOT
#define A_RUNTOZ
NPC_Wormhole
@ GOSSIP_OPTION_4
@ SPELL_STORM_PEAKS
@ GOSSIP_OPTION_6
@ SPELL_UNDERGROUND
@ MENU_ID_WORMHOLE
@ SPELL_SHOLAZAR_BASIN
@ GOSSIP_OPTION_3
@ SPELL_BOREAN_TUNDRA
@ GOSSIP_OPTION_2
@ SPELL_HOWLING_FJORD
@ GOSSIP_OPTION_5
@ GOSSIP_OPTION_1
@ SPELL_ICECROWN
@ NPC_TEXT_WORMHOLE
#define H_RUNTOX
float constexpr RANGE_TRIPWIRE
ArgentPonyBannerSpells const bannerSpells[5]
@ ACHIEVEMENT_PONY_UP
@ NPC_ARGENT_SQUIRE
TrainWrecker
@ MOVEID_CHASE
@ EVENT_DO_JUMP
@ SPELL_TOY_TRAIN_PULSE
@ NPC_EXULTING_WIND_UP_TRAIN_WRECKER
@ GO_TOY_TRAIN
@ EVENT_DO_DANCE
@ MOVEID_JUMP
@ SPELL_WRECK_TRAIN
@ EVENT_DO_WRECK
TournamentMounts
@ NPC_ARGENT_WARHORSE
@ NPC_DARNASSIAN_NIGHTSABER
@ NPC_STORMWIND_STEED
@ NPC_IRONFORGE_RAM
@ NPC_SILVERMOON_HAWKSTRIDER
@ NPC_FORSAKEN_WARHORSE
@ NPC_ARGENT_STEED_ASPIRANT
@ NPC_THUNDER_BLUFF_KODO
@ NPC_EXODAR_ELEKK
@ NPC_DARK_SPEAR_RAPTOR
@ NPC_GNOMEREGAN_MECHANOSTRIDER
@ NPC_ARGENT_HAWKSTRIDER_ASPIRANT
@ NPC_ORGRIMMAR_WOLF
@ SPELL_SILVERMOON_PENNANT
@ SPELL_UNDERCITY_PENNANT
@ SPELL_AURA_BANK_G
@ SPELL_TIRED_PLAYER
@ SPELL_AURA_POSTMAN_S
@ SPELL_GNOMEREGAN_PENNANT
@ SPELL_IRONFORGE_PENNANT
@ SPELL_AURA_SHOP_S
@ SPELL_AURA_TIRED_G
@ SPELL_DARNASSUS_PENNANT
@ SPELL_SENJIN_PENNANT
@ SPELL_ORGRIMMAR_PENNANT
@ SPELL_AURA_BANK_S
@ SPELL_AURA_SHOP_G
@ SPELL_STORMWIND_PENNANT
@ SPELL_AURA_TIRED_S
@ SPELL_AURA_POSTMAN_G
@ SPELL_THUNDERBLUFF_PENNANT
@ SPELL_EXODAR_PENNANT
#define A_RUNTOY
BrewfestReveler
@ SPELL_BREWFEST_TOAST
@ ALLIANCE_COORDS
@ SAY_DOC
@ HORDE_COORDS
@ DOCTOR_HORDE
@ DOCTOR_ALLIANCE
ChairSpells const _chairSpells
AirForceSpawn constexpr airforceSpawns[]
@ EVENT_CAST_RED_FIRE_RING
@ SPELL_RED_FIRE_RING
@ SPELL_RIBBON_DANCE_COSMETIC
@ GO_RIBBON_POLE
@ SPELL_BLUE_FIRE_RING
@ EVENT_CAST_BLUE_FIRE_RING
DancingFlames
@ SPELL_SUMMON_BRAZIER
@ SPELL_FIERY_SEDUCTION
@ SPELL_BRAZIER_DANCE
Emote const BrewfestRandomEmote[]
ChickenCluck
@ QUEST_CLUCK
@ EMOTE_HELLO_A
@ EMOTE_HELLO_H
@ EMOTE_CLUCK_TEXT
Position const AllianceCoords[]
rabbitSpells
@ NPC_SPRING_RABBIT
@ SPELL_SPRING_RABBIT_WANDER
@ SPELL_SPRING_FLING
@ SPELL_SPRING_RABBIT_JUMP
@ SPELL_SPRING_RABBIT_IN_LOVE
@ SPELL_SUMMON_BABY_BUNNY
uint32 const AllianceSoldierId[3]
TournamentPennantSpells
@ SPELL_PENNANT_EXODAR_ASPIRANT
@ SPELL_PENNANT_IRONFORGE_ASPIRANT
@ SPELL_PENNANT_GNOMEREGAN_ASPIRANT
@ SPELL_PENNANT_EBON_BLADE_CHAMPION
@ SPELL_PENNANT_IRONFORGE_CHAMPION
@ SPELL_PENNANT_ORGRIMMAR_CHAMPION
@ SPELL_PENNANT_THUNDER_BLUFF_CHAMPION
@ SPELL_PENNANT_ORGRIMMAR_VALIANT
@ SPELL_PENNANT_STORMWIND_CHAMPION
@ SPELL_PENNANT_THUNDER_BLUFF_VALIANT
@ SPELL_PENNANT_SEN_JIN_ASPIRANT
@ SPELL_PENNANT_ORGRIMMAR_ASPIRANT
@ SPELL_PENNANT_UNDERCITY_CHAMPION
@ SPELL_PENNANT_GNOMEREGAN_VALIANT
@ SPELL_PENNANT_GNOMEREGAN_CHAMPION
@ SPELL_PENNANT_EBON_BLADE_VALIANT
@ SPELL_PENNANT_IRONFORGE_VALIANT
@ SPELL_PENNANT_STORMWIND_VALIANT
@ SPELL_PENNANT_UNDERCITY_ASPIRANT
@ SPELL_PENNANT_UNDERCITY_VALIANT
@ SPELL_PENNANT_ARGENT_CRUSADE_VALIANT
@ SPELL_PENNANT_STORMWIND_ASPIRANT
@ SPELL_PENNANT_EXODAR_VALIANT
@ SPELL_PENNANT_ARGENT_CRUSADE_CHAMPION
@ SPELL_PENNANT_EBON_BLADE_ASPIRANT
@ SPELL_PENNANT_SILVERMOON_VALIANT
@ SPELL_PENNANT_SILVERMOON_CHAMPION
@ SPELL_PENNANT_SEN_JIN_VALIANT
@ SPELL_PENNANT_ARGENT_CRUSADE_ASPIRANT
@ SPELL_PENNANT_SEN_JIN_CHAMPION
@ SPELL_PENNANT_DARNASSUS_CHAMPION
@ SPELL_PENNANT_THUNDER_BLUFF_ASPIRANT
@ SPELL_PENNANT_DARNASSUS_VALIANT
@ SPELL_PENNANT_DARNASSUS_ASPIRANT
@ SPELL_PENNANT_EXODAR_CHAMPION
@ SPELL_PENNANT_SILVERMOON_ASPIRANT
void AddSC_npcs_special()
BountifulTable
@ SPELL_TURKEY_SERVER
@ NPC_THE_TURKEY_CHAIR
@ NPC_THE_PIE_CHAIR
@ NPC_THE_SWEET_POTATO_CHAIR
@ SEAT_STUFFING_CHAIR
@ SPELL_CRANBERRY_SERVER
@ SEAT_CRANBERRY_CHAIR
@ SEAT_TURKEY_CHAIR
@ SEAT_SWEET_POTATO_CHAIR
@ NPC_THE_STUFFING_CHAIR
@ SEAT_PIE_CHAIR
@ SEAT_FOOD_HOLDER
@ SPELL_STUFFING_SERVER
@ NPC_THE_CRANBERRY_CHAIR
@ SPELL_SWEET_POTATOES_SERVER
@ SPELL_PIE_SERVER
@ SEAT_PLATE_HOLDER
TorchTossingTarget
@ SPELL_TORCH_TARGET_PICKER
#define H_RUNTOY
uint32 const HordeSoldierId[3]
AirForceBots
@ SPELL_GUARDS_MARK
@ ALARMBOT
@ TRIPWIRE
std::unordered_map< uint32, uint32 > ChairSpells
#define H_RUNTOZ
GuardianSpells
@ SPELL_DEATHTOUCH
@ SEAT_PLATE_HOLDER
AirForceBots type
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius)
Definition CellImpl.h:150
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:136
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr void Relocate(float x, float y)
Definition Position.h:74
constexpr float GetPositionZ() const
Definition Position.h:89
static AirForceSpawn const & FindSpawnFor(uint32 entry)
void MoveInLineOfSight(Unit *who) override
std::unordered_set< ObjectGuid > _toAttack
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
void PassengerBoarded(Unit *who, int8 seatId, bool) override
== Fields =======================================
void ReceiveEmote(Player *player, uint32 emote) override
void ReceiveEmote(Player *player, uint32 emote) override
npc_brewfest_reveler_2(Creature *creature)
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
void ReceiveEmote(Player *player, uint32 emote) override
void OnQuestAccept(Player *, Quest const *quest) override
void OnQuestReward(Player *, Quest const *quest, LootItemType, uint32) override
void ReceiveEmote(Player *player, uint32 emote) override
void Reset() override
TaskScheduler _scheduler
npc_dancing_flames(Creature *creature)
void UpdateAI(uint32 diff) override
void BeginEvent(Player *player)
void PatientSaved(Creature *, Player *player, Position const *point)
void PatientDied(Position const *point)
npc_doctorAI(Creature *creature)
std::vector< Position const * > Coordinates
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *) override
void OnQuestAccept(Player *player, Quest const *quest) override
void UpdateAI(uint32 diff) override
TaskScheduler _scheduler
npc_gen_void_zone(Creature *creature)
void JustAppeared() override
void InitializeAI() override
void JustEngagedWith(Unit *) override
void UpdateAI(uint32) override
npc_guardianAI(Creature *creature)
void IsSummonedBy(WorldObject *summoner) override
void UpdateAI(uint32 diff) override
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
void UpdateAI(uint32 diff) override
npc_steam_tonkAI(Creature *creature)
void JustEngagedWith(Unit *) override
uint32 GetPennantSpellId(Player *player) const
void PassengerBoarded(Unit *passenger, int8, bool apply) override
== Fields =======================================
void UpdateAI(uint32 diff) override
void SpellHitTarget(WorldObject *, SpellInfo const *spellInfo) override
void MovementInform(uint32, uint32 id) override
void JustEnteredCombat(Unit *who) override
std::unordered_map< ObjectGuid, Milliseconds > _combatTimer
void DamageTaken(Unit *attacker, uint32 &damage, DamageEffectType damageType, SpellInfo const *) override
npc_training_dummy(Creature *creature)
void UpdateAI(uint32 diff) override
bool OnGossipHello(Player *player) override
npc_wormholeAI(Creature *creature)
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override