Skip to content

Commit 66a2113

Browse files
authored
Fix replacement items being lost in furnace (#3208)
1 parent aac492d commit 66a2113

File tree

1 file changed

+57
-35
lines changed

1 file changed

+57
-35
lines changed

mods/default/furnace.lua

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,19 @@ end
5353
--
5454

5555
local function can_dig(pos, player)
56-
local meta = minetest.get_meta(pos);
56+
local meta = core.get_meta(pos)
5757
local inv = meta:get_inventory()
5858
return inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src")
5959
end
6060

6161
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
62-
if minetest.is_protected(pos, player:get_player_name()) then
62+
if core.is_protected(pos, player:get_player_name()) then
6363
return 0
6464
end
65-
local meta = minetest.get_meta(pos)
65+
local meta = core.get_meta(pos)
6666
local inv = meta:get_inventory()
6767
if listname == "fuel" then
68-
if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
68+
if core.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
6969
if inv:is_empty("src") then
7070
meta:set_string("infotext", S("Furnace is empty"))
7171
end
@@ -81,44 +81,53 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player)
8181
end
8282

8383
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
84-
local meta = minetest.get_meta(pos)
84+
local meta = core.get_meta(pos)
8585
local inv = meta:get_inventory()
8686
local stack = inv:get_stack(from_list, from_index)
8787
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
8888
end
8989

9090
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
91-
if minetest.is_protected(pos, player:get_player_name()) then
91+
if core.is_protected(pos, player:get_player_name()) then
9292
return 0
9393
end
9494
return stack:get_count()
9595
end
9696

9797
local function stop_furnace_sound(pos, fadeout_step)
98-
local hash = minetest.hash_node_position(pos)
98+
local hash = core.hash_node_position(pos)
9999
local sound_ids = furnace_fire_sounds[hash]
100100
if sound_ids then
101101
for _, sound_id in ipairs(sound_ids) do
102-
minetest.sound_fade(sound_id, -1, 0)
102+
core.sound_fade(sound_id, -1, 0)
103103
end
104104
furnace_fire_sounds[hash] = nil
105105
end
106106
end
107107

108108
local function swap_node(pos, name)
109-
local node = minetest.get_node(pos)
109+
local node = core.get_node(pos)
110110
if node.name == name then
111111
return
112112
end
113113
node.name = name
114-
minetest.swap_node(pos, node)
114+
core.swap_node(pos, node)
115+
end
116+
117+
local function add_item_or_drop(inv, pos, item)
118+
local leftover = inv:add_item("dst", item)
119+
if not leftover:is_empty() then
120+
local above = vector.offset(pos, 0, 1, 0)
121+
local drop_pos = core.find_node_near(pos, 1, {"air"}) or above
122+
core.item_drop(leftover, nil, drop_pos)
123+
end
115124
end
116125

117126
local function furnace_node_timer(pos, elapsed)
118127
--
119128
-- Initialize metadata
120129
--
121-
local meta = minetest.get_meta(pos)
130+
local meta = core.get_meta(pos)
122131
local fuel_time = meta:get_float("fuel_time") or 0
123132
local src_time = meta:get_float("src_time") or 0
124133
local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
@@ -132,7 +141,6 @@ local function furnace_node_timer(pos, elapsed)
132141

133142
local cookable, cooked
134143
local fuel
135-
136144
local update = true
137145
local items_smelt = 0
138146
while elapsed > 0 and update do
@@ -147,7 +155,7 @@ local function furnace_node_timer(pos, elapsed)
147155

148156
-- Check if we have cookable content
149157
local aftercooked
150-
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
158+
cooked, aftercooked = core.get_craft_result({method = "cooking", width = 1, items = srclist})
151159
cookable = cooked.time ~= 0
152160

