mirror of
https://github.com/minetest-mods/hopper.git
synced 2024-08-19 12:44:05 +02:00
186 lines
6.2 KiB
Lua
186 lines
6.2 KiB
Lua
|
-- internationalization boilerplate
|
||
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||
|
local S, NS = dofile(MP.."/intllib.lua")
|
||
|
|
||
|
local facedir_to_bottomdir = {
|
||
|
[0]={x=0, y=-1, z=0},
|
||
|
{x=0, y=0, z=-1},
|
||
|
{x=0, y=0, z=1},
|
||
|
{x=-1, y=0, z=0},
|
||
|
{x=1, y=0, z=0},
|
||
|
{x=0, y=1, z=0},
|
||
|
}
|
||
|
|
||
|
local bottomdir = function(facedir)
|
||
|
return facedir_to_bottomdir[math.floor(facedir/4)]
|
||
|
end
|
||
|
|
||
|
local function get_sorter_formspec(pos)
|
||
|
local spos = hopper.get_string_pos(pos)
|
||
|
local formspec =
|
||
|
"size[8,8.4]"
|
||
|
.. hopper.formspec_bg
|
||
|
.. "label[3.7,0;"..S("Filter").."]"
|
||
|
.. "list[nodemeta:" .. spos .. ";filter;0,0.5;8,1;]"
|
||
|
.. "list[nodemeta:" .. spos .. ";main;3,2.1;2,2;]"
|
||
|
.. hopper.get_eject_button_texts(pos, 7, 3)
|
||
|
.. "list[current_player;main;0,4.5;8,1;]"
|
||
|
.. "list[current_player;main;0,5.7;8,3;8]"
|
||
|
.. "listring[nodemeta:" .. spos .. ";main]"
|
||
|
.. "listring[current_player;main]"
|
||
|
return formspec
|
||
|
end
|
||
|
|
||
|
|
||
|
minetest.register_node("hopper:sorter", {
|
||
|
description = S("Sorter"),
|
||
|
_doc_items_longdesc = hopper.doc.sorter_long_desc,
|
||
|
_doc_items_usagehelp = hopper.doc.sorter_usage,
|
||
|
groups = {cracky = 3},
|
||
|
sounds = hopper.metal_sounds,
|
||
|
drawtype = "nodebox",
|
||
|
paramtype = "light",
|
||
|
paramtype2 = "facedir",
|
||
|
tiles = {
|
||
|
"hopper_bottom_" .. hopper.config.texture_resolution .. ".png",
|
||
|
"hopper_top_" .. hopper.config.texture_resolution .. ".png",
|
||
|
"hopper_bottom_" .. hopper.config.texture_resolution .. ".png^hopper_sorter_arrow_" .. hopper.config.texture_resolution .. ".png^[transformFX",
|
||
|
"hopper_bottom_" .. hopper.config.texture_resolution .. ".png^hopper_sorter_arrow_" .. hopper.config.texture_resolution .. ".png",
|
||
|
"hopper_top_" .. hopper.config.texture_resolution .. ".png",
|
||
|
"hopper_bottom_" .. hopper.config.texture_resolution .. ".png^hopper_sorter_arrow_" .. hopper.config.texture_resolution .. ".png",
|
||
|
},
|
||
|
node_box = {
|
||
|
type = "fixed",
|
||
|
fixed = {
|
||
|
{-0.3, -0.3, -0.4, 0.3, 0.4, 0.4},
|
||
|
{-0.2, -0.2, 0.4, 0.2, 0.2, 0.7},
|
||
|
{-0.2, -0.3, -0.2, 0.2, -0.7, 0.2},
|
||
|
},
|
||
|
},
|
||
|
|
||
|
on_construct = function(pos)
|
||
|
local meta = minetest.get_meta(pos)
|
||
|
local inv = meta:get_inventory()
|
||
|
inv:set_size("main", 2*2)
|
||
|
inv:set_size("filter", 8)
|
||
|
end,
|
||
|
|
||
|
on_place = function(itemstack, placer, pointed_thing, node_name)
|
||
|
local pos = pointed_thing.under
|
||
|
local pos2 = pointed_thing.above
|
||
|
local x = pos.x - pos2.x
|
||
|
local z = pos.z - pos2.z
|
||
|
|
||
|
local returned_stack, success = minetest.item_place_node(itemstack, placer, pointed_thing)
|
||
|
if success then
|
||
|
local meta = minetest.get_meta(pos2)
|
||
|
meta:set_string("placer", placer:get_player_name())
|
||
|
end
|
||
|
return returned_stack
|
||
|
end,
|
||
|
|
||
|
can_dig = function(pos,player)
|
||
|
local meta = minetest.get_meta(pos);
|
||
|
local inv = meta:get_inventory()
|
||
|
return inv:is_empty("main")
|
||
|
end,
|
||
|
|
||
|
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
|
||
|
return
|
||
|
end
|
||
|
minetest.show_formspec(clicker:get_player_name(),
|
||
|
"hopper_formspec:"..minetest.pos_to_string(pos), get_sorter_formspec(pos))
|
||
|
end,
|
||
|
|
||
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||
|
if listname == "filter" then
|
||
|
local inv = minetest.get_inventory({type="node", pos=pos})
|
||
|
inv:set_stack(listname, index, stack:take_item(1))
|
||
|
return 0
|
||
|
end
|
||
|
return stack:get_count()
|
||
|
end,
|
||
|
|
||
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||
|
if listname == "filter" then
|
||
|
local inv = minetest.get_inventory({type="node", pos=pos})
|
||
|
inv:set_stack(listname, index, ItemStack(""))
|
||
|
return 0
|
||
|
end
|
||
|
return stack:get_count()
|
||
|
end,
|
||
|
|
||
|
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||
|
minetest.log("action", S("@1 moves stuff to sorter at @2",
|
||
|
player:get_player_name(), minetest.pos_to_string(pos)))
|
||
|
|
||
|
local timer = minetest.get_node_timer(pos)
|
||
|
if not timer:is_started() then
|
||
|
timer:start(1)
|
||
|
end
|
||
|
end,
|
||
|
|
||
|
on_timer = function(pos, elapsed)
|
||
|
local meta = minetest.get_meta(pos);
|
||
|
local inv = meta:get_inventory()
|
||
|
|
||
|
-- build a filter list
|
||
|
local filter_items = {}
|
||
|
local filter_inv_size = inv:get_size("filter")
|
||
|
for i = 1, filter_inv_size do
|
||
|
local stack = inv:get_stack("filter", i)
|
||
|
local item = stack:get_name()
|
||
|
if item ~= "" then
|
||
|
filter_items[item] = true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local node = minetest.get_node(pos)
|
||
|
local dir = minetest.facedir_to_dir(node.param2)
|
||
|
local default_destination_pos = vector.add(pos, dir)
|
||
|
local default_output_direction
|
||
|
if dir.y == 0 then
|
||
|
default_output_direction = "horizontal"
|
||
|
end
|
||
|
|
||
|
dir = bottomdir(node.param2)
|
||
|
local filter_destination_pos = vector.add(pos, dir)
|
||
|
local filter_output_direction
|
||
|
if dir.y == 0 then
|
||
|
filter_output_direction = "horizontal"
|
||
|
end
|
||
|
|
||
|
local success = false
|
||
|
|
||
|
local filter_destination_node = minetest.get_node(filter_destination_pos)
|
||
|
local registered_inventories = hopper.get_registered_inventories_for(filter_destination_node.name)
|
||
|
if registered_inventories ~= nil then
|
||
|
if filter_output_direction == "horizontal" then
|
||
|
success = hopper.send_item_to(pos, filter_destination_pos, filter_destination_node, registered_inventories["side"], filter_items)
|
||
|
else
|
||
|
success = hopper.send_item_to(pos, filter_destination_pos, filter_destination_node, registered_inventories["bottom"], filter_items)
|
||
|
end
|
||
|
else
|
||
|
success = hopper.send_item_to(pos, filter_destination_pos, filter_destination_node, nil, filter_items)
|
||
|
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.
|
||
|
local default_destination_node = minetest.get_node(default_destination_pos)
|
||
|
local registered_inventories = hopper.get_registered_inventories_for(default_destination_node.name)
|
||
|
if registered_inventories ~= nil then
|
||
|
if default_output_direction == "horizontal" then
|
||
|
hopper.send_item_to(pos, default_destination_pos, default_destination_node, registered_inventories["side"])
|
||
|
else
|
||
|
hopper.send_item_to(pos, default_destination_pos, default_destination_node, registered_inventories["bottom"])
|
||
|
end
|
||
|
else
|
||
|
hopper.send_item_to(pos, default_destination_pos, default_destination_node)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if not inv:is_empty("main") then
|
||
|
minetest.get_node_timer(pos):start(1)
|
||
|
end
|
||
|
end,
|
||
|
})
|