From 93384188d5b619644945016121dde9dc9361ce7f Mon Sep 17 00:00:00 2001 From: tour <129965577+a-tour-ist@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:38:20 +0200 Subject: [PATCH] Make mesechest more reliable (#35) The current hack to get on the `on_player_receive_fields` function is quite likely to break with instrumented code. This also changes the workaround to get custom inventory callbacks by using `minetest.override_item`. --- .luacheckrc | 15 +---- moremesecons_mesechest/init.lua | 106 +++++++++++++++----------------- 2 files changed, 52 insertions(+), 69 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 45e7e01..aa5d02e 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1,22 +1,9 @@ read_globals = { -- Defined by Minetest - "vector", "PseudoRandom", "VoxelArea", "table", + "minetest", "vector", "PseudoRandom", "VoxelArea", "table", -- Mods "digiline", "default", "creative", - - -- Required for the mesechest registration - minetest = { - fields = { - register_lbm = {read_only = false}, - register_node = {read_only = false}, - registered_on_player_receive_fields = { - read_only = false, - other_fields = true, - }, - }, - other_fields = true - } } globals = {"moremesecons", "mesecon"} ignore = {"212", "631", "422", "432"} diff --git a/moremesecons_mesechest/init.lua b/moremesecons_mesechest/init.lua index 0d0fea0..2fe26cd 100644 --- a/moremesecons_mesechest/init.lua +++ b/moremesecons_mesechest/init.lua @@ -8,59 +8,8 @@ local function mesechest_get_output_rules(node) return rules end - -local open_chests = {} - --- Override minetest.register_node so it adds a prefix ":" -local old_minetest_register_node = minetest.register_node -minetest.register_node = function(name, def) - local old_on_metadata_inventory_put = def.on_metadata_inventory_put - local old_on_metadata_inventory_take = def.on_metadata_inventory_take - local old_on_rightclick = def.on_rightclick - - def.on_metadata_inventory_put = function(pos, ...) - old_on_metadata_inventory_put(pos, ...) - mesecon.receptor_on(pos, {mesechest_get_output_rules(minetest.get_node(pos))[2]}) - minetest.after(1, function(pos) - mesecon.receptor_off(pos, {mesechest_get_output_rules(minetest.get_node(pos))[2]}) - end, pos) - end - def.on_metadata_inventory_take = function(pos, ...) - old_on_metadata_inventory_take(pos, ...) - mesecon.receptor_on(pos, {mesechest_get_output_rules(minetest.get_node(pos))[3]}) - minetest.after(1, function(pos) - mesecon.receptor_off(pos, {mesechest_get_output_rules(minetest.get_node(pos))[3]}) - end, pos) - end - def.on_rightclick = function(pos, node, clicker, ...) - if old_on_rightclick(pos, node, clicker, ...) == nil then - mesecon.receptor_on(pos, {mesechest_get_output_rules(node)[1]}) - open_chests[clicker:get_player_name()] = pos - end - end - - old_minetest_register_node(":"..name, def) -end -local old_minetest_register_lbm = minetest.register_lbm -minetest.register_lbm = function() end - --- Get the on_player_receive_fields function. That's a huge hack -for i, f in ipairs(minetest.registered_on_player_receive_fields) do - local serialized = minetest.serialize(f) - if string.find(serialized, "default:chest") then - minetest.registered_on_player_receive_fields[i] = function(player, formname, fields) - if f(player, formname, fields) == true then - local pn = player:get_player_name() - if open_chests[pn] then - mesecon.receptor_off(open_chests[pn], {mesechest_get_output_rules(minetest.get_node(open_chests[pn]))[1]}) - open_chests[pn] = nil - end - end - end - break - end -end - +-- default.chest.register_chest() doesn't allow to register most of the callbacks we need +-- we have to override the chest node we registered again default.chest.register_chest("moremesecons_mesechest:mesechest", { description = "Mese Chest", tiles = { @@ -104,8 +53,55 @@ default.chest.register_chest("moremesecons_mesechest:mesechest_locked", { } }) -minetest.register_node = old_minetest_register_node -minetest.register_lbm = old_minetest_register_lbm +local moremesecons_chests = {} + +for _, chest in ipairs({"moremesecons_mesechest:mesechest", "moremesecons_mesechest:mesechest_locked", + "moremesecons_mesechest:mesechest_open", "moremesecons_mesechest:mesechest_locked_open"}) do + local old_def = minetest.registered_nodes[chest] + + local old_on_metadata_inventory_put = old_def.on_metadata_inventory_put + local old_on_metadata_inventory_take = old_def.on_metadata_inventory_take + local old_on_rightclick = old_def.on_rightclick + + local override = {} + override.on_metadata_inventory_put = function(pos, ...) + old_on_metadata_inventory_put(pos, ...) + mesecon.receptor_on(pos, {mesechest_get_output_rules(minetest.get_node(pos))[2]}) + minetest.after(1, function(pos) + mesecon.receptor_off(pos, {mesechest_get_output_rules(minetest.get_node(pos))[2]}) + end, pos) + end + override.on_metadata_inventory_take = function(pos, ...) + old_on_metadata_inventory_take(pos, ...) + mesecon.receptor_on(pos, {mesechest_get_output_rules(minetest.get_node(pos))[3]}) + minetest.after(1, function(pos) + mesecon.receptor_off(pos, {mesechest_get_output_rules(minetest.get_node(pos))[3]}) + end, pos) + end + override.on_rightclick = function(pos, node, clicker, ...) + if old_on_rightclick(pos, node, clicker, ...) == nil then + mesecon.receptor_on(pos, {mesechest_get_output_rules(node)[1]}) + end + end + + minetest.override_item(chest, override) + moremesecons_chests[chest] = true +end + +-- if the chest is getting closed, turn the signal off +-- luacheck: ignore 122 +local old_lid_close = default.chest.chest_lid_close +function default.chest.chest_lid_close(pn) + local pos = default.chest.open_chests[pn].pos + -- old_lid_close will return true if the chest won't be closed + if old_lid_close(pn) then + return true + end + local node = minetest.get_node(pos) + if moremesecons_chests[node.name] then + mesecon.receptor_off(pos, {mesechest_get_output_rules(node)[1]}) + end +end minetest.register_craft({ output = "moremesecons_mesechest:mesechest",