153161
local el = math.min(elapsed, fuel_totaltime - fuel_time)
@@ -166,9 +174,28 @@ local function furnace_node_timer(pos, elapsed)
166174
-- Place result in dst list if possible
167175
if inv:room_for_item("dst", cooked.item) then
168176
inv:add_item("dst", cooked.item)
169-
inv:set_stack("src", 1, aftercooked.items[1])
177+
178+
-- stop any final replacement from clogging "src"
179+
local can_cook = core.get_craft_result({
180+
method = "cooking", width = 1,
181+
items = {aftercooked.items[1]:to_string()}})
182+
can_cook = can_cook.time ~= 0 or not can_cook.item:is_empty()
183+
184+
if aftercooked.items[1]:is_empty() or can_cook then
185+
-- cook the final "src" item in the next cycle
186+
inv:set_stack("src", 1, aftercooked.items[1])
187+
else
188+
-- the final "src" item was replaced and is not cookable
189+
inv:set_stack("src", 1, "")
190+
add_item_or_drop(inv, pos, aftercooked.items[1])
191+
end
192+
170193
src_time = src_time - cooked.time
171194
update = true
195+
-- add replacement item to dst so they arent lost
196+
if cooked.replacements[1] then
197+
add_item_or_drop(inv, pos, cooked.replacements[1])
198+
end
172199
else
173200
dst_full = true
174201
end
@@ -183,15 +210,15 @@ local function furnace_node_timer(pos, elapsed)
183210
if cookable then
184211
-- We need to get new fuel
185212
local afterfuel
186-
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
213+
fuel, afterfuel = core.get_craft_result({method = "fuel", width = 1, items = fuellist})
187214

188215
if fuel.time == 0 then
189216
-- No valid fuel in fuel list
190217
fuel_totaltime = 0
191218
src_time = 0
192219
else
193220
-- prevent blocking of fuel inventory (for automatization mods)
194-
local is_fuel = minetest.get_craft_result({method = "fuel", width = 1, items = {afterfuel.items[1]:to_string()}})
221+
local is_fuel = core.get_craft_result({method = "fuel", width = 1, items = {afterfuel.items[1]:to_string()}})
195222
if is_fuel.time == 0 then
196223
table.insert(fuel.replacements, afterfuel.items[1])
197224
inv:set_stack("fuel", 1, "")
@@ -202,12 +229,7 @@ local function furnace_node_timer(pos, elapsed)
202229
-- Put replacements in dst list or drop them on the furnace.
203230
local replacements = fuel.replacements
204231
if replacements[1] then
205-
local leftover = inv:add_item("dst", replacements[1])
206-
if not leftover:is_empty() then
207-
local above = vector.new(pos.x, pos.y + 1, pos.z)
208-
local drop_pos = minetest.find_node_near(above, 1, {"air"}) or above
209-
minetest.item_drop(replacements[1], nil, drop_pos)
210-
end
232+
add_item_or_drop(inv, pos, replacements[1])
211233
end
212234
update = true
213235
fuel_totaltime = fuel.time + (fuel_totaltime - fuel_time)
@@ -225,7 +247,7 @@ local function furnace_node_timer(pos, elapsed)
225247

