/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#ifndef ACORE_SMARTAI_H
#define ACORE_SMARTAI_H
#include "Creature.h"
#include "CreatureAI.h"
#include "GameObjectAI.h"
#include "SmartScript.h"
#include "SmartScriptMgr.h"
#include "Spell.h"
#include "Unit.h"
enum SmartEscortState
{
SMART_ESCORT_NONE = 0x000, //nothing in progress
SMART_ESCORT_ESCORTING = 0x001, //escort is in progress
SMART_ESCORT_RETURNING = 0x002, //escort is returning after being in combat
SMART_ESCORT_PAUSED = 0x004 //will not proceed with waypoints before state is removed
};
enum SmartEscortVars
{
SMART_ESCORT_MAX_PLAYER_DIST = 60,
SMART_MAX_AID_DIST = SMART_ESCORT_MAX_PLAYER_DIST / 2,
};
#define DISTANCING_CONSTANT 1.f // buffer for better functionality of distancing
class SmartAI : public CreatureAI
{
public:
~SmartAI() override {};
explicit SmartAI(Creature* c);
// Check whether we are currently permitted to make the creature take action
bool IsAIControlled() const;
// Start moving to the desired MovePoint
void StartPath(ForcedMovement forcedMovement = FORCED_MOVEMENT_NONE, uint32 path = 0, bool repeat = false, Unit* invoker = nullptr, PathSource pathSource = PathSource::SMART_WAYPOINT_MGR);
bool LoadPath(uint32 entry, PathSource pathSource);
void PausePath(uint32 delay, bool forced = false);
void StopPath(uint32 DespawnTime = 0, uint32 quest = 0, bool fail = false);
void EndPath(bool fail = false);
void ResumePath();
WaypointData const* GetNextWayPoint();
void GenerateWayPointArray(Movement::PointsArray* points);
bool HasEscortState(uint32 uiEscortState) { return (mEscortState & uiEscortState); }
void AddEscortState(uint32 uiEscortState) { mEscortState |= uiEscortState; }
bool IsEscorted() override { return (mEscortState & SMART_ESCORT_ESCORTING); }
void RemoveEscortState(uint32 uiEscortState) { mEscortState &= ~uiEscortState; }
void SetAutoAttack(bool on) { mCanAutoAttack = on; }
void SetCombatMovement(bool on, bool stopOrStartMovement);
void SetCurrentRangeMode(bool on, float range = 0.f);
void DistanceYourself(float range);
void SetFollow(Unit* target, float dist = 0.0f, float angle = 0.0f, uint32 credit = 0, uint32 end = 0, uint32 creditType = 0, bool aliveState = true);
void StopFollow(bool complete);
void SetScript9(SmartScriptHolder& e, uint32 entry, WorldObject* invoker);
SmartScript* GetScript() { return &mScript; }
bool IsEscortInvokerInRange();
// Called when creature is spawned or respawned
void JustRespawned() override;
// Called at reaching home after evade, InitializeAI(), EnterEvadeMode() for resetting variables
void JustReachedHome() override;
// Called for reaction at enter to combat if not in combat yet (enemy can be nullptr)
void JustEngagedWith(Unit* enemy) override;
// Called for reaction at stopping attack at no attackers or targets
void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER) override;
// Called when the creature is killed
void JustDied(Unit* killer) override;
// Called when the creature kills a unit
void KilledUnit(Unit* victim) override;
// Called when the creature summon successfully other creature
void JustSummoned(Creature* creature) override;
// Called when a summoned unit dies
void SummonedCreatureDies(Creature* summon, Unit* killer) override;
// Called when a summoned unit evades
void SummonedCreatureEvade(Creature* summon) override;
// Tell creature to attack and follow the victim
void AttackStart(Unit* who) override;
// Called if IsVisible(Unit* who) is true at each *who move, reaction at visibility zone enter
void MoveInLineOfSight(Unit* who) override;
// Called when hit by a spell
void SpellHit(Unit* unit, SpellInfo const* spellInfo) override;
// Called when spell hits a target
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override;
// Called at any Damage from any attacker (before damage apply)
void DamageTaken(Unit* done_by, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override;
// Called when the creature receives heal
void HealReceived(Unit* doneBy, uint32& addhealth) override;
// Called at World update tick
void UpdateAI(uint32 diff) override;
// Called at text emote receive from player
void ReceiveEmote(Player* player, uint32 textEmote) override;
// Called at waypoint reached or point movement finished
void MovementInform(uint32 MovementType, uint32 Data) override;
// Called when creature is summoned by another unit
void IsSummonedBy(WorldObject* summoner) override;
// Called at any Damage to any victim (before damage apply)
void DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType damagetyp, SpellSchoolMask damageSchoolMask) override;
// Called when a summoned creature dissapears (UnSommoned)
void SummonedCreatureDespawn(Creature* unit) override;
// called when the corpse of this creature gets removed
void CorpseRemoved(uint32& respawnDelay) override;
// Called when a Player/Creature enters the creature (vehicle)
void PassengerBoarded(Unit* who, int8 seatId, bool apply) override;
// Called when gets initialized, when creature is added to world
void InitializeAI() override;
// Called when creature gets charmed by another unit
void OnCharmed(bool apply) override;
// Called when victim is in line of sight
bool CanAIAttack(Unit const* who) const override;
// Used in scripts to share variables
void DoAction(int32 param = 0) override;
// Used in scripts to share variables
uint32 GetData(uint32 id = 0) const override;
// Used in scripts to share variables
void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
void SetData(uint32 id, uint32 value, WorldObject* invoker);
// Used in scripts to share variables
void SetGUID(ObjectGuid const& guid, int32 id = 0) override;
// Used in scripts to share variables
ObjectGuid GetGUID(int32 id = 0) const override;
//core related
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
// Called at movepoint reached
void MovepointReached(uint32 id);
void SetFly(bool fly = true);
void SetSwim(bool swim = true);
void SetEvadeDisabled(bool disable = true);
void SetInvincibilityHpLevel(uint32 level) { mInvincibilityHpLevel = level; }
void sGossipHello(Player* player) override;
void sGossipSelect(Player* player, uint32 sender, uint32 action) override;
void sGossipSelectCode(Player* player, uint32 sender, uint32 action, const char* code) override;
void sQuestAccept(Player* player, Quest const* quest) override;
//void sQuestSelect(Player* player, Quest const* quest);
//void sQuestComplete(Player* player, Quest const* quest);
void sQuestReward(Player* player, Quest const* quest, uint32 opt) override;
void sOnGameEvent(bool start, uint16 eventId) override;
uint32 mEscortQuestID;
void SetDespawnTime (uint32 t)
{
mDespawnTime = t;
mDespawnState = t ? 1 : 0;
}
void StartDespawn() { mDespawnState = 2; }
void OnSpellClick(Unit* clicker, bool& result) override;
void PathEndReached(uint32 pathId) override;
bool CanRespawn() override { return mcanSpawn; };
void SetCanRespawn(bool canSpawn) { mcanSpawn = canSpawn; }
// Xinef
void SetWPPauseTimer(uint32 time) { mWPPauseTimer = time; }
void DistancingEnded() override;
private:
bool mIsCharmed;
uint32 mFollowCreditType;
uint32 mFollowArrivedTimer;
uint32 mFollowCredit;
uint32 mFollowArrivedEntry;
bool mFollowArrivedAlive;
ObjectGuid mFollowGuid;
float mFollowDist;
float mFollowAngle;
void ReturnToLastOOCPos();
void UpdatePath(const uint32 diff);
SmartScript mScript;
WaypointPath const* mWayPoints;
uint32 mEscortState;
uint32 mCurrentWPID;
bool mWPReached;
bool mOOCReached;
uint32 mWPPauseTimer;
WaypointData const* mLastWP;
uint32 mEscortNPCFlags;
uint32 GetWPCount() { return mWayPoints ? mWayPoints->size() : 0; }
bool mCanRepeatPath;
bool mEvadeDisabled;
bool mCanAutoAttack;
bool mForcedPaused;
uint32 mInvincibilityHpLevel;
ForcedMovement mForcedMovement;
bool AssistPlayerInCombatAgainst(Unit* who);
uint32 mDespawnTime;
uint32 mDespawnState;
void UpdateDespawn(const uint32 diff);
uint32 mEscortInvokerCheckTimer;
bool mJustReset;
bool mcanSpawn;
// Xinef: Vehicle conditions
void CheckConditions(const uint32 diff);
ConditionList conditions;
uint32 m_ConditionsTimer;
bool _chaseOnInterrupt;
std::unordered_map aiDataSet;
bool _currentRangeMode;
float _attackDistance;
float _pendingDistancing;
};
class SmartGameObjectAI : public GameObjectAI
{
public:
SmartGameObjectAI(GameObject* g) : GameObjectAI(g) {}
~SmartGameObjectAI() override {}
void UpdateAI(uint32 diff) override;
void InitializeAI() override;
void Reset() override;
SmartScript* GetScript() { return &mScript; }
static int32 Permissible(GameObject const* /*go*/) { return PERMIT_BASE_NO; }
bool GossipHello(Player* player, bool reportUse) override;
bool GossipSelect(Player* player, uint32 sender, uint32 action) override;
bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) override;
bool QuestAccept(Player* player, Quest const* quest) override;
bool QuestReward(Player* player, Quest const* quest, uint32 opt) override;
void Destroyed(Player* player, uint32 eventId) override;
void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
void SetData(uint32 id, uint32 value, WorldObject* invoker);
void SetScript9(SmartScriptHolder& e, uint32 entry, WorldObject* invoker);
void OnGameEvent(bool start, uint16 eventId) override;
void OnStateChanged(uint32 state, Unit* unit) override;
void EventInform(uint32 eventId) override;
void SpellHit(Unit* unit, SpellInfo const* spellInfo) override;
// Called when the gameobject summon successfully other creature
void JustSummoned(Creature* creature) override;
// Called when a summoned creature dissapears (UnSummoned)
void SummonedCreatureDespawn(Creature* unit) override;
// Called when a summoned unit dies
void SummonedCreatureDies(Creature* summon, Unit* killer) override;
// Called when a summoned unit evades
void SummonedCreatureEvade(Creature* summon) override;
protected:
SmartScript mScript;
};
/// Registers scripts required by the SAI scripting system
void AddSC_SmartScripts();
#endif