Fix sorter filter and error in eject (#32)

Also corrects eject for sorter, and simplifies it.
This commit is contained in:
Olivier Dragon 2024-09-25 14:41:03 -04:00 committed by GitHub
parent 0baf36e7d9
commit e91bc6ef0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 67 additions and 44 deletions

@ -97,9 +97,9 @@ minetest.register_abm({
destination_pos = vector.add(pos, destination_dir)
end
local output_direction
local output_direction = "bottom"
if destination_dir.y == 0 then
output_direction = "horizontal"
output_direction = "side"
end
local source_node = minetest.get_node(source_pos)
@ -112,13 +112,11 @@ minetest.register_abm({
local registered_destination_inventories = hopper.get_registered(destination_node.name)
if registered_destination_inventories ~= nil then
if output_direction == "horizontal" then
hopper.send_item_to(pos, destination_pos, destination_node, registered_destination_inventories["side"])
else
hopper.send_item_to(pos, destination_pos, destination_node, registered_destination_inventories["bottom"])
if not hopper.send_item_to(pos, destination_pos, destination_node, registered_destination_inventories[output_direction]) then
hopper.try_eject_item(pos, destination_pos)
end
else
hopper.send_item_to(pos, destination_pos, destination_node) -- for handling ejection
hopper.try_eject_item(pos, destination_pos)
end
end,
})

@ -88,21 +88,19 @@ minetest.register_node("hopper:chute", {
local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2)
local destination_pos = vector.add(pos, dir)
local output_direction
local output_direction = "bottom"
if dir.y == 0 then
output_direction = "horizontal"
output_direction = "side"
end
local destination_node = minetest.get_node(destination_pos)
local registered_inventories = hopper.get_registered(destination_node.name)
if registered_inventories ~= nil then
if output_direction == "horizontal" then
hopper.send_item_to(pos, destination_pos, destination_node, registered_inventories["side"])
else
hopper.send_item_to(pos, destination_pos, destination_node, registered_inventories["bottom"])
if not hopper.send_item_to(pos, destination_pos, destination_node, registered_inventories[output_direction]) then
hopper.try_eject_item(pos, destination_pos)
end
else
hopper.send_item_to(pos, destination_pos, destination_node)
hopper.try_eject_item(pos, destination_pos)
end
if not inv:is_empty("main") then

@ -175,21 +175,23 @@ minetest.register_node("hopper:sorter", {
local filter_output_direction = (dir.y == 0) and "side" or "bottom"
--- returns success? = true/false
local function try_send_item(output_dir, dst_pos)
local function try_send_item(output_dir, dst_pos, filter_items_map)
local dst_node = minetest.get_node(dst_pos)
local registered_inventories = hopper.get_registered(dst_node.name)
if registered_inventories ~= nil then
return hopper.send_item_to(pos, dst_pos, dst_node, registered_inventories[output_dir], filter_items)
return hopper.send_item_to(pos, dst_pos, dst_node, registered_inventories[output_dir], filter_items_map)
end
return hopper.send_item_to(pos, dst_pos, dst_node, nil, filter_items)
return false
end
if not try_send_item(filter_output_direction, filter_destination_pos) then
if not try_send_item(filter_output_direction, filter_destination_pos, filter_items) then
-- weren't able to put something in the filter destination, for whatever reason.
-- Now we can start moving stuff forward to the default.
try_send_item(default_output_direction, default_destination_pos)
if not try_send_item(default_output_direction, default_destination_pos) then
hopper.try_eject_item(pos, default_destination_pos)
end
end
if not inv:is_empty("main") then

@ -108,45 +108,56 @@ hopper.take_item_from = function(hopper_pos, target_pos, target_node, target_inv
if target_inv:is_empty(target_inv_name) == false then
for i = 1,target_inv_size do
local stack = target_inv:get_stack(target_inv_name, i)
local item = stack:get_name()
if item ~= "" then
if hopper_inv:room_for_item("main", item) then
local stack_to_take = stack:take_item(1)
if target_def.allow_metadata_inventory_take == nil
or placer == nil -- backwards compatibility, older versions of this mod didn't record who placed the hopper
or target_def.allow_metadata_inventory_take(target_pos, target_inv_name, i, stack_to_take, placer) > 0 then
target_inv:set_stack(target_inv_name, i, stack)
--add to hopper
hopper_inv:add_item("main", stack_to_take)
if target_def.on_metadata_inventory_take ~= nil and placer ~= nil then
target_def.on_metadata_inventory_take(target_pos, target_inv_name, i, stack_to_take, placer)
end
break
if not stack:is_empty() and hopper_inv:room_for_item("main", stack:get_name()) then
local stack_to_take = stack:take_item(1)
if target_def.allow_metadata_inventory_take == nil
or placer == nil -- backwards compatibility, older versions of this mod didn't record who placed the hopper
or target_def.allow_metadata_inventory_take(target_pos, target_inv_name, i, stack_to_take, placer) > 0 then
target_inv:set_stack(target_inv_name, i, stack)
--add to hopper
hopper_inv:add_item("main", stack_to_take)
if target_def.on_metadata_inventory_take ~= nil and placer ~= nil then
target_def.on_metadata_inventory_take(target_pos, target_inv_name, i, stack_to_take, placer)
end
break
end
end
end
end -- for
end
end
local function send_item_to_air(hopper_inv, target_pos, filtered_items)
local function try_send_item_to_air(hopper_inv, target_pos)
local stack
local stack_num
for i = 1, hopper_inv:get_size("main") do
stack = hopper_inv:get_stack("main", i)
local item = stack:get_name()
if item ~= "" and (filtered_items == nil or filtered_items[item]) then
if not stack:is_empty() then
stack_num = i
break
end
end
if not stack_num then
return false
local eject_node = minetest.get_node(target_pos)
local ndef = minetest.registered_nodes[eject_node.name]
if not ndef or not ndef.buildable_to then
minetest.log("verbose", "hopper.try_send_item_to_air: eject direction not buildable ("
..eject_node.name.." at "..target_pos:to_string().."). Looking for alternate.")
local air_pos = minetest.find_node_near(target_pos, 2, {"air"})
if not air_pos then
minetest.log("warning", "hopper.try_send_item_to_air: could not find an air node nearby")
return false
end
target_pos = air_pos
end
local stack_to_put = stack:take_item(1)
minetest.add_item(target_pos, stack_to_put)
hopper_inv:set_stack("main", stack_num, stack)
hopper.log_inventory("hopper ejecting "..stack:get_name().." as object to "..target_pos:to_string())
return true
end
@ -204,10 +215,24 @@ hopper.send_item_to = function(hopper_pos, target_pos, target_node, target_inv_i
return send_item_to_inv(hopper_inv, target_pos, filtered_items, placer, target_inv_info, target_def)
end
if hopper.config.eject_button_enabled and target_def.buildable_to
and hopper_meta:get_string("eject") == "true" then
return send_item_to_air(hopper_inv, target_pos, filtered_items)
end
return false
end
hopper.try_eject_item = function(hopper_pos, target_pos)
if not hopper.config.eject_button_enabled then
return false
end
local hopper_meta = minetest.get_meta(hopper_pos)
if hopper_meta:get_string("eject") ~= "true" then
return false
end
local hopper_inv = hopper_meta:get_inventory()
if hopper_inv:is_empty("main") then
return false
end
return try_send_item_to_air(hopper_inv, target_pos)
end