diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua index 2163f6ae..784075e9 100644 --- a/mods/default/furnace.lua +++ b/mods/default/furnace.lua @@ -163,6 +163,7 @@ minetest.register_abm({ 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 last_gametime = meta:get_float("last_gametime") or minetest.get_gametime() -- -- Inizialize inventory @@ -184,58 +185,84 @@ minetest.register_abm({ -- -- Cooking -- - - -- Check if we have cookable content - local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) - local cookable = true - - if cooked.time == 0 then - cookable = false - 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 + 1 - - -- If there is a cookable item then check if it is ready yet - if cookable then - src_time = src_time + 1 - 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 = 0 + + local cooked, aftercooked, cookable + + -- Get the time delta between last run + local delta = minetest.get_gametime() - last_gametime + last_gametime = minetest.get_gametime() + + -- Simulate the furnace for delta seconds + repeat + -- Check if we still have cookable content + cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cookable = cooked.time ~= 0 + + -- Determine appropriate time step size + local step = delta + local fuel_left = fuel_totaltime - fuel_time + if fuel_totaltime ~= 0 then + if fuel_left > 0 then + -- There is fuel left, step to the time when the cookable item is ready OR when the fuel dies, whichever is nearest + if cookable then + local src_left = cooked.time - src_time + step = math.min(delta, fuel_left, src_left) + else + step = math.min(delta, fuel_left) end + elseif cookable then + -- No fuel left, replacing costs 1 second + step = 1 end end - else - -- Furnace ran out of fuel - if cookable then - -- We need to get new fuel - local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + delta = delta - step + + -- 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 + step - if fuel.time == 0 then - -- No valid fuel in fuel list + -- If there is a cookable item then check if it is ready yet + if cookable then + src_time = src_time + step + 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]) + srclist = inv:get_list("src") + src_time = 0 + end + end + end + else + -- Furnace ran out of fuel + if cookable then + -- We need to get new fuel + local 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 + fuel_time = 0 + src_time = 0 + else + -- Take fuel from fuel list + inv:set_stack("fuel", 1, afterfuel.items[1]) + fuellist = inv:get_list("fuel") + + fuel_totaltime = fuel.time + fuel_time = 0 + + end + else + -- We don't need to get new fuel since there is no cookable item fuel_totaltime = 0 fuel_time = 0 src_time = 0 - else - -- Take fuel from fuel list - inv:set_stack("fuel", 1, afterfuel.items[1]) - - fuel_totaltime = fuel.time - fuel_time = 0 - end - else - -- We don't need to get new fuel since there is no cookable item - fuel_totaltime = 0 - fuel_time = 0 - src_time = 0 end - end + until delta <= 0 -- -- Update formspec, infotext and node @@ -274,6 +301,7 @@ minetest.register_abm({ -- -- Set meta values -- + meta:set_float("last_gametime", last_gametime) meta:set_float("fuel_totaltime", fuel_totaltime) meta:set_float("fuel_time", fuel_time) meta:set_float("src_time", src_time)