TrinityCore
Loading...
Searching...
No Matches
SmartAI.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 "SmartAI.h"
19#include "AreaTrigger.h"
20#include "ConditionMgr.h"
21#include "Creature.h"
22#include "CreatureGroups.h"
23#include "DB2Structure.h"
24#include "GameObject.h"
25#include "Group.h"
26#include "Log.h"
27#include "MotionMaster.h"
28#include "ObjectAccessor.h"
29#include "PetDefines.h"
30#include "Player.h"
31#include "ScriptMgr.h"
32#include "SpellAuras.h"
33#include "Vehicle.h"
34#include "WaypointManager.h"
35
36SmartAI::SmartAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), _charmed(false), _followCreditType(0), _followArrivedTimer(0), _followCredit(0), _followArrivedEntry(0), _followDistance(0.f), _followAngle(0.f),
37 _escortState(SMART_ESCORT_NONE), _escortNPCFlags(0), _escortInvokerCheckTimer(1000), _currentWaypointNodeId(0), _waypointReached(false), _waypointPauseTimer(0), _waypointPauseForced(false), _repeatWaypointPath(false),
38 _OOCReached(false), _waypointPathEnded(false), _run(true), _evadeDisabled(false), _canCombatMove(true), _invincibilityHPLevel(0), _despawnTime(0), _despawnState(0), _vehicleConditionsTimer(0),
39 _gossipReturn(false), _escortQuestId(0)
40{
42}
43
45{
46 return !_charmed;
47}
48
49void SmartAI::StartPath(uint32 pathId/* = 0*/, bool repeat/* = false*/, Unit* invoker/* = nullptr*/, uint32 nodeId/* = 0*/, uint32 fadeObjectDuration /*= 0*/,
51{
53 StopPath();
54
55 if (!pathId)
56 return;
57
58 WaypointPath const* path = LoadPath(pathId);
59 if (!path)
60 return;
61
63 _waypointPathEnded = false;
64
65 _repeatWaypointPath = repeat;
66
67 // Do not use AddEscortState, removing everything from previous
69
70 if (invoker && invoker->GetTypeId() == TYPEID_PLAYER)
71 {
74 }
75
77 if (fadeObjectDuration)
78 fadeObject.emplace(Milliseconds(fadeObjectDuration));
79
81 {}, {}, {}, {}, true, fadeObject, std::move(scriptResult));
82}
83
85{
87 return nullptr;
88
89 WaypointPath const* path = sWaypointMgr->GetPath(entry);
90 if (!path || path->Nodes.empty())
91 {
92 GetScript()->SetPathId(0);
93 return nullptr;
94 }
95
96 GetScript()->SetPathId(entry);
97 return path;
98}
99
100void SmartAI::PausePath(uint32 delay, bool forced)
101{
103 {
104 me->PauseMovement(delay, MOTION_SLOT_DEFAULT, forced);
106 {
107 std::pair<uint32, uint32> waypointInfo = me->GetCurrentWaypointInfo();
108 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_PAUSED, nullptr, waypointInfo.first, waypointInfo.second);
109 }
110 return;
111 }
112
114 {
115 TC_LOG_ERROR("scripts.ai.sai", "SmartAI::PausePath: Creature wanted to pause waypoint (current waypoint: {}) movement while already paused, ignoring. ({})", _currentWaypointNodeId, me->GetGUID().ToString());
116 return;
117 }
118
119 _waypointPauseTimer = delay;
120
121 if (forced)
122 {
123 _waypointPauseForced = forced;
124 SetRun(_run);
125 me->PauseMovement();
127 }
128 else
129 _waypointReached = false;
130
133}
134
136{
138 {
139 // The whole resume logic doesn't support this case
140 return false;
141 }
142
144}
145
146void SmartAI::StopPath(uint32 DespawnTime, uint32 quest, bool fail)
147{
149 {
150 std::pair<uint32, uint32> waypointInfo = { 0, 0 };
152 waypointInfo = me->GetCurrentWaypointInfo();
153
154 if (_despawnState != 2)
155 SetDespawnTime(DespawnTime);
156
158
159 if (waypointInfo.second)
160 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_STOPPED, nullptr, waypointInfo.first, waypointInfo.second);
161
162 if (!fail)
163 {
164 if (waypointInfo.second)
165 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, nullptr, waypointInfo.first, waypointInfo.second);
166 if (_despawnState == 1)
167 StartDespawn();
168 }
169 return;
170 }
171
172 if (quest)
173 _escortQuestId = quest;
174
175 if (_despawnState != 2)
176 SetDespawnTime(DespawnTime);
177
179
181
182 EndPath(fail);
183}
184
185void SmartAI::EndPath(bool fail)
186{
188
190
191 if (_escortNPCFlags)
192 {
194 _escortNPCFlags = 0;
195 }
196
198 if (targets && _escortQuestId)
199 {
200 if (targets->size() == 1 && targets->front()->IsPlayer())
201 {
202 Player* player = targets->front()->ToPlayer();
203 if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse())
205
206 if (fail)
207 player->FailQuest(_escortQuestId);
208
209 if (Group* group = player->GetGroup())
210 {
211 for (GroupReference const& groupRef : group->GetMembers())
212 {
213 Player* groupGuy = groupRef.GetSource();
214 if (!groupGuy->IsInMap(player))
215 continue;
216
217 if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->HasCorpse())
219 else if (fail)
220 groupGuy->FailQuest(_escortQuestId);
221 }
222 }
223 }
224 else
225 {
226 for (WorldObject* target : *targets)
227 {
228 if (Player* player = target->ToPlayer())
229 {
230 if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse())
231 player->AreaExploredOrEventHappens(_escortQuestId);
232 else if (fail)
233 player->FailQuest(_escortQuestId);
234 }
235 }
236 }
237 }
238
239 // End Path events should be only processed if it was SUCCESSFUL stop or stop called by SMART_ACTION_WAYPOINT_STOP
240 if (fail)
241 return;
242
243 uint32 pathid = GetScript()->GetPathId();
245
247 {
248 if (IsAIControlled())
249 StartPath(GetScript()->GetPathId(), _repeatWaypointPath);
250 }
251 else if (pathid == GetScript()->GetPathId()) // if it's not the same pathid, our script wants to start another path; don't override it
252 GetScript()->SetPathId(0);
253
254 if (_despawnState == 1)
255 StartDespawn();
256}
257
271
280
282{
283 if (!me->IsAlive())
284 {
285 if (IsEngaged())
287 return;
288 }
289
290 CheckConditions(diff);
291
292 UpdateVictim();
293
294 GetScript()->OnUpdate(diff);
295
296 UpdatePath(diff);
297 UpdateFollow(diff);
298 UpdateDespawn(diff);
299}
300
302{
303 if (ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS, *me))
304 {
306 if (targets->size() == 1 && targets->front()->IsPlayer())
307 {
308 Player* player = targets->front()->ToPlayer();
309 if (me->GetDistance(player) <= checkDist)
310 return true;
311
312 if (Group* group = player->GetGroup())
313 {
314 for (GroupReference const& groupRef : group->GetMembers())
315 {
316 Player* groupGuy = groupRef.GetSource();
317 if (groupGuy->IsInMap(player) && me->GetDistance(groupGuy) <= checkDist)
318 return true;
319 }
320 }
321 }
322 else
323 {
324 for (WorldObject* target : *targets)
325 if (target->IsPlayer() && me->GetDistance(target) <= checkDist)
326 return true;
327 }
328
329 // no valid target found
330 return false;
331 }
332
333 // no player invoker was stored, just ignore range check
334 return true;
335}
336
338{
340 {
341 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_REACHED, nullptr, nodeId, pathId);
342 return;
343 }
344
345 _currentWaypointNodeId = nodeId;
346
348
350 {
351 _waypointReached = true;
352 me->PauseMovement();
354 }
356 {
357 WaypointPath const* path = sWaypointMgr->GetPath(pathId);
358 if (path && _currentWaypointNodeId == path->Nodes.back().Id)
359 _waypointPathEnded = true;
360 else
361 SetRun(_run);
362 }
363}
364
367{
369 {
370 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, nullptr, nodeId, pathId);
371 return;
372 }
373}
374
376{
379
381
383 return;
384
386 _OOCReached = true;
387}
388
390{
391 if (_evadeDisabled)
392 {
394 return;
395 }
396
397 if (!IsAIControlled())
398 {
399 me->AttackStop();
400 return;
401 }
402
403 if (!_EnterEvadeMode())
404 return;
405
407
408 GetScript()->ProcessEventsFor(SMART_EVENT_EVADE); // must be after _EnterEvadeMode (spells, auras, ...)
409
410 SetRun(_run);
411
412 if (Unit* owner = me->GetCharmerOrOwner())
413 {
416 }
418 {
421 }
422 else if (Unit* target = !_followGUID.IsEmpty() ? ObjectAccessor::GetUnit(*me, _followGUID) : nullptr)
423 {
425 // evade is not cleared in MoveFollow, so we can't keep it
427 }
428 else
430
432 GetScript()->OnReset();
433}
434
436{
437 if (!who)
438 return;
439
441
442 if (!IsAIControlled())
443 return;
444
446 return;
447
449}
450
452{
454 return false;
455
456 if (!who || !who->GetVictim())
457 return false;
458
459 // experimental (unknown) flag not present
461 return false;
462
463 // not a player
465 return false;
466
467 if (!who->isInAccessiblePlaceFor(me))
468 return false;
469
470 if (!CanAIAttack(who))
471 return false;
472
473 // we cannot attack in evade mode
474 if (me->IsInEvadeMode())
475 return false;
476
477 // or if enemy is in evade mode
478 if (who->GetTypeId() == TYPEID_UNIT && who->ToCreature()->IsInEvadeMode())
479 return false;
480
481 if (!me->IsValidAssistTarget(who->GetVictim()))
482 return false;
483
484 // too far away and no free sight
486 {
487 me->EngageWithTarget(who);
488 return true;
489 }
490
491 return false;
492}
493
495{
497
498 _despawnTime = 0;
499 _despawnState = 0;
501 _followGUID.Clear(); // do not reset follower on Reset(), we need it after combat evade
502 _followDistance = 0;
503 _followAngle = 0;
504 _followCredit = 0;
505 _followArrivedTimer = 1000;
508}
509
511{
513
514 if (me->isDead())
515 return;
516
518 GetScript()->OnReset();
519}
520
522{
523 GetScript()->OnReset();
525
526 CreatureGroup* formation = me->GetFormation();
527 if (!formation || formation->GetLeader() == me || !formation->IsFormed())
528 {
530 {
531 if (me->GetWaypointPathId())
533 }
534
536 }
537 else if (formation->IsFormed())
538 me->GetMotionMaster()->MoveIdle(); // wait the order of leader
539}
540
542{
543 if (IsAIControlled())
544 me->InterruptNonMeleeSpells(false); // must be before ProcessEvents
545
547}
548
550{
552 EndPath(true);
553
555}
556
558{
560}
561
566
571
573{
574 // dont allow charmed npcs to act on their own
575 if (!IsAIControlled())
576 {
577 if (who)
578 me->Attack(who, true);
579 return;
580 }
581
582 if (who && me->Attack(who, true))
583 {
585 me->PauseMovement();
586
587 if (_canCombatMove)
588 {
589 SetRun(_run);
591 }
592 }
593}
594
595void SmartAI::SpellHit(WorldObject* caster, SpellInfo const* spellInfo)
596{
597 GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT, caster->ToUnit(), 0, 0, false, spellInfo, caster->ToGameObject());
598}
599
600void SmartAI::SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo)
601{
602 GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT_TARGET, target->ToUnit(), 0, 0, false, spellInfo, target->ToGameObject());
603}
604
605void SmartAI::OnSpellCast(SpellInfo const* spellInfo)
606{
607 GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELL_CAST, nullptr, 0, 0, false, spellInfo);
608}
609
610void SmartAI::OnSpellFailed(SpellInfo const* spellInfo)
611{
612 GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELL_FAILED, nullptr, 0, 0, false, spellInfo);
613}
614
615void SmartAI::OnSpellStart(SpellInfo const* spellInfo)
616{
617 GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELL_START, nullptr, 0, 0, false, spellInfo);
618}
619
621{
622 GetScript()->ProcessEventsFor(SMART_EVENT_ON_AURA_APPLIED, nullptr, 0, 0, false, aurApp->GetBase()->GetSpellInfo());
623}
624
626{
627 GetScript()->ProcessEventsFor(SMART_EVENT_ON_AURA_REMOVED, nullptr, 0, 0, false, aurApp->GetBase()->GetSpellInfo());
628}
629
630void SmartAI::DamageTaken(Unit* doneBy, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/)
631{
633
634 if (!IsAIControlled()) // don't allow players to use unkillable units
635 return;
636
638 damage = me->GetHealth() - _invincibilityHPLevel; // damage should not be nullified, because of player damage req.
639}
640
641void SmartAI::HealReceived(Unit* doneBy, uint32& addhealth)
642{
644}
645
646void SmartAI::ReceiveEmote(Player* player, uint32 textEmote)
647{
649}
650
652{
653 GetScript()->ProcessEventsFor(SMART_EVENT_JUST_SUMMONED, summoner->ToUnit(), 0, 0, false, nullptr, summoner->ToGameObject());
654}
655
656void SmartAI::DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/)
657{
659}
660
665
667{
668 GetScript()->ProcessEventsFor(SMART_EVENT_CORPSE_REMOVED, nullptr, respawnDelay);
669}
670
675
676void SmartAI::PassengerBoarded(Unit* who, int8 seatId, bool apply)
677{
679}
680
681void SmartAI::OnCharmed(bool isNew)
682{
683 bool const charmed = me->IsCharmed();
684 if (charmed) // do this before we change charmed state, as charmed state might prevent these things from processing
685 {
687 EndPath(true);
688 }
689
690 _charmed = charmed;
691
692 if (charmed && !me->isPossessed() && !me->IsVehicle())
694
695 if (!charmed && !me->IsInEvadeMode())
696 {
698 StartPath(GetScript()->GetPathId(), true);
699 else
700 me->SetWalk(!_run);
701
702 if (!me->LastCharmerGUID.IsEmpty())
703 {
705 if (Unit* lastCharmer = ObjectAccessor::GetUnit(*me, me->LastCharmerGUID))
706 me->EngageWithTarget(lastCharmer);
708
709 if (!me->IsInCombat())
711 }
712 }
713
714 GetScript()->ProcessEventsFor(SMART_EVENT_CHARMED, nullptr, 0, 0, charmed);
715
716 if (!GetScript()->HasAnyEventWithFlag(SMART_EVENT_FLAG_WHILE_CHARMED)) // we can change AI if there are no events with this flag
717 UnitAI::OnCharmed(isNew);
718}
719
721{
723}
724
726{
727 return 0;
728}
729
730void SmartAI::SetData(uint32 id, uint32 value, Unit* invoker)
731{
732 GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value);
733}
734
735void SmartAI::SetGUID(ObjectGuid const& /*guid*/, int32 /*id*/) { }
736
738{
739 return ObjectGuid::Empty;
740}
741
742void SmartAI::SetRun(bool run)
743{
744 me->SetWalk(!run);
745 _run = run;
746}
747
749{
750 _evadeDisabled = disable;
751}
752
754{
755 _gossipReturn = false;
757 return _gossipReturn;
758}
759
760bool SmartAI::OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId)
761{
762 _gossipReturn = false;
763 GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_SELECT, player, menuId, gossipListId);
764 return _gossipReturn;
765}
766
767bool SmartAI::OnGossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/)
768{
769 return false;
770}
771
772void SmartAI::OnQuestAccept(Player* player, Quest const* quest)
773{
775}
776
777void SmartAI::OnQuestReward(Player* player, Quest const* quest, LootItemType /*type*/, uint32 opt)
778{
780}
781
782void SmartAI::SetCombatMove(bool on, bool stopMoving)
783{
784 if (_canCombatMove == on)
785 return;
786
787 _canCombatMove = on;
788
789 if (!IsAIControlled())
790 return;
791
792 if (me->IsEngaged())
793 {
794 if (on)
795 {
796 if (!me->HasReactState(REACT_PASSIVE) && me->GetVictim() && !me->GetMotionMaster()->HasMovementGenerator([](MovementGenerator const* movement) -> bool
797 {
798 return movement->GetMovementGeneratorType() == CHASE_MOTION_TYPE && movement->Mode == MOTION_MODE_DEFAULT && movement->Priority == MOTION_PRIORITY_NORMAL;
799 }))
800 {
801 SetRun(_run);
803 }
804 }
805 else if (MovementGenerator* movement = me->GetMotionMaster()->GetMovementGenerator([](MovementGenerator const* a) -> bool
806 {
807 return a->GetMovementGeneratorType() == CHASE_MOTION_TYPE && a->Mode == MOTION_MODE_DEFAULT && a->Priority == MOTION_PRIORITY_NORMAL;
808 }))
809 {
810 me->GetMotionMaster()->Remove(movement);
811 if (stopMoving)
812 me->StopMoving();
813 }
814 }
815}
816
817void SmartAI::SetFollow(Unit* target, float dist, float angle, uint32 credit, uint32 end, uint32 creditType)
818{
819 if (!target)
820 {
821 StopFollow(false);
822 return;
823 }
824
825 _followGUID = target->GetGUID();
826 _followDistance = dist;
827 _followAngle = angle;
828 _followArrivedTimer = 1000;
829 _followCredit = credit;
831 _followCreditType = creditType;
832 SetRun(_run);
834}
835
836void SmartAI::StopFollow(bool complete)
837{
839 _followDistance = 0;
840 _followAngle = 0;
841 uint32 followCredit = std::exchange(_followCredit, 0);
842 _followArrivedTimer = 1000;
847
848 if (!complete)
849 return;
850
852 if (player)
853 {
855 player->RewardPlayerAndGroupAtEvent(followCredit, me);
856 else
857 player->GroupEventHappens(followCredit, me);
858 }
859
860 SetDespawnTime(5000);
861 StartDespawn();
863}
864
865void SmartAI::SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker, uint32 startFromEventId)
866{
867 GetScript()->SetTimedActionList(e, entry, invoker, startFromEventId);
868}
869
870void SmartAI::OnGameEvent(bool start, uint16 eventId)
871{
873}
874
875void SmartAI::OnSpellClick(Unit* clicker, bool spellClickHandled)
876{
877 if (!spellClickHandled)
878 return;
879
881}
882
884{
886 return;
887
888 if (_vehicleConditionsTimer <= diff)
889 {
890 if (Vehicle* vehicleKit = me->GetVehicleKit())
891 {
892 for (std::pair<int8 const, VehicleSeat>& seat : vehicleKit->Seats)
893 if (Unit* passenger = ObjectAccessor::GetUnit(*me, seat.second.Passenger.Guid))
894 {
895 if (Player* player = passenger->ToPlayer())
896 {
897 if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry(), player, me))
898 {
899 player->ExitVehicle();
900 return; // check other pessanger in next tick
901 }
902 }
903 }
904 }
905
907 }
908 else
910}
911
913{
915 return;
916
917 if (_escortInvokerCheckTimer < diff)
918 {
920 {
921 StopPath(0, _escortQuestId, true);
922
923 // allow to properly hook out of range despawn action, which in most cases should perform the same operation as dying
926 return;
927 }
929 }
930 else
932
933 // handle pause
935 {
936 // Resume only if there was a pause timer set
938 {
939 if (_waypointPauseTimer <= diff)
940 ResumePath();
941 else
942 _waypointPauseTimer -= diff;
943 }
944 }
945 else if (_waypointPathEnded) // end path
946 {
947 _waypointPathEnded = false;
948 StopPath();
949 return;
950 }
951
953 {
954 if (_OOCReached) // reached OOC WP
955 {
956 _OOCReached = false;
959 ResumePath();
960 }
961 }
962}
963
965{
966 if (!_followGUID.IsEmpty())
967 {
968 if (_followArrivedTimer < diff)
969 {
971 {
972 StopFollow(true);
973 return;
974 }
975
976 _followArrivedTimer = 1000;
977 }
978 else
979 _followArrivedTimer -= diff;
980 }
981}
982
984{
985 if (_despawnState <= 1 || _despawnState > 3)
986 return;
987
988 if (_despawnTime < diff)
989 {
990 if (_despawnState == 2)
991 {
992 me->SetVisible(false);
993 _despawnTime = 5000;
995 }
996 else
998 }
999 else
1000 _despawnTime -= diff;
1001}
1002
1004{
1005 GetScript()->OnUpdate(diff);
1006}
1007
1009{
1011 // do not call respawn event if go is not spawned
1012 if (me->isSpawned())
1014 //Reset();
1015}
1016
1018{
1019 GetScript()->OnReset();
1020}
1021
1022// Called when a player opens a gossip dialog with the gameobject.
1024{
1025 _gossipReturn = false;
1026 GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_HELLO, player, 0, 0, false, nullptr, me);
1027 return _gossipReturn;
1028}
1029
1030// Called when a player selects a gossip item in the gameobject's gossip menu.
1032{
1033 _gossipReturn = false;
1034 GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_SELECT, player, sender, action, false, nullptr, me);
1035 return _gossipReturn;
1036}
1037
1038// Called when a player selects a gossip with a code in the gameobject's gossip menu.
1039bool SmartGameObjectAI::OnGossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/)
1040{
1041 return false;
1042}
1043
1044// Called when a player accepts a quest from the gameobject.
1046{
1047 GetScript()->ProcessEventsFor(SMART_EVENT_ACCEPTED_QUEST, player, quest->GetQuestId(), 0, false, nullptr, me);
1048}
1049
1050// Called when a player selects a quest reward.
1051void SmartGameObjectAI::OnQuestReward(Player* player, Quest const* quest, LootItemType /*type*/, uint32 opt)
1052{
1053 GetScript()->ProcessEventsFor(SMART_EVENT_REWARD_QUEST, player, quest->GetQuestId(), opt, false, nullptr, me);
1054}
1055
1057{
1058 _gossipReturn = false;
1059 GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_HELLO, player, 1, 0, false, nullptr, me);
1060 return _gossipReturn;
1061}
1062
1063// Called when the gameobject is destroyed (destructible buildings only).
1065{
1066 GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, attacker ? attacker->ToUnit() : nullptr, eventId, 0, false, nullptr, me);
1067}
1068
1070{
1071 GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value);
1072}
1073
1075{
1076 GetScript()->SetTimedActionList(e, entry, invoker);
1077}
1078
1080{
1082}
1083
1088
1093
1095{
1096 GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT, caster->ToUnit(), 0, 0, false, spellInfo);
1097}
1098
1103
1108
1113
1115{
1116 public:
1117
1118 SmartTrigger() : AreaTriggerScript("SmartTrigger") { }
1119
1120 bool OnTrigger(Player* player, AreaTriggerEntry const* trigger) override
1121 {
1122 TC_LOG_DEBUG("scripts.ai", "AreaTrigger {} enter is using SmartTrigger script", trigger->ID);
1123 SmartScript script;
1124 script.OnInitialize(player, trigger);
1126 return true;
1127 }
1128
1129 bool OnExit(Player* player, AreaTriggerEntry const* trigger) override
1130 {
1131 TC_LOG_DEBUG("scripts.ai", "AreaTrigger {} exit is using SmartTrigger script", trigger->ID);
1132 SmartScript script;
1133 script.OnInitialize(player, trigger);
1135 return true;
1136 }
1137};
1138
1143
1145{
1146 GetScript()->OnUpdate(diff);
1147}
1148
1153
1158
1160{
1161 GetScript()->SetTimedActionList(e, entry, invoker);
1162}
1163
1165{
1166public:
1168 {
1169 }
1170
1171 AreaTriggerAI* GetAI(AreaTrigger* areaTrigger) const override
1172 {
1173 return new SmartAreaTriggerAI(areaTrigger);
1174 }
1175};
1176
1178{
1179public:
1180 SmartScene() : SceneScript("SmartScene") { }
1181
1182 void OnSceneStart(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
1183 {
1184 SmartScript smartScript;
1185 smartScript.OnInitialize(player, nullptr, sceneTemplate);
1186 smartScript.ProcessEventsFor(SMART_EVENT_SCENE_START, player);
1187 }
1188
1189 void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate, std::string const& triggerName) override
1190 {
1191 SmartScript smartScript;
1192 smartScript.OnInitialize(player, nullptr, sceneTemplate);
1193 smartScript.ProcessEventsFor(SMART_EVENT_SCENE_TRIGGER, player, 0, 0, false, nullptr, nullptr, triggerName);
1194 }
1195
1196 void OnSceneCancel(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
1197 {
1198 SmartScript smartScript;
1199 smartScript.OnInitialize(player, nullptr, sceneTemplate);
1200 smartScript.ProcessEventsFor(SMART_EVENT_SCENE_CANCEL, player);
1201 }
1202
1203 void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
1204 {
1205 SmartScript smartScript;
1206 smartScript.OnInitialize(player, nullptr, sceneTemplate);
1207 smartScript.ProcessEventsFor(SMART_EVENT_SCENE_COMPLETE, player);
1208 }
1209};
1210
1212{
1213public:
1214 SmartQuest() : QuestScript("SmartQuest") { }
1215
1216 // Called when a quest status change
1217 void OnQuestStatusChange(Player* player, Quest const* quest, QuestStatus /*oldStatus*/, QuestStatus newStatus) override
1218 {
1219 SmartScript smartScript;
1220 smartScript.OnInitialize(player, nullptr, nullptr, quest);
1221 switch (newStatus)
1222 {
1224 smartScript.ProcessEventsFor(SMART_EVENT_QUEST_ACCEPTED, player);
1225 break;
1228 break;
1230 smartScript.ProcessEventsFor(SMART_EVENT_QUEST_FAIL, player);
1231 break;
1233 smartScript.ProcessEventsFor(SMART_EVENT_QUEST_REWARDED, player);
1234 break;
1235 case QUEST_STATUS_NONE:
1236 default:
1237 break;
1238 }
1239 }
1240
1241 // Called when a quest objective data change
1242 void OnQuestObjectiveChange(Player* player, Quest const* quest, QuestObjective const& objective, int32 /*oldAmount*/, int32 /*newAmount*/) override
1243 {
1244 uint16 slot = player->FindQuestSlot(quest->GetQuestId());
1245 if (slot < MAX_QUEST_LOG_SIZE && player->IsQuestObjectiveComplete(slot, quest, objective))
1246 {
1247 SmartScript smartScript;
1248 smartScript.OnInitialize(player, nullptr, nullptr, quest);
1249 smartScript.ProcessEventsFor(SMART_EVENT_QUEST_OBJ_COMPLETION, player, objective.ID);
1250 }
1251 }
1252};
1253
1255{
1256public:
1257 SmartEventTrigger() : EventScript("SmartEventTrigger") { }
1258
1259 void OnTrigger(WorldObject* object, WorldObject* invoker, uint32 eventId) override
1260 {
1261 TC_LOG_DEBUG("scripts.ai", "Event {} is using SmartEventTrigger script", eventId);
1262 SmartScript script;
1263 // Set invoker as BaseObject if there isn't target for GameEvents::Trigger
1264 script.OnInitialize(Coalesce<WorldObject>(object, invoker), nullptr, nullptr, nullptr, eventId);
1265 script.ProcessEventsFor(SMART_EVENT_SEND_EVENT_TRIGGER, invoker->ToUnit(), 0, 0, false, nullptr, invoker->ToGameObject());
1266 }
1267};
1268
1270{
1271 new SmartTrigger();
1273 new SmartScene();
1274 new SmartQuest();
1275 new SmartEventTrigger();
1276}
AreaTriggerExitReason
Definition AreaTrigger.h:69
#define sConditionMgr
@ CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
LootItemType
@ MOTION_PRIORITY_NORMAL
@ MOTION_SLOT_DEFAULT
@ WAYPOINT_MOTION_TYPE
@ POINT_MOTION_TYPE
#define INTERACTION_DISTANCE
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
#define PET_FOLLOW_ANGLE
Definition PetDefines.h:99
#define PET_FOLLOW_DIST
Definition PetDefines.h:98
QuestStatus
Definition QuestDef.h:146
@ QUEST_STATUS_REWARDED
Definition QuestDef.h:153
@ QUEST_STATUS_FAILED
Definition QuestDef.h:152
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:150
@ QUEST_STATUS_NONE
Definition QuestDef.h:147
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:148
@ CREATURE_TYPE_FLAG_CAN_ASSIST
void AddSC_SmartScripts()
Registers scripts required by the SAI scripting system.
Definition SmartAI.cpp:1269
static float constexpr SMART_MAX_AID_DIST
Definition SmartAI.h:40
@ SMART_ESCORT_ESCORTING
Definition SmartAI.h:34
@ SMART_ESCORT_PAUSED
Definition SmartAI.h:36
@ SMART_ESCORT_RETURNING
Definition SmartAI.h:35
@ SMART_ESCORT_NONE
Definition SmartAI.h:33
static float constexpr SMART_ESCORT_MAX_PLAYER_DIST
Definition SmartAI.h:39
@ SMART_EVENT_FLAG_WHILE_CHARMED
std::vector< WorldObject * > ObjectVector
@ SMART_EVENT_EVADE
@ SMART_EVENT_ACTION_DONE
@ SMART_EVENT_SUMMON_DESPAWNED
@ SMART_EVENT_SPELLHIT
@ SMART_EVENT_SCENE_START
@ SMART_EVENT_RECEIVE_EMOTE
@ SMART_EVENT_QUEST_FAIL
@ SMART_EVENT_ON_AURA_APPLIED
@ SMART_EVENT_DATA_SET
@ SMART_EVENT_RECEIVE_HEAL
@ SMART_EVENT_SCENE_COMPLETE
@ SMART_EVENT_QUEST_COMPLETION
@ SMART_EVENT_ON_SPELLCLICK
@ SMART_EVENT_MOVEMENTINFORM
@ SMART_EVENT_PASSENGER_REMOVED
@ SMART_EVENT_ON_AURA_REMOVED
@ SMART_EVENT_WAYPOINT_PAUSED
@ SMART_EVENT_REACHED_HOME
@ SMART_EVENT_REWARD_QUEST
@ SMART_EVENT_GO_EVENT_INFORM
@ SMART_EVENT_AREATRIGGER_EXIT
@ SMART_EVENT_GO_LOOT_STATE_CHANGED
@ SMART_EVENT_SCENE_CANCEL
@ SMART_EVENT_JUST_SUMMONED
@ SMART_EVENT_CHARMED
@ SMART_EVENT_ON_SPELL_CAST
@ SMART_EVENT_SPELLHIT_TARGET
@ SMART_EVENT_GAME_EVENT_START
@ SMART_EVENT_KILL
@ SMART_EVENT_GOSSIP_HELLO
@ SMART_EVENT_GOSSIP_SELECT
@ SMART_EVENT_CORPSE_REMOVED
@ SMART_EVENT_PASSENGER_BOARDED
@ SMART_EVENT_SCENE_TRIGGER
@ SMART_EVENT_AREATRIGGER_ENTER
@ SMART_EVENT_WAYPOINT_ENDED
@ SMART_EVENT_ACCEPTED_QUEST
@ SMART_EVENT_WAYPOINT_RESUMED
@ SMART_EVENT_ON_SPELL_FAILED
@ SMART_EVENT_WAYPOINT_REACHED
@ SMART_EVENT_RESPAWN
@ SMART_EVENT_QUEST_ACCEPTED
@ SMART_EVENT_QUEST_REWARDED
@ SMART_EVENT_DEATH
@ SMART_EVENT_GAME_EVENT_END
@ SMART_EVENT_DAMAGED
@ SMART_EVENT_FOLLOW_COMPLETED
@ SMART_EVENT_QUEST_OBJ_COMPLETION
@ SMART_EVENT_WAYPOINT_STOPPED
@ SMART_EVENT_SUMMONED_UNIT_DIES
@ SMART_EVENT_SEND_EVENT_TRIGGER
@ SMART_EVENT_ON_SPELL_START
@ SMART_EVENT_ON_DESPAWN
@ SMART_EVENT_AGGRO
@ SMART_EVENT_DAMAGED_TARGET
@ SMART_EVENT_SUMMONED_UNIT
@ SMART_ESCORT_LAST_OOC_POINT
@ SMART_ESCORT_TARGETS
EvadeReason
@ REACT_PASSIVE
NPCFlags
Non Player Character flags.
@ UNIT_NPC_FLAG_NONE
DamageEffectType
@ UNIT_STATE_EVADE
Definition Unit.h:283
#define sWaypointMgr
AreaTrigger *const at
Aura * GetBase() const
Definition SpellAuras.h:82
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:182
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
virtual void MoveInLineOfSight(Unit *)
bool IsEngaged() const
Definition CreatureAI.h:79
bool _EnterEvadeMode(EvadeReason why=EvadeReason::Other)
virtual void JustAppeared()
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void EngagementOver()
Creature * GetLeader() const
bool IsFormed() const
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:386
void StartDefaultCombatMovement(Unit *victim, Optional< float > range={}, Optional< float > angle={})
CreatureDifficulty const * GetCreatureDifficulty() const
Definition Creature.h:268
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition Creature.h:388
bool HasReactState(ReactStates state) const
Definition Creature.h:176
bool IsEngaged() const override
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
uint32 GetWaypointPathId() const
Definition Creature.h:396
std::pair< uint32, uint32 > GetCurrentWaypointInfo() const
Definition Creature.h:400
CreatureGroup * GetFormation()
Definition Creature.h:406
bool IsInEvadeMode() const
Definition Creature.h:217
GameObject *const me
bool isSpawned() const
Definition GameObject.h:259
Definition Group.h:205
bool HasMovementGenerator(std::function< bool(MovementGenerator const *)> const &filter, MovementSlot slot=MOTION_SLOT_ACTIVE) const
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MoveFollow(Unit *target, float dist, Optional< ChaseAngle > angle={}, Optional< Milliseconds > duration={}, bool ignoreTargetWalk=false, MovementSlot slot=MOTION_SLOT_ACTIVE, 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 MoveTargetedHome()
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={})
MovementGenerator * GetMovementGenerator(std::function< bool(MovementGenerator const *)> const &filter, MovementSlot slot=MOTION_SLOT_ACTIVE) const
void Remove(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
static ObjectGuid const Empty
Definition ObjectGuid.h:314
bool IsEmpty() const
Definition ObjectGuid.h:362
std::string ToString() const
void Clear()
Definition ObjectGuid.h:329
Player * ToPlayer()
Definition Object.h:126
GameObject * ToGameObject()
Definition Object.h:131
uint32 GetEntry() const
Definition Object.h:89
Creature * ToCreature()
Definition Object.h:121
Unit * ToUnit()
Definition Object.h:116
uint16 FindQuestSlot(uint32 quest_id) const
Definition Player.cpp:16383
bool HasCorpse() const
Definition Player.h:2337
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
Definition Player.cpp:16573
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:26434
void AreaExploredOrEventHappens(uint32 questId)
Definition Player.cpp:16552
void FailQuest(uint32 quest_id)
Definition Player.cpp:15347
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2796
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:26409
uint32 GetQuestId() const
Definition QuestDef.h:637
uint32 _escortQuestId
Definition SmartAI.h:287
void OnGameEvent(bool start, uint16 eventId) override
Definition SmartAI.cpp:870
void AddEscortState(uint32 escortState)
Definition SmartAI.h:67
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
Definition SmartAI.cpp:600
void OnSpellStart(SpellInfo const *spellInfo) override
Definition SmartAI.cpp:615
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
Definition SmartAI.cpp:760
void AttackStart(Unit *who) override
== Triggered Actions Requested ==================
Definition SmartAI.cpp:572
bool _charmed
Definition SmartAI.h:252
void IsSummonedBy(WorldObject *summoner) override
Definition SmartAI.cpp:651
void WaypointPathEnded(uint32 nodeId, uint32 pathId) override
Definition SmartAI.cpp:366
bool CanResumePath()
Definition SmartAI.cpp:135
bool HasEscortState(uint32 escortState) const
Definition SmartAI.h:63
uint32 _followArrivedEntry
Definition SmartAI.h:256
float _followDistance
Definition SmartAI.h:258
void PausePath(uint32 delay, bool forced=false)
Definition SmartAI.cpp:100
void PassengerBoarded(Unit *who, int8 seatId, bool apply) override
== Fields =======================================
Definition SmartAI.cpp:676
void EnterEvadeMode(EvadeReason why) override
Definition SmartAI.cpp:389
void OnQuestReward(Player *player, Quest const *quest, LootItemType type, uint32 opt) override
Definition SmartAI.cpp:777
bool OnGossipHello(Player *player) override
Definition SmartAI.cpp:753
void DamageDealt(Unit *doneTo, uint32 &damage, DamageEffectType) override
Definition SmartAI.cpp:656
void OnSpellClick(Unit *clicker, bool spellClickHandled) override
Definition SmartAI.cpp:875
void OnCharmed(bool isNew) override
Definition SmartAI.cpp:681
bool _run
Definition SmartAI.h:272
ObjectGuid GetGUID(int32 id) const override
Definition SmartAI.cpp:737
uint32 _vehicleConditionsTimer
Definition SmartAI.h:282
bool AssistPlayerInCombatAgainst(Unit *who)
Definition SmartAI.cpp:451
uint32 _escortInvokerCheckTimer
Definition SmartAI.h:263
void OnSpellCast(SpellInfo const *spellInfo) override
Definition SmartAI.cpp:605
bool _waypointPathEnded
Definition SmartAI.h:270
uint32 _currentWaypointNodeId
Definition SmartAI.h:264
void StopPath(uint32 DespawnTime=0, uint32 quest=0, bool fail=false)
Definition SmartAI.cpp:146
void SetDespawnTime(uint32 t)
Definition SmartAI.h:216
void StartDespawn()
Definition SmartAI.h:221
void OnQuestAccept(Player *player, Quest const *quest) override
Definition SmartAI.cpp:772
void JustReachedHome() override
Definition SmartAI.cpp:521
bool _canCombatMove
Definition SmartAI.h:274
void EndPath(bool fail=false)
Definition SmartAI.cpp:185
bool _vehicleConditions
Definition SmartAI.h:281
bool _waypointReached
Definition SmartAI.h:265
void SetFollow(Unit *target, float dist=0.0f, float angle=0.0f, uint32 credit=0, uint32 end=0, uint32 creditType=0)
Definition SmartAI.cpp:817
uint32 _despawnTime
Definition SmartAI.h:277
void DamageTaken(Unit *doneBy, uint32 &damage, DamageEffectType, SpellInfo const *) override
Definition SmartAI.cpp:630
void OnAuraRemoved(AuraApplication const *aurApp) override
Definition SmartAI.cpp:625
uint32 _despawnState
Definition SmartAI.h:278
void JustEngagedWith(Unit *enemy) override
Definition SmartAI.cpp:541
void UpdateAI(uint32 diff) override
Definition SmartAI.cpp:281
void OnDespawn() override
Definition SmartAI.cpp:671
bool OnGossipSelectCode(Player *player, uint32 menuId, uint32 gossipListId, char const *code) override
Definition SmartAI.cpp:767
void UpdateDespawn(uint32 diff)
Definition SmartAI.cpp:983
void SetCombatMove(bool on, bool stopMoving=false)
Definition SmartAI.cpp:782
bool _gossipReturn
Definition SmartAI.h:285
float _followAngle
Definition SmartAI.h:259
void StopFollow(bool complete)
Definition SmartAI.cpp:836
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker, uint32 startFromEventId=0)
Definition SmartAI.cpp:865
void JustDied(Unit *killer) override
Definition SmartAI.cpp:549
void RemoveEscortState(uint32 escortState)
Definition SmartAI.h:71
void DoAction(int32 param) override
Definition SmartAI.cpp:720
WaypointPath const * LoadPath(uint32 entry)
Definition SmartAI.cpp:84
void InitializeAI() override
Definition SmartAI.cpp:494
uint32 _escortNPCFlags
Definition SmartAI.h:262
bool _waypointPauseForced
Definition SmartAI.h:267
uint32 _followArrivedTimer
Definition SmartAI.h:254
void OnAuraApplied(AuraApplication const *aurApp) override
Definition SmartAI.cpp:620
void SetGUID(ObjectGuid const &guid, int32 id) override
Definition SmartAI.cpp:735
void WaypointReached(uint32 nodeId, uint32 pathId) override
Definition SmartAI.cpp:337
bool IsAIControlled() const
Definition SmartAI.cpp:44
ObjectGuid _followGUID
Definition SmartAI.h:257
void OnSpellFailed(SpellInfo const *spellInfo) override
Definition SmartAI.cpp:610
void SummonedCreatureDespawn(Creature *unit) override
Definition SmartAI.cpp:661
void JustAppeared() override
Definition SmartAI.cpp:510
void HealReceived(Unit *doneBy, uint32 &addhealth) override
Definition SmartAI.cpp:641
bool _evadeDisabled
Definition SmartAI.h:273
void ReturnToLastOOCPos()
Definition SmartAI.cpp:272
uint32 _waypointPauseTimer
Definition SmartAI.h:266
void CorpseRemoved(uint32 &respawnDelay) override
== State checks =================================
Definition SmartAI.cpp:666
bool _OOCReached
Definition SmartAI.h:269
void SummonedCreatureDies(Creature *summon, Unit *killer) override
Definition SmartAI.cpp:567
uint32 _followCredit
Definition SmartAI.h:255
void JustSummoned(Creature *creature) override
Definition SmartAI.cpp:562
SmartAI(Creature *creature, uint32 scriptId={})
Definition SmartAI.cpp:36
uint32 _followCreditType
Definition SmartAI.h:253
void StartPath(uint32 pathId=0, bool repeat=false, Unit *invoker=nullptr, uint32 nodeId=0, uint32 fadeObjectDuration=0, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
Definition SmartAI.cpp:49
void SetEvadeDisabled(bool disable=true)
Definition SmartAI.cpp:748
void CheckConditions(uint32 diff)
Definition SmartAI.cpp:883
SmartScript * GetScript()
Definition SmartAI.h:88
void SetData(uint32 id, uint32 value) override
Definition SmartAI.h:190
void SetRun(bool run=true)
Definition SmartAI.cpp:742
void MoveInLineOfSight(Unit *who) override
Definition SmartAI.cpp:435
void ReceiveEmote(Player *player, uint32 textEmote) override
Definition SmartAI.cpp:646
void UpdatePath(uint32 diff)
Definition SmartAI.cpp:912
uint32 _escortState
Definition SmartAI.h:261
void KilledUnit(Unit *victim) override
Definition SmartAI.cpp:557
void MovementInform(uint32 MovementType, uint32 Data) override
Definition SmartAI.cpp:375
void ResumePath()
Definition SmartAI.cpp:258
uint32 _invincibilityHPLevel
Definition SmartAI.h:275
void UpdateFollow(uint32 diff)
Definition SmartAI.cpp:964
bool _repeatWaypointPath
Definition SmartAI.h:268
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
Definition SmartAI.cpp:595
bool IsEscortInvokerInRange()
Definition SmartAI.cpp:301
uint32 GetData(uint32 id) const override
Definition SmartAI.cpp:725
void OnUnitEnter(Unit *unit) override
Definition SmartAI.cpp:1149
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker)
Definition SmartAI.cpp:1159
SmartScript * GetScript()
Definition SmartAI.h:353
void OnUpdate(uint32 diff) override
Definition SmartAI.cpp:1144
void OnUnitExit(Unit *unit, AreaTriggerExitReason reason) override
Definition SmartAI.cpp:1154
void OnInitialize() override
Definition SmartAI.cpp:1139
AreaTriggerAI * GetAI(AreaTrigger *areaTrigger) const override
Definition SmartAI.cpp:1171
void OnTrigger(WorldObject *object, WorldObject *invoker, uint32 eventId) override
Definition SmartAI.cpp:1259
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
Definition SmartAI.cpp:1031
void InitializeAI() override
Definition SmartAI.cpp:1008
void OnGameEvent(bool start, uint16 eventId) override
Definition SmartAI.cpp:1079
void UpdateAI(uint32 diff) override
Definition SmartAI.cpp:1003
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker)
Definition SmartAI.cpp:1074
void EventInform(uint32 eventId) override
Definition SmartAI.cpp:1089
bool OnGossipHello(Player *player) override
Definition SmartAI.cpp:1023
SmartScript * GetScript()
Definition SmartAI.h:299
void OnQuestReward(Player *player, Quest const *quest, LootItemType type, uint32 opt) override
Definition SmartAI.cpp:1051
void OnLootStateChanged(uint32 state, Unit *unit) override
Definition SmartAI.cpp:1084
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
Definition SmartAI.cpp:1094
bool OnReportUse(Player *player) override
Definition SmartAI.cpp:1056
void Destroyed(WorldObject *attacker, uint32 eventId) override
Definition SmartAI.cpp:1064
void OnQuestAccept(Player *player, Quest const *quest) override
Definition SmartAI.cpp:1045
void SetData(uint32 id, uint32 value, Unit *invoker)
Definition SmartAI.cpp:1069
void SummonedCreatureDespawn(Creature *unit) override
Definition SmartAI.cpp:1109
bool OnGossipSelectCode(Player *player, uint32 menuId, uint32 gossipListId, char const *code) override
Definition SmartAI.cpp:1039
void SummonedCreatureDies(Creature *summon, Unit *killer) override
Definition SmartAI.cpp:1104
void Reset() override
Definition SmartAI.cpp:1017
void JustSummoned(Creature *creature) override
Definition SmartAI.cpp:1099
void OnQuestStatusChange(Player *player, Quest const *quest, QuestStatus, QuestStatus newStatus) override
Definition SmartAI.cpp:1217
void OnQuestObjectiveChange(Player *player, Quest const *quest, QuestObjective const &objective, int32, int32) override
Definition SmartAI.cpp:1242
void OnSceneStart(Player *player, uint32, SceneTemplate const *sceneTemplate) override
Definition SmartAI.cpp:1182
void OnSceneCancel(Player *player, uint32, SceneTemplate const *sceneTemplate) override
Definition SmartAI.cpp:1196
void OnSceneTriggerEvent(Player *player, uint32, SceneTemplate const *sceneTemplate, std::string const &triggerName) override
Definition SmartAI.cpp:1189
void OnSceneComplete(Player *player, uint32, SceneTemplate const *sceneTemplate) override
Definition SmartAI.cpp:1203
void OnUpdate(const uint32 diff)
void OnInitialize(WorldObject *obj, AreaTriggerEntry const *at=nullptr, SceneTemplate const *scene=nullptr, Quest const *qst=nullptr, uint32 evnt=0)
void OnMoveInLineOfSight(Unit *who)
uint32 GetPathId() const
Definition SmartScript.h:65
ObjectVector const * GetStoredTargetVector(uint32 id, WorldObject const &ref) const
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker, uint32 startFromEventId=0)
void SetPathId(uint32 id)
Definition SmartScript.h:64
void ProcessEventsFor(SMART_EVENT e, Unit *unit=nullptr, uint32 var0=0, uint32 var1=0, bool bvar=false, SpellInfo const *spell=nullptr, GameObject *gob=nullptr, std::string_view varString={ })
bool OnExit(Player *player, AreaTriggerEntry const *trigger) override
Definition SmartAI.cpp:1129
bool OnTrigger(Player *player, AreaTriggerEntry const *trigger) override
Definition SmartAI.cpp:1120
virtual bool CanAIAttack(Unit const *) const
Definition UnitAI.h:58
virtual void OnCharmed(bool isNew)
Definition UnitAI.cpp:49
Definition Unit.h:635
void ClearUnitState(uint32 f)
Definition Unit.h:744
bool IsVehicle() const
Definition Unit.h:754
bool IsCharmed() const
Definition Unit.h:1236
void SetVisible(bool x)
Definition Unit.cpp:8768
NPCFlags GetNpcFlags() const
Definition Unit.h:995
Unit * GetCharmer() const
Definition Unit.h:1209
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3231
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
void ResumeMovement(uint32 timer=0, uint8 slot=0)
Definition Unit.cpp:10707
void PauseMovement(uint32 timer=0, uint8 slot=0, bool forced=true)
Definition Unit.cpp:10695
bool IsAlive() const
Definition Unit.h:1185
void StopMoving()
Definition Unit.cpp:10680
void AddUnitState(uint32 f)
Definition Unit.h:742
bool isInAccessiblePlaceFor(Creature const *c) const
Definition Unit.cpp:3310
Unit * EnsureVictim() const
Definition Unit.h:728
Unit * GetCharmerOrOwner() const
Definition Unit.h:1221
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:5853
bool isPossessed() const
Definition Unit.h:1237
uint64 GetHealth() const
Definition Unit.h:788
bool SetWalk(bool enable)
Definition Unit.cpp:13343
void EngageWithTarget(Unit *who)
Definition Unit.cpp:8494
virtual float GetFollowAngle() const
Definition Unit.h:1816
Unit * GetVictim() const
Definition Unit.h:726
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
ObjectGuid LastCharmerGUID
Definition Unit.h:1779
Vehicle * GetVehicleKit() const
Definition Unit.h:1782
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:999
bool AttackStop()
Definition Unit.cpp:5965
bool IsInCombat() const
Definition Unit.h:1058
bool isDead() const
Definition Unit.h:1187
InstanceScript * GetInstanceScript() const
Definition Object.cpp:396
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition Object.cpp:535
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:1517
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Object.cpp:1621
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:501
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2482
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:432
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:469
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
std::vector< WaypointNode > Nodes