mt-mods / technic

Technic mod for Minetest

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fuel-fired alloy furnaces destroy fuel when dug

Kimapr opened this issue · comments

When you dig a fuel-fired furnace with it's input and output slots empty, but the fuel slot filled with fuel, it lets you dig it while not dropping fuel.
I found this bug while playing a game with diggable_chests, and assumed it's a bug with that mod, but this also happens without that mod installed. Also, because the mod uses can_dig to determine if it should change the default digging behavior of nodes, and technic's can_dig has a side effect of printing an error message, digging a non-empty technic machine will cause an "can't dig machine because not empty" error to display while still allowing you to dig the node. (i could probably fix this by simply always taking all items from all inventories without calling can_dig at all, which would work around the fuel loss issue as well)

you are right, can_dig delegates to here:

function technic.machine_can_dig(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("src") or not inv:is_empty("dst") then
if player then
minetest.chat_send_player(player:get_player_name(),
S("Machine cannot be removed because it is not empty"))
end
return false
end
return true
end

Not sure yet how to fix both issues (the message and the fuel inventory check).

This might be better refactored to a method-factory, kinda like this:

function technic.machine_can_dig(opts)
 return function(pos, player)
  if opts.message then
   -- stuff
  end
  for _, invname in ipairs(opts.inventories or {}) do
   -- check inventories
  end
 end
end

Suggestions welcome 😉

The bug is easy to fix, just extending the if statement:

-if not inv:is_empty("src") or not inv:is_empty("dst") then
+if not inv:is_empty("src") or not inv:is_empty("dst") or not inv:is_empty("fuel") then

The chat message could be avoided, as you said, by removing the items before trying to dig the node (which I think is a better way to do it anyway). I was thinking though, why does there even need to be a chat message? It's fairly easy to figure out why you can't dig the machine.

commented

This might be better refactored to a method-factory, kinda like this:

This would be best for flexibility and extensibility, however changing existing technic.machine_can_dig(opts) to work as factory method might not be good idea because it'll break machine outside technic mod and would affect API compatibility.
There's workaround of course to make it work without introducing new API function: dynamic function through metatable index or restoring previous behavior when all mods have been loaded.

Another somewhat similar option would be to add optional options table to node def but not sure if it is good idea to extend nodedefs that far...

Of course one option is to just fix this for specific machine definition, that could also make sense because most technic machines do not use fuel inventories. There one could do:

can_dig = function(pos, player)
	return technic.machine_can_dig(pos, player) and minetest.get_meta(pos):get_inventory():is_empty("fuel")
end,