]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/script/lua_api/l_item.cpp
Merge branch 'master' of https://github.com/minetest/minetest
[dragonfireclient.git] / src / script / lua_api / l_item.cpp
index 9bbf9826bc88e8ef3f1bd1209c3e93381dd3e184..bae6701a095eb803a50ad704a7853a5c06ed2b97 100644 (file)
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "lua_api/l_internal.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
+#include "common/c_packer.h"
 #include "itemdef.h"
 #include "nodedef.h"
 #include "server.h"
@@ -198,6 +199,16 @@ int LuaItemStack::l_get_description(lua_State *L)
        return 1;
 }
 
+// get_short_description(self)
+int LuaItemStack::l_get_short_description(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       LuaItemStack *o = checkobject(L, 1);
+       std::string desc = o->m_stack.getShortDescription(getGameDef(L)->idef());
+       lua_pushstring(L, desc.c_str());
+       return 1;
+}
+
 // clear(self) -> true
 int LuaItemStack::l_clear(lua_State *L)
 {
@@ -234,9 +245,12 @@ int LuaItemStack::l_to_table(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        LuaItemStack *o = checkobject(L, 1);
        const ItemStack &item = o->m_stack;
-       if (item.empty()) {
+       if(item.empty())
+       {
                lua_pushnil(L);
-       } else {
+       }
+       else
+       {
                lua_newtable(L);
                lua_pushstring(L, item.name.c_str());
                lua_setfield(L, -2, "name");
@@ -311,7 +325,8 @@ int LuaItemStack::l_get_definition(lua_State *L)
        lua_getfield(L, -1, "registered_items");
        luaL_checktype(L, -1, LUA_TTABLE);
        lua_getfield(L, -1, item.name.c_str());
-       if (lua_isnil(L, -1)) {
+       if(lua_isnil(L, -1))
+       {
                lua_pop(L, 1);
                lua_getfield(L, -1, "unknown");
        }
@@ -326,7 +341,8 @@ int LuaItemStack::l_get_tool_capabilities(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
-       const ToolCapabilities &prop = item.getToolCapabilities(getGameDef(L)->idef());
+       const ToolCapabilities &prop =
+               item.getToolCapabilities(getGameDef(L)->idef());
        push_tool_capabilities(L, prop);
        return 1;
 }
@@ -370,8 +386,8 @@ int LuaItemStack::l_item_fits(lua_State *L)
        ItemStack newitem = read_item(L, 2, getGameDef(L)->idef());
        ItemStack restitem;
        bool fits = item.itemFits(newitem, &restitem, getGameDef(L)->idef());
-       lua_pushboolean(L, fits); // first return value
-       create(L, restitem);      // second return value
+       lua_pushboolean(L, fits);  // first return value
+       create(L, restitem);       // second return value
        return 2;
 }
 
@@ -382,7 +398,7 @@ int LuaItemStack::l_take_item(lua_State *L)
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
        u32 takecount = 1;
-       if (!lua_isnone(L, 2))
+       if(!lua_isnone(L, 2))
                takecount = luaL_checkinteger(L, 2);
        ItemStack taken = item.takeItem(takecount);
        create(L, taken);
@@ -396,22 +412,23 @@ int LuaItemStack::l_peek_item(lua_State *L)
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
        u32 peekcount = 1;
-       if (!lua_isnone(L, 2))
+       if(!lua_isnone(L, 2))
                peekcount = lua_tointeger(L, 2);
        ItemStack peekaboo = item.peekItem(peekcount);
        create(L, peekaboo);
        return 1;
 }
 
-LuaItemStack::LuaItemStack(const ItemStack &item) : m_stack(item)
+LuaItemStack::LuaItemStack(const ItemStack &item):
+       m_stack(item)
 {
 }
 
-const ItemStack &LuaItemStack::getItem() const
+const ItemStackLuaItemStack::getItem() const
 {
        return m_stack;
 }
-ItemStack &LuaItemStack::getItem()
+ItemStackLuaItemStack::getItem()
 {
        return m_stack;
 }
@@ -430,6 +447,7 @@ int LuaItemStack::create_object(lua_State *L)
        lua_setmetatable(L, -2);
        return 1;
 }
+
 // Not callable from Lua
 int LuaItemStack::create(lua_State *L, const ItemStack &item)
 {
@@ -446,6 +464,20 @@ LuaItemStack *LuaItemStack::checkobject(lua_State *L, int narg)
        return *(LuaItemStack **)luaL_checkudata(L, narg, className);
 }
 
+void *LuaItemStack::packIn(lua_State *L, int idx)
+{
+       LuaItemStack *o = checkobject(L, idx);
+       return new ItemStack(o->getItem());
+}
+
+void LuaItemStack::packOut(lua_State *L, void *ptr)
+{
+       ItemStack *stack = reinterpret_cast<ItemStack*>(ptr);
+       if (L)
+               create(L, *stack);
+       delete stack;
+}
+
 void LuaItemStack::Register(lua_State *L)
 {
        lua_newtable(L);
@@ -470,32 +502,47 @@ void LuaItemStack::Register(lua_State *L)
        lua_pushcfunction(L, mt_tostring);
        lua_settable(L, metatable);
 
-       lua_pop(L, 1); // drop metatable
+       lua_pop(L, 1);  // drop metatable
 
-       luaL_openlib(L, 0, methods, 0); // fill methodtable
-       lua_pop(L, 1);                  // drop methodtable
+       luaL_register(L, nullptr, methods);  // fill methodtable
+       lua_pop(L, 1);  // drop methodtable
 
        // Can be created from Lua (ItemStack(itemstack or itemstring or table or nil))
        lua_register(L, className, create_object);
+
+       script_register_packer(L, className, packIn, packOut);
 }
 
 const char LuaItemStack::className[] = "ItemStack";
-const luaL_Reg LuaItemStack::methods[] = {luamethod(LuaItemStack, is_empty),
-               luamethod(LuaItemStack, get_name), luamethod(LuaItemStack, set_name),
-               luamethod(LuaItemStack, get_count), luamethod(LuaItemStack, set_count),
-               luamethod(LuaItemStack, get_wear), luamethod(LuaItemStack, set_wear),
-               luamethod(LuaItemStack, get_meta), luamethod(LuaItemStack, get_metadata),
-               luamethod(LuaItemStack, set_metadata),
-               luamethod(LuaItemStack, get_description), luamethod(LuaItemStack, clear),
-               luamethod(LuaItemStack, replace), luamethod(LuaItemStack, to_string),
-               luamethod(LuaItemStack, to_table), luamethod(LuaItemStack, get_stack_max),
-               luamethod(LuaItemStack, get_free_space),
-               luamethod(LuaItemStack, is_known),
-               luamethod(LuaItemStack, get_definition),
-               luamethod(LuaItemStack, get_tool_capabilities),
-               luamethod(LuaItemStack, add_wear), luamethod(LuaItemStack, add_item),
-               luamethod(LuaItemStack, item_fits), luamethod(LuaItemStack, take_item),
-               luamethod(LuaItemStack, peek_item), {0, 0}};
+const luaL_Reg LuaItemStack::methods[] = {
+       luamethod(LuaItemStack, is_empty),
+       luamethod(LuaItemStack, get_name),
+       luamethod(LuaItemStack, set_name),
+       luamethod(LuaItemStack, get_count),
+       luamethod(LuaItemStack, set_count),
+       luamethod(LuaItemStack, get_wear),
+       luamethod(LuaItemStack, set_wear),
+       luamethod(LuaItemStack, get_meta),
+       luamethod(LuaItemStack, get_metadata),
+       luamethod(LuaItemStack, set_metadata),
+       luamethod(LuaItemStack, get_description),
+       luamethod(LuaItemStack, get_short_description),
+       luamethod(LuaItemStack, clear),
+       luamethod(LuaItemStack, replace),
+       luamethod(LuaItemStack, to_string),
+       luamethod(LuaItemStack, to_table),
+       luamethod(LuaItemStack, get_stack_max),
+       luamethod(LuaItemStack, get_free_space),
+       luamethod(LuaItemStack, is_known),
+       luamethod(LuaItemStack, get_definition),
+       luamethod(LuaItemStack, get_tool_capabilities),
+       luamethod(LuaItemStack, add_wear),
+       luamethod(LuaItemStack, add_item),
+       luamethod(LuaItemStack, item_fits),
+       luamethod(LuaItemStack, take_item),
+       luamethod(LuaItemStack, peek_item),
+       {0,0}
+};
 
 /*
        ItemDefinition
@@ -509,13 +556,15 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
        int table = 1;
 
        // Get the writable item and node definition managers from the server
-       IWritableItemDefManager *idef = getGameDef(L)->getWritableItemDefManager();
-       NodeDefManager *ndef = getGameDef(L)->getWritableNodeDefManager();
+       IWritableItemDefManager *idef =
+                       getGameDef(L)->getWritableItemDefManager();
+       NodeDefManager *ndef =
+                       getGameDef(L)->getWritableNodeDefManager();
 
        // Check if name is defined
        std::string name;
        lua_getfield(L, table, "name");
-       if (lua_isstring(L, -1)) {
+       if(lua_isstring(L, -1)){
                name = readParam<std::string>(L, -1);
        } else {
                throw LuaError("register_item_raw: name is not defined or not a string");
@@ -532,8 +581,8 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
 
        // Default to having client-side placement prediction for nodes
        // ("" in item definition sets it off)
-       if (def.node_placement_prediction == "__default") {
-               if (def.type == ITEM_NODE)
+       if(def.node_placement_prediction == "__default"){
+               if(def.type == ITEM_NODE)
                        def.node_placement_prediction = name;
                else
                        def.node_placement_prediction = "";
@@ -544,21 +593,26 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
 
        // Read the node definition (content features) and register it
        if (def.type == ITEM_NODE) {
-               ContentFeatures f = read_content_features(L, table);
+               ContentFeatures f;
+               read_content_features(L, f, table);
                // when a mod reregisters ignore, only texture changes and such should
                // be done
                if (f.name == "ignore")
                        return 0;
+               // This would break everything
+               if (f.name.empty())
+                       throw LuaError("Cannot register node with empty name");
 
                content_t id = ndef->set(f.name, f);
 
                if (id > MAX_REGISTERED_CONTENT) {
-                       throw LuaError("Number of registerable nodes (" +
-                                       itos(MAX_REGISTERED_CONTENT + 1) +
-                                       ") exceeded (" + name + ")");
+                       throw LuaError("Number of registerable nodes ("
+                                       + itos(MAX_REGISTERED_CONTENT+1)
+                                       ") exceeded (" + name + ")");
                }
+               
        }
-
+       
        return 0; /* number of results */
 }
 
@@ -568,11 +622,13 @@ int ModApiItemMod::l_unregister_item_raw(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        std::string name = luaL_checkstring(L, 1);
 
-       IWritableItemDefManager *idef = getGameDef(L)->getWritableItemDefManager();
+       IWritableItemDefManager *idef =
+                       getGameDef(L)->getWritableItemDefManager();
 
        // Unregister the node
        if (idef->get(name).type == ITEM_NODE) {
-               NodeDefManager *ndef = getGameDef(L)->getWritableNodeDefManager();
+               NodeDefManager *ndef =
+                       getGameDef(L)->getWritableNodeDefManager();
                ndef->removeNode(name);
        }
 
@@ -589,7 +645,8 @@ int ModApiItemMod::l_register_alias_raw(lua_State *L)
        std::string convert_to = luaL_checkstring(L, 2);
 
        // Get the writable item definition manager from the server
-       IWritableItemDefManager *idef = getGameDef(L)->getWritableItemDefManager();
+       IWritableItemDefManager *idef =
+                       getGameDef(L)->getWritableItemDefManager();
 
        idef->registerAlias(name, convert_to);
 
@@ -602,8 +659,8 @@ int ModApiItemMod::l_get_content_id(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        std::string name = luaL_checkstring(L, 1);
 
-       const IItemDefManager *idef = getGameDef(L)->getItemDefManager();
-       const NodeDefManager *ndef = getGameDef(L)->getNodeDefManager();
+       const IItemDefManager *idef = getGameDef(L)->idef();
+       const NodeDefManager *ndef = getGameDef(L)->ndef();
 
        // If this is called at mod load time, NodeDefManager isn't aware of
        // aliases yet, so we need to handle them manually
@@ -612,8 +669,8 @@ int ModApiItemMod::l_get_content_id(lua_State *L)
        content_t content_id;
        if (alias_name != name) {
                if (!ndef->getId(alias_name, content_id))
-                       throw LuaError("Unknown node: " + alias_name + " (from alias " +
-                                       name + ")");
+                       throw LuaError("Unknown node: " + alias_name +
+                                       " (from alias " + name + ")");
        } else if (!ndef->getId(name, content_id)) {
                throw LuaError("Unknown node: " + name);
        }
@@ -628,7 +685,7 @@ int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        content_t c = luaL_checkint(L, 1);
 
-       const NodeDefManager *ndef = getGameDef(L)->getNodeDefManager();
+       const NodeDefManager *ndef = getGameDef(L)->ndef();
        const char *name = ndef->get(c).name.c_str();
 
        lua_pushstring(L, name);
@@ -643,3 +700,10 @@ void ModApiItemMod::Initialize(lua_State *L, int top)
        API_FCT(get_content_id);
        API_FCT(get_name_from_content_id);
 }
+
+void ModApiItemMod::InitializeAsync(lua_State *L, int top)
+{
+       // all read-only functions
+       API_FCT(get_content_id);
+       API_FCT(get_name_from_content_id);
+}