TrinityCore
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 "Vehicle.h"
33#include "WaypointManager.h"
34
35SmartAI::SmartAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), _charmed(false), _followCreditType(0), _followArrivedTimer(0), _followCredit(0), _followArrivedEntry(0), _followDistance(0.f), _followAngle(0.f),
36 _escortState(SMART_ESCORT_NONE), _escortNPCFlags(0), _escortInvokerCheckTimer(1000), _currentWaypointNodeId(0), _waypointReached(false), _waypointPauseTimer(0), _waypointPauseForced(false), _repeatWaypointPath(false),
37 _OOCReached(false), _waypointPathEnded(false), _run(true), _evadeDisabled(false), _canCombatMove(true), _invincibilityHPLevel(0), _despawnTime(0), _despawnState(0), _vehicleConditionsTimer(0),
38 _gossipReturn(false), _escortQuestId(0)
39{
41}
42
44{
45 return !_charmed;
46}
47
48void SmartAI::StartPath(uint32 pathId/* = 0*/, bool repeat/* = false*/, Unit* invoker/* = nullptr*/, uint32 nodeId/* = 0*/)
49{
51 StopPath();
52
53 if (!pathId)
54 return;
55
56 WaypointPath const* path = LoadPath(pathId);
57 if (!path)
58 return;
59
61 _waypointPathEnded = false;
62
63 _repeatWaypointPath = repeat;
64
65 // Do not use AddEscortState, removing everything from previous
67
68 if (invoker && invoker->GetTypeId() == TYPEID_PLAYER)
69 {
72 }
73
75}
76
78{
80 return nullptr;
81
82 WaypointPath const* path = sWaypointMgr->GetPath(entry);
83 if (!path || path->Nodes.empty())
84 {
85 GetScript()->SetPathId(0);
86 return nullptr;
87 }
88
89 GetScript()->SetPathId(entry);
90 return path;
91}
92
93void SmartAI::PausePath(uint32 delay, bool forced)
94{
96 {
97 me->PauseMovement(delay, MOTION_SLOT_DEFAULT, forced);
99 {
100 std::pair<uint32, uint32> waypointInfo = me->GetCurrentWaypointInfo();
101 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_PAUSED, nullptr, waypointInfo.first, waypointInfo.second);
102 }
103 return;
104 }
105
107 {
108 TC_LOG_ERROR("scripts.ai.sai", "SmartAI::PausePath: Creature wanted to pause waypoint (current waypoint: {}) movement while already paused, ignoring. ({})", _currentWaypointNodeId, me->GetGUID().ToString());
109 return;
110 }
111
112 _waypointPauseTimer = delay;
113
114 if (forced)
115 {
116 _waypointPauseForced = forced;
117 SetRun(_run);
118 me->PauseMovement();
120 }
121 else
122 _waypointReached = false;
123
126}
127
129{
131 {
132 // The whole resume logic doesn't support this case
133 return false;
134 }
135
137}
138
139void SmartAI::StopPath(uint32 DespawnTime, uint32 quest, bool fail)
140{
142 {
143 std::pair<uint32, uint32> waypointInfo = { 0, 0 };
145 waypointInfo = me->GetCurrentWaypointInfo();
146
147 if (_despawnState != 2)
148 SetDespawnTime(DespawnTime);
149
151
152 if (waypointInfo.second)
153 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_STOPPED, nullptr, waypointInfo.first, waypointInfo.second);
154
155 if (!fail)
156 {
157 if (waypointInfo.second)
158 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, nullptr, waypointInfo.first, waypointInfo.second);
159 if (_despawnState == 1)
160 StartDespawn();
161 }
162 return;
163 }
164
165 if (quest)
166 _escortQuestId = quest;
167
168 if (_despawnState != 2)
169 SetDespawnTime(DespawnTime);
170
172
174
175 EndPath(fail);
176}
177
178void SmartAI::EndPath(bool fail)
179{
181
183
184 if (_escortNPCFlags)
185 {
187 _escortNPCFlags = 0;
188 }
189
191 if (targets && _escortQuestId)
192 {
193 if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
194 {
195 Player* player = targets->front()->ToPlayer();
196 if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse())
198
199 if (fail)
200 player->FailQuest(_escortQuestId);
201
202 if (Group* group = player->GetGroup())
203 {
204 for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
205 {
206 Player* groupGuy = groupRef->GetSource();
207 if (!groupGuy->IsInMap(player))
208 continue;
209
210 if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->HasCorpse())
212 else if (fail)
213 groupGuy->FailQuest(_escortQuestId);
214 }
215 }
216 }
217 else
218 {
219 for (WorldObject* target : *targets)
220 {
221 if (GetScript()->IsPlayer(target))
222 {
223 Player* player = target->ToPlayer();
224 if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse())
226 else if (fail)
227 player->FailQuest(_escortQuestId);
228 }
229 }
230 }
231 }
232
233 // End Path events should be only processed if it was SUCCESSFUL stop or stop called by SMART_ACTION_WAYPOINT_STOP
234 if (fail)
235 return;
236
237 uint32 pathid = GetScript()->GetPathId();
239
241 {
242 if (IsAIControlled())
243 StartPath(GetScript()->GetPathId(), _repeatWaypointPath);
244 }
245 else if (pathid == GetScript()->GetPathId()) // if it's not the same pathid, our script wants to start another path; don't override it
246 GetScript()->SetPathId(0);
247
248 if (_despawnState == 1)
249 StartDespawn();
250}
251
253{
255
257
258 _waypointPauseForced = false;
259 _waypointReached = false;
261
262 SetRun(_run);
264}
265
267{
268 if (!IsAIControlled())
269 return;
270
271 me->SetWalk(false);
273}
274
276{
277 if (!me->IsAlive())
278 {
279 if (IsEngaged())
281 return;
282 }
283
284 CheckConditions(diff);
285
286 UpdateVictim();
287
288 GetScript()->OnUpdate(diff);
289
290 UpdatePath(diff);
291 UpdateFollow(diff);
292 UpdateDespawn(diff);
293}
294
296{
297 if (ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS, *me))
298 {
300 if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
301 {
302 Player* player = (*targets->begin())->ToPlayer();
303 if (me->GetDistance(player) <= checkDist)
304 return true;
305
306 if (Group* group = player->GetGroup())
307 {
308 for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
309 {
310 Player* groupGuy = groupRef->GetSource();
311 if (groupGuy->IsInMap(player) && me->GetDistance(groupGuy) <= checkDist)
312 return true;
313 }
314 }
315 }
316 else
317 {
318 for (WorldObject* target : *targets)
319 {
320 if (GetScript()->IsPlayer(target))
321 {
322 if (me->GetDistance(target->ToPlayer()) <= checkDist)
323 return true;
324 }
325 }
326 }
327
328 // no valid target found
329 return false;
330 }
331
332 // no player invoker was stored, just ignore range check
333 return true;
334}
335
337{
339 {
340 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_REACHED, nullptr, nodeId, pathId);
341 return;
342 }
343
344 _currentWaypointNodeId = nodeId;
345
347
349 {
350 _waypointReached = true;
351 me->PauseMovement();
353 }
355 {
356 WaypointPath const* path = sWaypointMgr->GetPath(pathId);
357 if (path && _currentWaypointNodeId == path->Nodes.back().Id)
358 _waypointPathEnded = true;
359 else
360 SetRun(_run);
361 }
362}
363
366{
368 {
369 GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_ENDED, nullptr, nodeId, pathId);
370 return;
371 }
372}
373
375{
378
380
382 return;
383
385 _OOCReached = true;
386}
387
389{
390 if (_evadeDisabled)
391 {
393 return;
394 }
395
396 if (!IsAIControlled())
397 {
398 me->AttackStop();
399 return;
400 }
401
402 if (!_EnterEvadeMode())
403 return;
404
406
407 GetScript()->ProcessEventsFor(SMART_EVENT_EVADE); // must be after _EnterEvadeMode (spells, auras, ...)
408
409 SetRun(_run);
410
411 if (Unit* owner = me->GetCharmerOrOwner())
412 {
415 }
417 {
420 }
421 else if (Unit* target = !_followGUID.IsEmpty() ? ObjectAccessor::GetUnit(*me, _followGUID) : nullptr)
422 {
424 // evade is not cleared in MoveFollow, so we can't keep it
426 }
427 else
429
431 GetScript()->OnReset();
432}
433
435{
436 if (!who)
437 return;
438
440
441 if (!IsAIControlled())
442 return;
443
445 return;
446
448}
449
451{
453 return false;
454
455 if (!who || !who->GetVictim())
456 return false;
457
458 // experimental (unknown) flag not present
460 return false;
461
462 // not a player
464 return false;
465
466 if (!who->isInAccessiblePlaceFor(me))
467 return false;
468
469 if (!CanAIAttack(who))
470 return false;
471
472 // we cannot attack in evade mode
473 if (me->IsInEvadeMode())
474 return false;
475
476 // or if enemy is in evade mode
477 if (who->GetTypeId() == TYPEID_UNIT && who->ToCreature()->IsInEvadeMode())
478 return false;
479
480 if (!me->IsValidAssistTarget(who->GetVictim()))
481 return false;
482
483 // too far away and no free sight
485 {
486 me->EngageWithTarget(who);
487 return true;
488 }
489
490 return false;
491}
492
494{
496
497 _despawnTime = 0;
498 _despawnState = 0;
500 _followGUID.Clear(); // do not reset follower on Reset(), we need it after combat evade
501 _followDistance = 0;
502 _followAngle = 0;
503 _followCredit = 0;
504 _followArrivedTimer = 1000;
507}
508
510{
512
513 if (me->isDead())
514 return;
515
517 GetScript()->OnReset();
518}
519
521{
522 GetScript()->OnReset();
524
525 CreatureGroup* formation = me->GetFormation();
526 if (!formation || formation->GetLeader() == me || !formation->IsFormed())
527 {
529 {
530 if (me->GetWaypointPathId())
532 }
533
535 }
536 else if (formation->IsFormed())
537 me->GetMotionMaster()->MoveIdle(); // wait the order of leader
538}
539
541{
542 if (IsAIControlled())
543 me->InterruptNonMeleeSpells(false); // must be before ProcessEvents
544
546}
547
549{
551 EndPath(true);
552
554}
555
557{
559}
560
562{
564}
565
567{
569}
570
572{
573 // dont allow charmed npcs to act on their own
574 if (!IsAIControlled())
575 {
576 if (who)
577 me->Attack(who, true);
578 return;
579 }
580
581 if (who && me->Attack(who, true))
582 {
584 me->PauseMovement();
585
586 if (_canCombatMove)
587 {
588 SetRun(_run);
590 }
591 }
592}
593
594void SmartAI::SpellHit(WorldObject* caster, SpellInfo const* spellInfo)
595{
596 GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT, caster->ToUnit(), 0, 0, false, spellInfo, caster->ToGameObject());
597}
598
599void SmartAI::SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo)
600{
601 GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT_TARGET, target->ToUnit(), 0, 0, false, spellInfo, target->ToGameObject());
602}
603
604void SmartAI::OnSpellCast(SpellInfo const* spellInfo)
605{
606 GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELL_CAST, nullptr, 0, 0, false, spellInfo);
607}
608
609void SmartAI::OnSpellFailed(SpellInfo const* spellInfo)
610{
611 GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELL_FAILED, nullptr, 0, 0, false, spellInfo);
612}
613
614void SmartAI::OnSpellStart(SpellInfo const* spellInfo)
615{
616 GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELL_START, nullptr, 0, 0, false, spellInfo);
617}
618
619void SmartAI::DamageTaken(Unit* doneBy, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/)
620{
622
623 if (!IsAIControlled()) // don't allow players to use unkillable units
624 return;
625
627 damage = me->GetHealth() - _invincibilityHPLevel; // damage should not be nullified, because of player damage req.
628}
629
630void SmartAI::HealReceived(Unit* doneBy, uint32& addhealth)
631{
633}
634
635void SmartAI::ReceiveEmote(Player* player, uint32 textEmote)
636{
638}
639
641{
642 GetScript()->ProcessEventsFor(SMART_EVENT_JUST_SUMMONED, summoner->ToUnit(), 0, 0, false, nullptr, summoner->ToGameObject());
643}
644
645void SmartAI::DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/)
646{
648}
649
651{
653}
654
656{
657 GetScript()->ProcessEventsFor(SMART_EVENT_CORPSE_REMOVED, nullptr, respawnDelay);
658}
659
661{
663}
664
665void SmartAI::PassengerBoarded(Unit* who, int8 seatId, bool apply)
666{
668}
669
670void SmartAI::OnCharmed(bool isNew)
671{
672 bool const charmed = me->IsCharmed();
673 if (charmed) // do this before we change charmed state, as charmed state might prevent these things from processing
674 {
676 EndPath(true);
677 }
678
679 _charmed = charmed;
680
681 if (charmed && !me->isPossessed() && !me->IsVehicle())
683
684 if (!charmed && !me->IsInEvadeMode())
685 {
687 StartPath(GetScript()->GetPathId(), true);
688 else
689 me->SetWalk(!_run);
690
691 if (!me->LastCharmerGUID.IsEmpty())
692 {
694 if (Unit* lastCharmer = ObjectAccessor::GetUnit(*me, me->LastCharmerGUID))
695 me->EngageWithTarget(lastCharmer);
697
698 if (!me->IsInCombat())
700 }
701 }
702
703 GetScript()->ProcessEventsFor(SMART_EVENT_CHARMED, nullptr, 0, 0, charmed);
704
705 if (!GetScript()->HasAnyEventWithFlag(SMART_EVENT_FLAG_WHILE_CHARMED)) // we can change AI if there are no events with this flag
706 UnitAI::OnCharmed(isNew);
707}
708
710{
712}
713
715{
716 return 0;
717}
718
719void SmartAI::SetData(uint32 id, uint32 value, Unit* invoker)
720{
721 GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value);
722}
723
724void SmartAI::SetGUID(ObjectGuid const& /*guid*/, int32 /*id*/) { }
725
727{
728 return ObjectGuid::Empty;
729}
730
731void SmartAI::SetRun(bool run)
732{
733 me->SetWalk(!run);
734 _run = run;
735}
736
738{
739 me->SetDisableGravity(fly);
740}
741
743{
744 _evadeDisabled = disable;
745}
746
748{
749 _gossipReturn = false;
751 return _gossipReturn;
752}
753
754bool SmartAI::OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId)
755{
756 _gossipReturn = false;
757 GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_SELECT, player, menuId, gossipListId);
758 return _gossipReturn;
759}
760
761bool SmartAI::OnGossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/)
762{
763 return false;
764}
765
766void SmartAI::OnQuestAccept(Player* player, Quest const* quest)
767{
769}
770
771void SmartAI::OnQuestReward(Player* player, Quest const* quest, LootItemType /*type*/, uint32 opt)
772{
774}
775
776void SmartAI::SetCombatMove(bool on, bool stopMoving)
777{
778 if (_canCombatMove == on)
779 return;
780
781 _canCombatMove = on;
782
783 if (!IsAIControlled())
784 return;
785
786 if (me->IsEngaged())
787 {
788 if (on)
789 {
790 if (!me->HasReactState(REACT_PASSIVE) && me->GetVictim() && !me->GetMotionMaster()->HasMovementGenerator([](MovementGenerator const* movement) -> bool
791 {
792 return movement->GetMovementGeneratorType() == CHASE_MOTION_TYPE && movement->Mode == MOTION_MODE_DEFAULT && movement->Priority == MOTION_PRIORITY_NORMAL;
793 }))
794 {
795 SetRun(_run);
797 }
798 }
799 else if (MovementGenerator* movement = me->GetMotionMaster()->GetMovementGenerator([](MovementGenerator const* a) -> bool
800 {
801 return a->GetMovementGeneratorType() == CHASE_MOTION_TYPE && a->Mode == MOTION_MODE_DEFAULT && a->Priority == MOTION_PRIORITY_NORMAL;
802 }))
803 {
804 me->GetMotionMaster()->Remove(movement);
805 if (stopMoving)
806 me->StopMoving();
807 }
808 }
809}
810
811void SmartAI::SetFollow(Unit* target, float dist, float angle, uint32 credit, uint32 end, uint32 creditType)
812{
813 if (!target)
814 {
815 StopFollow(false);
816 return;
817 }
818
819 _followGUID = target->GetGUID();
820 _followDistance = dist;
821 _followAngle = angle;
822 _followArrivedTimer = 1000;
823 _followCredit = credit;
825 _followCreditType = creditType;
826 SetRun(_run);
828}
829
830void SmartAI::StopFollow(bool complete)
831{
833 _followDistance = 0;
834 _followAngle = 0;
835 _followCredit = 0;
836 _followArrivedTimer = 1000;
841
842 if (!complete)
843 return;
844
846 if (player)
847 {
850 else
852 }
853
854 SetDespawnTime(5000);
855 StartDespawn();
857}
858
859void SmartAI::SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker, uint32 startFromEventId)
860{
861 GetScript()->SetTimedActionList(e, entry, invoker, startFromEventId);
862}
863
864void SmartAI::OnGameEvent(bool start, uint16 eventId)
865{
867}
868
869void SmartAI::OnSpellClick(Unit* clicker, bool spellClickHandled)
870{
871 if (!spellClickHandled)
872 return;
873
875}
876
878{
880 return;
881
882 if (_vehicleConditionsTimer <= diff)
883 {
884 if (Vehicle* vehicleKit = me->GetVehicleKit())
885 {
886 for (std::pair<int8 const, VehicleSeat>& seat : vehicleKit->Seats)
887 if (Unit* passenger = ObjectAccessor::GetUnit(*me, seat.second.Passenger.Guid))
888 {
889 if (Player* player = passenger->ToPlayer())
890 {
891 if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry(), player, me))
892 {
893 player->ExitVehicle();
894 return; // check other pessanger in next tick
895 }
896 }
897 }
898 }
899
901 }
902 else
904}
905
907{
909 return;
910
911 if (_escortInvokerCheckTimer < diff)
912 {
914 {
915 StopPath(0, _escortQuestId, true);
916
917 // allow to properly hook out of range despawn action, which in most cases should perform the same operation as dying
920 return;
921 }
923 }
924 else
926
927 // handle pause
929 {
930 // Resume only if there was a pause timer set
932 {
933 if (_waypointPauseTimer <= diff)
934 ResumePath();
935 else
936 _waypointPauseTimer -= diff;
937 }
938 }
939 else if (_waypointPathEnded) // end path
940 {
941 _waypointPathEnded = false;
942 StopPath();
943 return;
944 }
945
947 {
948 if (_OOCReached) // reached OOC WP
949 {
950 _OOCReached = false;
953 ResumePath();
954 }
955 }
956}
957
959{
960 if (!_followGUID.IsEmpty())
961 {
962 if (_followArrivedTimer < diff)
963 {
965 {
966 StopFollow(true);
967 return;
968 }
969
970 _followArrivedTimer = 1000;
971 }
972 else
973 _followArrivedTimer -= diff;
974 }
975}
976
978{
979 if (_despawnState <= 1 || _despawnState > 3)
980 return;
981
982 if (_despawnTime < diff)
983 {
984 if (_despawnState == 2)
985 {
986 me->SetVisible(false);
987 _despawnTime = 5000;
989 }
990 else
992 }
993 else
994 _despawnTime -= diff;
995}
996
998{
999 GetScript()->OnUpdate(diff);
1000}
1001
1003{
1005 // do not call respawn event if go is not spawned
1006 if (me->isSpawned())
1008 //Reset();
1009}
1010
1012{
1013 GetScript()->OnReset();
1014}
1015
1016// Called when a player opens a gossip dialog with the gameobject.
1018{
1019 _gossipReturn = false;
1020 GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_HELLO, player, 0, 0, false, nullptr, me);
1021 return _gossipReturn;
1022}
1023
1024// Called when a player selects a gossip item in the gameobject's gossip menu.
1026{
1027 _gossipReturn = false;
1028 GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_SELECT, player, sender, action, false, nullptr, me);
1029 return _gossipReturn;
1030}
1031
1032// Called when a player selects a gossip with a code in the gameobject's gossip menu.
1033bool SmartGameObjectAI::OnGossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/)
1034{
1035 return false;
1036}
1037
1038// Called when a player accepts a quest from the gameobject.
1040{
1041 GetScript()->ProcessEventsFor(SMART_EVENT_ACCEPTED_QUEST, player, quest->GetQuestId(), 0, false, nullptr, me);
1042}
1043
1044// Called when a player selects a quest reward.
1045void SmartGameObjectAI::OnQuestReward(Player* player, Quest const* quest, LootItemType /*type*/, uint32 opt)
1046{
1047 GetScript()->ProcessEventsFor(SMART_EVENT_REWARD_QUEST, player, quest->GetQuestId(), opt, false, nullptr, me);
1048}
1049
1051{
1052 _gossipReturn = false;
1053 GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_HELLO, player, 1, 0, false, nullptr, me);
1054 return _gossipReturn;
1055}
1056
1057// Called when the gameobject is destroyed (destructible buildings only).
1059{
1060 GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, attacker ? attacker->ToUnit() : nullptr, eventId, 0, false, nullptr, me);
1061}
1062
1064{
1065 GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value);
1066}
1067
1069{
1070 GetScript()->SetTimedActionList(e, entry, invoker);
1071}
1072
1074{
1076}
1077
1079{
1081}
1082
1084{
1086}
1087
1089{
1090 GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT, caster->ToUnit(), 0, 0, false, spellInfo);
1091}
1092
1094{
1096}
1097
1099{
1101}
1102
1104{
1106}
1107
1109{
1110 public:
1111
1112 SmartTrigger() : AreaTriggerScript("SmartTrigger") { }
1113
1114 bool OnTrigger(Player* player, AreaTriggerEntry const* trigger) override
1115 {
1116 if (!player->IsAlive())
1117 return false;
1118
1119 TC_LOG_DEBUG("scripts.ai", "AreaTrigger {} is using SmartTrigger script", trigger->ID);
1120 SmartScript script;
1121 script.OnInitialize(player, trigger);
1122 script.ProcessEventsFor(SMART_EVENT_AREATRIGGER_ONTRIGGER, player, trigger->ID);
1123 return true;
1124 }
1125};
1126
1128{
1130}
1131
1133{
1134 GetScript()->OnUpdate(diff);
1135}
1136
1138{
1140}
1141
1143{
1144 GetScript()->SetTimedActionList(e, entry, invoker);
1145}
1146
1148{
1149public:
1151 {
1152 }
1153
1154 AreaTriggerAI* GetAI(AreaTrigger* areaTrigger) const override
1155 {
1156 return new SmartAreaTriggerAI(areaTrigger);
1157 }
1158};
1159
1161{
1162public:
1163 SmartScene() : SceneScript("SmartScene") { }
1164
1165 void OnSceneStart(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
1166 {
1167 SmartScript smartScript;
1168 smartScript.OnInitialize(player, nullptr, sceneTemplate);
1169 smartScript.ProcessEventsFor(SMART_EVENT_SCENE_START, player);
1170 }
1171
1172 void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate, std::string const& triggerName) override
1173 {
1174 SmartScript smartScript;
1175 smartScript.OnInitialize(player, nullptr, sceneTemplate);
1176 smartScript.ProcessEventsFor(SMART_EVENT_SCENE_TRIGGER, player, 0, 0, false, nullptr, nullptr, triggerName);
1177 }
1178
1179 void OnSceneCancel(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
1180 {
1181 SmartScript smartScript;
1182 smartScript.OnInitialize(player, nullptr, sceneTemplate);
1183 smartScript.ProcessEventsFor(SMART_EVENT_SCENE_CANCEL, player);
1184 }
1185
1186 void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* sceneTemplate) override
1187 {
1188 SmartScript smartScript;
1189 smartScript.OnInitialize(player, nullptr, sceneTemplate);
1190 smartScript.ProcessEventsFor(SMART_EVENT_SCENE_COMPLETE, player);
1191 }
1192};
1193
1195{
1196public:
1197 SmartQuest() : QuestScript("SmartQuest") { }
1198
1199 // Called when a quest status change
1200 void OnQuestStatusChange(Player* player, Quest const* quest, QuestStatus /*oldStatus*/, QuestStatus newStatus) override
1201 {
1202 SmartScript smartScript;
1203 smartScript.OnInitialize(player, nullptr, nullptr, quest);
1204 switch (newStatus)
1205 {
1207 smartScript.ProcessEventsFor(SMART_EVENT_QUEST_ACCEPTED, player);
1208 break;
1211 break;
1213 smartScript.ProcessEventsFor(SMART_EVENT_QUEST_FAIL, player);
1214 break;
1216 smartScript.ProcessEventsFor(SMART_EVENT_QUEST_REWARDED, player);
1217 break;
1218 case QUEST_STATUS_NONE:
1219 default:
1220 break;
1221 }
1222 }
1223
1224 // Called when a quest objective data change
1225 void OnQuestObjectiveChange(Player* player, Quest const* quest, QuestObjective const& objective, int32 /*oldAmount*/, int32 /*newAmount*/) override
1226 {
1227 uint16 slot = player->FindQuestSlot(quest->GetQuestId());
1228 if (slot < MAX_QUEST_LOG_SIZE && player->IsQuestObjectiveComplete(slot, quest, objective))
1229 {
1230 SmartScript smartScript;
1231 smartScript.OnInitialize(player, nullptr, nullptr, quest);
1232 smartScript.ProcessEventsFor(SMART_EVENT_QUEST_OBJ_COMPLETION, player, objective.ID);
1233 }
1234 }
1235};
1236
1238{
1239public:
1240 SmartEventTrigger() : EventScript("SmartEventTrigger") { }
1241
1242 void OnTrigger(WorldObject* object, WorldObject* invoker, uint32 eventId) override
1243 {
1244 TC_LOG_DEBUG("scripts.ai", "Event {} is using SmartEventTrigger script", eventId);
1245 SmartScript script;
1246 // Set invoker as BaseObject if there isn't target for GameEvents::Trigger
1247 script.OnInitialize(Coalesce<WorldObject>(object, invoker), nullptr, nullptr, nullptr, eventId);
1248 script.ProcessEventsFor(SMART_EVENT_SEND_EVENT_TRIGGER, invoker->ToUnit(), 0, 0, false, nullptr, invoker->ToGameObject());
1249 }
1250};
1251
1253{
1254 new SmartTrigger();
1256 new SmartScene();
1257 new SmartQuest();
1258 new SmartEventTrigger();
1259}
#define sConditionMgr
Definition: ConditionMgr.h:365
@ CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE
Definition: ConditionMgr.h:170
int8_t int8
Definition: Define.h:140
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
LootItemType
Definition: LootItemType.h:24
@ MOTION_PRIORITY_NORMAL
@ MOTION_SLOT_DEFAULT
@ WAYPOINT_MOTION_TYPE
@ POINT_MOTION_TYPE
#define INTERACTION_DISTANCE
Definition: ObjectDefines.h:24
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
#define PET_FOLLOW_ANGLE
Definition: PetDefines.h:98
#define PET_FOLLOW_DIST
Definition: PetDefines.h:97
QuestStatus
Definition: QuestDef.h:141
@ QUEST_STATUS_REWARDED
Definition: QuestDef.h:148
@ QUEST_STATUS_FAILED
Definition: QuestDef.h:147
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:145
@ QUEST_STATUS_NONE
Definition: QuestDef.h:142
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:143
@ CREATURE_TYPE_FLAG_CAN_ASSIST
void AddSC_SmartScripts()
Registers scripts required by the SAI scripting system.
Definition: SmartAI.cpp:1252
static float constexpr SMART_MAX_AID_DIST
Definition: SmartAI.h:37
@ SMART_ESCORT_ESCORTING
Definition: SmartAI.h:31
@ SMART_ESCORT_PAUSED
Definition: SmartAI.h:33
@ SMART_ESCORT_RETURNING
Definition: SmartAI.h:32
@ SMART_ESCORT_NONE
Definition: SmartAI.h:30
static float constexpr SMART_ESCORT_MAX_PLAYER_DIST
Definition: SmartAI.h:36
@ 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_DATA_SET
@ SMART_EVENT_RECEIVE_HEAL
@ SMART_EVENT_SCENE_COMPLETE
@ SMART_EVENT_QUEST_COMPLETION
@ SMART_EVENT_AREATRIGGER_ONTRIGGER
@ SMART_EVENT_ON_SPELLCLICK
@ SMART_EVENT_MOVEMENTINFORM
@ SMART_EVENT_PASSENGER_REMOVED
@ SMART_EVENT_WAYPOINT_PAUSED
@ SMART_EVENT_REACHED_HOME
@ SMART_EVENT_REWARD_QUEST
@ SMART_EVENT_GO_EVENT_INFORM
@ 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_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
Definition: UnitAICommon.h:30
@ REACT_PASSIVE
Definition: UnitDefines.h:506
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:295
@ UNIT_NPC_FLAG_NONE
Definition: UnitDefines.h:296
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_STATE_EVADE
Definition: Unit.h:277
#define sWaypointMgr
AreaTrigger *const at
Definition: AreaTriggerAI.h:33
virtual void MoveInLineOfSight(Unit *)
Definition: CreatureAI.cpp:122
bool IsEngaged() const
Definition: CreatureAI.h:77
bool _EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:299
virtual void JustAppeared()
Definition: CreatureAI.cpp:194
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void EngagementOver()
Definition: CreatureAI.cpp:287
Creature * GetLeader() const
bool IsFormed() const
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:371
void StartDefaultCombatMovement(Unit *victim, Optional< float > range={}, Optional< float > angle={})
Definition: Creature.cpp:2855
CreatureDifficulty const * GetCreatureDifficulty() const
Definition: Creature.h:252
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition: Creature.h:373
bool HasReactState(ReactStates state) const
Definition: Creature.h:162
bool IsEngaged() const override
Definition: Creature.cpp:3601
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
uint32 GetWaypointPathId() const
Definition: Creature.h:381
std::pair< uint32, uint32 > GetCurrentWaypointInfo() const
Definition: Creature.h:385
CreatureGroup * GetFormation()
Definition: Creature.h:391
bool IsInEvadeMode() const
Definition: Creature.h:203
GameObject *const me
Definition: GameObjectAI.h:50
bool isSpawned() const
Definition: GameObject.h:256
GroupReference * next()
Definition: Group.h:197
bool HasMovementGenerator(std::function< bool(MovementGenerator const *)> const &filter, MovementSlot slot=MOTION_SLOT_ACTIVE) const
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={}, bool generatePath=true)
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void MoveFollow(Unit *target, float dist, ChaseAngle angle, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_ACTIVE)
void MoveTargetedHome()
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:274
bool IsEmpty() const
Definition: ObjectGuid.h:319
std::string ToString() const
Definition: ObjectGuid.cpp:554
void Clear()
Definition: ObjectGuid.h:286
static Creature * ToCreature(Object *o)
Definition: Object.h:219
static Unit * ToUnit(Object *o)
Definition: Object.h:225
static GameObject * ToGameObject(Object *o)
Definition: Object.h:231
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
uint16 FindQuestSlot(uint32 quest_id) const
Definition: Player.cpp:16432
bool HasCorpse() const
Definition: Player.h:2163
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
Definition: Player.cpp:16598
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition: Player.cpp:25673
void AreaExploredOrEventHappens(uint32 questId)
Definition: Player.cpp:16577
void FailQuest(uint32 quest_id)
Definition: Player.cpp:15446
Group * GetGroup(Optional< uint8 > partyIndex)
Definition: Player.h:2606
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:25645
uint32 GetQuestId() const
Definition: QuestDef.h:587
uint32 _escortQuestId
Definition: SmartAI.h:279
void OnGameEvent(bool start, uint16 eventId) override
Definition: SmartAI.cpp:864
void AddEscortState(uint32 escortState)
Definition: SmartAI.h:63
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
Definition: SmartAI.cpp:599
void StartPath(uint32 pathId=0, bool repeat=false, Unit *invoker=nullptr, uint32 nodeId=0)
Definition: SmartAI.cpp:48
void OnSpellStart(SpellInfo const *spellInfo) override
Definition: SmartAI.cpp:614
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
Definition: SmartAI.cpp:754
void AttackStart(Unit *who) override
== Triggered Actions Requested ==================
Definition: SmartAI.cpp:571
bool _charmed
Definition: SmartAI.h:244
void IsSummonedBy(WorldObject *summoner) override
Definition: SmartAI.cpp:640
void WaypointPathEnded(uint32 nodeId, uint32 pathId) override
Definition: SmartAI.cpp:365
bool CanResumePath()
Definition: SmartAI.cpp:128
bool HasEscortState(uint32 escortState) const
Definition: SmartAI.h:59
uint32 _followArrivedEntry
Definition: SmartAI.h:248
float _followDistance
Definition: SmartAI.h:250
void PausePath(uint32 delay, bool forced=false)
Definition: SmartAI.cpp:93
void PassengerBoarded(Unit *who, int8 seatId, bool apply) override
== Fields =======================================
Definition: SmartAI.cpp:665
void SetGUID(ObjectGuid const &guid, int32 id=0) override
Definition: SmartAI.cpp:724
void EnterEvadeMode(EvadeReason why) override
Definition: SmartAI.cpp:388
void OnQuestReward(Player *player, Quest const *quest, LootItemType type, uint32 opt) override
Definition: SmartAI.cpp:771
bool OnGossipHello(Player *player) override
Definition: SmartAI.cpp:747
void DamageDealt(Unit *doneTo, uint32 &damage, DamageEffectType) override
Definition: SmartAI.cpp:645
void OnSpellClick(Unit *clicker, bool spellClickHandled) override
Definition: SmartAI.cpp:869
void OnCharmed(bool isNew) override
Definition: SmartAI.cpp:670
bool _run
Definition: SmartAI.h:264
uint32 _vehicleConditionsTimer
Definition: SmartAI.h:274
bool AssistPlayerInCombatAgainst(Unit *who)
Definition: SmartAI.cpp:450
uint32 _escortInvokerCheckTimer
Definition: SmartAI.h:255
void OnSpellCast(SpellInfo const *spellInfo) override
Definition: SmartAI.cpp:604
bool _waypointPathEnded
Definition: SmartAI.h:262
uint32 _currentWaypointNodeId
Definition: SmartAI.h:256
void StopPath(uint32 DespawnTime=0, uint32 quest=0, bool fail=false)
Definition: SmartAI.cpp:139
void SetDespawnTime(uint32 t)
Definition: SmartAI.h:208
void StartDespawn()
Definition: SmartAI.h:213
void OnQuestAccept(Player *player, Quest const *quest) override
Definition: SmartAI.cpp:766
void JustReachedHome() override
Definition: SmartAI.cpp:520
bool _canCombatMove
Definition: SmartAI.h:266
void EndPath(bool fail=false)
Definition: SmartAI.cpp:178
bool _vehicleConditions
Definition: SmartAI.h:273
bool _waypointReached
Definition: SmartAI.h:257
void SetFollow(Unit *target, float dist=0.0f, float angle=0.0f, uint32 credit=0, uint32 end=0, uint32 creditType=0)
Definition: SmartAI.cpp:811
uint32 _despawnTime
Definition: SmartAI.h:269
void DamageTaken(Unit *doneBy, uint32 &damage, DamageEffectType, SpellInfo const *) override
Definition: SmartAI.cpp:619
uint32 _despawnState
Definition: SmartAI.h:270
void JustEngagedWith(Unit *enemy) override
Definition: SmartAI.cpp:540
void UpdateAI(uint32 diff) override
Definition: SmartAI.cpp:275
void OnDespawn() override
Definition: SmartAI.cpp:660
bool OnGossipSelectCode(Player *player, uint32 menuId, uint32 gossipListId, char const *code) override
Definition: SmartAI.cpp:761
void UpdateDespawn(uint32 diff)
Definition: SmartAI.cpp:977
void SetCombatMove(bool on, bool stopMoving=false)
Definition: SmartAI.cpp:776
bool _gossipReturn
Definition: SmartAI.h:277
float _followAngle
Definition: SmartAI.h:251
void StopFollow(bool complete)
Definition: SmartAI.cpp:830
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker, uint32 startFromEventId=0)
Definition: SmartAI.cpp:859
void JustDied(Unit *killer) override
Definition: SmartAI.cpp:548
void RemoveEscortState(uint32 escortState)
Definition: SmartAI.h:67
WaypointPath const * LoadPath(uint32 entry)
Definition: SmartAI.cpp:77
void InitializeAI() override
Definition: SmartAI.cpp:493
ObjectGuid GetGUID(int32 id=0) const override
Definition: SmartAI.cpp:726
uint32 _escortNPCFlags
Definition: SmartAI.h:254
bool _waypointPauseForced
Definition: SmartAI.h:259
uint32 _followArrivedTimer
Definition: SmartAI.h:246
uint32 GetData(uint32 id=0) const override
Definition: SmartAI.cpp:714
void WaypointReached(uint32 nodeId, uint32 pathId) override
Definition: SmartAI.cpp:336
bool IsAIControlled() const
Definition: SmartAI.cpp:43
ObjectGuid _followGUID
Definition: SmartAI.h:249
void OnSpellFailed(SpellInfo const *spellInfo) override
Definition: SmartAI.cpp:609
void SummonedCreatureDespawn(Creature *unit) override
Definition: SmartAI.cpp:650
void SetDisableGravity(bool disable=true)
Definition: SmartAI.cpp:737
void JustAppeared() override
Definition: SmartAI.cpp:509
void HealReceived(Unit *doneBy, uint32 &addhealth) override
Definition: SmartAI.cpp:630
bool _evadeDisabled
Definition: SmartAI.h:265
void ReturnToLastOOCPos()
Definition: SmartAI.cpp:266
uint32 _waypointPauseTimer
Definition: SmartAI.h:258
void CorpseRemoved(uint32 &respawnDelay) override
== State checks =================================
Definition: SmartAI.cpp:655
bool _OOCReached
Definition: SmartAI.h:261
void SummonedCreatureDies(Creature *summon, Unit *killer) override
Definition: SmartAI.cpp:566
uint32 _followCredit
Definition: SmartAI.h:247
void JustSummoned(Creature *creature) override
Definition: SmartAI.cpp:561
SmartAI(Creature *creature, uint32 scriptId={})
Definition: SmartAI.cpp:35
uint32 _followCreditType
Definition: SmartAI.h:245
void SetEvadeDisabled(bool disable=true)
Definition: SmartAI.cpp:742
void CheckConditions(uint32 diff)
Definition: SmartAI.cpp:877
void DoAction(int32 param=0) override
Definition: SmartAI.cpp:709
SmartScript * GetScript()
Definition: SmartAI.h:84
void SetData(uint32 id, uint32 value) override
Definition: SmartAI.h:180
void SetRun(bool run=true)
Definition: SmartAI.cpp:731
void MoveInLineOfSight(Unit *who) override
Definition: SmartAI.cpp:434
void ReceiveEmote(Player *player, uint32 textEmote) override
Definition: SmartAI.cpp:635
void UpdatePath(uint32 diff)
Definition: SmartAI.cpp:906
uint32 _escortState
Definition: SmartAI.h:253
void KilledUnit(Unit *victim) override
Definition: SmartAI.cpp:556
void MovementInform(uint32 MovementType, uint32 Data) override
Definition: SmartAI.cpp:374
void ResumePath()
Definition: SmartAI.cpp:252
uint32 _invincibilityHPLevel
Definition: SmartAI.h:267
void UpdateFollow(uint32 diff)
Definition: SmartAI.cpp:958
bool _repeatWaypointPath
Definition: SmartAI.h:260
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
Definition: SmartAI.cpp:594
bool IsEscortInvokerInRange()
Definition: SmartAI.cpp:295
void OnUnitEnter(Unit *unit) override
Definition: SmartAI.cpp:1137
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker)
Definition: SmartAI.cpp:1142
SmartScript * GetScript()
Definition: SmartAI.h:344
void OnUpdate(uint32 diff) override
Definition: SmartAI.cpp:1132
void OnInitialize() override
Definition: SmartAI.cpp:1127
AreaTriggerAI * GetAI(AreaTrigger *areaTrigger) const override
Definition: SmartAI.cpp:1154
void OnTrigger(WorldObject *object, WorldObject *invoker, uint32 eventId) override
Definition: SmartAI.cpp:1242
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
Definition: SmartAI.cpp:1025
void InitializeAI() override
Definition: SmartAI.cpp:1002
void OnGameEvent(bool start, uint16 eventId) override
Definition: SmartAI.cpp:1073
void UpdateAI(uint32 diff) override
Definition: SmartAI.cpp:997
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker)
Definition: SmartAI.cpp:1068
void EventInform(uint32 eventId) override
Definition: SmartAI.cpp:1083
bool OnGossipHello(Player *player) override
Definition: SmartAI.cpp:1017
SmartScript * GetScript()
Definition: SmartAI.h:291
void OnQuestReward(Player *player, Quest const *quest, LootItemType type, uint32 opt) override
Definition: SmartAI.cpp:1045
void OnLootStateChanged(uint32 state, Unit *unit) override
Definition: SmartAI.cpp:1078
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
Definition: SmartAI.cpp:1088
bool OnReportUse(Player *player) override
Definition: SmartAI.cpp:1050
void Destroyed(WorldObject *attacker, uint32 eventId) override
Definition: SmartAI.cpp:1058
void OnQuestAccept(Player *player, Quest const *quest) override
Definition: SmartAI.cpp:1039
void SetData(uint32 id, uint32 value, Unit *invoker)
Definition: SmartAI.cpp:1063
void SummonedCreatureDespawn(Creature *unit) override
Definition: SmartAI.cpp:1103
bool OnGossipSelectCode(Player *player, uint32 menuId, uint32 gossipListId, char const *code) override
Definition: SmartAI.cpp:1033
void SummonedCreatureDies(Creature *summon, Unit *killer) override
Definition: SmartAI.cpp:1098
void Reset() override
Definition: SmartAI.cpp:1011
bool _gossipReturn
Definition: SmartAI.h:332
void JustSummoned(Creature *creature) override
Definition: SmartAI.cpp:1093
void OnQuestStatusChange(Player *player, Quest const *quest, QuestStatus, QuestStatus newStatus) override
Definition: SmartAI.cpp:1200
void OnQuestObjectiveChange(Player *player, Quest const *quest, QuestObjective const &objective, int32, int32) override
Definition: SmartAI.cpp:1225
void OnSceneStart(Player *player, uint32, SceneTemplate const *sceneTemplate) override
Definition: SmartAI.cpp:1165
void OnSceneCancel(Player *player, uint32, SceneTemplate const *sceneTemplate) override
Definition: SmartAI.cpp:1179
void OnSceneTriggerEvent(Player *player, uint32, SceneTemplate const *sceneTemplate, std::string const &triggerName) override
Definition: SmartAI.cpp:1172
void OnSceneComplete(Player *player, uint32, SceneTemplate const *sceneTemplate) override
Definition: SmartAI.cpp:1186
void OnUpdate(const uint32 diff)
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 const &varString="")
void OnInitialize(WorldObject *obj, AreaTriggerEntry const *at=nullptr, SceneTemplate const *scene=nullptr, Quest const *qst=nullptr, uint32 evnt=0)
static bool IsPlayer(WorldObject *obj)
void OnMoveInLineOfSight(Unit *who)
uint32 GetPathId() const
Definition: SmartScript.h:57
void OnReset()
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:56
bool OnTrigger(Player *player, AreaTriggerEntry const *trigger) override
Definition: SmartAI.cpp:1114
virtual bool CanAIAttack(Unit const *) const
Definition: UnitAI.h:57
virtual void OnCharmed(bool isNew)
Definition: UnitAI.cpp:49
Definition: Unit.h:627
void ClearUnitState(uint32 f)
Definition: Unit.h:733
bool IsVehicle() const
Definition: Unit.h:743
bool IsCharmed() const
Definition: Unit.h:1215
void SetVisible(bool x)
Definition: Unit.cpp:8351
NPCFlags GetNpcFlags() const
Definition: Unit.h:980
Unit * GetCharmer() const
Definition: Unit.h:1188
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3089
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void ResumeMovement(uint32 timer=0, uint8 slot=0)
Definition: Unit.cpp:10076
void PauseMovement(uint32 timer=0, uint8 slot=0, bool forced=true)
Definition: Unit.cpp:10064
bool IsAlive() const
Definition: Unit.h:1164
void StopMoving()
Definition: Unit.cpp:10049
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition: Unit.cpp:12725
void AddUnitState(uint32 f)
Definition: Unit.h:731
bool isInAccessiblePlaceFor(Creature const *c) const
Definition: Unit.cpp:3165
Unit * EnsureVictim() const
Definition: Unit.h:717
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1200
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:5670
bool isPossessed() const
Definition: Unit.h:1216
uint64 GetHealth() const
Definition: Unit.h:776
bool SetWalk(bool enable)
Definition: Unit.cpp:12707
void EngageWithTarget(Unit *who)
Definition: Unit.cpp:8077
virtual float GetFollowAngle() const
Definition: Unit.h:1744
Unit * GetVictim() const
Definition: Unit.h:715
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
ObjectGuid LastCharmerGUID
Definition: Unit.h:1708
Vehicle * GetVehicleKit() const
Definition: Unit.h:1711
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:984
bool AttackStop()
Definition: Unit.cpp:5781
bool IsInCombat() const
Definition: Unit.h:1043
bool isDead() const
Definition: Unit.h:1166
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition: Object.cpp:1181
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Object.cpp:2252
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1147
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition: Object.cpp:3144
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1078
bool IsInMap(WorldObject const *obj) const
Definition: Object.cpp:1115
void apply(T *val)
Definition: ByteConverter.h:41
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:81
std::vector< WaypointNode > Nodes