feat(Core/SAI): SetData now has invoker (#19296)
* cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/cfc77fd84355d28737f3f85f2ba318be5caacdea) * cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/beb333738db0d493bf95994eb5557e174e5dd3a6) * Move IsSmart function from headerfile Co-authored-by: Treeston <14020072+Treeston@users.noreply.github.com> Co-authored-by: Shauren <shauren.trinity@gmail.com>
This commit is contained in:
@@ -23,6 +23,17 @@
|
|||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#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 Player;
|
class Player;
|
||||||
class Quest;
|
class Quest;
|
||||||
class Unit;
|
class Unit;
|
||||||
|
|||||||
@@ -25,8 +25,6 @@
|
|||||||
#include "InstanceScript.h"
|
#include "InstanceScript.h"
|
||||||
#include "TaskScheduler.h"
|
#include "TaskScheduler.h"
|
||||||
|
|
||||||
#define CAST_AI(a, b) (dynamic_cast<a*>(b))
|
|
||||||
|
|
||||||
typedef std::list<WorldObject*> ObjectList;
|
typedef std::list<WorldObject*> ObjectList;
|
||||||
|
|
||||||
class InstanceScript;
|
class InstanceScript;
|
||||||
|
|||||||
@@ -962,9 +962,9 @@ uint32 SmartAI::GetData(uint32 /*id*/) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmartAI::SetData(uint32 id, uint32 value)
|
void SmartAI::SetData(uint32 id, uint32 value, Unit* invoker)
|
||||||
{
|
{
|
||||||
GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, nullptr, id, value);
|
GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmartAI::SetGUID(ObjectGuid /*guid*/, int32 /*id*/)
|
void SmartAI::SetGUID(ObjectGuid /*guid*/, int32 /*id*/)
|
||||||
@@ -1232,9 +1232,9 @@ void SmartGameObjectAI::Destroyed(Player* player, uint32 eventId)
|
|||||||
GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, player, eventId, 0, false, nullptr, me);
|
GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, player, eventId, 0, false, nullptr, me);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmartGameObjectAI::SetData(uint32 id, uint32 value)
|
void SmartGameObjectAI::SetData(uint32 id, uint32 value, Unit* invoker)
|
||||||
{
|
{
|
||||||
GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, nullptr, id, value);
|
GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmartGameObjectAI::SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker)
|
void SmartGameObjectAI::SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker)
|
||||||
|
|||||||
@@ -159,7 +159,8 @@ public:
|
|||||||
uint32 GetData(uint32 id = 0) const override;
|
uint32 GetData(uint32 id = 0) const override;
|
||||||
|
|
||||||
// Used in scripts to share variables
|
// Used in scripts to share variables
|
||||||
void SetData(uint32 id, uint32 value) override;
|
void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
|
||||||
|
void SetData(uint32 id, uint32 value, Unit* invoker);
|
||||||
|
|
||||||
// Used in scripts to share variables
|
// Used in scripts to share variables
|
||||||
void SetGUID(ObjectGuid guid, int32 id = 0) override;
|
void SetGUID(ObjectGuid guid, int32 id = 0) override;
|
||||||
@@ -272,7 +273,8 @@ public:
|
|||||||
bool QuestAccept(Player* player, Quest const* quest) override;
|
bool QuestAccept(Player* player, Quest const* quest) override;
|
||||||
bool QuestReward(Player* player, Quest const* quest, uint32 opt) override;
|
bool QuestReward(Player* player, Quest const* quest, uint32 opt) override;
|
||||||
void Destroyed(Player* player, uint32 eventId) override;
|
void Destroyed(Player* player, uint32 eventId) override;
|
||||||
void SetData(uint32 id, uint32 value) override;
|
void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
|
||||||
|
void SetData(uint32 id, uint32 value, Unit* invoker);
|
||||||
void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
|
void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
|
||||||
void OnGameEvent(bool start, uint16 eventId) override;
|
void OnGameEvent(bool start, uint16 eventId) override;
|
||||||
void OnStateChanged(uint32 state, Unit* unit) override;
|
void OnStateChanged(uint32 state, Unit* unit) override;
|
||||||
|
|||||||
@@ -63,7 +63,46 @@ SmartScript::SmartScript()
|
|||||||
|
|
||||||
SmartScript::~SmartScript()
|
SmartScript::~SmartScript()
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SmartScript::IsSmart(Creature* c, bool silent) const
|
||||||
|
{
|
||||||
|
if (!c)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool smart = true;
|
||||||
|
if (!dynamic_cast<SmartAI*>(c->AI()))
|
||||||
|
smart = false;
|
||||||
|
|
||||||
|
if (!smart && !silent)
|
||||||
|
LOG_ERROR("sql.sql", "SmartScript: Action target Creature(entry: {}) is not using SmartAI, action skipped to prevent crash.", c ? c->GetEntry() : (me ? me->GetEntry() : 0));
|
||||||
|
|
||||||
|
return smart;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SmartScript::IsSmart(GameObject* g, bool silent) const
|
||||||
|
{
|
||||||
|
if (!g)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool smart = true;
|
||||||
|
if (!dynamic_cast<SmartGameObjectAI*>(g->AI()))
|
||||||
|
smart = false;
|
||||||
|
|
||||||
|
if (!smart && !silent)
|
||||||
|
LOG_ERROR("sql.sql", "SmartScript: Action target GameObject(entry: {}) is not using SmartGameObjectAI, action skipped to prevent crash.", g ? g->GetEntry() : (go ? go->GetEntry() : 0));
|
||||||
|
|
||||||
|
return smart;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SmartScript::IsSmart(bool silent) const
|
||||||
|
{
|
||||||
|
if (me)
|
||||||
|
return IsSmart(me, silent);
|
||||||
|
if (go)
|
||||||
|
return IsSmart(go, silent);
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmartScript::OnReset()
|
void SmartScript::OnReset()
|
||||||
@@ -1355,10 +1394,22 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
{
|
{
|
||||||
for (WorldObject* target : targets)
|
for (WorldObject* target : targets)
|
||||||
{
|
{
|
||||||
if (IsCreature(target))
|
if (Creature* cTarget = target->ToCreature())
|
||||||
target->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data);
|
{
|
||||||
else if (IsGameObject(target))
|
CreatureAI* ai = cTarget->AI();
|
||||||
target->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data);
|
if (IsSmart(cTarget))
|
||||||
|
ENSURE_AI(SmartAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me);
|
||||||
|
else
|
||||||
|
ai->SetData(e.action.setData.field, e.action.setData.data);
|
||||||
|
}
|
||||||
|
else if (GameObject* oTarget = target->ToGameObject())
|
||||||
|
{
|
||||||
|
GameObjectAI* ai = oTarget->AI();
|
||||||
|
if (IsSmart(oTarget))
|
||||||
|
ENSURE_AI(SmartGameObjectAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me);
|
||||||
|
else
|
||||||
|
ai->SetData(e.action.setData.field, e.action.setData.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1974,7 +2025,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
}
|
}
|
||||||
else if (GameObject* go = target->ToGameObject())
|
else if (GameObject* go = target->ToGameObject())
|
||||||
{
|
{
|
||||||
if (IsSmartGO(go))
|
if (IsSmart(go))
|
||||||
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
|
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2061,7 +2112,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
}
|
}
|
||||||
else if (GameObject* go = target->ToGameObject())
|
else if (GameObject* go = target->ToGameObject())
|
||||||
{
|
{
|
||||||
if (IsSmartGO(go))
|
if (IsSmart(go))
|
||||||
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker());
|
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2085,7 +2136,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
}
|
}
|
||||||
else if (GameObject* go = target->ToGameObject())
|
else if (GameObject* go = target->ToGameObject())
|
||||||
{
|
{
|
||||||
if (IsSmartGO(go))
|
if (IsSmart(go))
|
||||||
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker());
|
CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ public:
|
|||||||
void DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, float range, uint32 spellid) const;
|
void DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, float range, uint32 spellid) const;
|
||||||
Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly) const;
|
Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly) const;
|
||||||
|
|
||||||
|
bool IsSmart(Creature* c, bool silent = false) const;
|
||||||
|
bool IsSmart(GameObject* g, bool silent = false) const;
|
||||||
|
bool IsSmart(bool silent = false) const;
|
||||||
|
|
||||||
void StoreTargetList(ObjectVector const& targets, uint32 id)
|
void StoreTargetList(ObjectVector const& targets, uint32 id)
|
||||||
{
|
{
|
||||||
// insert or replace
|
// insert or replace
|
||||||
@@ -83,35 +87,6 @@ public:
|
|||||||
_storedTargets.emplace(id, ObjectGuidVector(targets));
|
_storedTargets.emplace(id, ObjectGuidVector(targets));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSmart(Creature* c = nullptr)
|
|
||||||
{
|
|
||||||
bool smart = true;
|
|
||||||
if (c && c->GetAIName() != "SmartAI")
|
|
||||||
smart = false;
|
|
||||||
|
|
||||||
if (!me || me->GetAIName() != "SmartAI")
|
|
||||||
smart = false;
|
|
||||||
|
|
||||||
if (!smart)
|
|
||||||
LOG_ERROR("sql.sql", "SmartScript: Action target Creature(entry: {}) is not using SmartAI, action skipped to prevent crash.", c ? c->GetEntry() : (me ? me->GetEntry() : 0));
|
|
||||||
|
|
||||||
return smart;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSmartGO(GameObject* g = nullptr)
|
|
||||||
{
|
|
||||||
bool smart = true;
|
|
||||||
if (g && g->GetAIName() != "SmartGameObjectAI")
|
|
||||||
smart = false;
|
|
||||||
|
|
||||||
if (!go || go->GetAIName() != "SmartGameObjectAI")
|
|
||||||
smart = false;
|
|
||||||
if (!smart)
|
|
||||||
LOG_ERROR("sql.sql", "SmartScript: Action target GameObject(entry: {}) is not using SmartGameObjectAI, action skipped to prevent crash.", g ? g->GetEntry() : (go ? go->GetEntry() : 0));
|
|
||||||
|
|
||||||
return smart;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectVector const* GetStoredTargetVector(uint32 id, WorldObject const& ref) const
|
ObjectVector const* GetStoredTargetVector(uint32 id, WorldObject const& ref) const
|
||||||
{
|
{
|
||||||
auto itr = _storedTargets.find(id);
|
auto itr = _storedTargets.find(id);
|
||||||
|
|||||||
@@ -346,6 +346,7 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
|||||||
case SMART_EVENT_TRANSPORT_ADDCREATURE:
|
case SMART_EVENT_TRANSPORT_ADDCREATURE:
|
||||||
case SMART_EVENT_NEAR_PLAYERS:
|
case SMART_EVENT_NEAR_PLAYERS:
|
||||||
case SMART_EVENT_SUMMONED_UNIT_EVADE:
|
case SMART_EVENT_SUMMONED_UNIT_EVADE:
|
||||||
|
case SMART_EVENT_DATA_SET:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user