Refactor mcl_chests.register_chest AGAIN + cleanup

Now you can define custom groups for the chests, as shown in the trapped
chests example (now they show up under "Mechanisms" tab in creative!).

I'm a bit suspicious of the new return-wrapped functions, as in *they
might break under some circumstances I didn't observe*. It will require
some heavy testing to make sure nothing crashes in the future.

Also, `on_rightclick` for double chests is something I really want to
return-wrap as well, but failed to do so. 🤷
This commit is contained in:
Mikita Wiśniewski 2024-06-22 16:35:52 +07:00 committed by the-real-herowl
parent 7a5ee4e6e2
commit 16dd8694a6
3 changed files with 262 additions and 285 deletions

View File

@ -10,11 +10,23 @@ local math = math
local sf = string.format local sf = string.format
-- Recursively merge tables with eachother
local function table_merge(tbl, ...)
local t = table.copy(tbl)
for k,v in pairs(...) do
if type(t[k]) == "table" and type(v) == "table" then
table_merge(t[k], v)
else
t[k] = v
end
end
return t
end
-- Chest Entity -- Chest Entity
-- ============ -- ============
-- This is necessary to show the chest as an animated mesh, as Minetest doesn't -- This is necessary to show the chest as an animated mesh, as Minetest doesn't support assigning animated meshes to
-- support assigning animated meshes to nodes directly. We're bypassing this -- nodes directly. We're bypassing this limitation by giving each chest its own entity, and making the chest node
-- limitation by giving each chest its own entity, and making the chest node
-- itself fully transparent. -- itself fully transparent.
local animated_chests = (minetest.settings:get_bool("animated_chests") ~= false) local animated_chests = (minetest.settings:get_bool("animated_chests") ~= false)
local entity_animations = { local entity_animations = {
@ -154,7 +166,8 @@ local function create_entity(pos, node_name, textures, param2, double, sound_pre
if obj and obj:get_pos() then if obj and obj:get_pos() then
return obj:get_luaentity() return obj:get_luaentity()
else else
minetest.log("warning", "[mcl_chests] Failed to create entity at " .. (entity_pos and minetest.pos_to_string(entity_pos, 1) or "nil")) minetest.log("warning", "[mcl_chests] Failed to create entity at " ..
(entity_pos and minetest.pos_to_string(entity_pos, 1) or "nil"))
end end
end end
mcl_chests.create_entity = create_entity mcl_chests.create_entity = create_entity
@ -209,9 +222,8 @@ local function player_chest_open(player, pos, node_name, textures, param2, doubl
} }
if animated_chests then if animated_chests then
local dir = minetest.facedir_to_dir(param2) local dir = minetest.facedir_to_dir(param2)
find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh,
dir): shulker and "shulker" or "chest", dir):open(name)
open(name)
end end
end end
mcl_chests.player_chest_open = player_chest_open mcl_chests.player_chest_open = player_chest_open
@ -228,7 +240,7 @@ local function protection_check_move(pos, from_list, from_index, to_list, to_ind
end end
mcl_chests.protection_check_move = protection_check_move mcl_chests.protection_check_move = protection_check_move
local function protection_check_put_take(pos, listname, index, stack, player) local function protection_check_take(pos, listname, index, stack, player)
local name = player:get_player_name() local name = player:get_player_name()
if minetest.is_protected(pos, name) then if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name) minetest.record_protection_violation(pos, name)
@ -237,7 +249,29 @@ local function protection_check_put_take(pos, listname, index, stack, player)
return stack:get_count() return stack:get_count()
end end
end end
mcl_chests.protection_check_put_take = protection_check_put_take mcl_chests.protection_check_put_take = protection_check_take
-- Logging functions
local function log_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", player:get_player_name() ..
" moves stuff to chest at " .. minetest.pos_to_string(pos))
end
local function log_inventory_put(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" moves stuff to chest at " .. minetest.pos_to_string(pos))
-- BEGIN OF LISTRING WORKAROUND
if listname == "input" then
local inv = minetest.get_inventory({ type = "node", pos = pos })
inv:add_item("main", stack)
end
-- END OF LISTRING WORKAROUND
end
local function log_inventory_take(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" takes stuff from chest at " .. minetest.pos_to_string(pos))
end
-- To be called when a chest is closed (only relevant for trapped chest atm) -- To be called when a chest is closed (only relevant for trapped chest atm)
local function chest_update_after_close(pos) local function chest_update_after_close(pos)
@ -337,7 +371,7 @@ local function limit_put_list(stack, list)
end end
local function limit_put(stack, inv1, inv2) local function limit_put(stack, inv1, inv2)
local leftover = ItemStack(stack) local leftover = ItemStack(staick)
leftover = limit_put_list(leftover, inv1:get_list("main")) leftover = limit_put_list(leftover, inv1:get_list("main"))
leftover = limit_put_list(leftover, inv2:get_list("main")) leftover = limit_put_list(leftover, inv2:get_list("main"))
return stack:get_count() - leftover:get_count() return stack:get_count() - leftover:get_count()
@ -353,6 +387,108 @@ local function close_forms(canonical_basename, pos)
end end
end end
-- Functions used in double chest registration code
-- ================================================
-- The `return function` wrapping is necessary to avoid stacking up parameters.
-- `side` is either "left" or "right".
local function hopper_pull_double(side) return function(pos, hop_pos, hop_inv, hop_list)
local node = minetest.get_node(pos)
local pos_other = get_double_container_neighbor_pos(pos, node.param2, side)
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
local stack_id = mcl_util.select_stack(inv_other, "main", hop_inv, hop_list)
if stack_id ~= nil then
return inv_other, "main", stack_id
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
stack_id = mcl_util.select_stack(inv, "main", hop_inv, hop_list)
return inv, "main", stack_id
end end
local function hopper_push_double(side) return function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack_id = mcl_util.select_stack(hop_inv, hop_list, inv, "main", nil, 1)
if stack_id ~= nil then
return inv, "main", stack_id
end
local node = minetest.get_node(pos)
local pos_other = get_double_container_neighbor_pos(pos, node.param2, side)
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
stack_id = mcl_util.select_stack(hop_inv, hop_list, inv_other, "main", nil, 1)
return inv_other, "main", stack_id
end end
local function construct_double_chest(side, names) return function(pos)
local n = minetest.get_node(pos)
local param2 = n.param2
local p = get_double_container_neighbor_pos(pos, param2, side)
-- Turn into a small chest if the neighbor is gone
if not p or minetest.get_node(p).name ~= names[side].cr then
n.name = names.small.a
minetest.swap_node(pos, n)
end
end end
local function destruct_double_chest(side, names, canonical_basename, small_textures) return function(pos)
local n = minetest.get_node(pos)
if n.name == names.small.a then
return
end
close_forms(canonical_basename, pos)
local param2 = n.param2
local p = get_double_container_neighbor_pos(pos, param2, side)
if not p or minetest.get_node(p).name ~= names[side].r then
return
end
close_forms(canonical_basename, p)
minetest.swap_node(p, { name = names.small.a, param2 = param2 })
create_entity(p, names.small.a, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest")
end end
-- Small chests use `protection_check_take` for both put and take actions.
local function protection_check_put(side) return function(pos, listname, index, stack, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
-- BEGIN OF LISTRING WORKAROUND
elseif listname == "input" then
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, side)
local other_inv = minetest.get_inventory({ type = "node", pos = other_pos })
local inv = minetest.get_inventory({ type = "node", pos = pos })
return limit_put(stack, other_inv, inv)
-- END OF LISTRING WORKAROUND
else
return stack:get_count()
end
end end
local function log_inventory_put_double(side) return function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" moves stuff to chest at " .. minetest.pos_to_string(pos))
-- BEGIN OF LISTRING WORKAROUND
if listname == "input" then
local inv = minetest.get_inventory({ type = "node", pos = pos })
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, side)
local other_inv = minetest.get_inventory({ type = "node", pos = other_pos })
inv:set_stack("input", 1, nil)
double_chest_add_item(inv, other_inv, "main", stack)
end
-- END OF LISTRING WORKAROUND
end end
-- This is a helper function to register regular chests (both small and double variants). -- This is a helper function to register regular chests (both small and double variants).
-- Some parameters here are only utilized by trapped chests. -- Some parameters here are only utilized by trapped chests.
function mcl_chests.register_chest(basename, d) function mcl_chests.register_chest(basename, d)
@ -364,20 +500,75 @@ function mcl_chests.register_chest(basename, d)
else else
d.drop = "mcl_chests:" .. d.drop d.drop = "mcl_chests:" .. d.drop
end end
local drop_items_chest = mcl_util.drop_items_from_meta_container("main")
if not d.groups then d.groups = {} end
local on_rightclick_side = {
left = d.on_rightclick_left,
right = d.on_rightclick_right
}
-- The basename of the "canonical" version of the node, if set (e.g.: trapped_chest_on → trapped_chest). -- The basename of the "canonical" version of the node, if set (e.g.: trapped_chest_on → trapped_chest).
-- Used to get a shared formspec ID and to swap the node back to the canonical version in on_construct. -- Used to get a shared formspec ID and to swap the node back to the canonical version in on_construct.
if not d.canonical_basename then if not d.canonical_basename then
d.canonical_basename = basename d.canonical_basename = basename
end end
local drop_items_chest = mcl_util.drop_items_from_meta_container("main") -- Names table
-- ===========
-- Accessed through names["kind"].x (names.kind.x), where x can be:
-- a = "actual"
-- c = canonical
-- r = reverse (only for double chests)
-- cr = canonical, reverse (only for double chests)
local names = {
small = {
a = "mcl_chests:" .. basename .. "_small",
c = "mcl_chests:" .. d.canonical_basename .. "_small",
},
left = {
a = "mcl_chests:" .. basename .. "_left",
c = "mcl_chests:" .. d.canonical_basename .. "_left",
},
right = {
a = "mcl_chests:" .. basename .. "_right",
c = "mcl_chests:" .. d.canonical_basename .. "_right",
},
}
names.left.r = names.right.a
names.right.r = names.left.a
names.left.cr = names.right.c
names.right.cr = names.left.c
local small_name = "mcl_chests:" .. basename .. "_small"
local small_textures = d.tiles.small local small_textures = d.tiles.small
local left_name = "mcl_chests:" .. basename .. "_left"
local right_name = "mcl_chests:" .. basename .. "_right"
local double_textures = d.tiles.double local double_textures = d.tiles.double
-- Construct groups
local groups_inv = table_merge({ deco_block = 1 }, d.groups)
local groups_small = table_merge(groups_inv, {
handy = 1,
axey = 1,
container = 2,
deco_block = 1,
material_wood = 1,
flammable = -1,
chest_entity = 1,
not_in_creative_inventory = 1
}, d.groups)
local groups_left = table_merge(groups_small, {
double_chest = 1
}, d.groups)
local groups_right = table_merge(groups_small, {
-- In a double chest, the entity is assigned to the left side, but not the right one.
chest_entity = 0,
double_chest = 2
}, d.groups)
-- Register
minetest.register_node("mcl_chests:" .. basename, { minetest.register_node("mcl_chests:" .. basename, {
description = d.desc, description = d.desc,
_tt_help = d.tt_help, _tt_help = d.tt_help,
@ -391,10 +582,10 @@ function mcl_chests.register_chest(basename, d)
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
sounds = d.sounds, sounds = d.sounds,
groups = { deco_block = 1 }, groups = groups_inv,
on_construct = function(pos, node) on_construct = function(pos, node)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
node.name = small_name node.name = names.small.a
minetest.set_node(pos, node) minetest.set_node(pos, node)
end, end,
after_place_node = function(pos, placer, itemstack, pointed_thing) after_place_node = function(pos, placer, itemstack, pointed_thing)
@ -402,7 +593,7 @@ function mcl_chests.register_chest(basename, d)
end, end,
}) })
minetest.register_node(small_name, { minetest.register_node(names.small.a, {
description = d.desc, description = d.desc,
_tt_help = d.tt_help, _tt_help = d.tt_help,
_doc_items_longdesc = d.longdesc, _doc_items_longdesc = d.longdesc,
@ -422,16 +613,7 @@ function mcl_chests.register_chest(basename, d)
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
drop = d.drop, drop = d.drop,
groups = { groups = groups_small,
handy = 1,
axey = 1,
container = 2,
deco_block = 1,
material_wood = 1,
flammable = -1,
chest_entity = 1,
not_in_creative_inventory = 1
},
is_ground_content = false, is_ground_content = false,
sounds = d.sounds, sounds = d.sounds,
on_construct = function(pos) on_construct = function(pos)
@ -465,22 +647,22 @@ function mcl_chests.register_chest(basename, d)
-- Combine into a double chest if neighbouring another small chest -- Combine into a double chest if neighbouring another small chest
if minetest.get_node(get_double_container_neighbor_pos(pos, param2, "right")).name == if minetest.get_node(get_double_container_neighbor_pos(pos, param2, "right")).name ==
small_name then names.small.a then
minetest.swap_node(pos, { name = right_name, param2 = param2 }) minetest.swap_node(pos, { name = names.right.a, param2 = param2 })
local p = get_double_container_neighbor_pos(pos, param2, "right") local p = get_double_container_neighbor_pos(pos, param2, "right")
minetest.swap_node(p, { name = left_name, param2 = param2 }) minetest.swap_node(p, { name = names.left.a, param2 = param2 })
create_entity(p, left_name, double_textures, param2, true, "default_chest", create_entity(p, names.left.a, double_textures, param2, true, "default_chest",
"mcl_chests_chest", "chest") "mcl_chests_chest", "chest")
elseif minetest.get_node(get_double_container_neighbor_pos(pos, param2, "left")).name == elseif minetest.get_node(get_double_container_neighbor_pos(pos, param2, "left")).name ==
small_name then names.small.a then
minetest.swap_node(pos, { name = left_name, param2 = param2 }) minetest.swap_node(pos, { name = names.left.a, param2 = param2 })
create_entity(pos, left_name, double_textures, param2, true, "default_chest", create_entity(pos, names.left.a, double_textures, param2, true, "default_chest",
"mcl_chests_chest", "chest") "mcl_chests_chest", "chest")
local p = get_double_container_neighbor_pos(pos, param2, "left") local p = get_double_container_neighbor_pos(pos, param2, "left")
minetest.swap_node(p, { name = right_name, param2 = param2 }) minetest.swap_node(p, { name = names.right.a, param2 = param2 })
else else
minetest.swap_node(pos, { name = small_name, param2 = param2 }) minetest.swap_node(pos, { name = names.small.a, param2 = param2 })
create_entity(pos, small_name, small_textures, param2, false, "default_chest", create_entity(pos, names.small.a, small_textures, param2, false, "default_chest",
"mcl_chests_chest", "chest") "mcl_chests_chest", "chest")
end end
end, end,
@ -490,26 +672,11 @@ function mcl_chests.register_chest(basename, d)
after_dig_node = drop_items_chest, after_dig_node = drop_items_chest,
on_blast = on_chest_blast, on_blast = on_chest_blast,
allow_metadata_inventory_move = protection_check_move, allow_metadata_inventory_move = protection_check_move,
allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_take = protection_check_take,
allow_metadata_inventory_put = protection_check_put_take, allow_metadata_inventory_put = protection_check_take,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) on_metadata_inventory_move = log_inventory_move,
minetest.log("action", player:get_player_name() .. on_metadata_inventory_put = log_inventory_put,
" moves stuff in chest at " .. minetest.pos_to_string(pos)) on_metadata_inventory_take = log_inventory_take,
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" moves stuff to chest at " .. minetest.pos_to_string(pos))
-- BEGIN OF LISTRING WORKAROUND
if listname == "input" then
local inv = minetest.get_inventory({ type = "node", pos = pos })
inv:add_item("main", stack)
end
-- END OF LISTRING WORKAROUND
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" takes stuff from chest at " .. minetest.pos_to_string(pos))
end,
_mcl_blast_resistance = d.hardness, _mcl_blast_resistance = d.hardness,
_mcl_hardness = d.hardness, _mcl_hardness = d.hardness,
@ -550,7 +717,7 @@ function mcl_chests.register_chest(basename, d)
d.on_rightclick(pos, node, clicker) d.on_rightclick(pos, node, clicker)
end end
player_chest_open(clicker, pos, small_name, small_textures, node.param2, false, "default_chest", player_chest_open(clicker, pos, names.small.a, small_textures, node.param2, false, "default_chest",
"mcl_chests_chest") "mcl_chests_chest")
end, end,
@ -561,7 +728,7 @@ function mcl_chests.register_chest(basename, d)
on_rotate = simple_rotate, on_rotate = simple_rotate,
}) })
minetest.register_node(left_name, { minetest.register_node(names.left.a, {
drawtype = "nodebox", drawtype = "nodebox",
node_box = { node_box = {
type = "fixed", type = "fixed",
@ -575,93 +742,23 @@ function mcl_chests.register_chest(basename, d)
_chest_entity_animation_type = "chest", _chest_entity_animation_type = "chest",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = { groups = groups_left,
handy = 1,
axey = 1,
container = 2,
not_in_creative_inventory = 1,
material_wood = 1,
flammable = -1,
chest_entity = 1,
double_chest = 1
},
drop = d.drop, drop = d.drop,
is_ground_content = false, is_ground_content = false,
sounds = d.sounds, sounds = d.sounds,
on_construct = function(pos) on_construct = construct_double_chest("left", names),
local n = minetest.get_node(pos)
local param2 = n.param2
local p = get_double_container_neighbor_pos(pos, param2, "left")
if not p or minetest.get_node(p).name ~= "mcl_chests:" .. d.canonical_basename .. "_right" then
n.name = "mcl_chests:" .. d.canonical_basename .. "_small"
minetest.swap_node(pos, n)
end
create_entity(pos, left_name, double_textures, param2, true, "default_chest", "mcl_chests_chest", "chest")
end,
after_place_node = function(pos, placer, itemstack, pointed_thing) after_place_node = function(pos, placer, itemstack, pointed_thing)
minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name"))
end, end,
on_destruct = function(pos) on_destruct = destruct_double_chest("left", names, d.canonical_basename, small_textures),
local n = minetest.get_node(pos)
if n.name == small_name then
return
end
close_forms(d.canonical_basename, pos)
local param2 = n.param2
local p = get_double_container_neighbor_pos(pos, param2, "left")
if not p or minetest.get_node(p).name ~= "mcl_chests:" .. basename .. "_right" then
return
end
close_forms(d.canonical_basename, p)
minetest.swap_node(p, { name = small_name, param2 = param2 })
create_entity(p, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest")
end,
after_dig_node = drop_items_chest, after_dig_node = drop_items_chest,
on_blast = on_chest_blast, on_blast = on_chest_blast,
allow_metadata_inventory_move = protection_check_move, allow_metadata_inventory_move = protection_check_move,
allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_take = protection_check_take,
allow_metadata_inventory_put = function(pos, listname, index, stack, player) allow_metadata_inventory_put = protection_check_put("left"),
local name = player:get_player_name() on_metadata_inventory_move = log_inventory_move,
if minetest.is_protected(pos, name) then on_metadata_inventory_put = log_inventory_put_double("left"),
minetest.record_protection_violation(pos, name) on_metadata_inventory_take = log_inventory_take,
return 0
-- BEGIN OF LISTRING WORKAROUND
elseif listname == "input" then
local inv = minetest.get_inventory({ type = "node", pos = pos })
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left")
local other_inv = minetest.get_inventory({ type = "node", pos = other_pos })
return limit_put(stack, inv, other_inv)
-- END OF LISTRING WORKAROUND
else
return stack:get_count()
end
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", player:get_player_name() ..
" moves stuff in chest at " .. minetest.pos_to_string(pos))
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" moves stuff to chest at " .. minetest.pos_to_string(pos))
-- BEGIN OF LISTRING WORKAROUND
if listname == "input" then
local inv = minetest.get_inventory({ type = "node", pos = pos })
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left")
local other_inv = minetest.get_inventory({ type = "node", pos = other_pos })
inv:set_stack("input", 1, nil)
double_chest_add_item(inv, other_inv, "main", stack)
end
-- END OF LISTRING WORKAROUND
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" takes stuff from chest at " .. minetest.pos_to_string(pos))
end,
_mcl_blast_resistance = d.hardness, _mcl_blast_resistance = d.hardness,
_mcl_hardness = d.hardness, _mcl_hardness = d.hardness,
@ -721,46 +818,16 @@ function mcl_chests.register_chest(basename, d)
d.on_rightclick_left(pos, node, clicker) d.on_rightclick_left(pos, node, clicker)
end end
player_chest_open(clicker, pos, left_name, double_textures, node.param2, true, "default_chest", player_chest_open(clicker, pos, names.left.a, double_textures, node.param2, true, "default_chest",
"mcl_chests_chest") "mcl_chests_chest")
end, end,
mesecons = d.mesecons, mesecons = d.mesecons,
on_rotate = no_rotate, on_rotate = no_rotate,
_mcl_hoppers_on_try_pull = function(pos, hop_pos, hop_inv, hop_list) _mcl_hoppers_on_try_pull = hopper_pull_double("left"),
local meta = minetest.get_meta(pos) _mcl_hoppers_on_try_push = hopper_push_double("left"),
local inv = meta:get_inventory()
local stack_id = mcl_util.select_stack(inv, "main", hop_inv, hop_list)
if stack_id ~= nil then
return inv, "main", stack_id
end
local node = minetest.get_node(pos)
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "left")
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
stack_id = mcl_util.select_stack(inv_other, "main", hop_inv, hop_list)
return inv_other, "main", stack_id
end,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack_id = mcl_util.select_stack(hop_inv, hop_list, inv, "main", nil, 1)
if stack_id ~= nil then
return inv, "main", stack_id
end
local node = minetest.get_node(pos)
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "left")
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
stack_id = mcl_util.select_stack(hop_inv, hop_list, inv_other, "main", nil, 1)
return inv_other, "main", stack_id
end,
}) })
minetest.register_node(right_name, { minetest.register_node(names.right.a, {
drawtype = "nodebox", drawtype = "nodebox",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
@ -770,91 +837,23 @@ function mcl_chests.register_chest(basename, d)
}, },
tiles = { "blank.png^[resize:16x16" }, tiles = { "blank.png^[resize:16x16" },
use_texture_alpha = "clip", use_texture_alpha = "clip",
groups = { groups = groups_right,
handy = 1,
axey = 1,
container = 2,
not_in_creative_inventory = 1,
material_wood = 1,
flammable = -1,
double_chest = 2
},
drop = d.drop, drop = d.drop,
is_ground_content = false, is_ground_content = false,
sounds = d.sounds, sounds = d.sounds,
on_construct = function(pos) on_construct = construct_double_chest("right", names),
local n = minetest.get_node(pos)
local param2 = n.param2
local p = get_double_container_neighbor_pos(pos, param2, "right")
if not p or minetest.get_node(p).name ~= left_name then
n.name = small_name
minetest.swap_node(pos, n)
end
end,
after_place_node = function(pos, placer, itemstack, pointed_thing) after_place_node = function(pos, placer, itemstack, pointed_thing)
minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name"))
end, end,
on_destruct = function(pos) on_destruct = destruct_double_chest("right", names, d.canonical_basename, small_textures),
local n = minetest.get_node(pos)
if n.name == small_name then
return
end
close_forms(d.canonical_basename, pos)
local param2 = n.param2
local p = get_double_container_neighbor_pos(pos, param2, "right")
if not p or minetest.get_node(p).name ~= left_name then
return
end
close_forms(d.canonical_basename, p)
minetest.swap_node(p, { name = small_name, param2 = param2 })
create_entity(p, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest")
end,
after_dig_node = drop_items_chest, after_dig_node = drop_items_chest,
on_blast = on_chest_blast, on_blast = on_chest_blast,
allow_metadata_inventory_move = protection_check_move, allow_metadata_inventory_move = protection_check_move,
allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_take = protection_check_take,
allow_metadata_inventory_put = function(pos, listname, index, stack, player) allow_metadata_inventory_put = protection_check_put("right"),
local name = player:get_player_name() on_metadata_inventory_move = log_inventory_move,
if minetest.is_protected(pos, name) then on_metadata_inventory_put = log_inventory_put_double("right"),
minetest.record_protection_violation(pos, name) on_metadata_inventory_take = log_inventory_take,
return 0
-- BEGIN OF LISTRING WORKAROUND
elseif listname == "input" then
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right")
local other_inv = minetest.get_inventory({ type = "node", pos = other_pos })
local inv = minetest.get_inventory({ type = "node", pos = pos })
return limit_put(stack, other_inv, inv)
-- END OF LISTRING WORKAROUND
else
return stack:get_count()
end
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", player:get_player_name() ..
" moves stuff in chest at " .. minetest.pos_to_string(pos))
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" moves stuff to chest at " .. minetest.pos_to_string(pos))
-- BEGIN OF LISTRING WORKAROUND
if listname == "input" then
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right")
local other_inv = minetest.get_inventory({ type = "node", pos = other_pos })
local inv = minetest.get_inventory({ type = "node", pos = pos })
inv:set_stack("input", 1, nil)
double_chest_add_item(other_inv, inv, "main", stack)
end
-- END OF LISTRING WORKAROUND
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" takes stuff from chest at " .. minetest.pos_to_string(pos))
end,
_mcl_blast_resistance = d.hardness, _mcl_blast_resistance = d.hardness,
_mcl_hardness = d.hardness, _mcl_hardness = d.hardness,
@ -919,43 +918,13 @@ function mcl_chests.register_chest(basename, d)
end, end,
mesecons = d.mesecons, mesecons = d.mesecons,
on_rotate = no_rotate, on_rotate = no_rotate,
_mcl_hoppers_on_try_pull = function(pos, hop_pos, hop_inv, hop_list) _mcl_hoppers_on_try_pull = hopper_pull_double("right"),
local node = minetest.get_node(pos) _mcl_hoppers_on_try_push = hopper_push_double("right"),
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "right")
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
local stack_id = mcl_util.select_stack(inv_other, "main", hop_inv, hop_list)
if stack_id ~= nil then
return inv_other, "main", stack_id
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
stack_id = mcl_util.select_stack(inv, "main", hop_inv, hop_list)
return inv, "main", stack_id
end,
_mcl_hoppers_on_try_push = function(pos, hop_pos, hop_inv, hop_list)
local node = minetest.get_node(pos)
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "right")
local meta_other = minetest.get_meta(pos_other)
local inv_other = meta_other:get_inventory()
local stack_id = mcl_util.select_stack(hop_inv, hop_list, inv_other, "main", nil, 1)
if stack_id ~= nil then
return inv_other, "main", stack_id
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
stack_id = mcl_util.select_stack(hop_inv, hop_list, inv, "main", nil, 1)
return inv, "main", stack_id
end,
}) })
if doc then if doc then
doc.add_entry_alias("nodes", small_name, "nodes", left_name) doc.add_entry_alias("nodes", names.small.a, "nodes", names.left.a)
doc.add_entry_alias("nodes", small_name, "nodes", right_name) doc.add_entry_alias("nodes", names.small.a, "nodes", names.right.a)
end end
end end

