--formspecs
+local chest = {}
-local furnace = {}
+local path = minetest.get_modpath("utility")
-function furnace.get_hotbar_bg(x,y)
- local out = ""
- for i=0,7,1 do
- out = out .."image["..x+i..","..y..";1,1;gui_furnace_arrow_bg.png]"
- end
- return(out)
-end
-
-function furnace.get_inventory_drops(pos, inventory, drops)
- local inv = minetest.get_meta(pos):get_inventory()
- local n = #drops
- for i = 1, inv:get_size(inventory) do
- local stack = inv:get_stack(inventory, i)
- if stack:get_count() > 0 then
- drops[n+1] = stack:to_table()
- n = n + 1
- end
- end
-end
-
-function furnace.get_furnace_active_formspec(fuel_percent, item_percent)
- return "size[8,8.5]"..
- "list[context;src;2.75,0.5;1,1;]"..
- "list[context;fuel;2.75,2.5;1,1;]"..
- "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
- (fuel_percent)..":default_furnace_fire_fg.png]"..
- "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
- (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]"..
- "list[context;dst;4.75,0.96;2,2;]"..
- "list[current_player;main;0,4.25;8,1;]"..
- "list[current_player;main;0,5.5;8,3;8]"..
- "listring[context;dst]"..
- "listring[current_player;main]"..
- "listring[context;src]"..
- "listring[current_player;main]"..
- "listring[context;fuel]"..
- "listring[current_player;main]"..
- furnace.get_hotbar_bg(0, 4.25)
-end
-
-function furnace.get_furnace_inactive_formspec()
- return "size[8,8.5]"..
- "list[context;src;2.75,0.5;1,1;]"..
- "list[context;fuel;2.75,2.5;1,1;]"..
- "image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
- "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
- "list[context;dst;4.75,0.96;2,2;]"..
- "list[current_player;main;0,4.25;8,1;]"..
- "list[current_player;main;0,5.5;8,3;8]"..
- "listring[context;dst]"..
- "listring[current_player;main]"..
- "listring[context;src]"..
- "listring[current_player;main]"..
- "listring[context;fuel]"..
- "listring[current_player;main]"..
- furnace.get_hotbar_bg(0, 4.25)
-end
-
---
--- Node callback functions that are the same for active and inactive furnace
---
-
-local function can_dig(pos, player)
- local meta = minetest.get_meta(pos);
- local inv = meta:get_inventory()
- return inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src")
-end
-
-local function allow_metadata_inventory_put(pos, listname, index, stack, player)
- if minetest.is_protected(pos, player:get_player_name()) then
- return 0
- end
- local meta = minetest.get_meta(pos)
- local inv = meta:get_inventory()
- if listname == "fuel" then
- if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
- if inv:is_empty("src") then
- meta:set_string("infotext", "Furnace is empty")
- end
- return stack:get_count()
- else
- return 0
- end
- elseif listname == "src" then
- return stack:get_count()
- elseif listname == "dst" then
- return 0
- end
-end
-
-local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
- local meta = minetest.get_meta(pos)
- local inv = meta:get_inventory()
- local stack = inv:get_stack(from_list, from_index)
- return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
-end
-
-local function allow_metadata_inventory_take(pos, listname, index, stack, player)
- if minetest.is_protected(pos, player:get_player_name()) then
- return 0
- end
- return stack:get_count()
-end
-
-local function swap_node(pos, name)
- local node = minetest.get_node(pos)
- if node.name == name then
- return
- end
- node.name = name
- minetest.swap_node(pos, node)
-end
-
-local function furnace_node_timer(pos, elapsed)
- --
- -- Initialize metadata
- --
- local meta = minetest.get_meta(pos)
- local fuel_time = meta:get_float("fuel_time") or 0
- local src_time = meta:get_float("src_time") or 0
- local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
-
- local inv = meta:get_inventory()
- local srclist, fuellist
- local dst_full = false
-
- local cookable, cooked
- local fuel
-
- local update = true
- while elapsed > 0 and update do
- update = false
-
- srclist = inv:get_list("src")
- fuellist = inv:get_list("fuel")
-
- --
- -- Cooking
- --
-
- -- Check if we have cookable content
- local aftercooked
- cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
- cookable = cooked.time ~= 0
-
- local el = math.min(elapsed, fuel_totaltime - fuel_time)
- if cookable then -- fuel lasts long enough, adjust el to cooking duration
- el = math.min(el, cooked.time - src_time)
- end
-
- -- Check if we have enough fuel to burn
- if fuel_time < fuel_totaltime then
- -- The furnace is currently active and has enough fuel
- fuel_time = fuel_time + el
- -- If there is a cookable item then check if it is ready yet
- if cookable then
- src_time = src_time + el
- if src_time >= cooked.time then
- -- Place result in dst list if possible
- if inv:room_for_item("dst", cooked.item) then
- inv:add_item("dst", cooked.item)
- inv:set_stack("src", 1, aftercooked.items[1])
- src_time = src_time - cooked.time
- update = true
- else
- dst_full = true
- end
- else
- -- Item could not be cooked: probably missing fuel
- update = true
- end
- end
- else
- -- Furnace ran out of fuel
- if cookable then
- -- We need to get new fuel
- local afterfuel
- fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
-
- if fuel.time == 0 then
- -- No valid fuel in fuel list
- fuel_totaltime = 0
- src_time = 0
- else
- -- Take fuel from fuel list
- inv:set_stack("fuel", 1, afterfuel.items[1])
- -- Put replacements in dst list or drop them on the furnace.
- local replacements = fuel.replacements
- if replacements[1] then
- local leftover = inv:add_item("dst", replacements[1])
- if not leftover:is_empty() then
- local above = vector.new(pos.x, pos.y + 1, pos.z)
- local drop_pos = minetest.find_node_near(above, 1, {"air"}) or above
- minetest.item_drop(replacements[1], nil, drop_pos)
- end
- end
- update = true
- fuel_totaltime = fuel.time + (fuel_totaltime - fuel_time)
- end
- else
- -- We don't need to get new fuel since there is no cookable item
- fuel_totaltime = 0
- src_time = 0
- end
- fuel_time = 0
- end
-
- elapsed = elapsed - el
- end
-
- if fuel and fuel_totaltime > fuel.time then
- fuel_totaltime = fuel.time
- end
- if srclist and srclist[1]:is_empty() then
- src_time = 0
- end
-
- --
- -- Update formspec, infotext and node
- --
- local formspec
- local item_state
- local item_percent = 0
- if cookable then
- item_percent = math.floor(src_time / cooked.time * 100)
- if dst_full then
- item_state = "100% (output full)"
- else
- item_state = "@1%", item_percent
- end
- else
- if srclist and not srclist[1]:is_empty() then
- item_state = "Not cookable"
- else
- item_state = "Empty"
- end
- end
-
- local fuel_state = "Empty"
- local active = false
- local result = false
-
- if fuel_totaltime ~= 0 then
- active = true
- local fuel_percent = 100 - math.floor(fuel_time / fuel_totaltime * 100)
- fuel_state = "@1%", fuel_percent
- formspec = furnace.get_furnace_active_formspec(fuel_percent, item_percent)
- swap_node(pos, "utility:furnace_active")
- -- make sure timer restarts automatically
- result = true
- else
- if fuellist and not fuellist[1]:is_empty() then
- fuel_state = "@1%", 0
- end
- formspec = furnace.get_furnace_inactive_formspec()
- swap_node(pos, "utility:furnace")
- -- stop timer on the inactive furnace
- minetest.get_node_timer(pos):stop()
- end
-
-
- local infotext
- if active then
- infotext = "Furnace active"
- else
- infotext = "Furnace inactive"
- end
- infotext = infotext .. "\n" .. "(Item: @1; Fuel: @2)", item_state, fuel_state
-
- --
- -- Set meta values
- --
- meta:set_float("fuel_totaltime", fuel_totaltime)
- meta:set_float("fuel_time", fuel_time)
- meta:set_float("src_time", src_time)
- meta:set_string("formspec", formspec)
- meta:set_string("infotext", infotext)
-
- return result
-end
-
---
--- Node definitions
---
-
-minetest.register_node("utility:furnace", {
- description = "Furnace",
- tiles = {
- "furnace_top.png", "furnace_bottom.png",
- "furnace_side.png", "furnace_side.png",
- "furnace_side.png", "furnace_front.png"
- },
- paramtype2 = "facedir",
- groups = {stone=2},
- legacy_facedir_simple = true,
- is_ground_content = false,
- sounds = main.stoneSound(),
-
- can_dig = can_dig,
-
- on_timer = furnace_node_timer,
-
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- local inv = meta:get_inventory()
- inv:set_size('src', 1)
- inv:set_size('fuel', 1)
- inv:set_size('dst', 4)
- furnace_node_timer(pos, 0)
- end,
-
- on_metadata_inventory_move = function(pos)
- minetest.get_node_timer(pos):start(1.0)
- end,
- on_metadata_inventory_put = function(pos)
- -- start timer function, it will sort out whether furnace can burn or not.
- minetest.get_node_timer(pos):start(1.0)
- end,
- on_blast = function(pos)
- local drops = {}
- furnace.get_inventory_drops(pos, "src", drops)
- furnace.get_inventory_drops(pos, "fuel", drops)
- furnace.get_inventory_drops(pos, "dst", drops)
- drops[#drops+1] = "default:furnace"
- minetest.remove_node(pos)
- return drops
- end,
-
- allow_metadata_inventory_put = allow_metadata_inventory_put,
- allow_metadata_inventory_move = allow_metadata_inventory_move,
- allow_metadata_inventory_take = allow_metadata_inventory_take,
-})
-
-minetest.register_node("utility:furnace_active", {
- description = "Furnace",
- tiles = {
- "furnace_top.png", "furnace_bottom.png",
- "furnace_side.png", "furnace_side.png",
- "furnace_side.png",
- {
- image = "furnace_front_active.png",
- backface_culling = false,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 1.5
- },
- }
- },
- paramtype2 = "facedir",
- light_source = 8,
- drop = "default:furnace",
- groups = {stone=2, not_in_creative_inventory=1},
- legacy_facedir_simple = true,
- is_ground_content = false,
- sounds = main.stoneSound(),
- on_timer = furnace_node_timer,
-
- can_dig = can_dig,
-
- allow_metadata_inventory_put = allow_metadata_inventory_put,
- allow_metadata_inventory_move = allow_metadata_inventory_move,
- allow_metadata_inventory_take = allow_metadata_inventory_take,
-})
-
-minetest.register_craft({
- output = "utility:furnace",
- recipe = {
- {"main:stone", "main:stone", "main:stone"},
- {"main:stone", "", "main:stone"},
- {"main:stone", "main:stone", "main:stone"},
- }
-})
+dofile(path.."/furnace.lua")