Refactored Engine::DoNextAction (#854)

Update Engine.cpp
This commit is contained in:
SaW
2025-01-10 18:52:20 +01:00
committed by GitHub
parent 8f37a0cdd4
commit 72db64ba84

View File

@@ -146,167 +146,106 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
bool actionExecuted = false; bool actionExecuted = false;
ActionBasket* basket = nullptr; ActionBasket* basket = nullptr;
time_t currentTime = time(nullptr); time_t currentTime = time(nullptr);
// aiObjectContext->Update();
// Update triggers and push default actions
ProcessTriggers(minimal); ProcessTriggers(minimal);
PushDefaultActions(); PushDefaultActions();
uint32 iterations = 0; uint32 iterations = 0;
uint32 iterationsPerTick = queue.Size() * (minimal ? 2 : sPlayerbotAIConfig->iterationsPerTick); uint32 iterationsPerTick = queue.Size() * (minimal ? 2 : sPlayerbotAIConfig->iterationsPerTick);
do
while (++iterations <= iterationsPerTick)
{ {
basket = queue.Peek(); basket = queue.Peek();
if (!basket)
break;
if (basket) float relevance = basket->getRelevance(); // for reference
bool skipPrerequisites = basket->isSkipPrerequisites();
if (minimal && (relevance < 100))
continue;
Event event = basket->getEvent();
ActionNode* actionNode = queue.Pop(); // NOTE: Pop() deletes basket
Action* action = InitializeAction(actionNode);
if (!action)
{ {
float relevance = basket->getRelevance(); // just for reference LogAction("A:%s - UNKNOWN", actionNode->getName().c_str());
bool skipPrerequisites = basket->isSkipPrerequisites(); }
else if (action->isUseful())
if (minimal && (relevance < 100)) {
continue; // Apply multipliers early to avoid unnecessary iterations
for (Multiplier* multiplier : multipliers)
Event event = basket->getEvent(); {
// NOTE: queue.Pop() deletes basket relevance *= multiplier->GetValue(action);
ActionNode* actionNode = queue.Pop();
Action* action = InitializeAction(actionNode);
if (action)
action->setRelevance(relevance); action->setRelevance(relevance);
if (!action) if (relevance <= 0)
{
// LOG_ERROR("playerbots", "Action: {} - is UNKNOWN - c:{} l:{}", actionNode->getName().c_str(),
// botAI->GetBot()->getClass(), botAI->GetBot()->GetLevel());
LogAction("A:%s - UNKNOWN", actionNode->getName().c_str());
}
else if (action->isUseful())
{
for (std::vector<Multiplier*>::iterator i = multipliers.begin(); i != multipliers.end(); i++)
{ {
Multiplier* multiplier = *i; LogAction("Multiplier %s made action %s useless", multiplier->getName().c_str(), action->getName().c_str());
relevance *= multiplier->GetValue(action); break;
action->setRelevance(relevance); }
}
if (!relevance) if (action->isPossible() && relevance > 0)
{
if (!skipPrerequisites)
{
LogAction("A:%s - PREREQ", action->getName().c_str());
if (MultiplyAndPush(actionNode->getPrerequisites(), relevance + 0.002f, false, event, "prereq"))
{ {
LogAction("Multiplier %s made action %s useless", multiplier->getName().c_str(), PushAgain(actionNode, relevance + 0.001f, event);
action->getName().c_str()); continue;
break;
} }
} }
if (action->isPossible() && relevance) PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_ACTION, action->getName(), &aiObjectContext->performanceStack);
actionExecuted = ListenAndExecute(action, event);
if (pmo)
pmo->finish();
if (actionExecuted)
{ {
if (!skipPrerequisites) LogAction("A:%s - OK", action->getName().c_str());
{ MultiplyAndPush(actionNode->getContinuers(), relevance, false, event, "cont");
LogAction("A:%s - PREREQ", action->getName().c_str()); lastRelevance = relevance;
delete actionNode; // Safe memory management
if (MultiplyAndPush(actionNode->getPrerequisites(), relevance + 0.002f, false, event, "prereq")) break;
{
PushAgain(actionNode, relevance + 0.001f, event);
continue;
}
}
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_ACTION, action->getName(),
&aiObjectContext->performanceStack);
actionExecuted = ListenAndExecute(action, event);
if (pmo)
pmo->finish();
if (actionExecuted)
{
LogAction("A:%s - OK", action->getName().c_str());
MultiplyAndPush(actionNode->getContinuers(), relevance, false, event, "cont");
lastRelevance = relevance;
delete actionNode;
break;
}
else
{
LogAction("A:%s - FAILED", action->getName().c_str());
MultiplyAndPush(actionNode->getAlternatives(), relevance + 0.003f, false, event, "alt");
}
} }
else else
{ {
if (botAI->HasStrategy("debug", BOT_STATE_NON_COMBAT)) LogAction("A:%s - FAILED", action->getName().c_str());
{
std::ostringstream out;
out << "do: ";
out << action->getName();
out << " impossible (";
out << action->getRelevance() << ")";
if (!event.GetSource().empty())
out << " [" << event.GetSource() << "]";
botAI->TellMasterNoFacing(out);
}
LogAction("A:%s - IMPOSSIBLE", action->getName().c_str());
MultiplyAndPush(actionNode->getAlternatives(), relevance + 0.003f, false, event, "alt"); MultiplyAndPush(actionNode->getAlternatives(), relevance + 0.003f, false, event, "alt");
} }
} }
else else
{ {
if (botAI->HasStrategy("debug", BOT_STATE_NON_COMBAT)) LogAction("A:%s - IMPOSSIBLE", action->getName().c_str());
{ MultiplyAndPush(actionNode->getAlternatives(), relevance + 0.003f, false, event, "alt");
std::ostringstream out;
out << "do: ";
out << action->getName();
out << " useless (";
out << action->getRelevance() << ")";
if (!event.GetSource().empty())
out << " [" << event.GetSource() << "]";
botAI->TellMasterNoFacing(out);
}
lastRelevance = relevance;
LogAction("A:%s - USELESS", action->getName().c_str());
} }
delete actionNode;
} }
} while (basket && ++iterations <= iterationsPerTick); else
// if (!basket)
// {
// lastRelevance = 0.0f;
// PushDefaultActions();
// // prevent the delay after pushing default actions
// if (queue.Peek() && depth < 1 && !minimal)
// return DoNextAction(unit, depth + 1, minimal);
// }
// MEMORY FIX TEST
/*
do
{
basket = queue.Peek();
if (basket)
{ {
// NOTE: queue.Pop() deletes basket LogAction("A:%s - USELESS", action->getName().c_str());
delete queue.Pop(); lastRelevance = relevance;
} }
delete actionNode; // Always delete after processing the action node
} }
while (basket);
*/
if (time(nullptr) - currentTime > 1) if (time(nullptr) - currentTime > 1)
{ {
LogAction("too long execution"); LogAction("Execution time exceeded 1 second");
} }
if (!actionExecuted) if (!actionExecuted)
LogAction("no actions executed"); LogAction("No actions executed");
queue.RemoveExpired();
queue.RemoveExpired(); // Clean up expired actions in the queue
return actionExecuted; return actionExecuted;
} }
@@ -567,7 +506,7 @@ std::string const Engine::ListStrategies()
std::string s = "Strategies: "; std::string s = "Strategies: ";
if (strategies.empty()) if (strategies.empty())
return std::move(s); return s;
for (std::map<std::string, Strategy*>::iterator i = strategies.begin(); i != strategies.end(); i++) for (std::map<std::string, Strategy*>::iterator i = strategies.begin(); i != strategies.end(); i++)
{ {