Working implementation of experimental:luafurnace
authorPerttu Ahola <celeron55@gmail.com>
Tue, 6 Dec 2011 16:07:13 +0000 (18:07 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Mon, 2 Jan 2012 00:59:14 +0000 (02:59 +0200)
data/builtin.lua
data/mods/experimental/init.lua
src/scriptapi.cpp

index 555cc3ab83e5026f84fe9723eaf0aaac794d0121..b2ce96881f676265fd46eefc2b097140dc98cc97 100644 (file)
@@ -301,7 +301,7 @@ end
 test_stackstring()
 
 --
--- nodeitem helpers
+-- NodeItem helpers
 --
 
 minetest.inventorycube = function(img1, img2, img3)
@@ -314,7 +314,7 @@ minetest.inventorycube = function(img1, img2, img3)
 end
 
 --
--- craftitem helpers
+-- CraftItem helpers
 --
 
 minetest.craftitem_place_item = function(item, placer, pos)
index 2c28f89f9bfaf7351044a878960ba6697823e1cf..2aae9b1998b591475ab19af2b3c77c780ecc45fa 100644 (file)
@@ -56,6 +56,15 @@ minetest.register_on_placenode(function(pos, newnode, placer)
        end
 end)
 
+local get_item_definition = function(item)
+       if not item then return nil end
+       if item.type == "node" then
+               return minetest.registered_nodes[item.name]
+       elseif item.type == "craft" then
+               return minetest.registered_craftitems[item.name]
+       end
+end
+
 minetest.register_abm({
        nodenames = {"experimental:luafurnace"},
        interval = 1.0,
@@ -68,58 +77,54 @@ minetest.register_abm({
                                "src_totaltime",
                                "src_time"
                }) do
-                       if not tonumber(meta:get_string(name)) then
+                       if not meta:get_string(name) then
                                meta:set_string(name, 0)
                        end
                end
 
                local inv = meta:get_inventory()
                
-               fuelitem = inv:get_stack("fuel", 1):peek_item()
-               srcitem = inv:get_stack("src", 1):peek_item()
+               local fuelitem = inv:get_stack("fuel", 1):peek_item()
+               local srcitem = inv:get_stack("src", 1):peek_item()
+               --print("fuelitem="..dump(fuelitem))
+               --print("srcitem="..dump(srcitem))
                
-               local cooked_something = false
+               local was_active = false
 
                local src_cooktime = -1
                local result_stackstring = nil
                
                if srcitem then
-                       local prop = nil
-                       if srcitem.type == "node" then
-                               prop = minetest.registered_nodes[srcitem.name]
-                       elseif srcitem.type == "craft" then
-                               prop = minetest.registered_craftitems[srcitem.name]
-                       end
+                       local prop = get_item_definition(srcitem)
                        if prop and prop.cookresult_itemstring ~= "" then
                                result_stackstring = prop.cookresult_itemstring
                                src_cooktime = prop.furnace_cooktime or 3
                        end
                end
 
+               print("src_cooktime="..dump(src_cooktime))
+               print("result_stackstring="..dump(result_stackstring))
+
                if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
+                       was_active = true
                        meta:set_string("fuel_time", tonumber(meta:get_string("fuel_time")) + 1)
                        meta:set_string("src_time", tonumber(meta:get_string("src_time")) + 1)
                        --print("result_stackstring="..dump(result_stackstring))
                        --print('tonumber(meta:get_string("src_time"))='..dump(tonumber(meta:get_string("src_time"))))
                        --print("src_cooktime="..dump(src_cooktime))
                        if result_stackstring and tonumber(meta:get_string("src_time")) >= src_cooktime and src_cooktime >= 0 then
-                               for i=1,4 do
-                                       -- Put result in "dst" list
-                                       dststack = inv:get_stack("dst", i)
-                                       success = dststack:put_stackstring(result_stackstring)
-                                       inv:set_stack("dst", i, dststack)
-                                       -- If succeeded, take stuff from "src" list
-                                       if success then
-                                               srcstack = inv:get_stack("src", 1)
-                                               srcstack:take_item()
-                                               inv:set_stack("src", 1, srcstack)
-                                               break
-                                       end
+                               -- Put result in "dst" list
+                               success = inv:autoinsert_stackstring("dst", result_stackstring)
+                               if not success then
+                                       print("Could not autoinsert '"..result_stackstring.."'")
+                               end
+                               -- If succeeded, take stuff from "src" list
+                               if success then
+                                       srcstack = inv:get_stack("src", 1)
+                                       srcstack:take_item()
+                                       inv:set_stack("src", 1, srcstack)
                                end
-                               meta:inventory_set_list("src", srclist)
-                               meta:inventory_set_list("dst", dstlist)
                                meta:set_string("src_time", 0)
-                               cooked_something = true
                        end
                end
                
@@ -128,50 +133,33 @@ minetest.register_abm({
                        return
                end
 
-               local srclist = meta:inventory_get_list("src")
-               _, srcitem = stackstring_take_item(srclist[1])
+               local srcitem = inv:get_stack("src", 1):peek_item()
 
                local src_cooktime = 0
                local result_stackstring = nil
                
                if srcitem then
-                       if srcitem.type == "node" then
-                               local prop = minetest.registered_nodes[srcitem.name]
-                               if prop and prop.cookresult_itemstring ~= "" then
-                                       result_stackstring = prop.cookresult_itemstring
-                                       src_cooktime = prop.furnace_cooktime or 3
-                               end
-                       elseif srcitem.type == "craft" then
-                               local prop = minetest.registered_craftitems[srcitem.name]
-                               if prop and prop.cookresult_itemstring ~= "" then
-                                       result_stackstring = prop.cookresult_itemstring
-                                       src_cooktime = prop.furnace_cooktime or 3
-                               end
+                       local prop = get_item_definition(srcitem)
+                       if prop and prop.cookresult_itemstring ~= "" then
+                               result_stackstring = prop.cookresult_itemstring
+                               src_cooktime = prop.furnace_cooktime or 3
                        end
                end
 
-               if not result_stackstring then
-                       if cooked_something then
+               local fuelitem = inv:get_stack("fuel", 1):peek_item()
+
+               if not result_stackstring or not fuelitem then
+                       if was_active then
                                meta:set_infotext("Furnace is empty")
                        end
                        return
                end
 
-               local fuellist = meta:inventory_get_list("fuel")
-               _, fuelitem = stackstring_take_item(fuellist[1])
-
                local burntime = -1
                if fuelitem then
-                       if fuelitem.type == "node" then
-                               local prop = minetest.registered_nodes[fuelitem.name]
-                               if prop then
-                                       burntime = prop.furnace_burntime or -1
-                               end
-                       elseif fuelitem.type == "craft" then
-                               local prop = minetest.registered_craftitems[fuelitem.name]
-                               if prop then
-                                       burntime = prop.furnace_burntime or -1
-                               end
+                       local prop = get_item_definition(fuelitem)
+                       if prop then
+                               burntime = prop.furnace_burntime or -1
                        end
                end
 
@@ -182,9 +170,10 @@ minetest.register_abm({
 
                meta:set_string("fuel_totaltime", burntime)
                meta:set_string("fuel_time", 0)
-
-               fuellist[1], _ = stackstring_take_item(fuellist[1])
-               meta:inventory_set_list("fuel", fuellist)
+               
+               local stack = inv:get_stack("fuel", 1)
+               stack:take_item()
+               inv:set_stack("fuel", 1, stack)
        end,
 })
 --[[
index 2efb8203df1ae3dacc75ff9426bcc11feed747e3..c6a44c914791b8f0fd6102b3d259b73c786cc099 100644 (file)
@@ -609,7 +609,7 @@ static void push_stack_item(lua_State *L, InventoryItem *item0)
        else if(std::string("MaterialItem") == item0->getName()){
                MaterialItem *item = (MaterialItem*)item0;
                lua_newtable(L);
-               lua_pushstring(L, "NodeItem");
+               lua_pushstring(L, "node");
                lua_setfield(L, -2, "type");
                lua_pushstring(L, item->getNodeName().c_str());
                lua_setfield(L, -2, "name");
@@ -617,7 +617,7 @@ static void push_stack_item(lua_State *L, InventoryItem *item0)
        else if(std::string("CraftItem") == item0->getName()){
                CraftItem *item = (CraftItem*)item0;
                lua_newtable(L);
-               lua_pushstring(L, "CraftItem");
+               lua_pushstring(L, "craft");
                lua_setfield(L, -2, "type");
                lua_pushstring(L, item->getSubName().c_str());
                lua_setfield(L, -2, "name");
@@ -625,7 +625,7 @@ static void push_stack_item(lua_State *L, InventoryItem *item0)
        else if(std::string("ToolItem") == item0->getName()){
                ToolItem *item = (ToolItem*)item0;
                lua_newtable(L);
-               lua_pushstring(L, "ToolItem");
+               lua_pushstring(L, "tool");
                lua_setfield(L, -2, "type");
                lua_pushstring(L, item->getToolName().c_str());
                lua_setfield(L, -2, "name");
@@ -1093,7 +1093,7 @@ private:
        {
                InvRef *ref = checkobject(L, 1);
                const char *listname = luaL_checkstring(L, 2);
-               int i = luaL_checknumber(L, 3);
+               int i = luaL_checknumber(L, 3) - 1;
                InventoryItem *item = getitem(L, ref, listname, i);
                if(!item){
                        ItemStack::create(L, NULL);
@@ -1108,7 +1108,7 @@ private:
        {
                InvRef *ref = checkobject(L, 1);
                const char *listname = luaL_checkstring(L, 2);
-               int i = luaL_checknumber(L, 3);
+               int i = luaL_checknumber(L, 3) - 1;
                ItemStack *stack = ItemStack::checkobject(L, 4);
                InventoryList *list = getlist(L, ref, listname);
                if(!list){
@@ -1151,6 +1151,53 @@ private:
                return 0;
        }
 
+       // autoinsert_stack(self, listname, stack)
+       static int l_autoinsert_stack(lua_State *L)
+       {
+               InvRef *ref = checkobject(L, 1);
+               const char *listname = luaL_checkstring(L, 2);
+               ItemStack *stack = ItemStack::checkobject(L, 3);
+               InventoryList *list = getlist(L, ref, listname);
+               if(!list){
+                       lua_pushboolean(L, false);
+                       return 1;
+               }
+               InventoryItem *item = stack->getItemCopy();
+               if(list->roomForItem(item)){
+                       delete list->addItem(item);
+                       lua_pushboolean(L, true);
+                       reportInventoryChange(L, ref);
+               } else {
+                       delete item;
+                       lua_pushboolean(L, false);
+               }
+               return 1;
+       }
+
+       // autoinsert_stackstring(self, listname, stackstring)
+       static int l_autoinsert_stackstring(lua_State *L)
+       {
+               InvRef *ref = checkobject(L, 1);
+               const char *listname = luaL_checkstring(L, 2);
+               const char *stackstring = luaL_checkstring(L, 3);
+               InventoryList *list = getlist(L, ref, listname);
+               if(!list){
+                       lua_pushboolean(L, false);
+                       return 1;
+               }
+               InventoryItem *item = InventoryItem::deSerialize(stackstring,
+                               get_server(L));
+               if(list->roomForItem(item)){
+                       delete list->addItem(item);
+                       lua_pushboolean(L, true);
+                       reportInventoryChange(L, ref);
+               } else {
+                       delete item;
+                       lua_pushboolean(L, false);
+               }
+               return 1;
+       }
+
 public:
        InvRef(const InventoryLocation &loc):
                m_loc(loc)
@@ -1219,6 +1266,8 @@ const luaL_reg InvRef::methods[] = {
        method(InvRef, set_stack),
        method(InvRef, get_list),
        method(InvRef, set_list),
+       method(InvRef, autoinsert_stack),
+       method(InvRef, autoinsert_stackstring),
        {0,0}
 };