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)
83 if (!path || path->
Nodes.empty())
143 std::pair<uint32, uint32> waypointInfo = { 0, 0 };
152 if (waypointInfo.second)
157 if (waypointInfo.second)
204 for (
GroupReference* groupRef = group->GetFirstMember(); groupRef !=
nullptr; groupRef = groupRef->
next())
206 Player* groupGuy = groupRef->GetSource();
207 if (!groupGuy->
IsInMap(player))
245 else if (pathid ==
GetScript()->GetPathId())
302 Player* player = (*targets->begin())->ToPlayer();
308 for (
GroupReference* groupRef = group->GetFirstMember(); groupRef !=
nullptr; groupRef = groupRef->
next())
310 Player* groupGuy = groupRef->GetSource();
792 return movement->GetMovementGeneratorType() == CHASE_MOTION_TYPE && movement->Mode == MOTION_MODE_DEFAULT && movement->Priority == MOTION_PRIORITY_NORMAL;
801 return a->GetMovementGeneratorType() == CHASE_MOTION_TYPE && a->Mode == MOTION_MODE_DEFAULT && a->Priority == MOTION_PRIORITY_NORMAL;
871 if (!spellClickHandled)
886 for (std::pair<int8 const, VehicleSeat>& seat : vehicleKit->Seats)
893 player->ExitVehicle();
979 if (_despawnState <= 1 || _despawnState > 3)
1119 TC_LOG_DEBUG(
"scripts.ai",
"AreaTrigger {} is using SmartTrigger script", trigger->
ID);
1168 smartScript.
OnInitialize(player,
nullptr, sceneTemplate);
1175 smartScript.
OnInitialize(player,
nullptr, sceneTemplate);
1182 smartScript.
OnInitialize(player,
nullptr, sceneTemplate);
1189 smartScript.
OnInitialize(player,
nullptr, sceneTemplate);
1203 smartScript.
OnInitialize(player,
nullptr,
nullptr, quest);
1228 if (slot < MAX_QUEST_LOG_SIZE && player->IsQuestObjectiveComplete(slot, quest, objective))
1231 smartScript.
OnInitialize(player,
nullptr,
nullptr, quest);
1244 TC_LOG_DEBUG(
"scripts.ai",
"Event {} is using SmartEventTrigger script", eventId);
1247 script.
OnInitialize(Coalesce<WorldObject>(
object, invoker),
nullptr,
nullptr,
nullptr, eventId);
@ CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
#define INTERACTION_DISTANCE
@ QUEST_STATUS_INCOMPLETE
@ CREATURE_TYPE_FLAG_CAN_ASSIST
void AddSC_SmartScripts()
Registers scripts required by the SAI scripting system.
static float constexpr SMART_MAX_AID_DIST
static float constexpr SMART_ESCORT_MAX_PLAYER_DIST
@ SMART_EVENT_FLAG_WHILE_CHARMED
std::vector< WorldObject * > ObjectVector
@ SMART_EVENT_ACTION_DONE
@ SMART_EVENT_SUMMON_DESPAWNED
@ SMART_EVENT_SCENE_START
@ SMART_EVENT_RECEIVE_EMOTE
@ 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_ON_SPELL_CAST
@ SMART_EVENT_SPELLHIT_TARGET
@ SMART_EVENT_GAME_EVENT_START
@ 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_QUEST_ACCEPTED
@ SMART_EVENT_QUEST_REWARDED
@ SMART_EVENT_GAME_EVENT_END
@ 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_DAMAGED_TARGET
@ SMART_EVENT_SUMMONED_UNIT
@ SMART_ESCORT_LAST_OOC_POINT
NPCFlags
Non Player Character flags.
virtual void MoveInLineOfSight(Unit *)
bool _EnterEvadeMode(EvadeReason why=EvadeReason::Other)
virtual void JustAppeared()
Creature * GetLeader() const
void SetHomePosition(float x, float y, float z, float o)
void StartDefaultCombatMovement(Unit *victim, Optional< float > range={}, Optional< float > angle={})
CreatureDifficulty const * GetCreatureDifficulty() const
void GetHomePosition(float &x, float &y, float &z, float &ori) const
bool HasReactState(ReactStates state) const
bool IsEngaged() const override
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
uint32 GetWaypointPathId() const
std::pair< uint32, uint32 > GetCurrentWaypointInfo() const
CreatureGroup * GetFormation()
bool IsInEvadeMode() const
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)
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
std::string ToString() const
static Creature * ToCreature(Object *o)
static Unit * ToUnit(Object *o)
static GameObject * ToGameObject(Object *o)
static ObjectGuid GetGUID(Object const *o)
static Player * ToPlayer(Object *o)
uint16 FindQuestSlot(uint32 quest_id) const
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
void AreaExploredOrEventHappens(uint32 questId)
void FailQuest(uint32 quest_id)
Group * GetGroup(Optional< uint8 > partyIndex)
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
uint32 GetQuestId() const
void OnGameEvent(bool start, uint16 eventId) override
void AddEscortState(uint32 escortState)
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void StartPath(uint32 pathId=0, bool repeat=false, Unit *invoker=nullptr, uint32 nodeId=0)
void OnSpellStart(SpellInfo const *spellInfo) override
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
void AttackStart(Unit *who) override
== Triggered Actions Requested ==================
void IsSummonedBy(WorldObject *summoner) override
void WaypointPathEnded(uint32 nodeId, uint32 pathId) override
bool HasEscortState(uint32 escortState) const
uint32 _followArrivedEntry
void PausePath(uint32 delay, bool forced=false)
void PassengerBoarded(Unit *who, int8 seatId, bool apply) override
== Fields =======================================
void SetGUID(ObjectGuid const &guid, int32 id=0) override
void EnterEvadeMode(EvadeReason why) override
void OnQuestReward(Player *player, Quest const *quest, LootItemType type, uint32 opt) override
bool OnGossipHello(Player *player) override
void DamageDealt(Unit *doneTo, uint32 &damage, DamageEffectType) override
void OnSpellClick(Unit *clicker, bool spellClickHandled) override
void OnCharmed(bool isNew) override
uint32 _vehicleConditionsTimer
bool AssistPlayerInCombatAgainst(Unit *who)
uint32 _escortInvokerCheckTimer
void OnSpellCast(SpellInfo const *spellInfo) override
uint32 _currentWaypointNodeId
void StopPath(uint32 DespawnTime=0, uint32 quest=0, bool fail=false)
void SetDespawnTime(uint32 t)
void OnQuestAccept(Player *player, Quest const *quest) override
void JustReachedHome() override
void EndPath(bool fail=false)
void SetFollow(Unit *target, float dist=0.0f, float angle=0.0f, uint32 credit=0, uint32 end=0, uint32 creditType=0)
void DamageTaken(Unit *doneBy, uint32 &damage, DamageEffectType, SpellInfo const *) override
void JustEngagedWith(Unit *enemy) override
void UpdateAI(uint32 diff) override
void OnDespawn() override
bool OnGossipSelectCode(Player *player, uint32 menuId, uint32 gossipListId, char const *code) override
void UpdateDespawn(uint32 diff)
void SetCombatMove(bool on, bool stopMoving=false)
void StopFollow(bool complete)
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker, uint32 startFromEventId=0)
void JustDied(Unit *killer) override
void RemoveEscortState(uint32 escortState)
WaypointPath const * LoadPath(uint32 entry)
void InitializeAI() override
ObjectGuid GetGUID(int32 id=0) const override
bool _waypointPauseForced
uint32 _followArrivedTimer
uint32 GetData(uint32 id=0) const override
void WaypointReached(uint32 nodeId, uint32 pathId) override
bool IsAIControlled() const
void OnSpellFailed(SpellInfo const *spellInfo) override
void SummonedCreatureDespawn(Creature *unit) override
void SetDisableGravity(bool disable=true)
void JustAppeared() override
void HealReceived(Unit *doneBy, uint32 &addhealth) override
void ReturnToLastOOCPos()
uint32 _waypointPauseTimer
void CorpseRemoved(uint32 &respawnDelay) override
== State checks =================================
void SummonedCreatureDies(Creature *summon, Unit *killer) override
void JustSummoned(Creature *creature) override
SmartAI(Creature *creature, uint32 scriptId={})
void SetEvadeDisabled(bool disable=true)
void CheckConditions(uint32 diff)
void DoAction(int32 param=0) override
SmartScript * GetScript()
void SetData(uint32 id, uint32 value) override
void SetRun(bool run=true)
void MoveInLineOfSight(Unit *who) override
void ReceiveEmote(Player *player, uint32 textEmote) override
void UpdatePath(uint32 diff)
void KilledUnit(Unit *victim) override
void MovementInform(uint32 MovementType, uint32 Data) override
uint32 _invincibilityHPLevel
void UpdateFollow(uint32 diff)
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
bool IsEscortInvokerInRange()
void OnUnitEnter(Unit *unit) override
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker)
SmartScript * GetScript()
void OnUpdate(uint32 diff) override
void OnInitialize() override
AreaTriggerAI * GetAI(AreaTrigger *areaTrigger) const override
SmartAreaTriggerEntityScript()
void OnTrigger(WorldObject *object, WorldObject *invoker, uint32 eventId) override
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
void InitializeAI() override
void OnGameEvent(bool start, uint16 eventId) override
void UpdateAI(uint32 diff) override
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker)
void EventInform(uint32 eventId) override
bool OnGossipHello(Player *player) override
SmartScript * GetScript()
void OnQuestReward(Player *player, Quest const *quest, LootItemType type, uint32 opt) override
void OnLootStateChanged(uint32 state, Unit *unit) override
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
bool OnReportUse(Player *player) override
void Destroyed(WorldObject *attacker, uint32 eventId) override
void OnQuestAccept(Player *player, Quest const *quest) override
void SetData(uint32 id, uint32 value, Unit *invoker)
void SummonedCreatureDespawn(Creature *unit) override
bool OnGossipSelectCode(Player *player, uint32 menuId, uint32 gossipListId, char const *code) override
void SummonedCreatureDies(Creature *summon, Unit *killer) override
void JustSummoned(Creature *creature) override
void OnQuestStatusChange(Player *player, Quest const *quest, QuestStatus, QuestStatus newStatus) override
void OnQuestObjectiveChange(Player *player, Quest const *quest, QuestObjective const &objective, int32, int32) override
void OnSceneStart(Player *player, uint32, SceneTemplate const *sceneTemplate) override
void OnSceneCancel(Player *player, uint32, SceneTemplate const *sceneTemplate) override
void OnSceneTriggerEvent(Player *player, uint32, SceneTemplate const *sceneTemplate, std::string const &triggerName) override
void OnSceneComplete(Player *player, uint32, SceneTemplate const *sceneTemplate) override
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)
ObjectVector const * GetStoredTargetVector(uint32 id, WorldObject const &ref) const
void SetTimedActionList(SmartScriptHolder &e, uint32 entry, Unit *invoker, uint32 startFromEventId=0)
void SetPathId(uint32 id)
bool OnTrigger(Player *player, AreaTriggerEntry const *trigger) override
virtual bool CanAIAttack(Unit const *) const
virtual void OnCharmed(bool isNew)
void ClearUnitState(uint32 f)
NPCFlags GetNpcFlags() const
Unit * GetCharmer() const
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
MotionMaster * GetMotionMaster()
void ResumeMovement(uint32 timer=0, uint8 slot=0)
void PauseMovement(uint32 timer=0, uint8 slot=0, bool forced=true)
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
void AddUnitState(uint32 f)
bool isInAccessiblePlaceFor(Creature const *c) const
Unit * EnsureVictim() const
Unit * GetCharmerOrOwner() const
bool Attack(Unit *victim, bool meleeAttack)
bool SetWalk(bool enable)
void EngageWithTarget(Unit *who)
virtual float GetFollowAngle() const
bool HasUnitState(const uint32 f) const
ObjectGuid LastCharmerGUID
Vehicle * GetVehicleKit() const
void ReplaceAllNpcFlags(NPCFlags flags)
InstanceScript * GetInstanceScript() const
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
float GetDistance(WorldObject const *obj) const
bool IsInMap(WorldObject const *obj) const
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
std::vector< WaypointNode > Nodes