Skip to content

Commit

Permalink
fix(Core/SmartAI) : use explicit stack DS for ProcessAction instead o…
Browse files Browse the repository at this point in the history
…f recursion (azerothcore#16739)

* Use dequeue instead of recursion

* Remove to do comments

* Fix formatting

* Fix more formatting :(

* Use references instead of copies in the stack to correctly update event state

* formatting

* Revert FindLinkedEvent parameter name change and check for event type

* Fix event processing in SmartScript::UpdateTimer

* Use struct for defining SmartScriptFrame instead of tuple

* Fix emplace_back not working on default constructor on clang 15

* Fix const placement
  • Loading branch information
Dantsz authored Oct 22, 2024
1 parent bb40bf7 commit 87aeaf1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
26 changes: 21 additions & 5 deletions src/server/game/AI/SmartScripts/SmartScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,16 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject(), me ? me->GetVictim() : nullptr);

if (sConditionMgr->IsObjectMeetToConditions(info, conds))
ProcessEvent(*i, unit, var0, var1, bvar, spell, gob);
{
ASSERT(executionStack.empty());
executionStack.emplace_back(SmartScriptFrame{ *i, unit, var0, var1, bvar, spell, gob });
while (!executionStack.empty())
{
auto [stack_holder , stack_unit, stack_var0, stack_var1, stack_bvar, stack_spell, stack_gob] = executionStack.back();
executionStack.pop_back();
ProcessEvent(stack_holder, stack_unit, stack_var0, stack_var1, stack_bvar, stack_spell, stack_gob);
}
}
}
}
}
Expand Down Expand Up @@ -3255,9 +3264,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u

if (e.link && e.link != e.event_id)
{
SmartScriptHolder linked = FindLinkedEvent(e.link);
if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
auto linked = FindLinkedEvent(e.link);
if (linked.has_value() && linked.value().get().GetEventType() == SMART_EVENT_LINK)
executionStack.emplace_back(SmartScriptFrame{ linked.value(), unit, var0, var1, bvar, spell, gob });
else
LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Link Event {} not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
}
Expand Down Expand Up @@ -4852,7 +4861,14 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff)
case SMART_EVENT_DISTANCE_CREATURE:
case SMART_EVENT_DISTANCE_GAMEOBJECT:
{
ProcessEvent(e);
ASSERT(executionStack.empty());
executionStack.emplace_back(SmartScriptFrame{ e, nullptr, 0, 0, false, nullptr, nullptr });
while (!executionStack.empty())
{
auto [stack_holder, stack_unit, stack_var0, stack_var1, stack_bvar, stack_spell, stack_gob] = executionStack.back();
executionStack.pop_back();
ProcessEvent(stack_holder, stack_unit, stack_var0, stack_var1, stack_bvar, stack_spell, stack_gob);
}
if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST)
{
e.enableTimed = false;//disable event if it is in an ActionList and was processed once
Expand Down
22 changes: 18 additions & 4 deletions src/server/game/AI/SmartScripts/SmartScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,21 @@
#include "SmartScriptMgr.h"
#include "Spell.h"
#include "Unit.h"
#include <deque>

class SmartScript
{
struct SmartScriptFrame
{
SmartScriptHolder& holder;
Unit* unit;
uint32 var0;
uint32 var1;
bool bvar;
SpellInfo const* spell;
GameObject* gob;
};

public:
SmartScript();
~SmartScript();
Expand Down Expand Up @@ -253,23 +265,25 @@ class SmartScript
}
}
}
SmartScriptHolder FindLinkedEvent (uint32 link)
std::optional<std::reference_wrapper<
SmartScriptHolder>> FindLinkedEvent(uint32 link)
{
if (!mEvents.empty())
{
for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
{
if (i->event_id == link)
{
return (*i);
return std::ref(*i);
}
}
}
SmartScriptHolder s;
return s;
return std::nullopt;
}

GuidUnorderedSet _summonList;

std::deque<SmartScriptFrame> executionStack;
};

#endif

0 comments on commit 87aeaf1

Please sign in to comment.