BACKEND: integrated the lua ai registry
parent
5b1ef3b6af
commit
517a9c5205
|
@ -0,0 +1,5 @@
|
|||
local luanode = REGISTRY.createNode("Test")
|
||||
function luanode:execute(ai, deltaMillis)
|
||||
print("Node execute called with parameters: ai=["..tostring(ai).."], deltaMillis=["..tostring(deltaMillis).."]")
|
||||
return FINISHED
|
||||
end
|
|
@ -123,12 +123,12 @@ public:
|
|||
/**
|
||||
* @see shutdown()
|
||||
*/
|
||||
bool init();
|
||||
virtual bool init();
|
||||
|
||||
/**
|
||||
* @see init()
|
||||
*/
|
||||
void shutdown();
|
||||
virtual void shutdown();
|
||||
|
||||
~LUAAIRegistry();
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# General
|
||||
|
||||
This module depends on [SimpleAI](https://github.com/mgerhardy/simpleai). A lot of its documentation is doxygen based.
|
||||
|
||||
See e.g. [SimpleAI.h](SimpleAI.h)
|
|
@ -65,6 +65,7 @@ generate_db_models(${LIB} ${CMAKE_CURRENT_SOURCE_DIR}/tables.tbl BackendModels.h
|
|||
|
||||
set(TEST_FILES
|
||||
tests/behaviourtrees.lua
|
||||
tests/behaviourtreenodes.lua
|
||||
tests/test-attributes.lua
|
||||
)
|
||||
set(TEST_SRCS
|
||||
|
|
|
@ -24,9 +24,23 @@
|
|||
|
||||
#include "attrib/ContainerProvider.h"
|
||||
|
||||
#include "core/io/Filesystem.h"
|
||||
#include "core/App.h"
|
||||
|
||||
namespace backend {
|
||||
|
||||
void AIRegistry::init() {
|
||||
bool AIRegistry::init() {
|
||||
if (!Super::init()) {
|
||||
Log::error("Failed to initialize the lua behaviour tree registry");
|
||||
return false;
|
||||
}
|
||||
|
||||
const core::String& script = io::filesystem()->load("behaviourtreenodes.lua");
|
||||
if (!evaluate(script)) {
|
||||
Log::error("Failed to load behaviour tree nodes");
|
||||
return false;
|
||||
}
|
||||
|
||||
registerNodeFactory("GoHome", GoHome::getFactory());
|
||||
registerNodeFactory("AttackOnSelection", AttackOnSelection::getFactory());
|
||||
registerNodeFactory("SetPointOfInterest", SetPointOfInterest::getFactory());
|
||||
|
@ -44,6 +58,7 @@ void AIRegistry::init() {
|
|||
registerFilterFactory("SelectEntitiesOfTypes", SelectEntitiesOfTypes::getFactory());
|
||||
|
||||
registerSteeringFactory("WanderAroundHome", WanderAroundHome::getFactory());
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@ namespace backend {
|
|||
/**
|
||||
* @ingroup AI
|
||||
*/
|
||||
class AIRegistry: public ai::AIRegistry {
|
||||
class AIRegistry: public ai::LUAAIRegistry {
|
||||
private:
|
||||
using Super = ai::LUAAIRegistry;
|
||||
public:
|
||||
void init();
|
||||
bool init() override;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<AIRegistry> AIRegistryPtr;
|
||||
|
|
|
@ -82,7 +82,7 @@ protected:
|
|||
network = std::make_shared<network::ServerNetwork>(protocolHandlerRegistry, _testApp->eventBus(), _testApp->metric());
|
||||
messageSender = std::make_shared<network::ServerMessageSender>(network, _testApp->metric());
|
||||
registry = std::make_shared<AIRegistry>();
|
||||
registry->init();
|
||||
ASSERT_TRUE(registry->init());
|
||||
loader = std::make_shared<AILoader>(registry);
|
||||
containerProvider = core::make_shared<attrib::ContainerProvider>();
|
||||
ASSERT_TRUE(containerProvider->init(CONTAINER));
|
||||
|
@ -95,6 +95,7 @@ protected:
|
|||
persistenceMgr = persistence::createPersistenceMgrMock();
|
||||
testing::Mock::AllowLeak(persistenceMgr.get());
|
||||
persistence::DBHandlerPtr dbHandler = persistence::createDbHandlerMock();
|
||||
// TODO: don't use the DBChunkPersister - but a mock
|
||||
core::Factory<backend::DBChunkPersister> chunkPersisterFactory;
|
||||
mapProvider = std::make_shared<MapProvider>(filesystem, eventBus, timeProvider,
|
||||
entityStorage, messageSender, loader, containerProvider, cooldownProvider,
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
_network = std::make_shared<network::ServerNetwork>(_protocolHandlerRegistry, _testApp->eventBus(), _testApp->metric());
|
||||
_messageSender = std::make_shared<network::ServerMessageSender>(_network, _testApp->metric());
|
||||
const AIRegistryPtr& registry = std::make_shared<AIRegistry>();
|
||||
registry->init();
|
||||
ASSERT_TRUE(registry->init());
|
||||
_loader = std::make_shared<AILoader>(registry);
|
||||
_containerProvider = core::make_shared<attrib::ContainerProvider>();
|
||||
_cooldownProvider = std::make_shared<cooldown::CooldownProvider>();
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
_network = std::make_shared<network::ServerNetwork>(_protocolHandlerRegistry, _testApp->eventBus(), _testApp->metric());
|
||||
_messageSender = std::make_shared<network::ServerMessageSender>(_network, _testApp->metric());
|
||||
const AIRegistryPtr& registry = std::make_shared<AIRegistry>();
|
||||
registry->init();
|
||||
ASSERT_TRUE(registry->init());
|
||||
_loader = std::make_shared<AILoader>(registry);
|
||||
_containerProvider = core::make_shared<attrib::ContainerProvider>();
|
||||
_cooldownProvider = std::make_shared<cooldown::CooldownProvider>();
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
_network = std::make_shared<network::ServerNetwork>(_protocolHandlerRegistry, _testApp->eventBus(), _testApp->metric());
|
||||
_messageSender = std::make_shared<network::ServerMessageSender>(_network, _testApp->metric());
|
||||
_aiRegistry = std::make_shared<AIRegistry>();
|
||||
_aiRegistry->init();
|
||||
ASSERT_TRUE(_aiRegistry->init());
|
||||
_loader = std::make_shared<AILoader>(_aiRegistry);
|
||||
_containerProvider = core::make_shared<attrib::ContainerProvider>();
|
||||
const core::String& attributes = _testApp->filesystem()->load("test-attributes.lua");
|
||||
|
|
|
@ -86,7 +86,10 @@ void World::construct() {
|
|||
}
|
||||
|
||||
bool World::init() {
|
||||
_registry->init();
|
||||
if (!_registry->init()) {
|
||||
Log::error("Failed to init the ai registry");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_mapProvider->init()) {
|
||||
Log::error("Failed to init the map provider");
|
||||
|
|
|
@ -16,6 +16,7 @@ set(LUA_BEHAVIOURTREES
|
|||
ai/undead-male-zombie.lua
|
||||
ai/shared.lua
|
||||
behaviourtrees.lua
|
||||
behaviourtreenodes.lua
|
||||
)
|
||||
set(LUA_ATTRIBUTES
|
||||
attrib/animal-rabbit.lua
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# Behaviour Trees
|
||||
|
||||
The behaviour trees are written in lua.
|
||||
|
||||
See the documentation given in the [ai module](../../../modules/ai/README.md)
|
||||
|
||||
# Functions
|
||||
|
||||
## `AI`
|
||||
|
||||
`createTree(name)`: Create a new behaviour tree.
|
||||
|
||||
## `Tree`
|
||||
|
||||
The object returned by `createTree` calls. The following methods are included:
|
||||
* `createRoot(id, name)`: The `id` if the node factory id as given while registering nodes. The name should match the npc type as given in the [network protocol definition](../../../modules/network/definitions/Shared.fbs).
|
||||
* `getName()`: Return the name of the root node
|
||||
|
||||
## `Node`
|
||||
|
||||
The object returned by `createRoot`. The following methods are included:
|
||||
* `addNode(id, name)`: The `id` if the node factory id as given while registering nodes. The name can be freely chosen.
|
||||
* `getName`: Return the name of the current node
|
||||
* `setCondition(conditionExpression)`: See the simpleai documentation for more details about the syntax. It might also be a good idea to check the existing behaviour trees or the unit tests.
|
||||
|
||||
# Nodes
|
||||
|
||||
The behaviour tree nodes can either be implemented in C++ - see [src/modules/backend/entity/ai/action](../../../modules/backend/entity/ai/action) for examples or in lua (see [src/server/lua/behaviourtreenodes.lua](../behaviourtreenodes.lua) for examples.
|
||||
|
||||
## LUARegistry
|
||||
|
||||
The lua registry exposes functions to write lua based ai tree nodes (actions, conditions, filter, ...).
|
||||
|
||||
This is most likely not complete and if you write a node in lua you will probably find objects or function not yet exposed that would be needed for your script to work. In that case, just go ahead and extend the [LUARegistry.cpp](../../../modules/ai/LUARegistry.cpp).
|
|
@ -0,0 +1,4 @@
|
|||
local luanode = REGISTRY.createNode("Empty")
|
||||
function luanode:execute(ai, deltaMillis)
|
||||
return FINISHED
|
||||
end
|
Loading…
Reference in New Issue