#375 Speed up hopper ABMs

This commit is contained in:
kay27 2022-07-19 23:42:57 +03:00
parent ee5d45152d
commit c3e208dbb0
3 changed files with 144 additions and 163 deletions

View File

@ -1,5 +1,11 @@
mcl_util = {} mcl_util = {}
local minetest_get_item_group = minetest.get_item_group
local minetest_get_meta = minetest.get_meta
local minetest_get_node = minetest.get_node
local minetest_get_node_timer = minetest.get_node_timer
local table_copy = table.copy
-- Updates all values in t using values from to*. -- Updates all values in t using values from to*.
function table.update(t, ...) function table.update(t, ...)
for _, to in ipairs{...} do for _, to in ipairs{...} do
@ -33,36 +39,6 @@ function mcl_util.rotate_axis(itemstack, placer, pointed_thing)
return itemstack return itemstack
end end
-- Returns position of the neighbor of a double chest node
-- or nil if node is invalid.
-- This function assumes that the large chest is actually intact
-- * pos: Position of the node to investigate
-- * param2: param2 of that node
-- * side: Which "half" the investigated node is. "left" or "right"
function mcl_util.get_double_container_neighbor_pos(pos, param2, side)
if side == "right" then
if param2 == 0 then
return {x=pos.x-1, y=pos.y, z=pos.z}
elseif param2 == 1 then
return {x=pos.x, y=pos.y, z=pos.z+1}
elseif param2 == 2 then
return {x=pos.x+1, y=pos.y, z=pos.z}
elseif param2 == 3 then
return {x=pos.x, y=pos.y, z=pos.z-1}
end
else
if param2 == 0 then
return {x=pos.x+1, y=pos.y, z=pos.z}
elseif param2 == 1 then
return {x=pos.x, y=pos.y, z=pos.z-1}
elseif param2 == 2 then
return {x=pos.x-1, y=pos.y, z=pos.z}
elseif param2 == 3 then
return {x=pos.x, y=pos.y, z=pos.z+1}
end
end
end
-- Iterates through all items in the given inventory and -- Iterates through all items in the given inventory and
-- returns the slot of the first item which matches a condition. -- returns the slot of the first item which matches a condition.
-- Returns nil if no item was found. -- Returns nil if no item was found.
@ -87,7 +63,7 @@ end
-- Returns true if itemstack is a shulker box -- Returns true if itemstack is a shulker box
local function is_not_shulker_box(itemstack) local function is_not_shulker_box(itemstack)
local g = minetest.get_item_group(itemstack:get_name(), "shulker_box") local g = minetest_get_item_group(itemstack:get_name(), "shulker_box")
return g == 0 or g == nil return g == 0 or g == nil
end end
@ -133,136 +109,116 @@ end
--- source_stack_id (optional): The inventory position ID of the source inventory to take the item from (-1 for slot of the first valid item; -1 is default) --- source_stack_id (optional): The inventory position ID of the source inventory to take the item from (-1 for slot of the first valid item; -1 is default)
--- destination_list (optional): List name of the destination inventory. Default is normally "main"; "src" for furnace --- destination_list (optional): List name of the destination inventory. Default is normally "main"; "src" for furnace
-- Returns true on success and false on failure. -- Returns true on success and false on failure.
local SHULKER_BOX = 3
local FURNACE = 4
local DOUBLE_CHEST_LEFT = 5
local DOUBLE_CHEST_RIGHT = 6
local CONTAINER_GROUP_TO_LIST = {
[1] = "main",
[2] = "main",
[SHULKER_BOX] = "main",
[FURNACE] = "dst",
[DOUBLE_CHEST_LEFT] = "main",
[DOUBLE_CHEST_RIGHT] = "main",
}
function mcl_util.move_item_container(source_pos, destination_pos, source_list, source_stack_id, destination_list) function mcl_util.move_item_container(source_pos, destination_pos, source_list, source_stack_id, destination_list)
local dpos = table.copy(destination_pos) local spos = table_copy(source_pos)
local spos = table.copy(source_pos) local snode = minetest_get_node(spos)
local snode = minetest.get_node(spos) local sctype = minetest_get_item_group(snode.name, "container")
local dnode = minetest.get_node(dpos) local default_source_list = CONTAINER_GROUP_TO_LIST[sctype]
if not default_source_list then return end
local dctype = minetest.get_item_group(dnode.name, "container") if sctype == DOUBLE_CHEST_RIGHT then
local sctype = minetest.get_item_group(snode.name, "container") local sparam2 = snode.param2
if sparam2 == 0 then spos.x = spos.x - 1
-- Container type 7 does not allow any movement elseif sparam2 == 1 then spos.z = spos.z + 1
if sctype == 7 then elseif sparam2 == 2 then spos.x = spos.x + 1
return false elseif sparam2 == 3 then spos.z = spos.z - 1
end
-- Normalize double container by forcing to always use the left segment first
local function normalize_double_container(pos, node, ctype)
if ctype == 6 then
pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
if not pos then
return false
end
node = minetest.get_node(pos)
ctype = minetest.get_item_group(node.name, "container")
-- The left segment seems incorrect? We better bail out!
if ctype ~= 5 then
return false
end
end end
return pos, node, ctype snode = minetest_get_node(spos)
sctype = minetest_get_item_group(snode.name, "container")
if sctype ~= DOUBLE_CHEST_LEFT then return end
end end
local smeta = minetest_get_meta(spos)
spos, snode, sctype = normalize_double_container(spos, snode, sctype)
dpos, dnode, dctype = normalize_double_container(dpos, dnode, dctype)
if not spos or not dpos then return false end
local smeta = minetest.get_meta(spos)
local dmeta = minetest.get_meta(dpos)
local sinv = smeta:get_inventory() local sinv = smeta:get_inventory()
local source_list = source_list or default_source_list
local dpos = table_copy(destination_pos)
local dnode = minetest_get_node(dpos)
local dctype = minetest_get_item_group(dnode.name, "container")
local default_destination_list = CONTAINER_GROUP_TO_LIST[sctype]
if not default_destination_list then return end
if dctype == DOUBLE_CHEST_RIGHT then
local dparam2 = dnode.param2
if dparam2 == 0 then dpos.x = dpos.x - 1
elseif dparam2 == 1 then dpos.z = dpos.z + 1
elseif dparam2 == 2 then dpos.x = dpos.x + 1
elseif dparam2 == 3 then dpos.z = dpos.z - 1
end
dnode = minetest_get_node(dpos)
dctype = minetest_get_item_group(dnode.name, "container")
if dctype ~= DOUBLE_CHEST_LEFT then return end
end
local dmeta = minetest_get_meta(dpos)
local dinv = dmeta:get_inventory() local dinv = dmeta:get_inventory()
-- Default source lists
if not source_list then
-- Main inventory for most container types
if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 or sctype == 7 then
source_list = "main"
-- Furnace: output
elseif sctype == 4 then
source_list = "dst"
-- Unknown source container type. Bail out
else
return false
end
end
-- Automatically select stack slot ID if set to automatic -- Automatically select stack slot ID if set to automatic
if not source_stack_id then local source_stack_id = source_stack_id or -1
source_stack_id = -1
end
if source_stack_id == -1 then if source_stack_id == -1 then
local cond = nil local cond = nil
-- Prevent shulker box inception -- Prevent shulker box inception
if dctype == 3 then if dctype == SHULKER_BOX then cond = is_not_shulker_box end
cond = is_not_shulker_box
end
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond) source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
if not source_stack_id then if not source_stack_id then
-- Try again if source is a double container if sctype == DOUBLE_CHEST_LEFT then
if sctype == 5 then local sparam2 = snode.param2
spos = mcl_util.get_double_container_neighbor_pos(spos, snode.param2, "left") if sparam2 == 0 then spos.x = spos.x + 1
smeta = minetest.get_meta(spos) elseif sparam2 == 1 then spos.z = spos.z - 1
sinv = smeta:get_inventory() elseif sparam2 == 2 then spos.x = spos.x - 1
elseif sparam2 == 3 then spos.z = spos.z + 1
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
if not source_stack_id then
return false
end end
else snode = minetest_get_node(spos)
return false sctype = minetest_get_item_group(snode.name, "container")
if sctype ~= DOUBLE_CHEST_RIGHT then return end
smeta = minetest_get_meta(spos)
sinv = smeta:get_inventory()
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
end end
end end
if not source_stack_id then return end
end end
-- Abort transfer if shulker box wants to go into shulker box -- Abort transfer if shulker box wants to go into shulker box
if dctype == 3 then if dctype == SHULKER_BOX then
local stack = sinv:get_stack(source_list, source_stack_id) local stack = sinv:get_stack(source_list, source_stack_id)
if stack and minetest.get_item_group(stack:get_name(), "shulker_box") == 1 then if stack and minetest_get_item_group(stack:get_name(), "shulker_box") == 1 then return end
return false
end
end
-- Container type 7 does not allow any placement
if dctype == 7 then
return false
end end
-- If it's a container, put it into the container local destination_list = destination_list or default_destination_list
if dctype ~= 0 then -- Move item
-- Automatically select a destination list if omitted local ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
if not destination_list then -- Try transfer to neighbor node if transfer failed and double container
-- Main inventory for most container types if not ok then
if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 or dctype == 7 then if dctype == DOUBLE_CHEST_LEFT then
destination_list = "main" local dparam2 = dnode.param2
-- Furnace source slot if dparam2 == 0 then dpos.x = dpos.x + 1
elseif dctype == 4 then elseif dparam2 == 1 then dpos.z = dpos.z - 1
destination_list = "src" elseif dparam2 == 2 then dpos.x = dpos.x - 1
elseif dparam2 == 3 then dpos.z = dpos.z + 1
end end
end dnode = minetest_get_node(dpos)
if destination_list then dctype = minetest_get_item_group(dnode.name, "container")
-- Move item if dctype ~= DOUBLE_CHEST_RIGHT then return end
local ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list) dmeta = minetest_get_meta(dpos)
dinv = dmeta:get_inventory()
-- Try transfer to neighbor node if transfer failed and double container ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
if not ok and dctype == 5 then
dpos = mcl_util.get_double_container_neighbor_pos(dpos, dnode.param2, "left")
dmeta = minetest.get_meta(dpos)
dinv = dmeta:get_inventory()
ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
end
-- Update furnace
if ok and dctype == 4 then
-- Start furnace's timer function, it will sort out whether furnace can burn or not.
minetest.get_node_timer(dpos):start(1.0)
end
return ok
end end
end end
return false -- Update furnace
if ok and dctype == FURNACE then
-- Start furnace's timer function, it will sort out whether furnace can burn or not.
minetest_get_node_timer(dpos):start(1.0)
end
return ok
end end
-- Returns the ID of the first non-empty slot in the given inventory list -- Returns the ID of the first non-empty slot in the given inventory list
@ -292,7 +248,7 @@ function mcl_util.generate_on_place_plant_function(condition)
end end
-- Call on_rightclick if the pointed node defines it -- Call on_rightclick if the pointed node defines it
local node = minetest.get_node(pointed_thing.under) local node = minetest_get_node(pointed_thing.under)
if placer and not placer:get_player_control().sneak then if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
@ -300,8 +256,8 @@ function mcl_util.generate_on_place_plant_function(condition)
end end
local place_pos local place_pos
local def_under = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] local def_under = minetest.registered_nodes[minetest_get_node(pointed_thing.under).name]
local def_above = minetest.registered_nodes[minetest.get_node(pointed_thing.above).name] local def_above = minetest.registered_nodes[minetest_get_node(pointed_thing.above).name]
if not def_under or not def_above then if not def_under or not def_above then
return itemstack return itemstack
end end
@ -359,7 +315,7 @@ function mcl_util.call_on_rightclick(itemstack, player, pointed_thing)
-- Call on_rightclick if the pointed node defines it -- Call on_rightclick if the pointed node defines it
if pointed_thing and pointed_thing.type == "node" then if pointed_thing and pointed_thing.type == "node" then
local pos = pointed_thing.under local pos = pointed_thing.under
local node = minetest.get_node(pos) local node = minetest_get_node(pos)
if player and not player:get_player_control().sneak then if player and not player:get_player_control().sneak then
local nodedef = minetest.registered_nodes[node.name] local nodedef = minetest.registered_nodes[node.name]
local on_rightclick = nodedef and nodedef.on_rightclick local on_rightclick = nodedef and nodedef.on_rightclick
@ -372,7 +328,7 @@ end
function mcl_util.calculate_durability(itemstack) function mcl_util.calculate_durability(itemstack)
local unbreaking_level = mcl_enchanting.get_enchantment(itemstack, "unbreaking") local unbreaking_level = mcl_enchanting.get_enchantment(itemstack, "unbreaking")
local armor_uses = minetest.get_item_group(itemstack:get_name(), "mcl_armor_uses") local armor_uses = minetest_get_item_group(itemstack:get_name(), "mcl_armor_uses")
local uses local uses

