Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/modules/Bots/playerbot/strategy/Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ namespace ai
class ActionBasket
{
public:
ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, Event event) :
ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, const Event& event) :
action(action), relevance(relevance), skipPrerequisites(skipPrerequisites), event(event) {}
virtual ~ActionBasket(void) {}
public:
float getRelevance() {return relevance;}
ActionNode* getAction() {return action;}
Event getEvent() { return event; }
const Event& getEvent() { return event; }
bool isSkipPrerequisites() { return skipPrerequisites; }
void AmendRelevance(float k) {relevance *= k; }
void setRelevance(float relevance) { this->relevance = relevance; }
Expand Down
79 changes: 49 additions & 30 deletions src/modules/Bots/playerbot/strategy/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ Engine::Engine(PlayerbotAI* ai, AiObjectContext *factory) : PlayerbotAIAware(ai)
{
lastRelevance = 0.0f;
testMode = false;
strategiesDirty = false;
}

// Executes actions before the main action
bool ActionExecutionListeners::Before(Action* action, Event event)
bool ActionExecutionListeners::Before(Action* action, const Event& event)
{
bool result = true;
for (list<ActionExecutionListener*>::iterator i = listeners.begin(); i!=listeners.end(); i++)
Expand All @@ -26,7 +27,7 @@ bool ActionExecutionListeners::Before(Action* action, Event event)
}

// Executes actions after the main action
void ActionExecutionListeners::After(Action* action, bool executed, Event event)
void ActionExecutionListeners::After(Action* action, bool executed, const Event& event)
{
for (list<ActionExecutionListener*>::iterator i = listeners.begin(); i!=listeners.end(); i++)
{
Expand All @@ -35,7 +36,7 @@ void ActionExecutionListeners::After(Action* action, bool executed, Event event)
}

// Overrides the result of the action execution
bool ActionExecutionListeners::OverrideResult(Action* action, bool executed, Event event)
bool ActionExecutionListeners::OverrideResult(Action* action, bool executed, const Event& event)
{
bool result = executed;
for (list<ActionExecutionListener*>::iterator i = listeners.begin(); i!=listeners.end(); i++)
Expand All @@ -46,7 +47,7 @@ bool ActionExecutionListeners::OverrideResult(Action* action, bool executed, Eve
}

// Checks if the action execution is allowed
bool ActionExecutionListeners::AllowExecution(Action* action, Event event)
bool ActionExecutionListeners::AllowExecution(Action* action, const Event& event)
{
bool result = true;
for (list<ActionExecutionListener*>::iterator i = listeners.begin(); i!=listeners.end(); i++)
Expand All @@ -71,6 +72,16 @@ Engine::~Engine(void)
{
Reset();
strategies.clear();
ClearActionNodeCache();
}

void Engine::ClearActionNodeCache()
{
for (unordered_map<string, ActionNode*>::iterator i = actionNodeCache.begin(); i != actionNodeCache.end(); i++)
{
delete i->second;
}
actionNodeCache.clear();
}

// Resets the engine by clearing the action queue, triggers, and multipliers
Expand All @@ -79,8 +90,7 @@ void Engine::Reset()
ActionNode* action = NULL;
do
{
action = queue.Pop();
delete action;
action = queue.Pop(); // popped from queue, remain in cache
} while (action != NULL);

for (list<TriggerNode*>::iterator i = triggers.begin(); i != triggers.end(); i++)
Expand All @@ -98,10 +108,18 @@ void Engine::Reset()
multipliers.clear();
}

// Initializes the engine by resetting it and initializing strategies
// Marks the engine for reinitialization at the next DoNextAction entry
void Engine::Init()
{
strategiesDirty = true;
}

// Initializes strategies, triggers, multipliers, and default actions
void Engine::InitStrategies()
{
Reset();
ClearActionNodeCache();
strategiesDirty = false;

for (map<string, Strategy*>::iterator i = strategies.begin(); i != strategies.end(); i++)
{
Expand Down Expand Up @@ -132,6 +150,11 @@ bool Engine::DoNextAction(Unit* unit, int depth)
bool actionExecuted = false;
ActionBasket* basket = NULL;

if (strategiesDirty)
{
InitStrategies();
}

time_t currentTime = time(0);
aiObjectContext->Update();
ProcessTriggers();
Expand Down Expand Up @@ -188,7 +211,6 @@ bool Engine::DoNextAction(Unit* unit, int depth)
LogAction("A:%s - OK", action->getName().c_str());
MultiplyAndPush(actionNode->getContinuers(), 0, false, event);
lastRelevance = relevance;
delete actionNode;
break;
}
else
Expand All @@ -208,7 +230,6 @@ bool Engine::DoNextAction(Unit* unit, int depth)
lastRelevance = relevance;
LogAction("A:%s - USELESS", action->getName().c_str());
}
delete actionNode;
}
}
while (basket);
Expand Down Expand Up @@ -240,23 +261,30 @@ bool Engine::DoNextAction(Unit* unit, int depth)
// Creates an action node based on the action name
ActionNode* Engine::CreateActionNode(string name)
{
unordered_map<string, ActionNode*>::iterator cached = actionNodeCache.find(name);
if (cached != actionNodeCache.end())
{
return cached->second;
}

ActionNode* node = NULL;
for (map<string, Strategy*>::iterator i = strategies.begin(); i != strategies.end(); i++)
{
Strategy* strategy = i->second;
ActionNode* node = strategy->GetAction(name);
node = i->second->GetAction(name);
if (node)
{
return node;
}
break;
}
if (!node)
{
node = new ActionNode(name, /*P*/ NULL, /*A*/ NULL, /*C*/ NULL);
}
return new ActionNode (name,
/*P*/ NULL,
/*A*/ NULL,
/*C*/ NULL);

actionNodeCache[name] = node;
return node;
}

