8 #include "LUAFunctions.h"
19 TreeNodeStatus runLUA(
const AIPtr& entity, int64_t deltaMillis) {
21 const std::string name =
"__meta_node_" + _type;
22 lua_getfield(_s, LUA_REGISTRYINDEX, name.c_str());
23 #if AI_LUA_SANTITY > 0
24 if (lua_isnil(_s, -1)) {
25 ai_log_error(
"LUA node: could not find lua userdata for %s", name.c_str());
26 return TreeNodeStatus::EXCEPTION;
30 lua_getmetatable(_s, -1);
31 #if AI_LUA_SANTITY > 0
32 if (!lua_istable(_s, -1)) {
33 ai_log_error(
"LUA node: userdata for %s doesn't have a metatable assigned", name.c_str());
34 return TreeNodeStatus::EXCEPTION;
38 lua_getfield(_s, -1,
"execute");
39 if (!lua_isfunction(_s, -1)) {
40 ai_log_error(
"LUA node: metatable for %s doesn't have the execute() function assigned", name.c_str());
41 return TreeNodeStatus::EXCEPTION;
45 lua_getfield(_s, LUA_REGISTRYINDEX, name.c_str());
48 if (luaAI_pushai(_s, entity) == 0) {
49 return TreeNodeStatus::EXCEPTION;
53 lua_pushinteger(_s, deltaMillis);
55 #if AI_LUA_SANTITY > 0
56 if (!lua_isfunction(_s, -4)) {
57 ai_log_error(
"LUA node: expected to find a function on stack -4");
58 return TreeNodeStatus::EXCEPTION;
60 if (!lua_isuserdata(_s, -3)) {
61 ai_log_error(
"LUA node: expected to find the userdata on -3");
62 return TreeNodeStatus::EXCEPTION;
64 if (!lua_isuserdata(_s, -2)) {
65 ai_log_error(
"LUA node: second parameter should be the ai");
66 return TreeNodeStatus::EXCEPTION;
68 if (!lua_isinteger(_s, -1)) {
69 ai_log_error(
"LUA node: first parameter should be the delta millis");
70 return TreeNodeStatus::EXCEPTION;
73 const int error = lua_pcall(_s, 3, 1, 0);
75 ai_log_error(
"LUA node script: %s", lua_isstring(_s, -1) ? lua_tostring(_s, -1) :
"Unknown Error");
77 lua_pop(_s, lua_gettop(_s));
78 return TreeNodeStatus::EXCEPTION;
80 const lua_Integer execstate = luaL_checkinteger(_s, -1);
81 if (execstate < 0 || execstate >= (lua_Integer)TreeNodeStatus::MAX_TREENODESTATUS) {
82 ai_log_error(
"LUA node: illegal tree node status returned: " LUA_INTEGER_FMT, execstate);
86 lua_pop(_s, lua_gettop(_s));
87 return (TreeNodeStatus)execstate;
97 _s(s), _type(typeStr) {
100 inline const std::string& type()
const {
105 return std::make_shared<LUATreeNode>(ctx->name, ctx->parameters, ctx->condition, _s, _type);
109 LUATreeNode(
const std::string& name,
const std::string& parameters,
const ConditionPtr& condition, lua_State* s,
const std::string& type) :
110 TreeNode(name, parameters, condition), _s(s) {
117 TreeNodeStatus
execute(
const AIPtr& entity, int64_t deltaMillis)
override {
119 return CANNOTEXECUTE;
125 return state(entity, runLUA(entity, deltaMillis));
130 return state(entity, EXCEPTION);
#define ai_log_error(...)
Logging macro to provide your own loggers.
Definition: Types.h:23
This factory will create tree nodes. It uses the TreeNodeFactoryContext to collect all the needed dat...
Definition: AIFactories.h:68
Definition: LUATreeNode.h:15
Definition: LUATreeNode.h:91
Context for ITreeNodeFactory.
Definition: AIFactories.h:15
virtual TreeNodeStatus execute(const AIPtr &entity, int64_t deltaMillis)
Definition: TreeNodeImpl.h:184
The base class for all behaviour tree actions.
Definition: TreeNode.h:88
TreeNodeStatus execute(const AIPtr &entity, int64_t deltaMillis) override
Definition: LUATreeNode.h:117