mirror of
https://github.com/minetest-mods/hopper.git
synced 2024-11-19 22:03:47 +01:00
Add multi-node containers support
+ remove trailing spaces + add new api for extra information about containers
This commit is contained in:
parent
d0c8e18c5a
commit
df5f8d8379
12
abms.lua
12
abms.lua
@ -9,7 +9,7 @@ minetest.register_abm({
|
|||||||
if active_object_count_wider == 0 then
|
if active_object_count_wider == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
local inv = minetest.get_meta(pos):get_inventory()
|
||||||
local posob
|
local posob
|
||||||
|
|
||||||
@ -96,21 +96,21 @@ minetest.register_abm({
|
|||||||
source_pos = vector.subtract(pos, destination_dir)
|
source_pos = vector.subtract(pos, destination_dir)
|
||||||
destination_pos = vector.add(pos, destination_dir)
|
destination_pos = vector.add(pos, destination_dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
local output_direction
|
local output_direction
|
||||||
if destination_dir.y == 0 then
|
if destination_dir.y == 0 then
|
||||||
output_direction = "horizontal"
|
output_direction = "horizontal"
|
||||||
end
|
end
|
||||||
|
|
||||||
local source_node = minetest.get_node(source_pos)
|
local source_node = minetest.get_node(source_pos)
|
||||||
local destination_node = minetest.get_node(destination_pos)
|
local destination_node = minetest.get_node(destination_pos)
|
||||||
|
|
||||||
local registered_source_inventories = hopper.get_registered_inventories_for(source_node.name)
|
local registered_source_inventories = hopper.get_registered(source_node.name)
|
||||||
if registered_source_inventories ~= nil then
|
if registered_source_inventories ~= nil then
|
||||||
hopper.take_item_from(pos, source_pos, source_node, registered_source_inventories["top"])
|
hopper.take_item_from(pos, source_pos, source_node, registered_source_inventories["top"])
|
||||||
end
|
end
|
||||||
|
|
||||||
local registered_destination_inventories = hopper.get_registered_inventories_for(destination_node.name)
|
local registered_destination_inventories = hopper.get_registered(destination_node.name)
|
||||||
if registered_destination_inventories ~= nil then
|
if registered_destination_inventories ~= nil then
|
||||||
if output_direction == "horizontal" then
|
if output_direction == "horizontal" then
|
||||||
hopper.send_item_to(pos, destination_pos, destination_node, registered_destination_inventories["side"])
|
hopper.send_item_to(pos, destination_pos, destination_node, registered_destination_inventories["side"])
|
||||||
|
130
api.lua
130
api.lua
@ -2,60 +2,112 @@ hopper.containers = {}
|
|||||||
hopper.groups = {}
|
hopper.groups = {}
|
||||||
hopper.neighbors = {}
|
hopper.neighbors = {}
|
||||||
|
|
||||||
|
local function parse_group(target_node)
|
||||||
|
local number
|
||||||
|
local identifier
|
||||||
|
|
||||||
|
local equals_index = string.find(target_node, "=")
|
||||||
|
if equals_index ~= nil then
|
||||||
|
identifier = string.sub(target_node, 7, equals_index-1)
|
||||||
|
-- it's possible that the string was of the form "group:blah = 1", in which case we want to trim spaces off the end of the group identifier
|
||||||
|
local space_index = string.find(identifier, " ")
|
||||||
|
if space_index ~= nil then
|
||||||
|
identifier = string.sub(identifier, 1, space_index-1)
|
||||||
|
end
|
||||||
|
number = tonumber(string.sub(target_node, equals_index+1, -1))
|
||||||
|
else
|
||||||
|
identifier = string.sub(target_node, 7, -1)
|
||||||
|
number = "all" -- special value to indicate no number was provided
|
||||||
|
end
|
||||||
|
|
||||||
|
return identifier, number
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_already_in_neighbors(neighbor_node)
|
||||||
|
for _, value in pairs(hopper.neighbors) do
|
||||||
|
if value == neighbor_node then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
-- global function to add new containers
|
-- global function to add new containers
|
||||||
function hopper:add_container(list)
|
function hopper:add_container(list)
|
||||||
for _, entry in pairs(list) do
|
for _, entry in pairs(list) do
|
||||||
|
|
||||||
local target_node = entry[2]
|
local target_node = entry[2]
|
||||||
local neighbor_node
|
local neighbor_node
|
||||||
|
|
||||||
if string.sub(target_node, 1, 6) == "group:" then
|
if string.sub(target_node, 1, 6) == "group:" then
|
||||||
local group_identifier, group_number
|
local group_identifier, group_number = parse_group(target_node)
|
||||||
local equals_index = string.find(target_node, "=")
|
|
||||||
if equals_index ~= nil then
|
if hopper.groups[group_identifier] == nil then
|
||||||
group_identifier = string.sub(target_node, 7, equals_index-1)
|
hopper.groups[group_identifier] = {}
|
||||||
-- it's possible that the string was of the form "group:blah = 1", in which case we want to trim spaces off the end of the group identifier
|
|
||||||
local space_index = string.find(group_identifier, " ")
|
|
||||||
if space_index ~= nil then
|
|
||||||
group_identifier = string.sub(group_identifier, 1, space_index-1)
|
|
||||||
end
|
|
||||||
group_number = tonumber(string.sub(target_node, equals_index+1, -1))
|
|
||||||
else
|
|
||||||
group_identifier = string.sub(target_node, 7, -1)
|
|
||||||
group_number = "all" -- special value to indicate no number was provided
|
|
||||||
end
|
end
|
||||||
|
local group = hopper.groups[group_identifier][group_number]
|
||||||
local group_info = hopper.groups[group_identifier]
|
if group == nil then
|
||||||
if group_info == nil then
|
group = {}
|
||||||
group_info = {}
|
|
||||||
end
|
end
|
||||||
if group_info[group_number] == nil then
|
if group[entry[1]] == nil then
|
||||||
group_info[group_number] = {}
|
group[entry[1]] = {}
|
||||||
end
|
end
|
||||||
group_info[group_number][entry[1]] = entry[3]
|
group[entry[1]]["inventory_name"] = entry[3]
|
||||||
hopper.groups[group_identifier] = group_info
|
if entry["get_inventory"] then
|
||||||
|
group[entry[1]]["get_inventory"] = entry["get_inventory"]
|
||||||
|
end
|
||||||
|
hopper.groups[group_identifier][group_number] = group
|
||||||
neighbor_node = "group:"..group_identifier
|
neighbor_node = "group:"..group_identifier
|
||||||
-- result is a table of the form groups[group_identifier][group_number][relative_position][inventory_name]
|
-- result is a table of the form:
|
||||||
|
-- groups[group_identifier][group_number][relative_position]{"inventory_name","get_inventory"}
|
||||||
else
|
else
|
||||||
local node_info = hopper.containers[target_node]
|
local node_info = hopper.containers[target_node]
|
||||||
if node_info == nil then
|
if node_info == nil then
|
||||||
node_info = {}
|
node_info = {}
|
||||||
end
|
end
|
||||||
node_info[entry[1]] = entry[3]
|
if node_info[entry[1]] == nil then
|
||||||
|
node_info[entry[1]] = {}
|
||||||
|
end
|
||||||
|
node_info[entry[1]]["inventory_name"] = entry[3]
|
||||||
|
if entry["get_inventory"] then
|
||||||
|
node_info[entry[1]]["get_inventory"] = entry["get_inventory"]
|
||||||
|
end
|
||||||
hopper.containers[target_node] = node_info
|
hopper.containers[target_node] = node_info
|
||||||
neighbor_node = target_node
|
neighbor_node = target_node
|
||||||
-- result is a table of the form containers[target_node_name][relative_position][inventory_name]
|
-- result is a table of the form:
|
||||||
|
-- containers[target_node_name][relative_position]{"inventory_name","get_inventory"}
|
||||||
end
|
end
|
||||||
|
|
||||||
local already_in_neighbors = false
|
if not is_already_in_neighbors(neighbor_node) then
|
||||||
for _, value in pairs(hopper.neighbors) do
|
table.insert(hopper.neighbors, neighbor_node)
|
||||||
if value == neighbor_node then
|
end
|
||||||
already_in_neighbors = true
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- global function for additional information about containers
|
||||||
|
function hopper:set_extra_container_info(list)
|
||||||
|
for _, entry in pairs(list) do
|
||||||
|
local target_node = entry[1]
|
||||||
|
table.remove(entry, 1) -- only extra information
|
||||||
|
if string.sub(target_node, 1, 6) == "group:" then
|
||||||
|
local group_identifier, group_number = parse_group(target_node)
|
||||||
|
if not is_already_in_neighbors("group:" .. group_identifier) then
|
||||||
|
minetest.log("error","An attempt to add extra information for " ..
|
||||||
|
target_node .. " in the absence of the main one")
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
hopper.groups[group_identifier][group_number].extra = entry
|
||||||
if not already_in_neighbors then
|
-- result is a table of the form:
|
||||||
table.insert(hopper.neighbors, neighbor_node)
|
-- groups[group_identifier][group_number]["extra"][list of extra information]
|
||||||
|
else
|
||||||
|
if not is_already_in_neighbors(target_node) then
|
||||||
|
minetest.log("error","An attempt to add extra information for " ..
|
||||||
|
target_node .. " in the absence of the main one")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
hopper.containers[target_node].extra = entry
|
||||||
|
-- result is a table of the form:
|
||||||
|
-- containers[target_node_name]["extra"][list of extra information]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -69,10 +121,10 @@ hopper:add_container({
|
|||||||
{"bottom", "hopper:hopper", "main"},
|
{"bottom", "hopper:hopper", "main"},
|
||||||
{"side", "hopper:hopper", "main"},
|
{"side", "hopper:hopper", "main"},
|
||||||
{"side", "hopper:hopper_side", "main"},
|
{"side", "hopper:hopper_side", "main"},
|
||||||
|
|
||||||
{"bottom", "hopper:chute", "main"},
|
{"bottom", "hopper:chute", "main"},
|
||||||
{"side", "hopper:chute", "main"},
|
{"side", "hopper:chute", "main"},
|
||||||
|
|
||||||
{"bottom", "hopper:sorter", "main"},
|
{"bottom", "hopper:sorter", "main"},
|
||||||
{"side", "hopper:sorter", "main"},
|
{"side", "hopper:sorter", "main"},
|
||||||
})
|
})
|
||||||
@ -82,15 +134,15 @@ if minetest.get_modpath("default") then
|
|||||||
{"top", "default:chest", "main"},
|
{"top", "default:chest", "main"},
|
||||||
{"bottom", "default:chest", "main"},
|
{"bottom", "default:chest", "main"},
|
||||||
{"side", "default:chest", "main"},
|
{"side", "default:chest", "main"},
|
||||||
|
|
||||||
{"top", "default:furnace", "dst"},
|
{"top", "default:furnace", "dst"},
|
||||||
{"bottom", "default:furnace", "src"},
|
{"bottom", "default:furnace", "src"},
|
||||||
{"side", "default:furnace", "fuel"},
|
{"side", "default:furnace", "fuel"},
|
||||||
|
|
||||||
{"top", "default:furnace_active", "dst"},
|
{"top", "default:furnace_active", "dst"},
|
||||||
{"bottom", "default:furnace_active", "src"},
|
{"bottom", "default:furnace_active", "src"},
|
||||||
{"side", "default:furnace_active", "fuel"},
|
{"side", "default:furnace_active", "fuel"},
|
||||||
|
|
||||||
{"top", "default:chest_locked", "main"},
|
{"top", "default:chest_locked", "main"},
|
||||||
{"bottom", "default:chest_locked", "main"},
|
{"bottom", "default:chest_locked", "main"},
|
||||||
{"side", "default:chest_locked", "main"},
|
{"side", "default:chest_locked", "main"},
|
||||||
|
@ -41,7 +41,7 @@ minetest.register_node("hopper:chute", {
|
|||||||
{-0.2, -0.2, 0.3, 0.2, 0.2, 0.7},
|
{-0.2, -0.2, 0.3, 0.2, 0.2, 0.7},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
local inv = minetest.get_meta(pos):get_inventory()
|
||||||
inv:set_size("main", 2*2)
|
inv:set_size("main", 2*2)
|
||||||
@ -60,7 +60,7 @@ minetest.register_node("hopper:chute", {
|
|||||||
end
|
end
|
||||||
return returned_stack
|
return returned_stack
|
||||||
end,
|
end,
|
||||||
|
|
||||||
can_dig = function(pos,player)
|
can_dig = function(pos,player)
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
local inv = minetest.get_meta(pos):get_inventory()
|
||||||
return inv:is_empty("main")
|
return inv:is_empty("main")
|
||||||
@ -81,7 +81,7 @@ minetest.register_node("hopper:chute", {
|
|||||||
local timer = minetest.get_node_timer(pos)
|
local timer = minetest.get_node_timer(pos)
|
||||||
if not timer:is_started() then
|
if not timer:is_started() then
|
||||||
timer:start(1)
|
timer:start(1)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_timer = function(pos, elapsed)
|
on_timer = function(pos, elapsed)
|
||||||
@ -95,9 +95,9 @@ minetest.register_node("hopper:chute", {
|
|||||||
if dir.y == 0 then
|
if dir.y == 0 then
|
||||||
output_direction = "horizontal"
|
output_direction = "horizontal"
|
||||||
end
|
end
|
||||||
|
|
||||||
local destination_node = minetest.get_node(destination_pos)
|
local destination_node = minetest.get_node(destination_pos)
|
||||||
local registered_inventories = hopper.get_registered_inventories_for(destination_node.name)
|
local registered_inventories = hopper.get_registered(destination_node.name)
|
||||||
if registered_inventories ~= nil then
|
if registered_inventories ~= nil then
|
||||||
if output_direction == "horizontal" then
|
if output_direction == "horizontal" then
|
||||||
hopper.send_item_to(pos, destination_pos, destination_node, registered_inventories["side"])
|
hopper.send_item_to(pos, destination_pos, destination_node, registered_inventories["side"])
|
||||||
@ -107,7 +107,7 @@ minetest.register_node("hopper:chute", {
|
|||||||
else
|
else
|
||||||
hopper.send_item_to(pos, destination_pos, destination_node)
|
hopper.send_item_to(pos, destination_pos, destination_node)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not inv:is_empty("main") then
|
if not inv:is_empty("main") then
|
||||||
minetest.get_node_timer(pos):start(1)
|
minetest.get_node_timer(pos):start(1)
|
||||||
end
|
end
|
||||||
|
@ -29,16 +29,22 @@ local hopper_on_place = function(itemstack, placer, pointed_thing, node_name)
|
|||||||
return returned_stack
|
return returned_stack
|
||||||
end
|
end
|
||||||
|
|
||||||
local pointed_pos = pointed_thing.under
|
local pointed_pos = pointed_thing.under
|
||||||
local hopper_pos = pointed_thing.above
|
local hopper_pos = pointed_thing.above
|
||||||
|
|
||||||
local param2_by_offset = {
|
local param2
|
||||||
[vector.new(-1, 0, 0):to_string()] = 0,
|
local pointed_registered = hopper.get_registered(minetest.get_node(pointed_pos).name)
|
||||||
[vector.new( 0, 0, 1):to_string()] = 1,
|
if pointed_registered and pointed_registered.extra.set_hopper_param2 then
|
||||||
[vector.new( 1, 0, 0):to_string()] = 2,
|
param2 = pointed_registered.extra.set_hopper_param2(hopper_pos, pointed_pos)
|
||||||
[vector.new( 0, 0,-1):to_string()] = 3,
|
else
|
||||||
}
|
local param2_by_offset = {
|
||||||
local param2 = param2_by_offset[(pointed_pos - hopper_pos):to_string()]
|
[vector.new(-1, 0, 0):to_string()] = 0,
|
||||||
|
[vector.new( 0, 0, 1):to_string()] = 1,
|
||||||
|
[vector.new( 1, 0, 0):to_string()] = 2,
|
||||||
|
[vector.new( 0, 0,-1):to_string()] = 3,
|
||||||
|
}
|
||||||
|
param2 = param2_by_offset[(pointed_pos - hopper_pos):to_string()]
|
||||||
|
end
|
||||||
|
|
||||||
if param2 then
|
if param2 then
|
||||||
returned_stack, success = minetest.item_place_node(ItemStack("hopper:hopper_side"), placer, pointed_thing, param2)
|
returned_stack, success = minetest.item_place_node(ItemStack("hopper:hopper_side"), placer, pointed_thing, param2)
|
||||||
@ -196,7 +202,7 @@ minetest.register_node("hopper:hopper_side", {
|
|||||||
{-0.7, -0.3, -0.15, 0.15, 0.0, 0.15},
|
{-0.7, -0.3, -0.15, 0.15, 0.0, 0.15},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
local inv = minetest.get_meta(pos):get_inventory()
|
||||||
inv:set_size("main", 4*4)
|
inv:set_size("main", 4*4)
|
||||||
@ -205,7 +211,7 @@ minetest.register_node("hopper:hopper_side", {
|
|||||||
on_place = function(itemstack, placer, pointed_thing)
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
return hopper_on_place(itemstack, placer, pointed_thing, "hopper:hopper_side")
|
return hopper_on_place(itemstack, placer, pointed_thing, "hopper:hopper_side")
|
||||||
end,
|
end,
|
||||||
|
|
||||||
can_dig = function(pos,player)
|
can_dig = function(pos,player)
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
local inv = minetest.get_meta(pos):get_inventory()
|
||||||
return inv:is_empty("main")
|
return inv:is_empty("main")
|
||||||
|
@ -16,7 +16,7 @@ end
|
|||||||
|
|
||||||
local function get_sorter_formspec(pos)
|
local function get_sorter_formspec(pos)
|
||||||
local spos = hopper.get_string_pos(pos)
|
local spos = hopper.get_string_pos(pos)
|
||||||
|
|
||||||
local filter_all = minetest.get_meta(pos):get_string("filter_all") == "true"
|
local filter_all = minetest.get_meta(pos):get_string("filter_all") == "true"
|
||||||
local y_displace = 0
|
local y_displace = 0
|
||||||
local filter_texture, filter_button_tooltip, filter_body
|
local filter_texture, filter_button_tooltip, filter_body
|
||||||
@ -30,11 +30,11 @@ local function get_sorter_formspec(pos)
|
|||||||
filter_button_tooltip = FS("This sorter is currently set to only send items listed\nin the filter list in the direction of the arrow.\nClick this button to set it to try sending all\nitems that way first.")
|
filter_button_tooltip = FS("This sorter is currently set to only send items listed\nin the filter list in the direction of the arrow.\nClick this button to set it to try sending all\nitems that way first.")
|
||||||
y_displace = 1.6
|
y_displace = 1.6
|
||||||
end
|
end
|
||||||
|
|
||||||
local formspec =
|
local formspec =
|
||||||
"size[8," .. 7 + y_displace .. "]"
|
"size[8," .. 7 + y_displace .. "]"
|
||||||
.. hopper.formspec_bg
|
.. hopper.formspec_bg
|
||||||
.. filter_body
|
.. filter_body
|
||||||
.. "list[nodemeta:" .. spos .. ";main;3,".. tostring(0.3 + y_displace) .. ";2,2;]"
|
.. "list[nodemeta:" .. spos .. ";main;3,".. tostring(0.3 + y_displace) .. ";2,2;]"
|
||||||
.. ("image_button_exit[0,%g;1,1;%s;filter_all;]"):format(y_displace, filter_texture)
|
.. ("image_button_exit[0,%g;1,1;%s;filter_all;]"):format(y_displace, filter_texture)
|
||||||
.. "tooltip[filter_all;" .. filter_button_tooltip.. "]"
|
.. "tooltip[filter_all;" .. filter_button_tooltip.. "]"
|
||||||
@ -72,14 +72,14 @@ minetest.register_node("hopper:sorter", {
|
|||||||
{-0.2, -0.3, -0.2, 0.2, -0.7, 0.2},
|
{-0.2, -0.3, -0.2, 0.2, -0.7, 0.2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
inv:set_size("main", 2*2)
|
inv:set_size("main", 2*2)
|
||||||
inv:set_size("filter", 8)
|
inv:set_size("filter", 8)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_place = function(itemstack, placer, pointed_thing, node_name)
|
on_place = function(itemstack, placer, pointed_thing, node_name)
|
||||||
local pos = pointed_thing.under
|
local pos = pointed_thing.under
|
||||||
local pos2 = pointed_thing.above
|
local pos2 = pointed_thing.above
|
||||||
@ -93,13 +93,13 @@ minetest.register_node("hopper:sorter", {
|
|||||||
end
|
end
|
||||||
return returned_stack
|
return returned_stack
|
||||||
end,
|
end,
|
||||||
|
|
||||||
can_dig = function(pos,player)
|
can_dig = function(pos,player)
|
||||||
local meta = minetest.get_meta(pos);
|
local meta = minetest.get_meta(pos);
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
return inv:is_empty("main")
|
return inv:is_empty("main")
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_rightclick = function(pos, node, clicker, itemstack)
|
on_rightclick = function(pos, node, clicker, itemstack)
|
||||||
if minetest.is_protected(pos, clicker:get_player_name()) and not minetest.check_player_privs(clicker, "protection_bypass") then
|
if minetest.is_protected(pos, clicker:get_player_name()) and not minetest.check_player_privs(clicker, "protection_bypass") then
|
||||||
return
|
return
|
||||||
@ -107,7 +107,7 @@ minetest.register_node("hopper:sorter", {
|
|||||||
minetest.show_formspec(clicker:get_player_name(),
|
minetest.show_formspec(clicker:get_player_name(),
|
||||||
"hopper_formspec:"..minetest.pos_to_string(pos), get_sorter_formspec(pos))
|
"hopper_formspec:"..minetest.pos_to_string(pos), get_sorter_formspec(pos))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
if listname == "filter" then
|
if listname == "filter" then
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||||
@ -116,7 +116,7 @@ minetest.register_node("hopper:sorter", {
|
|||||||
end
|
end
|
||||||
return stack:get_count()
|
return stack:get_count()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
if listname == "filter" then
|
if listname == "filter" then
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||||
@ -125,7 +125,7 @@ minetest.register_node("hopper:sorter", {
|
|||||||
end
|
end
|
||||||
return stack:get_count()
|
return stack:get_count()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||||
if to_list == "filter" then
|
if to_list == "filter" then
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||||
@ -135,11 +135,11 @@ minetest.register_node("hopper:sorter", {
|
|||||||
elseif from_list == "filter" then
|
elseif from_list == "filter" then
|
||||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||||
inv:set_stack(from_list, from_index, ItemStack(""))
|
inv:set_stack(from_list, from_index, ItemStack(""))
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
return count
|
return count
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
hopper.log_inventory(("%s moves stuff to sorter at %s"):format(
|
hopper.log_inventory(("%s moves stuff to sorter at %s"):format(
|
||||||
player:get_player_name(), minetest.pos_to_string(pos)))
|
player:get_player_name(), minetest.pos_to_string(pos)))
|
||||||
@ -147,15 +147,15 @@ minetest.register_node("hopper:sorter", {
|
|||||||
local timer = minetest.get_node_timer(pos)
|
local timer = minetest.get_node_timer(pos)
|
||||||
if not timer:is_started() then
|
if not timer:is_started() then
|
||||||
timer:start(1)
|
timer:start(1)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_timer = function(pos, elapsed)
|
on_timer = function(pos, elapsed)
|
||||||
local meta = minetest.get_meta(pos);
|
local meta = minetest.get_meta(pos);
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
|
|
||||||
-- build a filter list
|
-- build a filter list
|
||||||
local filter_items = nil
|
local filter_items = nil
|
||||||
if meta:get_string("filter_all") ~= "true" then
|
if meta:get_string("filter_all") ~= "true" then
|
||||||
filter_items = {}
|
filter_items = {}
|
||||||
local filter_inv_size = inv:get_size("filter")
|
local filter_inv_size = inv:get_size("filter")
|
||||||
@ -167,7 +167,7 @@ minetest.register_node("hopper:sorter", {
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
local dir = minetest.facedir_to_dir(node.param2)
|
local dir = minetest.facedir_to_dir(node.param2)
|
||||||
local default_destination_pos = vector.add(pos, dir)
|
local default_destination_pos = vector.add(pos, dir)
|
||||||
@ -184,9 +184,9 @@ minetest.register_node("hopper:sorter", {
|
|||||||
end
|
end
|
||||||
|
|
||||||
local success = false
|
local success = false
|
||||||
|
|
||||||
local filter_destination_node = minetest.get_node(filter_destination_pos)
|
local filter_destination_node = minetest.get_node(filter_destination_pos)
|
||||||
local registered_inventories = hopper.get_registered_inventories_for(filter_destination_node.name)
|
local registered_inventories = hopper.get_registered(filter_destination_node.name)
|
||||||
if registered_inventories ~= nil then
|
if registered_inventories ~= nil then
|
||||||
if filter_output_direction == "horizontal" then
|
if filter_output_direction == "horizontal" then
|
||||||
success = hopper.send_item_to(pos, filter_destination_pos, filter_destination_node, registered_inventories["side"], filter_items)
|
success = hopper.send_item_to(pos, filter_destination_pos, filter_destination_node, registered_inventories["side"], filter_items)
|
||||||
@ -196,10 +196,10 @@ minetest.register_node("hopper:sorter", {
|
|||||||
else
|
else
|
||||||
success = hopper.send_item_to(pos, filter_destination_pos, filter_destination_node, nil, filter_items)
|
success = hopper.send_item_to(pos, filter_destination_pos, filter_destination_node, nil, filter_items)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not success then -- weren't able to put something in the filter destination, for whatever reason. Now we can start moving stuff forward to the default.
|
if not success then -- weren't able to put something in the filter destination, for whatever reason. Now we can start moving stuff forward to the default.
|
||||||
local default_destination_node = minetest.get_node(default_destination_pos)
|
local default_destination_node = minetest.get_node(default_destination_pos)
|
||||||
local registered_inventories = hopper.get_registered_inventories_for(default_destination_node.name)
|
local registered_inventories = hopper.get_registered(default_destination_node.name)
|
||||||
if registered_inventories ~= nil then
|
if registered_inventories ~= nil then
|
||||||
if default_output_direction == "horizontal" then
|
if default_output_direction == "horizontal" then
|
||||||
hopper.send_item_to(pos, default_destination_pos, default_destination_node, registered_inventories["side"])
|
hopper.send_item_to(pos, default_destination_pos, default_destination_node, registered_inventories["side"])
|
||||||
@ -210,7 +210,7 @@ minetest.register_node("hopper:sorter", {
|
|||||||
hopper.send_item_to(pos, default_destination_pos, default_destination_node)
|
hopper.send_item_to(pos, default_destination_pos, default_destination_node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not inv:is_empty("main") then
|
if not inv:is_empty("main") then
|
||||||
minetest.get_node_timer(pos):start(1)
|
minetest.get_node_timer(pos):start(1)
|
||||||
end
|
end
|
||||||
|
64
utility.lua
64
utility.lua
@ -4,7 +4,7 @@ local FS = hopper.translator_escaped
|
|||||||
|
|
||||||
-- looks first for a registration matching the specific node name, then for a registration
|
-- looks first for a registration matching the specific node name, then for a registration
|
||||||
-- matching group and value, then for a registration matching a group and *any* value
|
-- matching group and value, then for a registration matching a group and *any* value
|
||||||
hopper.get_registered_inventories_for = function(target_node_name)
|
hopper.get_registered = function(target_node_name)
|
||||||
local output = hopper.containers[target_node_name]
|
local output = hopper.containers[target_node_name]
|
||||||
if output ~= nil then return output end
|
if output ~= nil then return output end
|
||||||
|
|
||||||
@ -70,38 +70,48 @@ local get_placer = function(player_name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Used to remove items from the target block and put it into the hopper's inventory
|
-- Used to remove items from the target block and put it into the hopper's inventory
|
||||||
hopper.take_item_from = function(hopper_pos, target_pos, target_node, target_inventory_name)
|
hopper.take_item_from = function(hopper_pos, target_pos, target_node, target_inv_info)
|
||||||
if target_inventory_name == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local target_def = minetest.registered_nodes[target_node.name]
|
local target_def = minetest.registered_nodes[target_node.name]
|
||||||
if not target_def then
|
if not target_def then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local target_inv_name = target_inv_info["inventory_name"]
|
||||||
|
local target_get_inv = target_inv_info["get_inventory"]
|
||||||
|
|
||||||
--hopper inventory
|
--hopper inventory
|
||||||
local hopper_meta = minetest.get_meta(hopper_pos);
|
local hopper_meta = minetest.get_meta(hopper_pos)
|
||||||
local hopper_inv = hopper_meta:get_inventory()
|
local hopper_inv = hopper_meta:get_inventory()
|
||||||
local placer = get_placer(hopper_meta:get_string("placer"))
|
local placer = get_placer(hopper_meta:get_string("placer"))
|
||||||
|
|
||||||
--source inventory
|
--source inventory
|
||||||
local target_inv = minetest.get_meta(target_pos):get_inventory()
|
local target_inv
|
||||||
local target_inv_size = target_inv:get_size(target_inventory_name)
|
if target_get_inv then
|
||||||
if target_inv:is_empty(target_inventory_name) == false then
|
target_inv = target_get_inv(target_pos)
|
||||||
|
if not target_inv then
|
||||||
|
minetest.log("error","No inventory from api get_inventory function: " ..
|
||||||
|
target_node.name .. " on " .. vector.to_string(target_pos))
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
target_inv = minetest.get_meta(target_pos):get_inventory()
|
||||||
|
end
|
||||||
|
local target_inv_size = target_inv:get_size(target_inv_name)
|
||||||
|
if target_inv:is_empty(target_inv_name) == false then
|
||||||
for i = 1,target_inv_size do
|
for i = 1,target_inv_size do
|
||||||
local stack = target_inv:get_stack(target_inventory_name, i)
|
local stack = target_inv:get_stack(target_inv_name, i)
|
||||||
local item = stack:get_name()
|
local item = stack:get_name()
|
||||||
if item ~= "" then
|
if item ~= "" then
|
||||||
if hopper_inv:room_for_item("main", item) then
|
if hopper_inv:room_for_item("main", item) then
|
||||||
local stack_to_take = stack:take_item(1)
|
local stack_to_take = stack:take_item(1)
|
||||||
if target_def.allow_metadata_inventory_take == nil
|
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 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_inventory_name, i, stack_to_take, placer) > 0 then
|
or target_def.allow_metadata_inventory_take(target_pos, target_inv_name, i, stack_to_take, placer) > 0 then
|
||||||
target_inv:set_stack(target_inventory_name, i, stack)
|
target_inv:set_stack(target_inv_name, i, stack)
|
||||||
--add to hopper
|
--add to hopper
|
||||||
hopper_inv:add_item("main", stack_to_take)
|
hopper_inv:add_item("main", stack_to_take)
|
||||||
if target_def.on_metadata_inventory_take ~= nil and placer ~= nil then
|
if target_def.on_metadata_inventory_take ~= nil and placer ~= nil then
|
||||||
target_def.on_metadata_inventory_take(target_pos, target_inventory_name, i, stack_to_take, placer)
|
target_def.on_metadata_inventory_take(target_pos, target_inv_name, i, stack_to_take, placer)
|
||||||
end
|
end
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@ -112,7 +122,7 @@ hopper.take_item_from = function(hopper_pos, target_pos, target_node, target_inv
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Used to put items from the hopper inventory into the target block
|
-- Used to put items from the hopper inventory into the target block
|
||||||
hopper.send_item_to = function(hopper_pos, target_pos, target_node, target_inventory_name, filtered_items)
|
hopper.send_item_to = function(hopper_pos, target_pos, target_node, target_inv_info, filtered_items)
|
||||||
local hopper_meta = minetest.get_meta(hopper_pos)
|
local hopper_meta = minetest.get_meta(hopper_pos)
|
||||||
local target_def = minetest.registered_nodes[target_node.name]
|
local target_def = minetest.registered_nodes[target_node.name]
|
||||||
if not target_def then
|
if not target_def then
|
||||||
@ -121,7 +131,7 @@ hopper.send_item_to = function(hopper_pos, target_pos, target_node, target_inven
|
|||||||
|
|
||||||
local eject_item = hopper.config.eject_button_enabled and hopper_meta:get_string("eject") == "true" and target_def.buildable_to
|
local eject_item = hopper.config.eject_button_enabled and hopper_meta:get_string("eject") == "true" and target_def.buildable_to
|
||||||
|
|
||||||
if not eject_item and not target_inventory_name then
|
if not eject_item and not target_inv_info then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -135,23 +145,35 @@ hopper.send_item_to = function(hopper_pos, target_pos, target_node, target_inven
|
|||||||
local placer = get_placer(hopper_meta:get_string("placer"))
|
local placer = get_placer(hopper_meta:get_string("placer"))
|
||||||
|
|
||||||
--target inventory
|
--target inventory
|
||||||
local target_inv = minetest.get_meta(target_pos):get_inventory()
|
local target_inv_name = target_inv_info["inventory_name"]
|
||||||
|
local target_get_inv = target_inv_info["get_inventory"]
|
||||||
|
local target_inv
|
||||||
|
if target_get_inv then
|
||||||
|
target_inv = target_get_inv(target_pos)
|
||||||
|
if not target_inv then
|
||||||
|
minetest.log("error","No inventory from api get_inventory function: " ..
|
||||||
|
target_node.name .. " on " .. vector.to_string(target_pos))
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
target_inv = minetest.get_meta(target_pos):get_inventory()
|
||||||
|
end
|
||||||
|
|
||||||
for i = 1,hopper_inv_size do
|
for i = 1,hopper_inv_size do
|
||||||
local stack = hopper_inv:get_stack("main", i)
|
local stack = hopper_inv:get_stack("main", i)
|
||||||
local item = stack:get_name()
|
local item = stack:get_name()
|
||||||
if item ~= "" and (filtered_items == nil or filtered_items[item]) then
|
if item ~= "" and (filtered_items == nil or filtered_items[item]) then
|
||||||
if target_inventory_name then
|
if target_inv_name then
|
||||||
if target_inv:room_for_item(target_inventory_name, item) then
|
if target_inv:room_for_item(target_inv_name, item) then
|
||||||
local stack_to_put = stack:take_item(1)
|
local stack_to_put = stack:take_item(1)
|
||||||
if target_def.allow_metadata_inventory_put == nil
|
if target_def.allow_metadata_inventory_put == nil
|
||||||
or placer == nil -- backwards compatibility, older versions of this mod didn't record who placed the hopper
|
or placer == nil -- backwards compatibility, older versions of this mod didn't record who placed the hopper
|
||||||
or target_def.allow_metadata_inventory_put(target_pos, target_inventory_name, i, stack_to_put, placer) > 0 then
|
or target_def.allow_metadata_inventory_put(target_pos, target_inv_name, i, stack_to_put, placer) > 0 then
|
||||||
hopper_inv:set_stack("main", i, stack)
|
hopper_inv:set_stack("main", i, stack)
|
||||||
--add to target node
|
--add to target node
|
||||||
target_inv:add_item(target_inventory_name, stack_to_put)
|
target_inv:add_item(target_inv_name, stack_to_put)
|
||||||
if target_def.on_metadata_inventory_put ~= nil and placer ~= nil then
|
if target_def.on_metadata_inventory_put ~= nil and placer ~= nil then
|
||||||
target_def.on_metadata_inventory_put(target_pos, target_inventory_name, i, stack_to_put, placer)
|
target_def.on_metadata_inventory_put(target_pos, target_inv_name, i, stack_to_put, placer)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user