View File

@ -18,6 +18,30 @@ local entity_animations = {
} }
} }
-- Returns position of the neighbor of a double chest node
-- or nil if node is invalid.
-- This function assumes that the large chest is actually intact
-- * pos: Position of the node to investigate
-- * param2: param2 of that node
-- * side: Which "half" the investigated node is. "left" or "right"
local function get_double_container_neighbor_pos(pos, param2, side)
local pos = pos
local param2 = param2
if side == "right" then
if param2 == 0 then return {x=pos.x-1, y=pos.y, z=pos.z}
elseif param2 == 1 then return {x=pos.x, y=pos.y, z=pos.z+1}
elseif param2 == 2 then return {x=pos.x+1, y=pos.y, z=pos.z}
elseif param2 == 3 then return {x=pos.x, y=pos.y, z=pos.z-1}
end
else
if param2 == 0 then return {x=pos.x+1, y=pos.y, z=pos.z}
elseif param2 == 1 then return {x=pos.x, y=pos.y, z=pos.z-1}
elseif param2 == 2 then return {x=pos.x-1, y=pos.y, z=pos.z}
elseif param2 == 3 then return {x=pos.x, y=pos.y, z=pos.z+1}
end
end
end
minetest.register_entity("mcl_chests:chest", { minetest.register_entity("mcl_chests:chest", {
initial_properties = { initial_properties = {
visual = "mesh", visual = "mesh",
@ -217,14 +241,14 @@ local function chest_update_after_close(pos)
find_or_create_entity(pos, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") find_or_create_entity(pos, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
mesecon.receptor_off(pos, trapped_chest_mesecons_rules) mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") local pos_other = get_double_container_neighbor_pos(pos, node.param2, "left")
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_right", param2 = node.param2}) minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_right", param2 = node.param2})
mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules) mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules)
elseif node.name == "mcl_chests:trapped_chest_on_right" then elseif node.name == "mcl_chests:trapped_chest_on_right" then
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_right", param2 = node.param2}) minetest.swap_node(pos, {name="mcl_chests:trapped_chest_right", param2 = node.param2})
mesecon.receptor_off(pos, trapped_chest_mesecons_rules) mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") local pos_other = get_double_container_neighbor_pos(pos, node.param2, "right")
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2}) minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules) mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules)
@ -438,15 +462,15 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
-- BEGIN OF LISTRING WORKAROUND -- BEGIN OF LISTRING WORKAROUND
inv:set_size("input", 1) inv:set_size("input", 1)
-- END OF LISTRING WORKAROUND -- END OF LISTRING WORKAROUND
if minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "right")).name == "mcl_chests:"..canonical_basename.."_small" then if minetest.get_node(get_double_container_neighbor_pos(pos, param2, "right")).name == "mcl_chests:"..canonical_basename.."_small" then
minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_right",param2=param2}) minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_right",param2=param2})
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") local p = get_double_container_neighbor_pos(pos, param2, "right")
minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_left", param2 = param2 }) minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_left", param2 = param2 })
create_entity(p, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") create_entity(p, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest")
elseif minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "left")).name == "mcl_chests:"..canonical_basename.."_small" then elseif minetest.get_node(get_double_container_neighbor_pos(pos, param2, "left")).name == "mcl_chests:"..canonical_basename.."_small" then
minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_left",param2=param2}) minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_left",param2=param2})
create_entity(pos, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") create_entity(pos, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest")
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") local p = get_double_container_neighbor_pos(pos, param2, "left")
minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_right", param2 = param2 }) minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_right", param2 = param2 })
else else
minetest.swap_node(pos, { name = "mcl_chests:"..canonical_basename.."_small", param2 = param2 }) minetest.swap_node(pos, { name = "mcl_chests:"..canonical_basename.."_small", param2 = param2 })
@ -541,7 +565,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
on_construct = function(pos) on_construct = function(pos)
local n = minetest.get_node(pos) local n = minetest.get_node(pos)
local param2 = n.param2 local param2 = n.param2
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") local p = get_double_container_neighbor_pos(pos, param2, "left")
if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_right" then if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_right" then
n.name = "mcl_chests:"..canonical_basename.."_small" n.name = "mcl_chests:"..canonical_basename.."_small"
minetest.swap_node(pos, n) minetest.swap_node(pos, n)
@ -560,7 +584,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
close_forms(canonical_basename, pos) close_forms(canonical_basename, pos)
local param2 = n.param2 local param2 = n.param2
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") local p = get_double_container_neighbor_pos(pos, param2, "left")
if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_right" then if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_right" then
return return
end end
@ -581,7 +605,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
-- BEGIN OF LISTRING WORKAROUND -- BEGIN OF LISTRING WORKAROUND
elseif listname == "input" then elseif listname == "input" then
local inv = minetest.get_inventory({type="node", pos=pos}) local inv = minetest.get_inventory({type="node", pos=pos})
local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left") 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}) local other_inv = minetest.get_inventory({type="node", pos=other_pos})
return limit_put(stack, inv, other_inv) return limit_put(stack, inv, other_inv)
--[[if inv:room_for_item("main", stack) then --[[if inv:room_for_item("main", stack) then
@ -609,7 +633,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
-- BEGIN OF LISTRING WORKAROUND -- BEGIN OF LISTRING WORKAROUND
if listname == "input" then if listname == "input" then
local inv = minetest.get_inventory({type="node", pos=pos}) local inv = minetest.get_inventory({type="node", pos=pos})
local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left") 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}) local other_inv = minetest.get_inventory({type="node", pos=other_pos})
inv:set_stack("input", 1, nil) inv:set_stack("input", 1, nil)
@ -626,7 +650,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
_mcl_hardness = 2.5, _mcl_hardness = 2.5,
on_rightclick = function(pos, node, clicker) on_rightclick = function(pos, node, clicker)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") local pos_other = get_double_container_neighbor_pos(pos, node.param2, "left")
local above_def = minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name] local above_def = minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name]
local above_def_other = minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name] local above_def_other = minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name]
@ -692,7 +716,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
on_construct = function(pos) on_construct = function(pos)
local n = minetest.get_node(pos) local n = minetest.get_node(pos)
local param2 = n.param2 local param2 = n.param2
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") local p = get_double_container_neighbor_pos(pos, param2, "right")
if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_left" then if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_left" then
n.name = "mcl_chests:"..canonical_basename.."_small" n.name = "mcl_chests:"..canonical_basename.."_small"
minetest.swap_node(pos, n) minetest.swap_node(pos, n)
@ -710,7 +734,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
close_forms(canonical_basename, pos) close_forms(canonical_basename, pos)
local param2 = n.param2 local param2 = n.param2
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") local p = get_double_container_neighbor_pos(pos, param2, "right")
if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_left" then if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_left" then
return return
end end
@ -730,7 +754,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
return 0 return 0
-- BEGIN OF LISTRING WORKAROUND -- BEGIN OF LISTRING WORKAROUND
elseif listname == "input" then elseif listname == "input" then
local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right") 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 other_inv = minetest.get_inventory({type="node", pos=other_pos})
local inv = minetest.get_inventory({type="node", pos=pos}) local inv = minetest.get_inventory({type="node", pos=pos})
--[[if other_inv:room_for_item("main", stack) then --[[if other_inv:room_for_item("main", stack) then
@ -757,7 +781,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
" moves stuff to chest at "..minetest.pos_to_string(pos)) " moves stuff to chest at "..minetest.pos_to_string(pos))
-- BEGIN OF LISTRING WORKAROUND -- BEGIN OF LISTRING WORKAROUND
if listname == "input" then if listname == "input" then
local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right") 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 other_inv = minetest.get_inventory({type="node", pos=other_pos})
local inv = minetest.get_inventory({type="node", pos=pos}) local inv = minetest.get_inventory({type="node", pos=pos})
@ -775,7 +799,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
_mcl_hardness = 2.5, _mcl_hardness = 2.5,
on_rightclick = function(pos, node, clicker) on_rightclick = function(pos, node, clicker)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") local pos_other = get_double_container_neighbor_pos(pos, node.param2, "right")
if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1
or minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name].groups.opaque == 1 then or minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name].groups.opaque == 1 then
-- won't open if there is no space from the top -- won't open if there is no space from the top
@ -892,12 +916,12 @@ register_chest("trapped_chest",
find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left")
mesecon.receptor_on(pos, trapped_chest_mesecons_rules) mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") local pos_other = get_double_container_neighbor_pos(pos, node.param2, "left")
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2}) minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2})
mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules) mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules)
end, end,
function(pos, node, clicker) function(pos, node, clicker)
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") local pos_other = get_double_container_neighbor_pos(pos, node.param2, "right")
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2}) minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2})
mesecon.receptor_on(pos, trapped_chest_mesecons_rules) mesecon.receptor_on(pos, trapped_chest_mesecons_rules)

