From 6be5441176a14137b92f03d9d519234ebee28f6c Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Tue, 6 Dec 2011 18:07:13 +0200 Subject: [PATCH] Working implementation of experimental:luafurnace --- data/builtin.lua | 4 +- data/mods/experimental/init.lua | 103 ++++++++++++++------------------ src/scriptapi.cpp | 59 ++++++++++++++++-- 3 files changed, 102 insertions(+), 64 deletions(-) diff --git a/data/builtin.lua b/data/builtin.lua index 555cc3ab8..b2ce96881 100644 --- a/data/builtin.lua +++ b/data/builtin.lua @@ -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) diff --git a/data/mods/experimental/init.lua b/data/mods/experimental/init.lua index 2c28f89f9..2aae9b199 100644 --- a/data/mods/experimental/init.lua +++ b/data/mods/experimental/init.lua @@ -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, }) --[[ diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 2efb8203d..c6a44c914 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -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} };