8 #include "LUAFunctions.h"
71 lua_State* _s =
nullptr;
74 typedef std::shared_ptr<LuaNodeFactory> LUATreeNodeFactoryPtr;
75 typedef std::map<std::string, LUATreeNodeFactoryPtr> TreeNodeFactoryMap;
78 typedef std::shared_ptr<LuaConditionFactory> LUAConditionFactoryPtr;
79 typedef std::map<std::string, LUAConditionFactoryPtr> ConditionFactoryMap;
82 typedef std::shared_ptr<LuaFilterFactory> LUAFilterFactoryPtr;
83 typedef std::map<std::string, LUAFilterFactoryPtr> FilterFactoryMap;
86 typedef std::shared_ptr<LuaSteeringFactory> LUASteeringFactoryPtr;
87 typedef std::map<std::string, LUASteeringFactoryPtr> SteeringFactoryMap;
90 TreeNodeFactoryMap _treeNodeFactories;
91 ConditionFactoryMap _conditionFactories;
92 FilterFactoryMap _filterFactories;
93 SteeringFactoryMap _steeringFactories;
100 return luaAI_getlightuserdata<LUAAIRegistry>(s, luaAI_metaregistry());
107 static LuaNodeFactory* luaAI_tonodefactory(lua_State * s,
int n) {
141 static int luaAI_nodeemptyexecute(lua_State* s) {
143 return luaL_error(s,
"There is no execute function set for node: %s", factory->type().c_str());
146 static int luaAI_nodetostring(lua_State* s) {
148 lua_pushfstring(s,
"node: %s", factory->type().c_str());
164 static int luaAI_createnode(lua_State* s) {
166 const std::string type = luaL_checkstring(s, -1);
167 const LUATreeNodeFactoryPtr& factory = std::make_shared<LuaNodeFactory>(s, type);
170 return luaL_error(s,
"tree node %s is already registered", type.c_str());
173 luaAI_newuserdata<LuaNodeFactory*>(s, factory.get());
174 const luaL_Reg nodes[] = {
175 {
"execute", luaAI_nodeemptyexecute},
176 {
"__tostring", luaAI_nodetostring},
177 {
"__newindex", luaAI_newindex},
180 luaAI_setupmetatable(s, type, nodes,
"node");
182 r->_treeNodeFactories.emplace(type, factory);
191 static int luaAI_conditionemptyevaluate(lua_State* s) {
193 return luaL_error(s,
"There is no evaluate function set for condition: %s", factory->type().c_str());
196 static int luaAI_conditiontostring(lua_State* s) {
198 lua_pushfstring(s,
"condition: %s", factory->type().c_str());
206 static int luaAI_createcondition(lua_State* s) {
208 const std::string type = luaL_checkstring(s, -1);
209 const LUAConditionFactoryPtr& factory = std::make_shared<LuaConditionFactory>(s, type);
210 const bool inserted = r->registerConditionFactory(type, *factory);
212 return luaL_error(s,
"condition %s is already registered", type.c_str());
215 luaAI_newuserdata<LuaConditionFactory*>(s, factory.get());
216 const luaL_Reg nodes[] = {
217 {
"evaluate", luaAI_conditionemptyevaluate},
218 {
"__tostring", luaAI_conditiontostring},
219 {
"__newindex", luaAI_newindex},
222 luaAI_setupmetatable(s, type, nodes,
"condition");
224 r->_conditionFactories.emplace(type, factory);
233 static int luaAI_filteremptyfilter(lua_State* s) {
235 return luaL_error(s,
"There is no filter function set for filter: %s", factory->type().c_str());
238 static int luaAI_filtertostring(lua_State* s) {
240 lua_pushfstring(s,
"filter: %s", factory->type().c_str());
244 static int luaAI_createfilter(lua_State* s) {
246 const std::string type = luaL_checkstring(s, -1);
247 const LUAFilterFactoryPtr& factory = std::make_shared<LuaFilterFactory>(s, type);
248 const bool inserted = r->registerFilterFactory(type, *factory);
250 return luaL_error(s,
"filter %s is already registered", type.c_str());
253 luaAI_newuserdata<LuaFilterFactory*>(s, factory.get());
254 const luaL_Reg nodes[] = {
255 {
"filter", luaAI_filteremptyfilter},
256 {
"__tostring", luaAI_filtertostring},
257 {
"__newindex", luaAI_newindex},
260 luaAI_setupmetatable(s, type, nodes,
"filter");
263 r->_filterFactories.emplace(type, factory);
267 static int luaAI_steeringemptyexecute(lua_State* s) {
269 return luaL_error(s,
"There is no execute() function set for steering: %s", factory->type().c_str());
272 static int luaAI_steeringtostring(lua_State* s) {
274 lua_pushfstring(s,
"steering: %s", factory->type().c_str());
278 static int luaAI_createsteering(lua_State* s) {
280 const std::string type = luaL_checkstring(s, -1);
281 const LUASteeringFactoryPtr& factory = std::make_shared<LuaSteeringFactory>(s, type);
282 const bool inserted = r->registerSteeringFactory(type, *factory);
284 return luaL_error(s,
"steering %s is already registered", type.c_str());
287 luaAI_newuserdata<LuaSteeringFactory*>(s, factory.get());
288 const luaL_Reg nodes[] = {
289 {
"filter", luaAI_steeringemptyexecute},
290 {
"__tostring", luaAI_steeringtostring},
291 {
"__newindex", luaAI_newindex},
294 luaAI_setupmetatable(s, type, nodes,
"steering");
297 r->_steeringFactories.emplace(type, factory);
306 std::vector<luaL_Reg> aiFuncs = {
308 {
"time", luaAI_aitime},
309 {
"hasZone", luaAI_aihaszone},
310 {
"zone", luaAI_aigetzone},
311 {
"filteredEntities", luaAI_aifilteredentities},
312 {
"setFilteredEntities", luaAI_aisetfilteredentities},
313 {
"addFilteredEntity", luaAI_aiaddfilteredentity},
314 {
"character", luaAI_aigetcharacter},
315 {
"aggroMgr", luaAI_aigetaggromgr},
316 {
"__tostring", luaAI_aitostring},
317 {
"__gc", luaAI_aigc},
318 {
"__eq", luaAI_aieq},
321 std::vector<luaL_Reg> vecFuncs = {
322 {
"__add", luaAI_vecadd},
323 {
"__sub", luaAI_vecsub},
324 {
"__mul", luaAI_vecdot},
325 {
"__div", luaAI_vecdiv},
326 {
"__unm", luaAI_vecnegate},
327 {
"__len", luaAI_veclen},
328 {
"__eq", luaAI_veceq},
329 {
"__tostring", luaAI_vectostring},
330 {
"__index", luaAI_vecindex},
331 {
"__newindex", luaAI_vecnewindex},
332 {
"dot", luaAI_vecdot},
335 std::vector<luaL_Reg> zoneFuncs = {
336 {
"size", luaAI_zonesize},
337 {
"name", luaAI_zonename},
338 {
"ai", luaAI_zoneai},
339 {
"execute", luaAI_zoneexecute},
340 {
"groupMgr", luaAI_zonegroupmgr},
341 {
"__tostring", luaAI_zonetostring},
344 std::vector<luaL_Reg> characterFuncs = {
345 {
"id", luaAI_characterid},
346 {
"position", luaAI_characterposition},
347 {
"setPosition", luaAI_charactersetposition},
348 {
"speed", luaAI_characterspeed},
349 {
"setSpeed", luaAI_charactersetspeed},
350 {
"orientation", luaAI_characterorientation},
351 {
"setOrientation", luaAI_charactersetorientation},
352 {
"setAttribute", luaAI_charactersetattribute},
353 {
"attributes", luaAI_characterattributes},
354 {
"__eq", luaAI_charactereq},
355 {
"__gc", luaAI_charactergc},
356 {
"__tostring", luaAI_charactertostring},
359 std::vector<luaL_Reg> aggroMgrFuncs = {
360 {
"setReduceByRatio", luaAI_aggromgrsetreducebyratio},
361 {
"setReduceByValue", luaAI_aggromgrsetreducebyvalue},
362 {
"resetReduceValue", luaAI_aggromgrresetreducevalue},
363 {
"addAggro", luaAI_aggromgraddaggro},
364 {
"highestEntry", luaAI_aggromgrhighestentry},
365 {
"entries", luaAI_aggromgrentries},
366 {
"__tostring", luaAI_aggromgrtostring},
369 std::vector<luaL_Reg> groupMgrFuncs = {
370 {
"add", luaAI_groupmgradd},
371 {
"remove", luaAI_groupmgrremove},
372 {
"isLeader", luaAI_groupmgrisleader},
373 {
"isInGroup", luaAI_groupmgrisingroup},
374 {
"isInAnyGroup", luaAI_groupmgrisinanygroup},
375 {
"size", luaAI_groupmgrsize},
376 {
"position", luaAI_groupmgrposition},
377 {
"leader", luaAI_groupmgrleader},
378 {
"__tostring", luaAI_groupmgrtostring},
381 std::vector<luaL_Reg> registryFuncs = {
382 {
"createNode", luaAI_createnode},
383 {
"createCondition", luaAI_createcondition},
384 {
"createFilter", luaAI_createfilter},
385 {
"createSteering", luaAI_createsteering},
389 static int luaAI_aisetfilteredentities(lua_State* s) {
391 luaL_checktype(s, 2, LUA_TTABLE);
393 const int n = lua_rawlen(s, 2);
394 FilteredEntities v(n);
395 for (
int i = 1; i <= n; ++i) {
396 lua_rawgeti(s, 2, i);
397 const int top = lua_gettop(s);
398 const CharacterId
id = (CharacterId)luaL_checknumber(s, top);
402 ai->ai->setFilteredEntities(v);
406 static int luaAI_aiaddfilteredentity(lua_State* s) {
408 const CharacterId
id = (CharacterId)luaL_checkinteger(s, 2);
409 ai->ai->addFilteredEntity(
id);
429 ai_assert(_s !=
nullptr,
"LUA state is not yet initialized");
430 return luaL_getmetatable(_s, luaAI_metaai());
438 ai_assert(_s !=
nullptr,
"LUA state is not yet initialized");
439 return luaL_getmetatable(_s, luaAI_metacharacter());
449 _s = luaL_newstate();
451 lua_atpanic(_s, [] (lua_State* L) {
452 ai_log_error(
"Lua panic. Error message: %s", (lua_isnil(L, -1) ?
"" : lua_tostring(L, -1)));
455 lua_gc(_s, LUA_GCSTOP, 0);
458 luaAI_registerfuncs(_s, ®istryFuncs.front(),
"META_REGISTRY");
459 lua_setglobal(_s,
"REGISTRY");
463 luaAI_globalpointer(_s,
this, luaAI_metaregistry());
465 luaAI_registerfuncs(_s, &aiFuncs.front(), luaAI_metaai());
466 luaAI_registerfuncs(_s, &vecFuncs.front(), luaAI_metavec());
467 luaAI_registerfuncs(_s, &zoneFuncs.front(), luaAI_metazone());
468 luaAI_registerfuncs(_s, &characterFuncs.front(), luaAI_metacharacter());
469 luaAI_registerfuncs(_s, &aggroMgrFuncs.front(), luaAI_metaaggromgr());
470 luaAI_registerfuncs(_s, &groupMgrFuncs.front(), luaAI_metagroupmgr());
472 const char* script =
""
473 "UNKNOWN, CANNOTEXECUTE, RUNNING, FINISHED, FAILED, EXCEPTION = 0, 1, 2, 3, 4, 5\n";
475 if (luaL_loadbufferx(_s, script, strlen(script),
"",
nullptr) || lua_pcall(_s, 0, 0, 0)) {
489 _treeNodeFactories.clear();
490 _conditionFactories.clear();
491 _filterFactories.clear();
492 _steeringFactories.clear();
504 inline bool evaluate(
const std::string& str) {
505 return evaluate(str.c_str(), str.length());
514 bool evaluate(
const char* luaBuffer,
size_t size) {
519 if (luaL_loadbufferx(_s, luaBuffer, size,
"",
nullptr) || lua_pcall(_s, 0, 0, 0)) {
#define ai_assert(condition,...)
Provide your own assert - this is only executed in DEBUG mode.
Definition: Types.h:75
Definition: LUAFunctions.h:11
Definition: LUACondition.h:86
void shutdown()
Definition: LUAAIRegistry.h:486
#define ai_log_error(...)
Logging macro to provide your own loggers.
Definition: Types.h:23
Definition: LUATreeNode.h:91
The place to register your TreeNode and ICondition factories at.
Definition: AIRegistry.h:64
int pushCharacterMetatable()
Pushes the character metatable onto the stack. This allows anyone to modify it to provide own functio...
Definition: LUAAIRegistry.h:437
Definition: LUASteering.h:94
int pushAIMetatable()
Pushes the AI metatable onto the stack. This allows anyone to modify it to provide own functions and ...
Definition: LUAAIRegistry.h:428
Allows you to register lua TreeNodes, Conditions, Filters and ISteerings.
Definition: LUAAIRegistry.h:69
#define ai_log_debug(...)
Logging macro to provide your own loggers.
Definition: Types.h:37
lua_State * getLuaState()
Access to the lua state.
Definition: LUAAIRegistry.h:417
bool registerNodeFactory(const std::string &type, const ITreeNodeFactory &factory)
Registers a tree node factory of the given type.
Definition: AIRegistry.h:221
Definition: LUAFilter.h:76
bool evaluate(const char *luaBuffer, size_t size)
Load your lua scripts into the lua state of the registry. This can be called multiple times to e...
Definition: LUAAIRegistry.h:514
bool init()
Definition: LUAAIRegistry.h:445