View File

@ -1,6 +1,7 @@
local S = minetest.get_translator(minetest.get_current_modname()) local S = minetest.get_translator(minetest.get_current_modname())
local math_abs = math.abs local math_abs = math.abs
local mcl_util_move_item_container = mcl_util.move_item_container
local minetest_facedir_to_dir = minetest.facedir_to_dir local minetest_facedir_to_dir = minetest.facedir_to_dir
local minetest_get_inventory = minetest.get_inventory local minetest_get_inventory = minetest.get_inventory
local minetest_get_item_group = minetest.get_item_group local minetest_get_item_group = minetest.get_item_group
@ -382,7 +383,7 @@ minetest.register_abm({
local dst_node_name = dst_node.name local dst_node_name = dst_node.name
local dst_container_group = minetest_get_item_group(dst_node_name, "container") local dst_container_group = minetest_get_item_group(dst_node_name, "container")
if GROUPS_TO_PUT_INTO_COMMON_SLOT[dst_container_group] then if GROUPS_TO_PUT_INTO_COMMON_SLOT[dst_container_group] then
mcl_util.move_item_container(pos, dst_pos) mcl_util_move_item_container(pos, dst_pos)
elseif GROUPS_TO_PUT_INTO_FUEL_SLOT[dst_container_group] then elseif GROUPS_TO_PUT_INTO_FUEL_SLOT[dst_container_group] then
local sinv = minetest_get_inventory({type="node", pos = pos}) local sinv = minetest_get_inventory({type="node", pos = pos})
local dinv = minetest_get_inventory({type="node", pos = dst_pos}) local dinv = minetest_get_inventory({type="node", pos = dst_pos})
@ -407,11 +408,11 @@ minetest.register_abm({
local above_container_group = minetest_get_item_group(above_node_name, "container") local above_container_group = minetest_get_item_group(above_node_name, "container")
if above_container_group ~= 0 then if above_container_group ~= 0 then
-- Suck an item from the container above into the hopper -- Suck an item from the container above into the hopper
if not mcl_util.move_item_container(pos_above, pos) if not mcl_util_move_item_container(pos_above, pos)
and above_container_group == 4 then and above_container_group == 4 then
local finv = minetest_get_inventory({type="node", pos = pos_above}) local finv = minetest_get_inventory({type="node", pos = pos_above})
if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then
mcl_util.move_item_container(pos_above, pos, "fuel") mcl_util_move_item_container(pos_above, pos, "fuel")
end end
end end
else else