View File

@ -42,6 +42,7 @@ mcl_chests.register_chest("trapped_chest", {
tt_help = S("27 inventory slots") .. tt_help = S("27 inventory slots") ..
"\n" .. S("Can be combined to a large chest") .. "\n" .. S("Emits a redstone signal when opened"), "\n" .. S("Can be combined to a large chest") .. "\n" .. S("Emits a redstone signal when opened"),
tiles = traptiles, tiles = traptiles,
groups = { mesecon = 2 },
sounds = mcl_sounds.node_sound_wood_defaults(), sounds = mcl_sounds.node_sound_wood_defaults(),
hardness = 2.5, hardness = 2.5,
hidden = false, hidden = false,

View File

@ -78,9 +78,13 @@ minetest.register_lbm({
minetest.register_lbm({ minetest.register_lbm({
label = "Replace old chest nodes", label = "Replace old chest nodes",
name = "mcl_chests:replace_old", name = "mcl_chests:replace_old",
nodenames = { "mcl_chests:chest", "mcl_chests:trapped_chest", "mcl_chests:trapped_chest_on", nodenames = {
"mcl_chests:chest",
"mcl_chests:trapped_chest",
"mcl_chests:trapped_chest_on",
"mcl_chests:ender_chest", "mcl_chests:ender_chest",
"group:old_shulker_box_node" }, "group:old_shulker_box_node"
},
run_at_every_load = true, run_at_every_load = true,
action = function(pos, node) action = function(pos, node)
local node_name = node.name local node_name = node.name
@ -102,8 +106,11 @@ minetest.register_lbm({
minetest.register_lbm({ minetest.register_lbm({
label = "Disable active trapped chests", label = "Disable active trapped chests",
name = "mcl_chests:reset_trapped_chests", name = "mcl_chests:reset_trapped_chests",
nodenames = { "mcl_chests:trapped_chest_on_small", "mcl_chests:trapped_chest_on_left", nodenames = {
"mcl_chests:trapped_chest_on_right" }, "mcl_chests:trapped_chest_on_small",
"mcl_chests:trapped_chest_on_left",
"mcl_chests:trapped_chest_on_right"
},
run_at_every_load = true, run_at_every_load = true,
action = function(pos, node) action = function(pos, node)
minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " .. minetest.pos_to_string(pos)) minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " .. minetest.pos_to_string(pos))