From dcedfdacd1ba77591cdc0aa2b8c123c6a5ef2f5d Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 12 Nov 2011 10:39:44 +0200 Subject: [PATCH] Scripting WIP --- .gitignore | 4 ++ data/scripts/default.lua | 11 +++- src/CMakeLists.txt | 1 + src/content_cao.cpp | 29 ++++++---- src/content_cao.h | 3 + src/content_sao.cpp | 11 +++- src/luaentity_common.cpp | 83 +++++++++++++++++++++++++++ src/luaentity_common.h | 42 ++++++++++++++ src/script.cpp | 2 +- src/script.h | 2 +- src/scriptapi.cpp | 117 ++++++++++++++++++--------------------- src/scriptapi.h | 27 +-------- 12 files changed, 228 insertions(+), 104 deletions(-) create mode 100644 src/luaentity_common.cpp create mode 100644 src/luaentity_common.h diff --git a/.gitignore b/.gitignore index 99ea36f7..654e3cea 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ src/jthread/libjthread.a debug.txt bin/debug.txt minetestmapper/map.png +locale/ +src/lua/build/ +src/lua/CMakeFiles/ +*bak* diff --git a/data/scripts/default.lua b/data/scripts/default.lua index ebd4e5ab..baf541f4 100644 --- a/data/scripts/default.lua +++ b/data/scripts/default.lua @@ -125,6 +125,10 @@ function dump(o, dumped) return tostring(o) elseif type(o) == "function" then return "" + elseif type(o) == "userdata" then + return "" + elseif type(o) == "nil" then + return "nil" else error("cannot dump a " .. type(o)) return nil @@ -139,7 +143,7 @@ local TNT = { -- Maybe handle gravity and collision this way? dunno physical = true, weight = 5, - boundingbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, + collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, visual = "cube", textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"}, -- Initial value for our timer @@ -161,10 +165,13 @@ end -- Called when object is right-clicked function TNT:on_rightclick(clicker) print("TNT:on_rightclick()") + print("self: "..dump(self)) + print("getmetatable(self): "..dump(getmetatable(self))) + print("getmetatable(getmetatable(self)): "..dump(getmetatable(getmetatable(self)))) pos = self.object:getpos() print("TNT:on_rightclick(): object position: "..dump(pos)) pos = {x=pos.x+0.5+1, y=pos.y+0.5, z=pos.z+0.5} - minetest.env:add_node(pos, 0) + --minetest.env:add_node(pos, 0) end print("TNT dump: "..dump(TNT)) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b41fc4a6..a511e6cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,6 +94,7 @@ configure_file( ) set(common_SRCS + luaentity_common.cpp scriptapi.cpp script.cpp log.cpp diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 157a5188..70bcbac1 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -1268,6 +1268,8 @@ void MobV2CAO::setLooks(const std::string &looks) LuaEntityCAO */ +#include "luaentity_common.h" + // Prototype LuaEntityCAO proto_LuaEntityCAO; @@ -1275,13 +1277,15 @@ LuaEntityCAO::LuaEntityCAO(): ClientActiveObject(0), m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.), m_node(NULL), - m_position(v3f(0,10*BS,0)) + m_position(v3f(0,10*BS,0)), + m_prop(new LuaEntityProperties) { ClientActiveObject::registerType(getType(), create); } LuaEntityCAO::~LuaEntityCAO() { + delete m_prop; } ClientActiveObject* LuaEntityCAO::create() @@ -1398,16 +1402,19 @@ void LuaEntityCAO::initialize(const std::string &data) { infostream<<"LuaEntityCAO: Got init data"<deSerialize(prop_is); + + infostream<<"m_prop: "<dump()< m_selection_box; scene::IMeshSceneNode *m_node; v3f m_position; + struct LuaEntityProperties *m_prop; }; diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 8a0e67a2..3802129c 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -1495,6 +1495,7 @@ void MobV2SAO::doDamage(u16 d) */ #include "scriptapi.h" +#include "luaentity_common.h" // Prototype LuaEntitySAO proto_LuaEntitySAO(NULL, v3f(0,0,0), "_prototype", ""); @@ -1527,14 +1528,13 @@ void LuaEntitySAO::addedToEnvironment(u16 id) { ServerActiveObject::addedToEnvironment(id); - // Create entity by name and state + // Create entity from name and state m_registered = true; lua_State *L = m_env->getLua(); scriptapi_luaentity_add(L, id, m_init_name.c_str(), m_init_state.c_str()); // Get properties - *m_prop = scriptapi_luaentity_get_properties(L, m_id); - infostream<<"m_prop->visual="<visual<serialize(prop_os); + os< + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "luaentity_common.h" + +#include "utility.h" + +#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" + +LuaEntityProperties::LuaEntityProperties(): + physical(true), + weight(5), + collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5), + visual("single_sprite") +{ + textures.push_back("unknown_block.png"); +} + +std::string LuaEntityProperties::dump() +{ + std::ostringstream os(std::ios::binary); + os<<"physical="<::Iterator i = textures.begin(); + i != textures.end(); i++){ + os<<"\""<<(*i)<<"\" "; + } + os<<"]"; + return os.str(); +} + +void LuaEntityProperties::serialize(std::ostream &os) +{ + writeU8(os, 0); // version + writeU8(os, physical); + writeF1000(os, weight); + writeV3F1000(os, collisionbox.MinEdge); + writeV3F1000(os, collisionbox.MaxEdge); + os<::Iterator i = textures.begin(); + i != textures.end(); i++){ + os< + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef LUAENTITY_COMMON_HEADER +#define LUAENTITY_COMMON_HEADER + +#include +#include "irrlichttypes.h" +#include + +struct LuaEntityProperties +{ + bool physical; + float weight; + core::aabbox3d collisionbox; + std::string visual; + core::list textures; + + LuaEntityProperties(); + std::string dump(); + void serialize(std::ostream &os); + void deSerialize(std::istream &is); +}; + +#endif + diff --git a/src/script.cpp b/src/script.cpp index 167f81c7..f5881109 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -61,7 +61,7 @@ lua_State* script_init() return L; } -lua_State* script_deinit(lua_State *L) +void script_deinit(lua_State *L) { lua_close(L); } diff --git a/src/script.h b/src/script.h index 5f3b3912..ce697bc5 100644 --- a/src/script.h +++ b/src/script.h @@ -24,7 +24,7 @@ typedef struct lua_State lua_State; //#include lua_State* script_init(); -lua_State* script_deinit(lua_State *L); +void script_deinit(lua_State *L); void script_error(lua_State *L, const char *fmt, ...); bool script_load(lua_State *L, const char *path); diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 3c39da6a..a50516ed 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -33,6 +33,22 @@ extern "C" { #include "serverobject.h" #include "script.h" //#include "luna.h" +#include "luaentity_common.h" + +/* +TODO: +- Global environment step function +- Random node triggers +- Object network and client-side stuff +- Named node types and dynamic id allocation +- LuaNodeMetadata + blockdef.has_metadata = true/false + - Stores an inventory and stuff in a Settings object + meta.inventory_add_list("main") + blockdef.on_inventory_modified + meta.set("owner", playername) + meta.get("owner") +*/ static void stackDump(lua_State *L, std::ostream &o) { @@ -128,28 +144,8 @@ static int l_register_entity(lua_State *L) return 0; /* number of results */ } -#if 0 -static int l_new_entity(lua_State *L) -{ - /* o = o or {} - setmetatable(o, self) - self.__index = self - return o */ - if(lua_isnil(L, -1)) - lua_newtable(L); - luaL_checktype(L, -1, LUA_TTABLE); - luaL_getmetatable(L, "minetest.entity"); - lua_pushvalue(L, -1); // duplicate metatable - lua_setfield(L, -2, "__index"); - lua_setmetatable(L, -2); - // return table - return 1; -} -#endif - static const struct luaL_Reg minetest_f [] = { {"register_entity", l_register_entity}, - //{"new_entity", l_new_entity}, {NULL, NULL} }; @@ -163,6 +159,30 @@ static const struct luaL_Reg minetest_entity_m [] = { {NULL, NULL} }; +static void objectref_get(lua_State *L, u16 id) +{ + // Get minetest.object_refs[i] + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "object_refs"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_pushnumber(L, id); + lua_gettable(L, -2); + lua_remove(L, -2); // object_refs + lua_remove(L, -2); // minetest +} + +static void luaentity_get(lua_State *L, u16 id) +{ + // Get minetest.luaentities[i] + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "luaentities"); + luaL_checktype(L, -1, LUA_TTABLE); + lua_pushnumber(L, id); + lua_gettable(L, -2); + lua_remove(L, -2); // luaentities + lua_remove(L, -2); // minetest +} + /* Reference objects */ @@ -552,18 +572,6 @@ void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj) lua_pop(L, 2); } -static void objectref_get(lua_State *L, u16 id) -{ - // Get minetest.object_refs[i] - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "object_refs"); - luaL_checktype(L, -1, LUA_TTABLE); - lua_pushnumber(L, id); - lua_gettable(L, -2); - lua_remove(L, -2); // object_refs - lua_remove(L, -2); // minetest -} - /* luaentity */ @@ -646,18 +654,6 @@ void scriptapi_luaentity_rm(lua_State *L, u16 id) lua_pop(L, 2); // pop luaentities, minetest } -static void luaentity_get(lua_State *L, u16 id) -{ - // Get minetest.luaentities[i] - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "luaentities"); - luaL_checktype(L, -1, LUA_TTABLE); - lua_pushnumber(L, id); - lua_gettable(L, -2); - lua_remove(L, -2); // luaentities - lua_remove(L, -2); // minetest -} - std::string scriptapi_luaentity_get_state(lua_State *L, u16 id) { realitycheck(L); @@ -667,74 +663,71 @@ std::string scriptapi_luaentity_get_state(lua_State *L, u16 id) return ""; } -LuaEntityProperties scriptapi_luaentity_get_properties(lua_State *L, u16 id) +void scriptapi_luaentity_get_properties(lua_State *L, u16 id, + LuaEntityProperties *prop) { realitycheck(L); assert(lua_checkstack(L, 20)); infostream<<"scriptapi_luaentity_get_properties: id="<physical = lua_toboolean(L, -1); lua_pop(L, 1); lua_getfield(L, -1, "weight"); - prop.weight = lua_tonumber(L, -1); + prop->weight = lua_tonumber(L, -1); lua_pop(L, 1); - lua_getfield(L, -1, "boundingbox"); + lua_getfield(L, -1, "collisionbox"); if(lua_istable(L, -1)){ lua_rawgeti(L, -1, 1); - prop.boundingbox.MinEdge.X = lua_tonumber(L, -1); + prop->collisionbox.MinEdge.X = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); - prop.boundingbox.MinEdge.Y = lua_tonumber(L, -1); + prop->collisionbox.MinEdge.Y = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 3); - prop.boundingbox.MinEdge.Z = lua_tonumber(L, -1); + prop->collisionbox.MinEdge.Z = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 4); - prop.boundingbox.MaxEdge.X = lua_tonumber(L, -1); + prop->collisionbox.MaxEdge.X = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 5); - prop.boundingbox.MaxEdge.Y = lua_tonumber(L, -1); + prop->collisionbox.MaxEdge.Y = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 6); - prop.boundingbox.MaxEdge.Z = lua_tonumber(L, -1); + prop->collisionbox.MaxEdge.Z = lua_tonumber(L, -1); lua_pop(L, 1); } lua_pop(L, 1); lua_getfield(L, -1, "visual"); if(lua_isstring(L, -1)) - prop.visual = lua_tostring(L, -1); + prop->visual = lua_tostring(L, -1); lua_pop(L, 1); lua_getfield(L, -1, "textures"); if(lua_istable(L, -1)){ - prop.textures.clear(); + prop->textures.clear(); int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 if(lua_isstring(L, -1)) - prop.textures.push_back(lua_tostring(L, -1)); + prop->textures.push_back(lua_tostring(L, -1)); else - prop.textures.push_back(""); + prop->textures.push_back(""); // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); - - return prop; } void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime) diff --git a/src/scriptapi.h b/src/scriptapi.h index 891342fa..2a5eb25a 100644 --- a/src/scriptapi.h +++ b/src/scriptapi.h @@ -27,6 +27,7 @@ class Server; class ServerEnvironment; class ServerActiveObject; typedef struct lua_State lua_State; +struct LuaEntityProperties; void scriptapi_export(lua_State *L, Server *server); void scriptapi_add_environment(lua_State *L, ServerEnvironment *env); @@ -34,34 +35,12 @@ void scriptapi_add_environment(lua_State *L, ServerEnvironment *env); void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj); void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj); -struct LuaEntityProperties -{ - bool physical; - float weight; - core::aabbox3d boundingbox; - std::string visual; - core::list textures; - - LuaEntityProperties(): - physical(true), - weight(5), - boundingbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5), - visual("cube") - { - textures.push_back("unknown_block.png"); - textures.push_back("unknown_block.png"); - textures.push_back("unknown_block.png"); - textures.push_back("unknown_block.png"); - textures.push_back("unknown_block.png"); - textures.push_back("unknown_block.png"); - } -}; - void scriptapi_luaentity_add(lua_State *L, u16 id, const char *name, const char *init_state); void scriptapi_luaentity_rm(lua_State *L, u16 id); std::string scriptapi_luaentity_get_state(lua_State *L, u16 id); -LuaEntityProperties scriptapi_luaentity_get_properties(lua_State *L, u16 id); +void scriptapi_luaentity_get_properties(lua_State *L, u16 id, + LuaEntityProperties *prop); void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime); void scriptapi_luaentity_rightclick_player(lua_State *L, u16 id, const char *playername); -- 2.30.2