226248
if items_smelt > 0 then
227249
-- Play cooling sound
228-
minetest.sound_play("default_cool_lava",
250+
core.sound_play("default_cool_lava",
229251
{ pos = pos, max_hear_distance = 16, gain = 0.07 * math.min(items_smelt, 7) }, true)
230252
end
231253
if fuel and fuel_totaltime > fuel.time then
@@ -271,17 +293,17 @@ local function furnace_node_timer(pos, elapsed)
271293

272294
-- Play sound every 5 seconds while the furnace is active
273295
if timer_elapsed == 0 or (timer_elapsed + 1) % 5 == 0 then
274-
local sound_id = minetest.sound_play("default_furnace_active",
296+
local sound_id = core.sound_play("default_furnace_active",
275297
{pos = pos, max_hear_distance = 16, gain = 0.25})
276-
local hash = minetest.hash_node_position(pos)
298+
local hash = core.hash_node_position(pos)
277299
furnace_fire_sounds[hash] = furnace_fire_sounds[hash] or {}
278300
table.insert(furnace_fire_sounds[hash], sound_id)
279301
-- Only remember the 3 last sound handles
280302
if #furnace_fire_sounds[hash] > 3 then
281303
table.remove(furnace_fire_sounds[hash], 1)
282304
end
283305
-- Remove the sound ID automatically from table after 11 seconds
284-
minetest.after(11, function()
306+
core.after(11, function()
285307
if not furnace_fire_sounds[hash] then
286308
return
287309
end
@@ -302,7 +324,7 @@ local function furnace_node_timer(pos, elapsed)
302324
formspec = default.get_furnace_inactive_formspec()
303325
swap_node(pos, "default:furnace")
304326
-- stop timer on the inactive furnace
305-
minetest.get_node_timer(pos):stop()
327+
core.get_node_timer(pos):stop()
306328
meta:set_int("timer_elapsed", 0)
307329

308330
stop_furnace_sound(pos)
@@ -338,7 +360,7 @@ local function apply_logger(def)
338360
return def
339361
end
340362

341-
minetest.register_node("default:furnace", apply_logger({
363+
core.register_node("default:furnace", apply_logger({
342364
description = S("Furnace"),
343365
tiles = {
344366
"default_furnace_top.png", "default_furnace_bottom.png",
@@ -356,7 +378,7 @@ minetest.register_node("default:furnace", apply_logger({
356378
on_timer = furnace_node_timer,
357379

358380
on_construct = function(pos)
359-
local meta = minetest.get_meta(pos)
381+
local meta = core.get_meta(pos)
360382
local inv = meta:get_inventory()
361383
inv:set_size('src', 1)
362384
inv:set_size('fuel', 1)
@@ -365,23 +387,23 @@ minetest.register_node("default:furnace", apply_logger({
365387
end,
366388

367389
on_metadata_inventory_move = function(pos)
368-
minetest.get_node_timer(pos):start(1.0)
390+
core.get_node_timer(pos):start(1.0)
369391
end,
370392
on_metadata_inventory_put = function(pos)
371393
-- start timer function, it will sort out whether furnace can burn or not.
372-
minetest.get_node_timer(pos):start(1.0)
394+
core.get_node_timer(pos):start(1.0)
373395
end,
374396
on_metadata_inventory_take = function(pos)
375397
-- check whether the furnace is empty or not.
376-
minetest.get_node_timer(pos):start(1.0)
398+
core.get_node_timer(pos):start(1.0)
377399
end,
378400
on_blast = function(pos)
379401
local drops = {}
380402
default.get_inventory_drops(pos, "src", drops)
381403
default.get_inventory_drops(pos, "fuel", drops)
382404
default.get_inventory_drops(pos, "dst", drops)
383405
drops[#drops+1] = "default:furnace"
384-
minetest.remove_node(pos)
406+
core.remove_node(pos)
385407
return drops
386408
end,
387409

@@ -390,7 +412,7 @@ minetest.register_node("default:furnace", apply_logger({
390412
allow_metadata_inventory_take = allow_metadata_inventory_take,
391413
}))
392414

393-
minetest.register_node("default:furnace_active", apply_logger({
415+
core.register_node("default:furnace_active", apply_logger({
394416
description = S("Furnace"),
395417
tiles = {
396418
"default_furnace_top.png", "default_furnace_bottom.png",
@@ -426,7 +448,7 @@ minetest.register_node("default:furnace_active", apply_logger({
426448
allow_metadata_inventory_take = allow_metadata_inventory_take,
427449
}))
428450

429-
minetest.register_craft({
451+
core.register_craft({
430452
output = "default:furnace",
431453
recipe = {
432454
{"group:stone", "group:stone", "group:stone"},

0 commit comments

Comments
 (0)