aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/AI/ScriptedAI
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/AI/ScriptedAI')
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp56
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h39
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp23
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.h7
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp22
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h7
6 files changed, 102 insertions, 52 deletions
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 5464b99f8c9..d32ac53cb9f 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -17,13 +17,19 @@
*/
#include "ScriptedCreature.h"
-#include "Spell.h"
-#include "GridNotifiers.h"
-#include "GridNotifiersImpl.h"
+#include "AreaBoundary.h"
#include "Cell.h"
#include "CellImpl.h"
-#include "ObjectMgr.h"
-#include "AreaBoundary.h"
+#include "DBCStores.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "InstanceScript.h"
+#include "Log.h"
+#include "MotionMaster.h"
+#include "ObjectAccessor.h"
+#include "Spell.h"
+#include "SpellMgr.h"
+#include "TemporarySummon.h"
// Spell summary for ScriptedAI::SelectSpell
struct TSpellSummary
@@ -32,6 +38,16 @@ struct TSpellSummary
uint8 Effects; // set of enum SelectEffect
} extern* SpellSummary;
+void SummonList::Summon(Creature const* summon)
+{
+ storage_.push_back(summon->GetGUID());
+}
+
+void SummonList::Despawn(Creature const* summon)
+{
+ storage_.remove(summon->GetGUID());
+}
+
void SummonList::DoZoneInCombat(uint32 entry, float maxRangeToNearestTarget)
{
for (StorageType::iterator i = storage_.begin(); i != storage_.end();)
@@ -97,6 +113,16 @@ bool SummonList::HasEntry(uint32 entry) const
return false;
}
+void SummonList::DoActionImpl(int32 action, StorageType const& summons)
+{
+ for (auto const& guid : summons)
+ {
+ Creature* summon = ObjectAccessor::GetCreature(*me, guid);
+ if (summon && summon->IsAIEnabled)
+ summon->AI()->DoAction(action);
+ }
+}
+
ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature),
IsFleeing(false),
_isCombatMovementAllowed(true)
@@ -179,6 +205,16 @@ Creature* ScriptedAI::DoSpawnCreature(uint32 entry, float offsetX, float offsetY
return me->SummonCreature(entry, me->GetPositionX() + offsetX, me->GetPositionY() + offsetY, me->GetPositionZ() + offsetZ, angle, TempSummonType(type), despawntime);
}
+bool ScriptedAI::HealthBelowPct(uint32 pct) const
+{
+ return me->HealthBelowPct(pct);
+}
+
+bool ScriptedAI::HealthAbovePct(uint32 pct) const
+{
+ return me->HealthAbovePct(pct);
+}
+
SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect effects)
{
//No target so we can't cast
@@ -444,6 +480,11 @@ void BossAI::_JustDied()
instance->SetBossState(_bossId, DONE);
}
+void BossAI::_JustReachedHome()
+{
+ me->setActive(false);
+}
+
void BossAI::_EnterCombat()
{
if (instance)
@@ -507,6 +548,11 @@ void BossAI::UpdateAI(uint32 diff)
DoMeleeAttackIfReady();
}
+bool BossAI::CanAIAttack(Unit const* target) const
+{
+ return CheckBoundary(target);
+}
+
void BossAI::_DespawnAtEvade(uint32 delayToRespawn /*= 30*/, Creature* who /*= nullptr*/)
{
if (delayToRespawn < 2)
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index b4db664a980..3b24203a146 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -19,23 +19,11 @@
#ifndef SCRIPTEDCREATURE_H_
#define SCRIPTEDCREATURE_H_
-#include "Creature.h"
#include "CreatureAI.h"
-#include "CreatureAIImpl.h"
-#include "InstanceScript.h"
+#include "Creature.h" // convenience include for scripts, all uses of ScriptedCreature also need Creature (except ScriptedCreature itself doesn't need Creature)
+#include "DBCEnums.h"
#include "TaskScheduler.h"
-#define CAST_AI(a, b) (dynamic_cast<a*>(b))
-#define ENSURE_AI(a,b) (EnsureAI<a>(b))
-
-template<class T, class U>
-T* EnsureAI(U* ai)
-{
- T* cast_ai = dynamic_cast<T*>(ai);
- ASSERT(cast_ai);
- return cast_ai;
-};
-
class InstanceScript;
class TC_GAME_API SummonList
@@ -95,13 +83,13 @@ public:
storage_.clear();
}
- void Summon(Creature const* summon) { storage_.push_back(summon->GetGUID()); }
- void Despawn(Creature const* summon) { storage_.remove(summon->GetGUID()); }
+ void Summon(Creature const* summon);
+ void Despawn(Creature const* summon);
void DespawnEntry(uint32 entry);
void DespawnAll();
template <typename T>
- void DespawnIf(T const &predicate)
+ void DespawnIf(T const& predicate)
{
storage_.remove_if(predicate);
}
@@ -112,12 +100,7 @@ public:
// We need to use a copy of SummonList here, otherwise original SummonList would be modified
StorageType listCopy = storage_;
Trinity::Containers::RandomResize<StorageType, Predicate>(listCopy, std::forward<Predicate>(predicate), max);
- for (StorageType::iterator i = listCopy.begin(); i != listCopy.end(); )
- {
- Creature* summon = ObjectAccessor::GetCreature(*me, *i++);
- if (summon && summon->IsAIEnabled)
- summon->AI()->DoAction(info);
- }
+ DoActionImpl(info, listCopy);
}
void DoZoneInCombat(uint32 entry = 0, float maxRangeToNearestTarget = 250.0f);
@@ -125,6 +108,8 @@ public:
bool HasEntry(uint32 entry) const;
private:
+ void DoActionImpl(int32 action, StorageType const& summons);
+
Creature* me;
StorageType storage_;
};
@@ -256,8 +241,8 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
//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 { return me->HealthBelowPct(pct); }
- bool HealthAbovePct(uint32 pct) const { return me->HealthAbovePct(pct); }
+ bool HealthBelowPct(uint32 pct) const;
+ bool HealthAbovePct(uint32 pct) const;
//Returns spells that meet the specified criteria from the creatures spell list
SpellInfo const* SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect effect);
@@ -369,13 +354,13 @@ class TC_GAME_API BossAI : public ScriptedAI
void JustDied(Unit* /*killer*/) override { _JustDied(); }
void JustReachedHome() override { _JustReachedHome(); }
- bool CanAIAttack(Unit const* target) const override { return CheckBoundary(target); }
+ bool CanAIAttack(Unit const* target) const override;
protected:
void _Reset();
void _EnterCombat();
void _JustDied();
- void _JustReachedHome() { me->setActive(false); }
+ void _JustReachedHome();
void _DespawnAtEvade(uint32 delayToRespawn = 30, Creature* who = nullptr);
void _DespawnAtEvade(Seconds const& time, Creature* who = nullptr) { _DespawnAtEvade(uint32(time.count()), who); }
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index 085ef9c4047..6f5b7f1aa71 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -23,10 +23,14 @@ SDComment:
SDCategory: Npc
EndScriptData */
-#include "Player.h"
-#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
+#include "Creature.h"
#include "Group.h"
+#include "Log.h"
+#include "Map.h"
+#include "MotionMaster.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
enum Points
{
@@ -39,7 +43,7 @@ npc_escortAI::npc_escortAI(Creature* creature) : ScriptedAI(creature),
m_uiPlayerCheckTimer(1000),
m_uiEscortState(STATE_ESCORT_NONE),
MaxPlayerDistance(DEFAULT_MAX_PLAYER_DISTANCE),
- m_pQuestForEscort(NULL),
+ m_pQuestForEscort(nullptr),
m_bIsActiveAttacker(true),
m_bIsRunning(false),
m_bCanInstantRespawn(false),
@@ -65,6 +69,11 @@ void npc_escortAI::AttackStart(Unit* who)
}
}
+Player* npc_escortAI::GetPlayerForEscort()
+{
+ return ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID);
+}
+
//see followerAI
bool npc_escortAI::AssistPlayerInCombatAgainst(Unit* who)
{
@@ -148,7 +157,7 @@ void npc_escortAI::JustDied(Unit* /*killer*/)
{
if (Group* group = player->GetGroup())
{
- for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
if (Player* member = groupRef->GetSource())
if (member->IsInMap(player))
member->FailQuest(m_pQuestForEscort->GetQuestId());
@@ -186,7 +195,7 @@ void npc_escortAI::EnterEvadeMode(EvadeReason /*why*/)
me->RemoveAllAuras();
me->DeleteThreatList();
me->CombatStop(true);
- me->SetLootRecipient(NULL);
+ me->SetLootRecipient(nullptr);
if (HasEscortState(STATE_ESCORT_ESCORTING))
{
@@ -209,7 +218,7 @@ bool npc_escortAI::IsPlayerOrGroupInRange()
{
if (Group* group = player->GetGroup())
{
- for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
if (Player* member = groupRef->GetSource())
if (me->IsWithinDistInMap(member, GetMaxPlayerDistance()))
return true;
@@ -431,7 +440,7 @@ void npc_escortAI::SetRun(bool on)
}
/// @todo get rid of this many variables passed in function.
-void npc_escortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, ObjectGuid playerGUID /* = 0 */, Quest const* quest /* = NULL */, bool instantRespawn /* = false */, bool canLoopPath /* = false */, bool resetWaypoints /* = true */)
+void npc_escortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, ObjectGuid playerGUID /* = 0 */, Quest const* quest /* = nullptr */, bool instantRespawn /* = false */, bool canLoopPath /* = false */, bool resetWaypoints /* = true */)
{
if (me->GetVictim())
{
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
index e1bf3af5343..754d96dced9 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
@@ -19,8 +19,11 @@
#ifndef SC_ESCORTAI_H
#define SC_ESCORTAI_H
+#include "ScriptedCreature.h"
#include "ScriptSystem.h"
+class Quest;
+
#define DEFAULT_MAX_PLAYER_DISTANCE 50
struct Escort_Waypoint
@@ -88,7 +91,7 @@ struct TC_GAME_API npc_escortAI : public ScriptedAI
virtual void WaypointReached(uint32 pointId) = 0;
virtual void WaypointStart(uint32 /*pointId*/) { }
- void Start(bool isActiveAttacker = true, bool run = false, ObjectGuid playerGUID = ObjectGuid::Empty, Quest const* quest = NULL, bool instantRespawn = false, bool canLoopPath = false, bool resetWaypoints = true);
+ void Start(bool isActiveAttacker = true, bool run = false, ObjectGuid playerGUID = ObjectGuid::Empty, Quest const* quest = nullptr, bool instantRespawn = false, bool canLoopPath = false, bool resetWaypoints = true);
void SetRun(bool on = true);
void SetEscortPaused(bool on);
@@ -106,7 +109,7 @@ struct TC_GAME_API npc_escortAI : public ScriptedAI
ObjectGuid GetEventStarterGUID() const { return m_uiPlayerGUID; }
protected:
- Player* GetPlayerForEscort() { return ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID); }
+ Player* GetPlayerForEscort();
private:
bool AssistPlayerInCombatAgainst(Unit* who);
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index 79c3c17d610..d18876fc439 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -23,10 +23,14 @@ SDComment: This AI is under development
SDCategory: Npc
EndScriptData */
-#include "Player.h"
-#include "ScriptedCreature.h"
#include "ScriptedFollowerAI.h"
+#include "Creature.h"
#include "Group.h"
+#include "Log.h"
+#include "Map.h"
+#include "MotionMaster.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
const float MAX_PLAYER_DISTANCE = 100.0f;
@@ -38,7 +42,7 @@ enum Points
FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature),
m_uiUpdateFollowTimer(2500),
m_uiFollowState(STATE_FOLLOW_NONE),
- m_pQuestForFollow(NULL)
+ m_pQuestForFollow(nullptr)
{ }
void FollowerAI::AttackStart(Unit* who)
@@ -146,7 +150,7 @@ void FollowerAI::JustDied(Unit* /*killer*/)
{
if (Group* group = player->GetGroup())
{
- for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
if (Player* member = groupRef->GetSource())
if (member->IsInMap(player))
member->FailQuest(m_pQuestForFollow->GetQuestId());
@@ -174,7 +178,7 @@ void FollowerAI::EnterEvadeMode(EvadeReason /*why*/)
me->RemoveAllAuras();
me->DeleteThreatList();
me->CombatStop(true);
- me->SetLootRecipient(NULL);
+ me->SetLootRecipient(nullptr);
if (HasFollowState(STATE_FOLLOW_INPROGRESS))
{
@@ -224,7 +228,7 @@ void FollowerAI::UpdateAI(uint32 uiDiff)
if (Group* group = player->GetGroup())
{
- for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
{
Player* member = groupRef->GetSource();
if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE))
@@ -282,7 +286,7 @@ void FollowerAI::MovementInform(uint32 motionType, uint32 pointId)
}
}
-void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, const Quest* quest)
+void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest const* quest)
{
if (me->GetVictim())
{
@@ -330,7 +334,7 @@ Player* FollowerAI::GetLeaderForFollower()
{
if (Group* group = player->GetGroup())
{
- for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
{
Player* member = groupRef->GetSource();
if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE) && member->IsAlive())
@@ -345,7 +349,7 @@ Player* FollowerAI::GetLeaderForFollower()
}
TC_LOG_DEBUG("scripts", "FollowerAI GetLeader can not find suitable leader.");
- return NULL;
+ return nullptr;
}
void FollowerAI::SetFollowComplete(bool bWithEndEvent)
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
index 6b5b06490f0..7fe877a7589 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
@@ -19,8 +19,11 @@
#ifndef SC_FOLLOWERAI_H
#define SC_FOLLOWERAI_H
+#include "ScriptedCreature.h"
#include "ScriptSystem.h"
+class Quest;
+
enum eFollowState
{
STATE_FOLLOW_NONE = 0x000,
@@ -55,7 +58,7 @@ class TC_GAME_API FollowerAI : public ScriptedAI
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)
- void StartFollow(Player* player, uint32 factionForFollower = 0, const Quest* quest = NULL);
+ 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);
@@ -75,7 +78,7 @@ class TC_GAME_API FollowerAI : public ScriptedAI
uint32 m_uiUpdateFollowTimer;
uint32 m_uiFollowState;
- const Quest* m_pQuestForFollow; //normally we have a quest
+ Quest const* m_pQuestForFollow; //normally we have a quest
};
#endif