Lua script

This commit is contained in:
2026-02-28 00:19:25 +03:00
parent 5434239b47
commit 2815369bb8
8 changed files with 202 additions and 7 deletions

View File

@@ -6,6 +6,7 @@
#include "ientity.h"
#include "entitymanager.h"
#include "world.h"
#include "game_object.h"
#include <pugixml.hpp>
@@ -67,10 +68,20 @@ void registerClasses()
// base thing
GetLuaState().GetGlobals().RegisterDirect("load_script", &luaLoadScript);
GetLuaState().DoString("g_factory = {}");
registerEngine();
}
struct LuaPrototype
{
std::string m_luaname;
std::string m_enginename;
std::string m_description;
};
std::vector<LuaPrototype> g_prototypes;
void initializeEntityPrototypesFromLua()
{
using namespace LuaPlus;
@@ -80,9 +91,27 @@ void initializeEntityPrototypesFromLua()
LuaObject entityTable = it.GetValue();
assert(entityTable.IsTable());
for (LuaTableIterator it2(entityTable); it2; it2.Next()) {
Logger::Msg("%s", it2.GetValue().ToString());
if (entityTable.GetTableCount() < 3)
{
Core::Error("Entry in entity prototype table is bad, missing argument");
}
LuaObject luaname = entityTable[1];
LuaObject classname = entityTable[2];
LuaObject description = entityTable[3];
Logger::Msg("lua ent: name: %s classname: %s description: %s", luaname.ToString(), classname.ToString(), description.ToString());
LuaPrototype prototype;
prototype.m_luaname = luaname.ToString();
prototype.m_enginename = classname.ToString();
prototype.m_description = description.ToString();
g_prototypes.push_back(prototype);
/*for (LuaTableIterator it2(entityTable); it2; it2.Next()) {
Logger::Msg("%s", it2.GetValue().ToString());
}*/
}
}
@@ -149,6 +178,8 @@ void Game::LoadLevelXML(const char* mapname)
buffer, result.description(), result.offset);
}
// std::map<std::string, std::string> properties;
for (pugi::xml_node entity : doc.child("Level").child("Entities").children("Entity")) {
pugi::xml_attribute entityname = entity.attribute("name");
pugi::xml_attribute classname = entity.attribute("classname");
@@ -162,11 +193,75 @@ void Game::LoadLevelXML(const char* mapname)
}
}
IEntityBase* entity = g_entityManager->CreateEntity(classname.as_string());
IEntityBase* entity = Lua_CreateEntity(classname.as_string());
// this is pure C++ entity :)
if (!entity)
entity = g_entityManager->CreateEntity(classname.as_string());
//IEntityBase* entity = g_entityManager->CreateEntity(classname.as_string());
g_world->AddEntity(entity);
}
}
IEntityBase* Game::Lua_CreateEntity(const char* classname)
{
using namespace LuaPlus;
//if (!classname)
// classname = "Entity";
SDL_assert_always(classname);
LuaPrototype* pluaprototype = nullptr;
// find a prototype
for (std::vector<LuaPrototype>::iterator it = g_prototypes.begin();
it != g_prototypes.end();
++it)
{
if (strcmp((*it).m_luaname.c_str(), classname) == 0)
{
pluaprototype = &(*it);
break;
}
}
if (pluaprototype)
{
Entity* entity = static_cast<Entity*>(g_entityManager->CreateEntity(pluaprototype->m_enginename.c_str()));
SDL_assert_always(entity);
// get a prototype
LuaObject prototype = GetLuaState().GetGlobal(pluaprototype->m_luaname.c_str());
SDL_assert_always(!prototype.IsNil());
prototype.SetObject("__index", prototype);
// generate table
LuaObject factory = GetLuaState().GetGlobal("g_factory");
// generate name
std::string entityname = pluaprototype->m_luaname + "_" + std::to_string(factory.GetTableCount());
// create an table
LuaObject entityTable = GetLuaState().GetGlobals().CreateTable(entityname.c_str());
entityTable.SetMetatable(prototype);
entityTable.SetString("m_name", entityname.c_str());
// push in to the factory
factory.SetObject(entityname.c_str(), entityTable);
// link to the entity
entity->InitFromTable(entityTable);
return entity;
}
//IEntityBase* entity = g_entityManager->CreateEntity(classname);
return nullptr;
}
void Game::Shutdown()
{
}