Page 1 of 1

[Mod Request] Auto-Furnace

PostPosted: Mon Jul 23, 2012 06:30
by cheapie
I was hoping somebody could make a furnace that could take objects from a locked chest on one side, smelt/cook/whatever them, and output the result into a locked chest on the other side. The fuel would come from a pipe (from the oil mod) carrying fuel.

PostPosted: Mon Jul 23, 2012 08:45
by Calinou
Probably possible but very tricky (you have to take an item from a chest then put it in a furnace using Lua).

PostPosted: Mon Jul 23, 2012 08:52
by PilzAdam
Its not that tricky. Just make an ABM on furnaces check weather the burn-slot it empty. When it is you can search for chests and get there inventory with "minetest.env:get_meta(pos):get_inventory()" and then get the first stack "inv:get_stack("main", 1)", delete it in the chest"inv:set_stack("main", 1, nil)" and place it in the furnace with "furnace_in:set_stack("src", 1, stack)".

PostPosted: Mon Jul 23, 2012 09:36
by cheapie
Now that I think about it... how about just a furnace that, when there is no fuel, turns a nearby oil:pipe_fuel into an oil:pipe_empty and adds an oil:fuel_bucket to the fuel slot? I don't really care about the chest operations too much.

PostPosted: Mon Jul 23, 2012 21:26
by cheapie
I managed to get the fuel part working (from a fuel pipe running underneath it). Here's the init.lua:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
default.furnace_inactive_formspec =
    "invsize[8,9;]"..
    "image[2,2;1,1;default_furnace_fire_bg.png]"..
    "list[current_name;fuel;2,3;1,1;]"..
    "list[current_name;src;2,1;1,1;]"..
    "list[current_name;dst;5,1;2,2;]"..
    "list[current_player;main;0,5;8,4;]"

minetest.register_node("autofurnace:furnace", {
    description = "Furnace",
    tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
        "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
    paramtype2 = "facedir",
    groups = {cracky=2},
    legacy_facedir_simple = true,
    sounds = default.node_sound_stone_defaults(),
    on_construct = function(pos)
        local meta = minetest.env:get_meta(pos)
        meta:set_string("formspec", default.furnace_inactive_formspec)
        meta:set_string("infotext", "Furnace")
        local inv = meta:get_inventory()
        inv:set_size("fuel", 1)
        inv:set_size("src", 1)
        inv:set_size("dst", 4)
    end,
    can_dig = function(pos,player)
        local meta = minetest.env:get_meta(pos);
        local inv = meta:get_inventory()
        if not inv:is_empty("fuel") then
            return false
        elseif not inv:is_empty("dst") then
            return false
        elseif not inv:is_empty("src") then
            return false
        end
        return true
    end,
})

minetest.register_node("autofurnace:furnace_active", {
    description = "Furnace",
    tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
        "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
    paramtype2 = "facedir",
    light_source = 8,
    drop = "autofurnace:furnace",
    groups = {cracky=2},
    legacy_facedir_simple = true,
    sounds = default.node_sound_stone_defaults(),
    on_construct = function(pos)
        local meta = minetest.env:get_meta(pos)
        meta:set_string("formspec", default.furnace_inactive_formspec)
        meta:set_string("infotext", "Furnace");
        local inv = meta:get_inventory()
        inv:set_size("fuel", 1)
        inv:set_size("src", 1)
        inv:set_size("dst", 4)
    end,
    can_dig = function(pos,player)
        local meta = minetest.env:get_meta(pos);
        local inv = meta:get_inventory()
        if not inv:is_empty("fuel") then
            return false
        elseif not inv:is_empty("dst") then
            return false
        elseif not inv:is_empty("src") then
            return false
        end
        return true
    end,
})

function hacky_swap_node(pos,name)
    local node = minetest.env:get_node(pos)
    local meta = minetest.env:get_meta(pos)
    local meta0 = meta:to_table()
    if node.name == name then
        return
    end
    node.name = name
    local meta0 = meta:to_table()
    minetest.env:set_node(pos,node)
    meta = minetest.env:get_meta(pos)
    meta:from_table(meta0)
