Scripts/SmartAI: SetData now has an invoker (if the setting is done by something using SmartAI).

Also, some refactors. SMARTAI IS SUCH A FUCKING CLUSTERFUCK I SWEAR.
This commit is contained in:
Treeston
2018-02-15 11:44:37 +01:00
parent b9aec3b4d3
commit cfc77fd843
5 changed files with 53 additions and 24 deletions

View File

@@ -692,9 +692,9 @@ uint32 SmartAI::GetData(uint32 /*id*/) const
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 const& /*guid*/, int32 /*id*/) { }
@@ -1028,9 +1028,9 @@ void SmartGameObjectAI::Destroyed(Player* player, uint32 eventId)
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::SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker)

View File

@@ -149,7 +149,8 @@ class TC_GAME_API SmartAI : public CreatureAI
uint32 GetData(uint32 id = 0) const override;
// 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
void SetGUID(ObjectGuid const& guid, int32 id = 0) override;
@@ -261,7 +262,8 @@ class TC_GAME_API SmartGameObjectAI : public GameObjectAI
void QuestAccept(Player* player, Quest const* quest) override;
void QuestReward(Player* player, Quest const* quest, uint32 opt) override;
void Destroyed(Player* player, uint32 eventId) override;
void SetData(uint32 id, uint32 value) override;
void SetData(uint32 id, uint32 value, Unit* invoker);
void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
void SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker);
void OnGameEvent(bool start, uint16 eventId) override;
void OnLootStateChanged(uint32 state, Unit* unit) override;

View File

@@ -62,35 +62,48 @@ SmartScript::~SmartScript()
{
}
bool SmartScript::IsSmart(Creature* c /*= nullptr*/)
// @todo this is an utter clusterfuck in terms of design - why in the world does this thing side effect?
// seriously, WHO WRITES THIS SHIT
bool SmartScript::IsSmart(Creature* c, bool silent)
{
if (!c)
return false;
bool smart = true;
if (c && c->GetAIName() != "SmartAI")
smart = false;
if (!me || me->GetAIName() != "SmartAI")
smart = false;
if (!smart)
if (!smart && !silent)
TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: %u Entry: %u) is not using SmartAI, action called by Creature (GUID: %u Entry: %u) skipped to prevent crash.", c ? c->GetSpawnId() : 0, c ? c->GetEntry() : 0, me ? me->GetSpawnId() : 0, me ? me->GetEntry() : 0);
return smart;
}
bool SmartScript::IsSmartGO(GameObject* g /*= nullptr*/)
// @todo this, too
bool SmartScript::IsSmart(GameObject* g, bool silent)
{
if (!g)
return false;
bool smart = true;
if (g && g->GetAIName() != "SmartGameObjectAI")
smart = false;
if (!go || go->GetAIName() != "SmartGameObjectAI")
smart = false;
if (!smart)
if (!smart && !silent)
TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: %u Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: %u Entry: %u) skipped to prevent crash.", g ? g->GetSpawnId() : 0, g ? g->GetEntry() : 0, go ? go->GetSpawnId() : 0, go ? go->GetEntry() : 0);
return smart;
}
bool SmartScript::IsSmart(bool silent)
{
if (me)
return IsSmart(me, silent);
if (go)
return IsSmart(go, silent);
return false;
}
void SmartScript::StoreTargetList(ObjectVector const& targets, uint32 id)
{
// insert or replace
@@ -1102,10 +1115,22 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
for (WorldObject* target : targets)
{
if (IsCreature(target))
target->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data);
else if (IsGameObject(target))
target->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data);
if (Creature* cTarget = target->ToCreature())
{
CreatureAI* ai = cTarget->AI();
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;
}
@@ -1593,7 +1618,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
else if (GameObject* goTarget = target->ToGameObject())
{
if (IsSmartGO(goTarget))
if (IsSmart(goTarget))
ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetTimedActionList(e, e.action.timedActionList.id, GetLastInvoker());
}
}
@@ -1680,7 +1705,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
else if (GameObject* goTarget = target->ToGameObject())
{
if (IsSmartGO(goTarget))
if (IsSmart(goTarget))
ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetTimedActionList(e, id, GetLastInvoker());
}
}
@@ -1704,7 +1729,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
else if (GameObject* goTarget = target->ToGameObject())
{
if (IsSmartGO(goTarget))
if (IsSmart(goTarget))
ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetTimedActionList(e, id, GetLastInvoker());
}
}

View File

@@ -69,8 +69,9 @@ class TC_GAME_API SmartScript
void DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, float range, uint32 spellid) const;
Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly) const;
bool IsSmart(Creature* c = nullptr);
bool IsSmartGO(GameObject* g = nullptr);
bool IsSmart(Creature* c, bool silent = false);
bool IsSmart(GameObject* g, bool silent = false);
bool IsSmart(bool silent = false);
void StoreTargetList(ObjectVector const& targets, uint32 id);
ObjectVector const* GetStoredTargetVector(uint32 id, WorldObject const& ref) const;

View File

@@ -452,6 +452,7 @@ SmartScriptHolder& SmartAIMgr::FindLinkedEvent(SmartAIEventList& list, uint32 li
case SMART_EVENT_IS_BEHIND_TARGET:
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
case SMART_EVENT_TRANSPORT_ADDCREATURE:
case SMART_EVENT_DATA_SET:
return true;
default:
return false;