aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.cpp29
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.h6
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.cpp8
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h2
-rw-r--r--src/server/game/AI/CoreAI/GuardAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.cpp17
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.h6
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp57
-rw-r--r--src/server/game/AI/CoreAI/PetAI.h14
-rw-r--r--src/server/game/AI/CoreAI/ReactorAI.h1
-rw-r--r--src/server/game/AI/CoreAI/TotemAI.cpp17
-rw-r--r--src/server/game/AI/CoreAI/TotemAI.h3
-rw-r--r--src/server/game/AI/CreatureAI.cpp62
-rw-r--r--src/server/game/AI/CreatureAI.h22
-rw-r--r--src/server/game/AI/CreatureAIImpl.h31
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.cpp8
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp72
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h42
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp31
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.h5
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp80
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h43
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedGossip.h4
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp6
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h27
-rw-r--r--src/server/worldserver/worldserver.conf.dist3
26 files changed, 296 insertions, 302 deletions
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp
index 98da20b3420..e5bbab8139d 100644
--- a/src/server/game/AI/CoreAI/CombatAI.cpp
+++ b/src/server/game/AI/CoreAI/CombatAI.cpp
@@ -123,11 +123,13 @@ void CasterAI::InitializeAI()
CombatAI::InitializeAI();
_attackDistance = 30.0f;
+
for (SpellVector::iterator itr = Spells.begin(); itr != Spells.end(); ++itr)
if (AISpellInfoType const* info = GetAISpellInfo(*itr, me->GetMap()->GetDifficultyID()))
if (info->condition == AICOND_COMBAT && _attackDistance > info->maxRange)
_attackDistance = info->maxRange;
+
if (_attackDistance == 30.0f)
_attackDistance = MELEE_RANGE;
}
@@ -188,18 +190,18 @@ void CasterAI::UpdateAI(uint32 diff)
// ArcherAI
//////////////
-ArcherAI::ArcherAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
+ArcherAI::ArcherAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId)
{
- if (!me->m_spells[0])
- TC_LOG_ERROR("misc", "ArcherAI set for creature (entry = %u) with spell1=0. AI will do nothing", me->GetEntry());
+ if (!creature->m_spells[0])
+ TC_LOG_ERROR("scripts.ai", "ArcherAI set for creature with spell1 = 0. AI will do nothing (%s)", creature->GetGUID().ToString().c_str());
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(me->m_spells[0], me->GetMap()->GetDifficultyID());
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(creature->m_spells[0], creature->GetMap()->GetDifficultyID());
_minimumRange = spellInfo ? spellInfo->GetMinRange(false) : 0;
if (!_minimumRange)
_minimumRange = MELEE_RANGE;
- me->m_CombatDistance = spellInfo ? spellInfo->GetMaxRange(false) : 0;
- me->m_SightDistance = me->m_CombatDistance;
+ creature->m_CombatDistance = spellInfo ? spellInfo->GetMaxRange(false) : 0;
+ creature->m_SightDistance = creature->m_CombatDistance;
}
void ArcherAI::AttackStart(Unit* who)
@@ -237,22 +239,21 @@ void ArcherAI::UpdateAI(uint32 /*diff*/)
// TurretAI
//////////////
-TurretAI::TurretAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
+TurretAI::TurretAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId)
{
- if (!me->m_spells[0])
- TC_LOG_ERROR("misc", "TurretAI set for creature (entry = %u) with spell1=0. AI will do nothing", me->GetEntry());
+ if (!creature->m_spells[0])
+ TC_LOG_ERROR("scripts.ai", "TurretAI set for creature with spell1 = 0. AI will do nothing (%s)", creature->GetGUID().ToString().c_str());
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(me->m_spells[0], me->GetMap()->GetDifficultyID());
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(creature->m_spells[0], creature->GetMap()->GetDifficultyID());
_minimumRange = spellInfo ? spellInfo->GetMinRange(false) : 0;
- me->m_CombatDistance = spellInfo ? spellInfo->GetMaxRange(false) : 0;
- me->m_SightDistance = me->m_CombatDistance;
+ creature->m_CombatDistance = spellInfo ? spellInfo->GetMaxRange(false) : 0;
+ creature->m_SightDistance = creature->m_CombatDistance;
}
bool TurretAI::CanAIAttack(Unit const* who) const
{
/// @todo use one function to replace it
- if (!me->IsWithinCombatRange(who, me->m_CombatDistance)
- || (_minimumRange && me->IsWithinCombatRange(who, _minimumRange)))
+ if (!me->IsWithinCombatRange(who, me->m_CombatDistance) || (_minimumRange && me->IsWithinCombatRange(who, _minimumRange)))
return false;
return true;
}
diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h
index 227d06eb82b..cb7e6520c03 100644
--- a/src/server/game/AI/CoreAI/CombatAI.h
+++ b/src/server/game/AI/CoreAI/CombatAI.h
@@ -55,7 +55,7 @@ class TC_GAME_API CombatAI : public CreatureAI
class TC_GAME_API CasterAI : public CombatAI
{
public:
- explicit CasterAI(Creature* c, uint32 scriptId = {}) : CombatAI(c, scriptId) { _attackDistance = MELEE_RANGE; }
+ explicit CasterAI(Creature* creature, uint32 scriptId = {}) : CombatAI(creature, scriptId) { _attackDistance = MELEE_RANGE; }
void InitializeAI() override;
void AttackStart(Unit* victim) override { AttackStartCaster(victim, _attackDistance); }
void UpdateAI(uint32 diff) override;
@@ -67,7 +67,7 @@ class TC_GAME_API CasterAI : public CombatAI
struct TC_GAME_API ArcherAI : public CreatureAI
{
public:
- explicit ArcherAI(Creature* c, uint32 scriptId = {});
+ explicit ArcherAI(Creature* creature, uint32 scriptId = {});
void AttackStart(Unit* who) override;
void UpdateAI(uint32 diff) override;
@@ -80,7 +80,7 @@ struct TC_GAME_API ArcherAI : public CreatureAI
struct TC_GAME_API TurretAI : public CreatureAI
{
public:
- explicit TurretAI(Creature* c, uint32 scriptId = {});
+ explicit TurretAI(Creature* creature, uint32 scriptId = {});
bool CanAIAttack(Unit const* who) const override;
void AttackStart(Unit* who) override;
void UpdateAI(uint32 diff) override;
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.cpp b/src/server/game/AI/CoreAI/GameObjectAI.cpp
index 4dca8fbd59d..6d65a0f1c85 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.cpp
+++ b/src/server/game/AI/CoreAI/GameObjectAI.cpp
@@ -21,14 +21,14 @@
#include "QuestDef.h"
#include "Errors.h"
-GameObjectAI::GameObjectAI(GameObject* g, uint32 scriptId) : _scriptId(scriptId ? scriptId : g->GetScriptId()), me(g)
+int32 GameObjectAI::Permissible(GameObject const* /*go*/)
{
- ASSERT(_scriptId, "A GameObjectAI was initialized with an invalid scriptId!");
+ return PERMIT_BASE_NO;
}
-int32 GameObjectAI::Permissible(GameObject const* /*go*/)
+GameObjectAI::GameObjectAI(GameObject* go, uint32 scriptId) : _scriptId(scriptId ? scriptId : go->GetScriptId()), me(go)
{
- return PERMIT_BASE_NO;
+ ASSERT(_scriptId, "A GameObjectAI was initialized with an invalid scriptId!");
}
Optional<QuestGiverStatus> GameObjectAI::GetDialogStatus(Player* /*player*/)
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index 8da5d34118f..cec28d4c420 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -41,7 +41,7 @@ class TC_GAME_API GameObjectAI
GameObject* const me;
public:
- explicit GameObjectAI(GameObject* g, uint32 scriptId = {});
+ explicit GameObjectAI(GameObject* go, uint32 scriptId = {});
virtual ~GameObjectAI() { }
// Gets the id of the AI (script id)
diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp
index b455fdfab32..3cb7315ec40 100644
--- a/src/server/game/AI/CoreAI/GuardAI.cpp
+++ b/src/server/game/AI/CoreAI/GuardAI.cpp
@@ -56,7 +56,7 @@ void GuardAI::EnterEvadeMode(EvadeReason /*why*/)
return;
}
- TC_LOG_DEBUG("entities.unit", "Guard entry: %u enters evade mode.", me->GetEntry());
+ TC_LOG_TRACE("scritps.ai", "GuardAI::EnterEvadeMode: %s enters evade mode.", me->GetGUID().ToString().c_str());
me->RemoveAllAuras();
me->GetThreatManager().ClearAllThreat();
diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp
index 701d1a3dc42..e762e8d4aad 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.cpp
+++ b/src/server/game/AI/CoreAI/PassiveAI.cpp
@@ -18,9 +18,20 @@
#include "PassiveAI.h"
#include "Creature.h"
-PassiveAI::PassiveAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId) { me->SetReactState(REACT_PASSIVE); }
-PossessedAI::PossessedAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId) { me->SetReactState(REACT_PASSIVE); }
-NullCreatureAI::NullCreatureAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId) { me->SetReactState(REACT_PASSIVE); }
+PassiveAI::PassiveAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
+{
+ me->SetReactState(REACT_PASSIVE);
+}
+
+PossessedAI::PossessedAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
+{
+ me->SetReactState(REACT_PASSIVE);
+}
+
+NullCreatureAI::NullCreatureAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
+{
+ me->SetReactState(REACT_PASSIVE);
+}
int32 NullCreatureAI::Permissible(Creature const* creature)
{
diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h
index d8621ae40f1..08946e33eb5 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.h
+++ b/src/server/game/AI/CoreAI/PassiveAI.h
@@ -23,7 +23,7 @@
class TC_GAME_API PassiveAI : public CreatureAI
{
public:
- explicit PassiveAI(Creature* c, uint32 scriptId = {});
+ explicit PassiveAI(Creature* creature, uint32 scriptId = {});
void MoveInLineOfSight(Unit*) override { }
void AttackStart(Unit*) override { }
@@ -35,7 +35,7 @@ class TC_GAME_API PassiveAI : public CreatureAI
class TC_GAME_API PossessedAI : public CreatureAI
{
public:
- explicit PossessedAI(Creature* c, uint32 scriptId = {});
+ explicit PossessedAI(Creature* creature, uint32 scriptId = {});
void MoveInLineOfSight(Unit*) override { }
void AttackStart(Unit* target) override;
@@ -51,7 +51,7 @@ class TC_GAME_API PossessedAI : public CreatureAI
class TC_GAME_API NullCreatureAI : public CreatureAI
{
public:
- explicit NullCreatureAI(Creature* c, uint32 scriptId = {});
+ explicit NullCreatureAI(Creature* creature, uint32 scriptId = {});
void MoveInLineOfSight(Unit*) override { }
void AttackStart(Unit*) override { }
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index ea8d4c1c464..e92db6063f4 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -44,7 +44,7 @@ int32 PetAI::Permissible(Creature const* creature)
return PERMIT_BASE_NO;
}
-PetAI::PetAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId), _tracker(TIME_INTERVAL_LOOK)
+PetAI::PetAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), _tracker(TIME_INTERVAL_LOOK)
{
if (!me->GetCharmInfo())
throw InvalidAIException("Creature doesn't have a valid charm info");
@@ -107,7 +107,7 @@ void PetAI::UpdateAI(uint32 diff)
if (NeedToStop())
{
- TC_LOG_DEBUG("misc", "Pet AI stopped attacking [%s]", me->GetGUID().ToString().c_str());
+ TC_LOG_TRACE("scripts.ai.petai", "PetAI::UpdateAI: AI stopped attacking %s", me->GetGUID().ToString().c_str());
StopAttack();
return;
}
@@ -262,7 +262,7 @@ void PetAI::UpdateAI(uint32 diff)
void PetAI::UpdateAllies()
{
- _updateAlliesTimer = 10 * IN_MILLISECONDS; // update friendly targets every 10 seconds, lesser checks increase performance
+ _updateAlliesTimer = 10 * IN_MILLISECONDS; // update friendly targets every 10 seconds, lesser checks increase performance
Unit* owner = me->GetCharmerOrOwner();
if (!owner)
@@ -272,17 +272,17 @@ void PetAI::UpdateAllies()
if (Player* player = owner->ToPlayer())
group = player->GetGroup();
- //only pet and owner/not in group->ok
+ // only pet and owner/not in group->ok
if (_allySet.size() == 2 && !group)
return;
- //owner is in group; group members filled in already (no raid -> subgroupcount = whole count)
+ // owner is in group; group members filled in already (no raid -> subgroupcount = whole count)
if (group && !group->isRaidGroup() && _allySet.size() == (group->GetMembersCount() + 2))
return;
_allySet.clear();
_allySet.insert(me->GetGUID());
- if (group) //add group
+ if (group) // add group
{
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
@@ -296,7 +296,7 @@ void PetAI::UpdateAllies()
_allySet.insert(Target->GetGUID());
}
}
- else //remove group
+ else // remove group
_allySet.insert(owner->GetGUID());
}
@@ -588,36 +588,33 @@ bool PetAI::CanAttack(Unit* target)
void PetAI::ReceiveEmote(Player* player, uint32 emote)
{
- if (!me->GetOwnerGUID().IsEmpty() && me->GetOwnerGUID() == player->GetGUID())
+ if (me->GetOwnerGUID() != player->GetGUID())
+ return;
+
+ switch (emote)
{
- switch (emote)
- {
- case TEXT_EMOTE_COWER:
- if (me->IsPet() && me->ToPet()->IsPetGhoul())
- me->HandleEmoteCommand(/*EMOTE_ONESHOT_ROAR*/EMOTE_ONESHOT_OMNICAST_GHOUL);
- break;
- case TEXT_EMOTE_ANGRY:
- if (me->IsPet() && me->ToPet()->IsPetGhoul())
- me->HandleEmoteCommand(/*EMOTE_ONESHOT_COWER*/EMOTE_STATE_STUN);
- break;
- case TEXT_EMOTE_GLARE:
- if (me->IsPet() && me->ToPet()->IsPetGhoul())
- me->HandleEmoteCommand(EMOTE_STATE_STUN);
- break;
- case TEXT_EMOTE_SOOTHE:
- if (me->IsPet() && me->ToPet()->IsPetGhoul())
- me->HandleEmoteCommand(EMOTE_ONESHOT_OMNICAST_GHOUL);
- break;
- }
+ case TEXT_EMOTE_COWER:
+ if (me->IsPet() && me->ToPet()->IsPetGhoul())
+ me->HandleEmoteCommand(/*EMOTE_ONESHOT_ROAR*/EMOTE_ONESHOT_OMNICAST_GHOUL);
+ break;
+ case TEXT_EMOTE_ANGRY:
+ if (me->IsPet() && me->ToPet()->IsPetGhoul())
+ me->HandleEmoteCommand(/*EMOTE_ONESHOT_COWER*/EMOTE_STATE_STUN);
+ break;
+ case TEXT_EMOTE_GLARE:
+ if (me->IsPet() && me->ToPet()->IsPetGhoul())
+ me->HandleEmoteCommand(EMOTE_STATE_STUN);
+ break;
+ case TEXT_EMOTE_SOOTHE:
+ if (me->IsPet() && me->ToPet()->IsPetGhoul())
+ me->HandleEmoteCommand(EMOTE_ONESHOT_OMNICAST_GHOUL);
+ break;
}
}
void PetAI::ClearCharmInfoFlags()
{
- // Quick access to set all flags to FALSE
-
CharmInfo* ci = me->GetCharmInfo();
-
if (ci)
{
ci->SetIsAtStay(false);
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index ddf97354b2b..5df11ad8282 100644
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -29,15 +29,16 @@ typedef std::vector<std::pair<Unit*, Spell*>> TargetSpellList;
class TC_GAME_API PetAI : public CreatureAI
{
public:
-
- explicit PetAI(Creature* c, uint32 scriptId = {});
+ explicit PetAI(Creature* creature, uint32 scriptId = {});
void UpdateAI(uint32) override;
static int32 Permissible(Creature const* creature);
void KilledUnit(Unit* /*victim*/) override;
- void AttackStart(Unit* target) override; // only start attacking if not attacking something else already
- void _AttackStart(Unit* target); // always start attacking if possible
+ // only start attacking if not attacking something else already
+ void AttackStart(Unit* target) override;
+ // always start attacking if possible
+ void _AttackStart(Unit* target);
void MovementInform(uint32 moveType, uint32 data) override;
void OwnerAttackedBy(Unit* attacker) override;
void OwnerAttacked(Unit* target) override;
@@ -45,8 +46,8 @@ class TC_GAME_API PetAI : public CreatureAI
void ReceiveEmote(Player* player, uint32 textEmote) override;
// The following aren't used by the PetAI but need to be defined to override
- // default CreatureAI functions which interfere with the PetAI
- //
+ // default CreatureAI functions which interfere with the PetAI
+
void MoveInLineOfSight(Unit* /*who*/) override { } // CreatureAI interferes with returning pets
void MoveInLineOfSight_Safe(Unit* /*who*/) { } // CreatureAI interferes with returning pets
void EnterEvadeMode(EvadeReason /*why*/) override { } // For fleeing, pets don't use this type of Evade mechanic
@@ -59,6 +60,7 @@ class TC_GAME_API PetAI : public CreatureAI
void HandleReturnMovement();
void DoAttack(Unit* target, bool chase);
bool CanAttack(Unit* target);
+ // Quick access to set all flags to FALSE
void ClearCharmInfoFlags();
TimeTracker _tracker;
diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h
index 08e89b10912..0b23c6d96c5 100644
--- a/src/server/game/AI/CoreAI/ReactorAI.h
+++ b/src/server/game/AI/CoreAI/ReactorAI.h
@@ -23,7 +23,6 @@
class TC_GAME_API ReactorAI : public CreatureAI
{
public:
-
using CreatureAI::CreatureAI;
void MoveInLineOfSight(Unit*) override { }
diff --git a/src/server/game/AI/CoreAI/TotemAI.cpp b/src/server/game/AI/CoreAI/TotemAI.cpp
index 8047c3cca39..48940a1412b 100644
--- a/src/server/game/AI/CoreAI/TotemAI.cpp
+++ b/src/server/game/AI/CoreAI/TotemAI.cpp
@@ -16,13 +16,14 @@
*/
#include "TotemAI.h"
-#include "Totem.h"
+#include "CellImpl.h"
#include "Creature.h"
-#include "ObjectAccessor.h"
-#include "SpellMgr.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
-#include "CellImpl.h"
+#include "ObjectAccessor.h"
+#include "SpellInfo.h"
+#include "SpellMgr.h"
+#include "Totem.h"
int32 TotemAI::Permissible(Creature const* creature)
{
@@ -32,9 +33,9 @@ int32 TotemAI::Permissible(Creature const* creature)
return PERMIT_BASE_NO;
}
-TotemAI::TotemAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId), _victimGUID()
+TotemAI::TotemAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), _victimGUID()
{
- ASSERT(c->IsTotem());
+ ASSERT(creature->IsTotem(), "TotemAI: AI assigned to a no-totem creature (%s)!", creature->GetGUID().ToString().c_str());
}
void TotemAI::MoveInLineOfSight(Unit* /*who*/) { }
@@ -66,9 +67,7 @@ void TotemAI::UpdateAI(uint32 /*diff*/)
Unit* victim = !_victimGUID.IsEmpty() ? ObjectAccessor::GetUnit(*me, _victimGUID) : nullptr;
// Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
- if (!victim ||
- !victim->isTargetableForAttack() || !me->IsWithinDistInMap(victim, max_range) ||
- me->IsFriendlyTo(victim) || !me->CanSeeOrDetect(victim))
+ if (!victim || !victim->isTargetableForAttack() || !me->IsWithinDistInMap(victim, max_range) || me->IsFriendlyTo(victim) || !me->CanSeeOrDetect(victim))
{
victim = nullptr;
Trinity::NearestAttackableUnitInObjectRangeCheck u_check(me, me->GetCharmerOrOwnerOrSelf(), max_range);
diff --git a/src/server/game/AI/CoreAI/TotemAI.h b/src/server/game/AI/CoreAI/TotemAI.h
index 13c024ccbe4..606641999bc 100644
--- a/src/server/game/AI/CoreAI/TotemAI.h
+++ b/src/server/game/AI/CoreAI/TotemAI.h
@@ -27,8 +27,7 @@ class Totem;
class TC_GAME_API TotemAI : public CreatureAI
{
public:
-
- explicit TotemAI(Creature* c, uint32 scriptId = {});
+ explicit TotemAI(Creature* creature, uint32 scriptId = {});
void MoveInLineOfSight(Unit* who) override;
void AttackStart(Unit* victim) override;
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index 359fb0fa206..c705eb7e7f2 100644
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -34,19 +34,6 @@
#include "Vehicle.h"
#include "World.h"
-//Disable CreatureAI when charmed
-void CreatureAI::OnCharmed(bool isNew)
-{
- if (isNew && !me->IsCharmed() && !me->LastCharmerGUID.IsEmpty())
- {
- if (!me->HasReactState(REACT_PASSIVE))
- if (Unit* lastCharmer = ObjectAccessor::GetUnit(*me, me->LastCharmerGUID))
- me->EngageWithTarget(lastCharmer);
- me->LastCharmerGUID.Clear();
- }
- UnitAI::OnCharmed(isNew);
-}
-
std::unordered_map<std::pair<uint32, Difficulty>, AISpellInfoType> UnitAI::AISpellInfo;
AISpellInfoType* GetAISpellInfo(uint32 spellId, Difficulty difficulty)
{
@@ -69,15 +56,32 @@ void CreatureAI::Talk(uint8 id, WorldObject const* whisperTarget /*= nullptr*/)
sCreatureTextMgr->SendChat(me, id, whisperTarget);
}
+// Disable CreatureAI when charmed
+void CreatureAI::OnCharmed(bool isNew)
+{
+ if (isNew && !me->IsCharmed() && !me->LastCharmerGUID.IsEmpty())
+ {
+ if (!me->HasReactState(REACT_PASSIVE))
+ {
+ if (Unit* lastCharmer = ObjectAccessor::GetUnit(*me, me->LastCharmerGUID))
+ me->EngageWithTarget(lastCharmer);
+ }
+
+ me->LastCharmerGUID.Clear();
+ }
+
+ UnitAI::OnCharmed(isNew);
+}
+
void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/)
{
if (!creature)
creature = me;
Map* map = creature->GetMap();
- if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
+ if (!map->IsDungeon()) // use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
{
- TC_LOG_ERROR("misc", "DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0);
+ TC_LOG_ERROR("scripts.ai", "CreatureAI::DoZoneInCombat: call for map that isn't an instance (%s)", creature->GetGUID().ToString().c_str());
return;
}
@@ -86,17 +90,21 @@ void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/)
return;
for (auto const& ref : playerList)
+ {
if (Player* player = ref.GetSource())
{
if (!player->IsAlive() || !CombatManager::CanBeginCombat(creature, player))
continue;
creature->EngageWithTarget(player);
+
for (Unit* pet : player->m_Controlled)
creature->EngageWithTarget(pet);
+
if (Unit* vehicle = player->GetVehicleBase())
creature->EngageWithTarget(vehicle);
}
+ }
}
// scripts does not take care about MoveInLineOfSight loops
@@ -155,7 +163,7 @@ void CreatureAI::EnterEvadeMode(EvadeReason why)
if (!_EnterEvadeMode(why))
return;
- TC_LOG_DEBUG("entities.unit", "Creature %u enters evade mode.", me->GetEntry());
+ TC_LOG_DEBUG("scripts.ai", "CreatureAI::EnterEvadeMode: entering evade mode (why: %u) (%s)", why, me->GetGUID().ToString().c_str());
if (!me->GetVehicle()) // otherwise me will be in evade mode forever
{
@@ -247,11 +255,11 @@ int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) con
std::unordered_set<coordinate> outOfBounds;
Position startPosition = owner->GetPosition();
- if (!IsInBoundary(&startPosition))
- { // fall back to creature position
+ if (!IsInBoundary(&startPosition)) // fall back to creature position
+ {
startPosition = me->GetPosition();
- if (!IsInBoundary(&startPosition))
- { // fall back to creature home position
+ if (!IsInBoundary(&startPosition)) // fall back to creature home position
+ {
startPosition = me->GetHomePosition();
if (!IsInBoundary(&startPosition))
return LANG_CREATURE_NO_INTERIOR_POINT_FOUND;
@@ -265,7 +273,7 @@ int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) con
{
coordinate front = Q.front();
bool hasOutOfBoundsNeighbor = false;
- for (coordinate off : std::initializer_list<coordinate>{{1,0}, {0,1}, {-1,0}, {0,-1}})
+ for (coordinate const& off : std::list<coordinate>{ {1, 0}, {0, 1}, {-1, 0}, {0, -1} })
{
coordinate next(front.first + off.first, front.second + off.second);
if (next.first > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.first < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT)
@@ -285,12 +293,12 @@ int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) con
}
alreadyChecked.insert(next);
}
- else
- if (outOfBounds.find(next) != outOfBounds.end())
- hasOutOfBoundsNeighbor = true;
+ else if (outOfBounds.find(next) != outOfBounds.end())
+ hasOutOfBoundsNeighbor = true;
}
if (fill || hasOutOfBoundsNeighbor)
- if (TempSummon* point = owner->SummonCreature(BOUNDARY_VISUALIZE_CREATURE, Position(startPosition.GetPositionX() + front.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + front.second*BOUNDARY_VISUALIZE_STEP_SIZE, spawnZ), TEMPSUMMON_TIMED_DESPAWN, duration * IN_MILLISECONDS))
+ {
+ if (TempSummon* point = owner->SummonCreature(BOUNDARY_VISUALIZE_CREATURE, Position(startPosition.GetPositionX() + front.first * BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + front.second * BOUNDARY_VISUALIZE_STEP_SIZE, spawnZ), TEMPSUMMON_TIMED_DESPAWN, duration * IN_MILLISECONDS))
{
point->SetObjectScale(BOUNDARY_VISUALIZE_CREATURE_SCALE);
point->AddUnitFlag(UNIT_FLAG_STUNNED);
@@ -298,6 +306,8 @@ int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) con
if (!hasOutOfBoundsNeighbor)
point->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
+ }
+
Q.pop();
}
return boundsWarning ? LANG_CREATURE_MOVEMENT_MAYBE_UNBOUNDED : 0;
@@ -311,7 +321,7 @@ bool CreatureAI::IsInBoundary(Position const* who) const
if (!who)
who = me;
- return (CreatureAI::IsInBounds(*_boundary, who) != _negateBoundary);
+ return CreatureAI::IsInBounds(*_boundary, who) != _negateBoundary;
}
bool CreatureAI::IsInBounds(CreatureBoundary const& boundary, Position const* pos)
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index 5b0ab08c4db..e6fb48571b9 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -18,12 +18,12 @@
#ifndef TRINITY_CREATUREAI_H
#define TRINITY_CREATUREAI_H
-#include "UnitAI.h"
#include "Common.h"
#include "LootItemType.h"
#include "ObjectDefines.h"
#include "Optional.h"
#include "QuestDef.h"
+#include "UnitAI.h"
class AreaBoundary;
class AreaTrigger;
@@ -40,6 +40,16 @@ typedef std::vector<AreaBoundary const*> CreatureBoundary;
#define TIME_INTERVAL_LOOK 5000
#define VISIBILITY_RANGE 10000
+enum Permitions : int32
+{
+ PERMIT_BASE_NO = -1,
+ PERMIT_BASE_IDLE = 1,
+ PERMIT_BASE_REACTIVE = 100,
+ PERMIT_BASE_PROACTIVE = 200,
+ PERMIT_BASE_FACTION_SPECIFIC = 400,
+ PERMIT_BASE_SPECIAL = 800
+};
+
enum SCEquip
{
EQUIP_NO_CHANGE = -1,
@@ -239,14 +249,4 @@ class TC_GAME_API CreatureAI : public UnitAI
bool _moveInLOSLocked;
};
-enum Permitions : int32
-{
- PERMIT_BASE_NO = -1,
- PERMIT_BASE_IDLE = 1,
- PERMIT_BASE_REACTIVE = 100,
- PERMIT_BASE_PROACTIVE = 200,
- PERMIT_BASE_FACTION_SPECIFIC = 400,
- PERMIT_BASE_SPECIAL = 800
-};
-
#endif
diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h
index fa3b5662d99..c8425fb08eb 100644
--- a/src/server/game/AI/CreatureAIImpl.h
+++ b/src/server/game/AI/CreatureAIImpl.h
@@ -50,29 +50,26 @@ enum AICondition
#define AI_DEFAULT_COOLDOWN 5000
-//Spell targets used by SelectSpell
+// Spell targets used by SelectSpell
enum SelectTargetType : uint8
{
- SELECT_TARGET_DONTCARE = 0, //All target types allowed
-
- SELECT_TARGET_SELF, //Only Self casting
-
- SELECT_TARGET_SINGLE_ENEMY, //Only Single Enemy
- SELECT_TARGET_AOE_ENEMY, //Only AoE Enemy
- SELECT_TARGET_ANY_ENEMY, //AoE or Single Enemy
-
- SELECT_TARGET_SINGLE_FRIEND, //Only Single Friend
- SELECT_TARGET_AOE_FRIEND, //Only AoE Friend
- SELECT_TARGET_ANY_FRIEND //AoE or Single Friend
+ SELECT_TARGET_DONTCARE = 0, // All target types allowed
+ SELECT_TARGET_SELF, // Only Self casting
+ SELECT_TARGET_SINGLE_ENEMY, // Only Single Enemy
+ SELECT_TARGET_AOE_ENEMY, // Only AoE Enemy
+ SELECT_TARGET_ANY_ENEMY, // AoE or Single Enemy
+ SELECT_TARGET_SINGLE_FRIEND, // Only Single Friend
+ SELECT_TARGET_AOE_FRIEND, // Only AoE Friend
+ SELECT_TARGET_ANY_FRIEND // AoE or Single Friend
};
-//Spell Effects used by SelectSpell
+// Spell Effects used by SelectSpell
enum SelectEffect : uint8
{
- SELECT_EFFECT_DONTCARE = 0, //All spell effects allowed
- SELECT_EFFECT_DAMAGE, //Spell does damage
- SELECT_EFFECT_HEALING, //Spell does healing
- SELECT_EFFECT_AURA //Spell applies an aura
+ SELECT_EFFECT_DONTCARE = 0, // All spell effects allowed
+ SELECT_EFFECT_DAMAGE, // Spell does damage
+ SELECT_EFFECT_HEALING, // Spell does healing
+ SELECT_EFFECT_AURA // Spell applies an aura
};
struct AISpellInfoType
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp
index 9dd296a7924..6303e91c14a 100644
--- a/src/server/game/AI/PlayerAI/PlayerAI.cpp
+++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp
@@ -1226,13 +1226,13 @@ PlayerAI::TargetedSpell SimpleCharmedPlayerAI::SelectAppropriateCastForSpec()
}
static const float CASTER_CHASE_DISTANCE = 28.0f;
-void SimpleCharmedPlayerAI::UpdateAI(const uint32 diff)
+void SimpleCharmedPlayerAI::UpdateAI(uint32 diff)
{
Creature* charmer = GetCharmer();
if (!charmer)
return;
- //kill self if charm aura has infinite duration
+ // kill self if charm aura has infinite duration
if (charmer->IsInEvadeMode())
{
Player::AuraEffectList const& auras = me->GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
@@ -1296,8 +1296,8 @@ void SimpleCharmedPlayerAI::UpdateAI(const uint32 diff)
_castCheckTimer = 0;
else
{
- if (IsRangedAttacker())
- { // chase to zero if the target isn't in line of sight
+ if (IsRangedAttacker()) // chase to zero if the target isn't in line of sight
+ {
bool inLOS = me->IsWithinLOSInMap(target);
if (_chaseCloser != !inLOS)
{
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 32ba4bdf5a1..3af141dae8a 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -118,9 +118,7 @@ void SummonList::DoActionImpl(int32 action, StorageType const& summons)
ScriptedAI::ScriptedAI(Creature* creature) : ScriptedAI(creature, creature->GetScriptId()) { }
-ScriptedAI::ScriptedAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId),
- IsFleeing(false),
- _isCombatMovementAllowed(true)
+ScriptedAI::ScriptedAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), IsFleeing(false), _isCombatMovementAllowed(true)
{
_isHeroic = me->GetMap()->IsHeroic();
_difficulty = me->GetMap()->GetDifficultyID();
@@ -145,7 +143,7 @@ void ScriptedAI::AttackStart(Unit* who)
void ScriptedAI::UpdateAI(uint32 /*diff*/)
{
- //Check if we have a current target
+ // Check if we have a current target
if (!UpdateVictim())
return;
@@ -188,7 +186,7 @@ void ScriptedAI::DoPlaySoundToSet(WorldObject* source, uint32 soundId)
if (!sSoundKitStore.LookupEntry(soundId))
{
- TC_LOG_ERROR("scripts", "Invalid soundId %u used in DoPlaySoundToSet (Source: %s)", soundId, source->GetGUID().ToString().c_str());
+ TC_LOG_ERROR("scripts.ai", "ScriptedAI::DoPlaySoundToSet: Invalid soundId %u used in DoPlaySoundToSet (Source: %s)", soundId, source->GetGUID().ToString().c_str());
return;
}
@@ -255,15 +253,15 @@ bool ScriptedAI::HealthAbovePct(uint32 pct) const
SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect)
{
- //No target so we can't cast
+ // No target so we can't cast
if (!target)
return nullptr;
- //Silenced so we can't cast
+ // Silenced so we can't cast
if (me->HasUnitFlag(UNIT_FLAG_SILENCED))
return nullptr;
- //Using the extended script system we first create a list of viable spells
+ // Using the extended script system we first create a list of viable spells
SpellInfo const* apSpell[MAX_CREATURE_SPELLS];
memset(apSpell, 0, MAX_CREATURE_SPELLS * sizeof(SpellInfo*));
@@ -272,49 +270,63 @@ SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mec
SpellInfo const* tempSpell = nullptr;
AISpellInfoType const* aiSpell = nullptr;
- //Check if each spell is viable(set it to null if not)
+ // Check if each spell is viable(set it to null if not)
for (uint32 i = 0; i < MAX_CREATURE_SPELLS; i++)
{
tempSpell = sSpellMgr->GetSpellInfo(me->m_spells[i], me->GetMap()->GetDifficultyID());
aiSpell = GetAISpellInfo(me->m_spells[i], me->GetMap()->GetDifficultyID());
- //This spell doesn't exist
+ // This spell doesn't exist
if (!tempSpell || !aiSpell)
continue;
// Targets and Effects checked first as most used restrictions
- //Check the spell targets if specified
+ // Check the spell targets if specified
if (targets && !(aiSpell->Targets & (1 << (targets-1))))
continue;
- //Check the type of spell if we are looking for a specific spell type
+ // Check the type of spell if we are looking for a specific spell type
if (effect && !(aiSpell->Effects & (1 << (effect-1))))
continue;
- //Check for school if specified
+ // Check for school if specified
if (school && (tempSpell->SchoolMask & school) == 0)
continue;
- //Check for spell mechanic if specified
+ // Check for spell mechanic if specified
if (mechanic && tempSpell->Mechanic != mechanic)
continue;
- //Check if the spell meets our range requirements
+ // Continue if we don't have the mana to actually cast this spell
+ bool hasPower = true;
+ for (SpellPowerCost const& cost : tempSpell->CalcPowerCost(me, tempSpell->GetSchoolMask()))
+ {
+ if (cost.Amount > me->GetPower(cost.Power))
+ {
+ hasPower = false;
+ break;
+ }
+ }
+
+ if (!hasPower)
+ continue;
+
+ // Check if the spell meets our range requirements
if (rangeMin && me->GetSpellMinRangeForTarget(target, tempSpell) < rangeMin)
continue;
if (rangeMax && me->GetSpellMaxRangeForTarget(target, tempSpell) > rangeMax)
continue;
- //Check if our target is in range
+ // Check if our target is in range
if (me->IsWithinDistInMap(target, float(me->GetSpellMinRangeForTarget(target, tempSpell))) || !me->IsWithinDistInMap(target, float(me->GetSpellMaxRangeForTarget(target, tempSpell))))
continue;
- //All good so lets add it to the spell list
+ // All good so lets add it to the spell list
apSpell[spellCount] = tempSpell;
++spellCount;
}
- //We got our usable spells so now lets randomly pick one
+ // We got our usable spells so now lets randomly pick one
if (!spellCount)
return nullptr;
@@ -341,7 +353,7 @@ void ScriptedAI::DoTeleportPlayer(Unit* unit, float x, float y, float z, float o
if (Player* player = unit->ToPlayer())
player->TeleportTo(unit->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT);
else
- TC_LOG_ERROR("scripts", "Creature %s Tried to teleport non-player unit (%s) to x: %f y:%f z: %f o: %f. Aborted.",
+ TC_LOG_ERROR("scripts.ai", "ScriptedAI::DoTeleportPlayer: Creature %s Tried to teleport non-player unit (%s) to x: %f y:%f z: %f o: %f. Aborted.",
me->GetGUID().ToString().c_str(), unit->GetGUID().ToString().c_str(), x, y, z, o);
}
@@ -432,19 +444,8 @@ void ScriptedAI::SetCombatMovement(bool allowMovement)
_isCombatMovementAllowed = allowMovement;
}
-enum NPCs
-{
- NPC_BROODLORD = 12017,
- NPC_VOID_REAVER = 19516,
- NPC_JAN_ALAI = 23578,
- NPC_SARTHARION = 28860
-};
-
// BossAI - for instanced bosses
-BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature),
- instance(creature->GetInstanceScript()),
- summons(creature),
- _bossId(bossId)
+BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature), instance(creature->GetInstanceScript()), summons(creature), _bossId(bossId)
{
if (instance)
SetBoundary(instance->GetBossBoundary(bossId));
@@ -555,7 +556,7 @@ void BossAI::_DespawnAtEvade(Seconds delayToRespawn /*= 30s*/, Creature* who /*=
{
if (delayToRespawn < Seconds(2))
{
- TC_LOG_ERROR("scripts", "_DespawnAtEvade called with delay of " SI64FMTD " seconds, defaulting to 2.", delayToRespawn.count());
+ TC_LOG_ERROR("scripts.ai", "BossAI::_DespawnAtEvade: called with delay of " SI64FMTD " seconds, defaulting to 2 (me: %s)", delayToRespawn.count(), me->GetGUID().ToString().c_str());
delayToRespawn = Seconds(2);
}
@@ -564,7 +565,7 @@ void BossAI::_DespawnAtEvade(Seconds delayToRespawn /*= 30s*/, Creature* who /*=
if (TempSummon* whoSummon = who->ToTempSummon())
{
- TC_LOG_WARN("scripts", "_DespawnAtEvade called on a temporary summon.");
+ TC_LOG_WARN("scripts.ai", "BossAI::_DespawnAtEvade: called on a temporary summon (who: %s)", who->GetGUID().ToString().c_str());
whoSummon->UnSummon();
return;
}
@@ -576,10 +577,7 @@ void BossAI::_DespawnAtEvade(Seconds delayToRespawn /*= 30s*/, Creature* who /*=
}
// WorldBossAI - for non-instanced bosses
-
-WorldBossAI::WorldBossAI(Creature* creature) :
- ScriptedAI(creature),
- summons(creature) { }
+WorldBossAI::WorldBossAI(Creature* creature) : ScriptedAI(creature), summons(creature) { }
void WorldBossAI::_Reset()
{
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index f6f9f23a322..68980803da5 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SCRIPTEDCREATURE_H_
-#define SCRIPTEDCREATURE_H_
+#ifndef TRINITY_SCRIPTEDCREATURE_H
+#define TRINITY_SCRIPTEDCREATURE_H
#include "CreatureAI.h"
#include "Creature.h" // convenience include for scripts, all uses of ScriptedCreature also need Creature (except ScriptedCreature itself doesn't need Creature)
@@ -136,45 +136,45 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
virtual ~ScriptedAI() { }
// *************
- //CreatureAI Functions
+ // CreatureAI Functions
// *************
void AttackStartNoMove(Unit* target);
- //Called at World update tick
+ // Called at World update tick
virtual void UpdateAI(uint32 diff) override;
// *************
// Variables
// *************
- //For fleeing
+ // For fleeing
bool IsFleeing;
// *************
- //Pure virtual functions
+ // Pure virtual functions
// *************
// Called before JustEngagedWith even before the creature is in combat.
void AttackStart(Unit* /*target*/) override;
// *************
- //AI Helper Functions
+ // AI Helper Functions
// *************
- //Start movement toward victim
+ // Start movement toward victim
void DoStartMovement(Unit* target, float distance = 0.0f, float angle = 0.0f);
- //Start no movement on victim
+ // Start no movement on victim
void DoStartNoMovement(Unit* target);
- //Stop attack of current victim
+ // Stop attack of current victim
void DoStopAttack();
- //Cast spell by spell info
+ // Cast spell by spell info
void DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool triggered = false);
- //Plays a sound to all nearby players
+ // Plays a sound to all nearby players
void DoPlaySoundToSet(WorldObject* source, uint32 soundId);
// Add specified amount of threat directly to victim (ignores redirection effects) - also puts victim in combat and engages them if necessary
@@ -191,32 +191,32 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
void DoTeleportTo(float x, float y, float z, uint32 time = 0);
void DoTeleportTo(float const pos[4]);
- //Teleports a player without dropping threat (only teleports to same map)
+ // Teleports a player without dropping threat (only teleports to same map)
void DoTeleportPlayer(Unit* unit, float x, float y, float z, float o);
void DoTeleportAll(float x, float y, float z, float o);
- //Returns friendly unit with the most amount of hp missing from max hp
+ // Returns friendly unit with the most amount of hp missing from max hp
Unit* DoSelectLowestHpFriendly(float range, uint32 minHPDiff = 1);
- //Returns friendly unit with hp pct below specified and with specified entry
+ // Returns friendly unit with hp pct below specified and with specified entry
Unit* DoSelectBelowHpPctFriendlyWithEntry(uint32 entry, float range, uint8 hpPct = 1, bool excludeSelf = true);
- //Returns a list of friendly CC'd units within range
+ // Returns a list of friendly CC'd units within range
std::list<Creature*> DoFindFriendlyCC(float range);
- //Returns a list of all friendly units missing a specific buff within range
+ // Returns a list of all friendly units missing a specific buff within range
std::list<Creature*> DoFindFriendlyMissingBuff(float range, uint32 spellId);
- //Return a player with at least minimumRange from me
+ // Return a player with at least minimumRange from me
Player* GetPlayerAtMinimumRange(float minRange);
- //Spawns a creature relative to me
+ // Spawns a creature relative to me
Creature* DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, uint32 despawntime);
bool HealthBelowPct(uint32 pct) const;
bool HealthAbovePct(uint32 pct) const;
- //Returns spells that meet the specified criteria from the creatures spell list
+ // Returns spells that meet the specified criteria from the creatures spell list
SpellInfo const* SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect);
void SetEquipmentSlots(bool loadDefault, int32 mainHand = EQUIP_NO_CHANGE, int32 offHand = EQUIP_NO_CHANGE, int32 ranged = EQUIP_NO_CHANGE);
@@ -405,4 +405,4 @@ inline void GetPlayerListInGrid(Container& container, WorldObject* source, float
source->GetPlayerListInGrid(container, maxSearchRange);
}
-#endif // SCRIPTEDCREATURE_H_
+#endif // TRINITY_SCRIPTEDCREATURE_H
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index da3fe4c0783..fdc8214f254 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -101,7 +101,7 @@ void EscortAI::EnterEvadeMode(EvadeReason /*why*/)
{
AddEscortState(STATE_ESCORT_RETURNING);
ReturnToLastPoint();
- TC_LOG_DEBUG("scripts", "EscortAI::EnterEvadeMode: left combat and is now returning to last point");
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::EnterEvadeMode: left combat and is now returning to last point (%s)", me->GetGUID().ToString().c_str());
}
else
{
@@ -126,22 +126,22 @@ void EscortAI::MovementInform(uint32 type, uint32 id)
// continue waypoint movement
if (id == POINT_LAST_POINT)
{
- TC_LOG_DEBUG("scripts", "EscortAI::MovementInform: returned to before combat position");
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::MovementInform: returned to before combat position (%s)", me->GetGUID().ToString().c_str());
me->SetWalk(!_running);
RemoveEscortState(STATE_ESCORT_RETURNING);
}
else if (id == POINT_HOME)
{
- TC_LOG_DEBUG("scripts", "EscortAI::MovementInform: returned to home location and restarting waypoint path");
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::MovementInform: returned to home location and restarting waypoint path (%s)", me->GetGUID().ToString().c_str());
_started = false;
}
}
else if (type == WAYPOINT_MOTION_TYPE)
{
- ASSERT(id < _path.nodes.size(), "EscortAI::MovementInform: referenced movement id (%u) points to non-existing node in loaded path", id);
+ ASSERT(id < _path.nodes.size(), "EscortAI::MovementInform: referenced movement id (%u) points to non-existing node in loaded path (%s)", id, me->GetGUID().ToString().c_str());
WaypointNode waypoint = _path.nodes[id];
- TC_LOG_DEBUG("scripts", "EscortAI::MovementInform: waypoint node %u reached", waypoint.id);
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::MovementInform: waypoint node %u reached (%s)", waypoint.id, me->GetGUID().ToString().c_str());
// last point
if (id == _path.nodes.size() - 1)
@@ -171,7 +171,7 @@ void EscortAI::UpdateAI(uint32 diff)
if (_despawnAtEnd)
{
- TC_LOG_DEBUG("scripts", "EscortAI::UpdateAI: reached end of waypoints, despawning at end");
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::UpdateAI: reached end of waypoints, despawning at end (%s)", me->GetGUID().ToString().c_str());
if (_returnToStart)
{
Position respawnPosition;
@@ -179,14 +179,14 @@ void EscortAI::UpdateAI(uint32 diff)
me->GetRespawnPosition(respawnPosition.m_positionX, respawnPosition.m_positionY, respawnPosition.m_positionZ, &orientation);
respawnPosition.SetOrientation(orientation);
me->GetMotionMaster()->MovePoint(POINT_HOME, respawnPosition);
- TC_LOG_DEBUG("scripts", "EscortAI::UpdateAI: returning to spawn location: %s", respawnPosition.ToString().c_str());
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::UpdateAI: returning to spawn location: %s (%s)", respawnPosition.ToString().c_str(), me->GetGUID().ToString().c_str());
}
else if (_instantRespawn)
me->Respawn(true);
else
me->DespawnOrUnsummon();
}
- TC_LOG_DEBUG("scripts", "EscortAI::UpdateAI: reached end of waypoints");
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::UpdateAI: reached end of waypoints (%s)", me->GetGUID().ToString().c_str());
RemoveEscortState(STATE_ESCORT_ESCORTING);
return;
}
@@ -215,7 +215,7 @@ void EscortAI::UpdateAI(uint32 diff)
{
if (!IsPlayerOrGroupInRange())
{
- TC_LOG_DEBUG("scripts", "EscortAI::UpdateAI: failed because player/group was to far away or not found");
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::UpdateAI: failed because player/group was to far away or not found (%s)", me->GetGUID().ToString().c_str());
bool isEscort = false;
if (CreatureData const* creatureData = me->GetCreatureData())
@@ -290,15 +290,15 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */,
}
}
- if (me->GetVictim())
+ if (me->IsEngaged())
{
- TC_LOG_ERROR("scripts", "EscortAI::Start: (script: %s, creature entry: %u) attempts to Start while in combat", me->GetScriptName().c_str(), me->GetEntry());
+ TC_LOG_ERROR("scripts.ai.escortai", "EscortAI::Start: (script: %s) attempts to Start while in combat (%s)", me->GetScriptName().c_str(), me->GetGUID().ToString().c_str());
return;
}
if (HasEscortState(STATE_ESCORT_ESCORTING))
{
- TC_LOG_ERROR("scripts", "EscortAI::Start: (script: %s, creature entry: %u) attempts to Start while already escorting", me->GetScriptName().c_str(), me->GetEntry());
+ TC_LOG_ERROR("scripts.ai.escortai", "EscortAI::Start: (script: %s) attempts to Start while already escorting (%s)", me->GetScriptName().c_str(), me->GetGUID().ToString().c_str());
return;
}
@@ -309,7 +309,7 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */,
if (_path.nodes.empty())
{
- TC_LOG_ERROR("scripts", "EscortAI::Start: (script: %s, creature entry: %u) starts with 0 waypoints (possible missing entry in script_waypoint. Quest: %u).", me->GetScriptName().c_str(), me->GetEntry(), quest ? quest->GetQuestId() : 0);
+ TC_LOG_ERROR("scripts.ai.escortai", "EscortAI::Start: (script: %s) is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn (%s)", me->GetScriptName().c_str(), me->GetGUID().ToString().c_str());
return;
}
@@ -321,7 +321,7 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */,
_returnToStart = canLoopPath;
if (_returnToStart && _instantRespawn)
- TC_LOG_DEBUG("scripts", "EscortAI::Start: (script: %s, creature entry: %u) is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn.", me->GetScriptName().c_str(), me->GetEntry());
+ TC_LOG_ERROR("scripts.ai.escortai", "EscortAI::Start: (script: %s) is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn (%s)", me->GetScriptName().c_str(), me->GetGUID().ToString().c_str());
me->GetMotionMaster()->MoveIdle();
me->GetMotionMaster()->Clear(MOTION_PRIORITY_NORMAL);
@@ -335,7 +335,8 @@ void EscortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */,
me->SetImmuneToNPC(false);
}
- TC_LOG_DEBUG("scripts", "EscortAI::Start: (script: %s, creature entry: %u) started with %u waypoints. ActiveAttacker = %d, Run = %d, Player = %s", me->GetScriptName().c_str(), me->GetEntry(), uint32(_path.nodes.size()), _activeAttacker, _running, _playerGUID.ToString().c_str());
+ TC_LOG_DEBUG("scripts.ai.escortai", "EscortAI::Start: (script: %s) started with %u waypoints. ActiveAttacker = %d, Run = %d, Player = %s (%s)",
+ me->GetScriptName().c_str(), uint32(_path.nodes.size()), _activeAttacker, _running, _playerGUID.ToString().c_str(), me->GetGUID().ToString().c_str());
// set initial speed
me->SetWalk(!_running);
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
index 69bd4b5f6f3..903f81cc8d3 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SC_ESCORTAI_H
-#define SC_ESCORTAI_H
+#ifndef TRINITY_SCRIPTEDESCORTAI_H
+#define TRINITY_SCRIPTEDESCORTAI_H
#include "ScriptedCreature.h"
#include "WaypointDefines.h"
@@ -98,4 +98,5 @@ struct TC_GAME_API EscortAI : public ScriptedAI
bool _ended;
bool _resume;
};
+
#endif
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index 156daa0aed9..9e36c07ffa4 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -15,13 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: FollowerAI
-SD%Complete: 50
-SDComment: This AI is under development
-SDCategory: Npc
-EndScriptData */
-
#include "ScriptedFollowerAI.h"
#include "Creature.h"
#include "Group.h"
@@ -31,18 +24,14 @@ EndScriptData */
#include "ObjectAccessor.h"
#include "Player.h"
-const float MAX_PLAYER_DISTANCE = 100.0f;
+float constexpr MAX_PLAYER_DISTANCE = 100.0f;
enum Points
{
- POINT_COMBAT_START = 0xFFFFFF
+ POINT_COMBAT_START = 0xFFFFFF
};
-FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature),
- _updateFollowTimer(2500),
- _followState(STATE_FOLLOW_NONE),
- _questForFollow(nullptr)
-{ }
+FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature), _updateFollowTimer(2500), _followState(STATE_FOLLOW_NONE), _questForFollow(nullptr) { }
void FollowerAI::AttackStart(Unit* who)
{
@@ -61,27 +50,27 @@ void FollowerAI::AttackStart(Unit* who)
}
}
-//This part provides assistance to a player that are attacked by who, even if out of normal aggro range
-//It will cause me to attack who that are attacking _any_ player (which has been confirmed may happen also on offi)
-//The flag (type_flag) is unconfirmed, but used here for further research and is a good candidate.
+// This part provides assistance to a player that are attacked by who, even if out of normal aggro range
+// It will cause me to attack who that are attacking _any_ player (which has been confirmed may happen also on offi)
+// The flag (type_flag) is unconfirmed, but used here for further research and is a good candidate.
bool FollowerAI::AssistPlayerInCombatAgainst(Unit* who)
{
if (!who || !who->GetVictim())
return false;
- //experimental (unknown) flag not present
+ // experimental (unknown) flag not present
if (!(me->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_CAN_ASSIST))
return false;
- //not a player
+ // not a player
if (!who->EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
return false;
- //never attack friendly
+ // never attack friendly
if (me->IsFriendlyTo(who))
return false;
- //too far away and no free sight?
+ // too far away and no free sight?
if (me->IsWithinDistInMap(who, MAX_PLAYER_DISTANCE) && me->IsWithinLOSInMap(who))
{
me->EngageWithTarget(who);
@@ -166,14 +155,10 @@ void FollowerAI::EnterEvadeMode(EvadeReason /*why*/)
if (HasFollowState(STATE_FOLLOW_INPROGRESS))
{
- TC_LOG_DEBUG("scripts", "FollowerAI left combat, returning to CombatStartPosition.");
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::EnterEvadeMode: left combat, returning to CombatStartPosition. (%s)", me->GetGUID().ToString().c_str());
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
- {
- float fPosX, fPosY, fPosZ;
- me->GetPosition(fPosX, fPosY, fPosZ);
- me->GetMotionMaster()->MovePoint(POINT_COMBAT_START, fPosX, fPosY, fPosZ);
- }
+ me->GetMotionMaster()->MovePoint(POINT_COMBAT_START, me->GetPosition());
}
else
{
@@ -186,24 +171,24 @@ void FollowerAI::EnterEvadeMode(EvadeReason /*why*/)
void FollowerAI::UpdateAI(uint32 uiDiff)
{
- if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !me->GetVictim())
+ if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !me->IsEngaged())
{
if (_updateFollowTimer <= uiDiff)
{
if (HasFollowState(STATE_FOLLOW_COMPLETE) && !HasFollowState(STATE_FOLLOW_POSTEVENT))
{
- TC_LOG_DEBUG("scripts", "FollowerAI is set completed, despawns.");
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::UpdateAI: is set completed, despawns. (%s)", me->GetGUID().ToString().c_str());
me->DespawnOrUnsummon();
return;
}
- bool bIsMaxRangeExceeded = true;
+ bool maxRangeExceeded = true;
if (Player* player = GetLeaderForFollower())
{
if (HasFollowState(STATE_FOLLOW_RETURNING))
{
- TC_LOG_DEBUG("scripts", "FollowerAI is returning to leader.");
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::UpdateAI: is returning to leader. (%s)", me->GetGUID().ToString().c_str());
RemoveFollowState(STATE_FOLLOW_RETURNING);
me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
@@ -217,7 +202,7 @@ void FollowerAI::UpdateAI(uint32 uiDiff)
Player* member = groupRef->GetSource();
if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE))
{
- bIsMaxRangeExceeded = false;
+ maxRangeExceeded = false;
break;
}
}
@@ -225,13 +210,13 @@ void FollowerAI::UpdateAI(uint32 uiDiff)
else
{
if (me->IsWithinDistInMap(player, MAX_PLAYER_DISTANCE))
- bIsMaxRangeExceeded = false;
+ maxRangeExceeded = false;
}
}
- if (bIsMaxRangeExceeded)
+ if (maxRangeExceeded)
{
- TC_LOG_DEBUG("scripts", "FollowerAI failed because player/group was to far away or not found");
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::UpdateAI: failed because player/group was to far away or not found (%s)", me->GetGUID().ToString().c_str());
me->DespawnOrUnsummon();
return;
}
@@ -253,12 +238,12 @@ void FollowerAI::UpdateFollowerAI(uint32 /*uiDiff*/)
DoMeleeAttackIfReady();
}
-void FollowerAI::MovementInform(uint32 motionType, uint32 pointId)
+void FollowerAI::MovementInform(uint32 type, uint32 id)
{
- if (motionType != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS))
+ if (type != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS))
return;
- if (pointId == POINT_COMBAT_START)
+ if (id == POINT_COMBAT_START)
{
if (GetLeaderForFollower())
{
@@ -272,19 +257,19 @@ void FollowerAI::MovementInform(uint32 motionType, uint32 pointId)
void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest const* quest)
{
- if (me->GetVictim())
+ if (me->IsEngaged())
{
- TC_LOG_DEBUG("scripts", "FollowerAI attempt to StartFollow while in combat.");
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::StartFollow: attempt to StartFollow while in combat. (%s)", me->GetGUID().ToString().c_str());
return;
}
if (HasFollowState(STATE_FOLLOW_INPROGRESS))
{
- TC_LOG_ERROR("scripts", "FollowerAI attempt to StartFollow while already following.");
+ TC_LOG_ERROR("scripts.ai.followerai", "FollowerAI::StartFollow: attempt to StartFollow while already following. (%s)", me->GetGUID().ToString().c_str());
return;
}
- //set variables
+ // set variables
_leaderGUID = player->GetGUID();
if (factionForFollower)
@@ -296,7 +281,6 @@ void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest co
{
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveIdle();
- TC_LOG_DEBUG("scripts", "FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle.");
}
me->SetNpcFlags(UNIT_NPC_FLAG_NONE);
@@ -306,7 +290,7 @@ void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest co
me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- TC_LOG_DEBUG("scripts", "FollowerAI start follow %s (%s)", player->GetName().c_str(), _leaderGUID.ToString().c_str());
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::StartFollow: start follow %s - %s (%s)", player->GetName().c_str(), _leaderGUID.ToString().c_str(), me->GetGUID().ToString().c_str());
}
Player* FollowerAI::GetLeaderForFollower()
@@ -324,7 +308,7 @@ Player* FollowerAI::GetLeaderForFollower()
Player* member = groupRef->GetSource();
if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE) && member->IsAlive())
{
- TC_LOG_DEBUG("scripts", "FollowerAI GetLeader changed and returned new leader.");
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::GetLeaderForFollower: GetLeader changed and returned new leader. (%s)", me->GetGUID().ToString().c_str());
_leaderGUID = member->GetGUID();
return member;
}
@@ -333,11 +317,11 @@ Player* FollowerAI::GetLeaderForFollower()
}
}
- TC_LOG_DEBUG("scripts", "FollowerAI GetLeader can not find suitable leader.");
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::GetLeaderForFollower: GetLeader can not find suitable leader. (%s)", me->GetGUID().ToString().c_str());
return nullptr;
}
-void FollowerAI::SetFollowComplete(bool bWithEndEvent)
+void FollowerAI::SetFollowComplete(bool withEndEvent)
{
if (me->HasUnitState(UNIT_STATE_FOLLOW))
{
@@ -348,7 +332,7 @@ void FollowerAI::SetFollowComplete(bool bWithEndEvent)
me->GetMotionMaster()->MoveIdle();
}
- if (bWithEndEvent)
+ if (withEndEvent)
AddFollowState(STATE_FOLLOW_POSTEVENT);
else
{
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
index f0f8fbb26a1..775e67988f3 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
@@ -15,23 +15,22 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SC_FOLLOWERAI_H
-#define SC_FOLLOWERAI_H
+#ifndef TRINITY_SCRIPTEDFOLLOWERAI_H
+#define TRINITY_SCRIPTEDFOLLOWERAI_H
#include "ScriptedCreature.h"
-#include "ScriptSystem.h"
class Quest;
-enum eFollowState
+enum FollowerState : uint32
{
STATE_FOLLOW_NONE = 0x000,
- STATE_FOLLOW_INPROGRESS = 0x001, //must always have this state for any follow
- STATE_FOLLOW_RETURNING = 0x002, //when returning to combat start after being in combat
- STATE_FOLLOW_PAUSED = 0x004, //disables following
- STATE_FOLLOW_COMPLETE = 0x008, //follow is completed and may end
- STATE_FOLLOW_PREEVENT = 0x010, //not implemented (allow pre event to run, before follow is initiated)
- STATE_FOLLOW_POSTEVENT = 0x020 //can be set at complete and allow post event to run
+ STATE_FOLLOW_INPROGRESS = 0x001, // must always have this state for any follow
+ STATE_FOLLOW_RETURNING = 0x002, // when returning to combat start after being in combat
+ STATE_FOLLOW_PAUSED = 0x004, // disables following
+ STATE_FOLLOW_COMPLETE = 0x008, // follow is completed and may end
+ STATE_FOLLOW_PREEVENT = 0x010, // not implemented (allow pre event to run, before follow is initiated)
+ STATE_FOLLOW_POSTEVENT = 0x020 // can be set at complete and allow post event to run
};
class TC_GAME_API FollowerAI : public ScriptedAI
@@ -40,25 +39,22 @@ class TC_GAME_API FollowerAI : public ScriptedAI
explicit FollowerAI(Creature* creature);
~FollowerAI() { }
- void MovementInform(uint32 motionType, uint32 pointId) override;
-
+ void MovementInform(uint32 type, uint32 id) override;
void AttackStart(Unit*) override;
-
void MoveInLineOfSight(Unit*) override;
-
void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override;
-
void JustDied(Unit*) override;
-
void JustAppeared() override;
+ // the "internal" update, calls UpdateFollowerAI()
+ void UpdateAI(uint32) override;
- void UpdateAI(uint32) override; //the "internal" update, calls UpdateFollowerAI()
- virtual void UpdateFollowerAI(uint32); //used when it's needed to add code in update (abilities, scripted events, etc)
+ // used when it's needed to add code in update (abilities, scripted events, etc)
+ virtual void UpdateFollowerAI(uint32);
void StartFollow(Player* player, uint32 factionForFollower = 0, Quest const* quest = nullptr);
-
- void SetFollowPaused(bool bPaused); //if special event require follow mode to hold/resume during the follow
- void SetFollowComplete(bool bWithEndEvent = false);
+ // if special event require follow mode to hold/resume during the follow
+ void SetFollowPaused(bool paused);
+ void SetFollowComplete(bool withEndEvent = false);
bool HasFollowState(uint32 uiFollowState) { return (_followState & uiFollowState) != 0; }
@@ -66,9 +62,8 @@ class TC_GAME_API FollowerAI : public ScriptedAI
Player* GetLeaderForFollower();
private:
- void AddFollowState(uint32 uiFollowState) { _followState |= uiFollowState; }
- void RemoveFollowState(uint32 uiFollowState) { _followState &= ~uiFollowState; }
-
+ void AddFollowState(uint32 followState) { _followState |= followState; }
+ void RemoveFollowState(uint32 followState) { _followState &= ~followState; }
bool AssistPlayerInCombatAgainst(Unit* who);
ObjectGuid _leaderGUID;
diff --git a/src/server/game/AI/ScriptedAI/ScriptedGossip.h b/src/server/game/AI/ScriptedAI/ScriptedGossip.h
index 5e82ef115e8..15d72787e76 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedGossip.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedGossip.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SC_GOSSIP_H
-#define SC_GOSSIP_H
+#ifndef TRINITY_SCRIPTEDGOSSIP_H
+#define TRINITY_SCRIPTEDGOSSIP_H
#include "Define.h"
#include "GossipDef.h"
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 4218ca172ae..b1c46fc8abc 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -45,9 +45,9 @@ bool SmartAI::IsAIControlled() const
void SmartAI::StartPath(bool run/* = false*/, uint32 pathId/* = 0*/, bool repeat/* = false*/, Unit* invoker/* = nullptr*/, uint32 nodeId/* = 1*/)
{
- if (me->IsInCombat()) // no wp movement in combat
+ if (me->IsEngaged()) // no wp movement in combat
{
- TC_LOG_ERROR("scripts.ai.sai", "SmartAI::StartPath: Creature entry %u wanted to start waypoint movement (%u) while in combat, ignoring.", me->GetEntry(), pathId);
+ TC_LOG_ERROR("scripts.ai.sai", "SmartAI::StartPath: Creature wanted to start waypoint movement (pathId: %u) while in combat, ignoring. (%s)", pathId, me->GetGUID().ToString().c_str());
return;
}
@@ -124,7 +124,7 @@ void SmartAI::PausePath(uint32 delay, bool forced)
if (HasEscortState(SMART_ESCORT_PAUSED))
{
- TC_LOG_ERROR("scripts.ai.sai", "SmartAI::PausePath: Creature entry %u wanted to pause waypoint (current waypoint: %u) movement while already paused, ignoring.", me->GetEntry(), _currentWaypointNode);
+ TC_LOG_ERROR("scripts.ai.sai", "SmartAI::PausePath: Creature wanted to pause waypoint (current waypoint: %u) movement while already paused, ignoring. (%s)", _currentWaypointNode, me->GetGUID().ToString().c_str());
return;
}
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 26658533b2a..806902d9072 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -26,25 +26,22 @@
#include "SmartScript.h"
#include "WaypointDefines.h"
-enum SmartEscortState
+enum SmartEscortState : uint8
{
- 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
+ SMART_ESCORT_NONE = 0x00, // nothing in progress
+ SMART_ESCORT_ESCORTING = 0x01, // escort is in progress
+ SMART_ESCORT_RETURNING = 0x02, // escort is returning after being in combat
+ SMART_ESCORT_PAUSED = 0x04 // 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
-};
+static float constexpr SMART_ESCORT_MAX_PLAYER_DIST = 60.f;
+static float constexpr SMART_MAX_AID_DIST = SMART_ESCORT_MAX_PLAYER_DIST / 2.f;
class TC_GAME_API SmartAI : public CreatureAI
{
public:
~SmartAI() { }
- explicit SmartAI(Creature* c, uint32 scriptId = {});
+ explicit SmartAI(Creature* creature, uint32 scriptId = {});
// core related
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
@@ -59,9 +56,9 @@ class TC_GAME_API SmartAI : public CreatureAI
void StopPath(uint32 DespawnTime = 0, uint32 quest = 0, bool fail = false);
void EndPath(bool fail = false);
void ResumePath();
- bool HasEscortState(uint32 uiEscortState) const { return (_escortState & uiEscortState) != 0; }
- void AddEscortState(uint32 uiEscortState) { _escortState |= uiEscortState; }
- void RemoveEscortState(uint32 uiEscortState) { _escortState &= ~uiEscortState; }
+ bool HasEscortState(uint32 escortState) const { return (_escortState & escortState) != 0; }
+ void AddEscortState(uint32 escortState) { _escortState |= escortState; }
+ void RemoveEscortState(uint32 escortState) { _escortState &= ~escortState; }
void SetAutoAttack(bool on) { _canAutoAttack = on; }
void SetCombatMove(bool on);
bool CanCombatMove() { return _canCombatMove; }
@@ -246,7 +243,7 @@ class TC_GAME_API SmartAI : public CreatureAI
class TC_GAME_API SmartGameObjectAI : public GameObjectAI
{
public:
- SmartGameObjectAI(GameObject* g, uint32 scriptId = {}) : GameObjectAI(g, scriptId), _gossipReturn(false) { }
+ SmartGameObjectAI(GameObject* go, uint32 scriptId = {}) : GameObjectAI(go, scriptId), _gossipReturn(false) { }
~SmartGameObjectAI() { }
void UpdateAI(uint32 diff) override;
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index e99fc1d2a72..dae37eb54eb 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -4082,6 +4082,9 @@ Logger.mmaps=3,Server
#Logger.scenes=3,Console Server
#Logger.scripts=3,Console Server
#Logger.scripts.ai=3,Console Server
+#Logger.scripts.ai.escortai=3,Console Server
+#Logger.scripts.ai.followerai=3,Console Server
+#Logger.scripts.ai.petai=3,Console Server
#Logger.scripts.ai.sai=3,Console Server
#Logger.server.bnetserver=3,Console Server
#Logger.spells=3,Console Server