end

minetest.register_abm({
    nodenames = {"autofurnace:furnace","autofurnace:furnace_active"},
    interval = 1.0,
    chance = 1,
    action = function(pos, node, active_object_count, active_object_count_wider)
        local meta = minetest.env:get_meta(pos)
        for i, name in ipairs({
                "fuel_totaltime",
                "fuel_time",
                "src_totaltime",
                "src_time"
        }) do
            if meta:get_string(name) == "" then
                meta:set_float(name, 0.0)
            end
        end

        local inv = meta:get_inventory()

        local srclist = inv:get_list("src")
        local cooked = nil
       
        if srclist then
            cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
        end
       
        local was_active = false
       
        if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
            was_active = true
            meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
            meta:set_float("src_time", meta:get_float("src_time") + 1)
            if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
                -- check if there's room for output in "dst" list
                if inv:room_for_item("dst",cooked.item) then
                    -- Put result in "dst" list
                    inv:add_item("dst", cooked.item)
                    -- take stuff from "src" list
                    srcstack = inv:get_stack("src", 1)
                    srcstack:take_item()
                    inv:set_stack("src", 1, srcstack)
                else
                    print("Could not insert item")
                end
                meta:set_string("src_time", 0)
            end
        end
       
        if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
            local percent = math.floor(meta:get_float("fuel_time") /
                    meta:get_float("fuel_totaltime") * 100)
            meta:set_string("infotext","Furnace active: "..percent.."%")
            hacky_swap_node(pos,"autofurnace:furnace_active")
            meta:set_string("formspec",
                "invsize[8,9;]"..
                "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
                        (100-percent)..":default_furnace_fire_fg.png]"..
                "list[current_name;fuel;2,3;1,1;]"..
                "list[current_name;src;2,1;1,1;]"..
                "list[current_name;dst;5,1;2,2;]"..
                "list[current_player;main;0,5;8,4;]")
            return
        end

        local fuel = nil
        local cooked = nil
        local fuellist = inv:get_list("fuel")
        local srclist = inv:get_list("src")
       
        if srclist then
            cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
        end
        if fuellist then
            fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
        end

        if fuel.time <= 0 then
            meta:set_string("infotext","Furnace out of fuel")
            hacky_swap_node(pos,"autofurnace:furnace")
            meta:set_string("formspec", default.furnace_inactive_formspec)
            fpos = {x=pos.x, y=pos.y - 1, z=pos.z}
            fnode = minetest.env:get_node(fpos)
            if (fnode.name == "oil:pipe_fuel") then
                minetest.env:add_node(fpos, {name="oil:pipe_empty"})
                inv:add_item("fuel", "oil:fuel_bucket")
            end   
            return
        end

        if cooked.item:is_empty() then
            if was_active then
                meta:set_string("infotext","Furnace is empty")
                hacky_swap_node(pos,"autofurnace:furnace")
                meta:set_string("formspec", default.furnace_inactive_formspec)
            end
            return
        end

        meta:set_string("fuel_totaltime", fuel.time)
        meta:set_string("fuel_time", 0)
       
        local stack = inv:get_stack("fuel", 1)
        stack:take_item()
        inv:set_stack("fuel", 1, stack)
    end,
})

PostPosted: Mon Jul 23, 2012 22:56
by Nexdah
This sounds a lot like the buildcraft/industrialcraft mod in minecraft

PostPosted: Tue Jul 24, 2012 02:21
by SegFault22
propane power :D

PostPosted: Tue Oct 02, 2012 22:05
by chris36202
hmm thats nice i put my ores when im done mineing then wela maby it can be like in the tecnic mod elcrit power not coal

PostPosted: Wed Oct 03, 2012 05:17
by tinoesroho
I had a working "Rail-furnace" script that would take ores from a cart and smelt it over in the carts thread. It's nice, but I couldn't figure out how to get it to dump the result back into a cart.