// Multiplies the relevance of actions and pushes them to the queue
bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event)
bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, const Event& event)
{
bool pushed = false;
if (actions)
Expand All @@ -281,11 +309,6 @@ bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool sk
queue.Push(new ActionBasket(action, k, skipPrerequisites, event));
pushed = true;
}
else
{
delete action;
}

delete nextAction;
}
else
Expand Down Expand Up @@ -317,21 +340,18 @@ ActionResult Engine::ExecuteAction(string &name)

if (!action->isPossible())
{
delete actionNode;
return ACTION_RESULT_IMPOSSIBLE;
}

if (!action->isUseful())
{
delete actionNode;
return ACTION_RESULT_USELESS;
}

action->MakeVerbose();
Event emptyEvent;
result = ListenAndExecute(action, emptyEvent);
MultiplyAndPush(action->getContinuers(), 0.0f, false, emptyEvent);
delete actionNode;
return result ? ACTION_RESULT_OK : ACTION_RESULT_FAILED;
}

Expand Down Expand Up @@ -487,13 +507,12 @@ string Engine::ListStrategies()
}

// Pushes an action node to the queue again
void Engine::PushAgain(ActionNode* actionNode, float relevance, Event event)
void Engine::PushAgain(ActionNode* actionNode, float relevance, const Event& event)
{
NextAction** nextAction = new NextAction*[2];
nextAction[0] = new NextAction(actionNode->getName(), relevance);
nextAction[1] = NULL;
MultiplyAndPush(nextAction, relevance, true, event);
delete actionNode;
}

// Checks if the engine contains a specific strategy type
Expand Down Expand Up @@ -523,7 +542,7 @@ Action* Engine::InitializeAction(ActionNode* actionNode)
}

// Listens and executes an action
bool Engine::ListenAndExecute(Action* action, Event event)
bool Engine::ListenAndExecute(Action* action, const Event& event)
{
bool actionExecuted = false;

Expand Down
27 changes: 16 additions & 11 deletions src/modules/Bots/playerbot/strategy/Engine.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <unordered_map>
#include "Action.h"
#include "Queue.h"
#include "Trigger.h"
Expand All @@ -16,10 +17,10 @@ namespace ai
{
public:
virtual ~ActionExecutionListener() = default; // Add a virtual destructor
virtual bool Before(Action* action, Event event) = 0;
virtual bool AllowExecution(Action* action, Event event) = 0;
virtual void After(Action* action, bool executed, Event event) = 0;
virtual bool OverrideResult(Action* action, bool executed, Event event) = 0;
virtual bool Before(Action* action, const Event& event) = 0;
virtual bool AllowExecution(Action* action, const Event& event) = 0;
virtual void After(Action* action, bool executed, const Event& event) = 0;
virtual bool OverrideResult(Action* action, bool executed, const Event& event) = 0;
};

// -----------------------------------------------------------------------------------------------------------------------
Expand All @@ -34,10 +35,10 @@ namespace ai

// ActionExecutionListener
public:
virtual bool Before(Action* action, Event event);
virtual bool AllowExecution(Action* action, Event event);
virtual void After(Action* action, bool executed, Event event);
virtual bool OverrideResult(Action* action, bool executed, Event event);
virtual bool Before(Action* action, const Event& event);
virtual bool AllowExecution(Action* action, const Event& event);
virtual void After(Action* action, bool executed, const Event& event);
virtual bool OverrideResult(Action* action, bool executed, const Event& event);

public:
/**
Expand Down Expand Up @@ -127,14 +128,16 @@ namespace ai
virtual ~Engine(void);

private:
bool MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event);
bool MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, const Event& event);
void Reset();
void ProcessTriggers();
void PushDefaultActions();
void PushAgain(ActionNode* actionNode, float relevance, Event event);
void PushAgain(ActionNode* actionNode, float relevance, const Event& event);
ActionNode* CreateActionNode(string name);
Action* InitializeAction(ActionNode* actionNode);
bool ListenAndExecute(Action* action, Event event);
bool ListenAndExecute(Action* action, const Event& event);
void ClearActionNodeCache();
void InitStrategies();

private:
void LogAction(const char* format, ...);
Expand All @@ -146,8 +149,10 @@ namespace ai
std::list<Multiplier*> multipliers; /**< List of multipliers */
AiObjectContext* aiObjectContext; /**< AI object context */
std::map<string, Strategy*> strategies; /**< Map of strategies */
std::unordered_map<string, ActionNode*> actionNodeCache; /**< Cache of action nodes by name */
float lastRelevance; /**< Last relevance value */
std::string lastAction; /**< Last executed action */
bool strategiesDirty; /**< True when strategies changed and ActualInit() is pending */

public:
bool testMode; /**< Flag for test mode */
Expand Down
4 changes: 2 additions & 2 deletions src/modules/Bots/playerbot/strategy/Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ namespace ai
*
* @return string The source of the event
*/
string getSource() { return source; }
const string& getSource() { return source; }

/**
* @brief Get the parameter of the event
*
* @return string The parameter of the event
*/
string getParam() { return param; }
const string& getParam() { return param; }

/**
* @brief Get the packet associated with the event
Expand Down
Loading
Loading