add eject setting for hoppers

This allows hoppers to dump the items they're ingesting out into the
world if there's not a compatible inventory to receive them (and the
target node is "open", tested via buildable_to)
This commit is contained in:
FaceDeer 2017-02-23 20:36:40 -07:00
parent 5b04908df5
commit 4b8d61568f
3 changed files with 139 additions and 35 deletions

@ -154,7 +154,11 @@ end
-- Used to put items from the hopper inventory into the target block
local function send_item_to(hopper_pos, target_pos, target_node, target_inventory_name)
if target_inventory_name == nil then
local hopper_meta = minetest.get_meta(hopper_pos)
local target_def = minetest.registered_nodes[target_node.name]
local eject_item = hopper_meta:get_string("eject") == "true" and target_def.buildable_to
if not eject_item and not target_inventory_name then
return
end
@ -169,12 +173,12 @@ local function send_item_to(hopper_pos, target_pos, target_node, target_inventor
--target inventory
local target_inv = minetest.get_meta(target_pos):get_inventory()
local target_def = minetest.registered_nodes[target_node.name]
for i = 1,hopper_inv_size do
local stack = hopper_inv:get_stack("main", i)
local item = stack:get_name()
if item ~= "" then
if target_inventory_name then
if target_inv:room_for_item(target_inventory_name, item) then
local stack_to_put = stack:take_item(1)
if target_def.allow_metadata_inventory_put == nil
@ -182,13 +186,18 @@ local function send_item_to(hopper_pos, target_pos, target_node, target_inventor
or target_def.allow_metadata_inventory_put(target_pos, target_inventory_name, i, stack_to_put, placer) > 0 then
hopper_inv:set_stack("main", i, stack)
--add to target node
target_inv:add_item(target_inventory_name, item)
target_inv:add_item(target_inventory_name, stack_to_put)
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)
end
break
end
end
elseif eject_item then
local stack_to_put = stack:take_item(1)
minetest.add_item(target_pos, stack_to_put)
hopper_inv:set_stack("main", i, stack)
end
end
end
end
@ -196,15 +205,31 @@ end
-------------------------------------------------------------------------------------------
-- Nodes
local function get_eject_button_texts(pos)
if minetest.get_meta(pos):get_string("eject") == "true" then
return S("Don't\nEject"), S("This hopper is currently set to eject items from its output\neven if there isn't a compatible block positioned to receive it.\nClick this button to disable this feature.")
else
return S("Eject\nItems"), S("This hopper is currently set to hold on to item if there\nisn't a compatible block positioned to receive it.\nClick this button to have it eject items instead.")
end
end
local function get_string_pos(pos)
return pos.x .. "," .. pos.y .. "," ..pos.z
end
-- formspec
local function get_hopper_formspec(pos)
local spos = pos.x .. "," .. pos.y .. "," ..pos.z
local eject_button_text, eject_button_tooltip = get_eject_button_texts(pos)
local spos = get_string_pos(pos)
local formspec =
"size[8,9]"
.. default.gui_bg
.. default.gui_bg_img
.. default.gui_slots
.. "list[nodemeta:" .. spos .. ";main;2,0.3;4,4;]"
.. "button_exit[7,2;1,1;eject;"..eject_button_text.."]"
.. "tooltip[eject;"..eject_button_tooltip.."]"
.. "list[current_player;main;0,4.85;8,1;]"
.. "list[current_player;main;0,6.08;8,3;8]"
.. "listring[nodemeta:" .. spos .. ";main]"
@ -309,7 +334,7 @@ minetest.register_node("hopper:hopper", {
return
end
minetest.show_formspec(clicker:get_player_name(),
"hopper:hopper", get_hopper_formspec(pos))
"hopper_formspec:"..minetest.pos_to_string(pos), get_hopper_formspec(pos))
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
@ -400,7 +425,7 @@ minetest.register_node("hopper:hopper_side", {
return
end
minetest.show_formspec(clicker:get_player_name(),
"hopper:hopper_side", get_hopper_formspec(pos))
"hopper_formspec:"..minetest.pos_to_string(pos), get_hopper_formspec(pos))
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
@ -420,6 +445,7 @@ minetest.register_node("hopper:hopper_side", {
})
local function get_chute_formspec(pos)
local eject_button_text, eject_button_tooltip = get_eject_button_texts(pos)
local spos = pos.x .. "," .. pos.y .. "," ..pos.z
local formspec =
"size[8,7]"
@ -427,6 +453,8 @@ local function get_chute_formspec(pos)
.. default.gui_bg_img
.. default.gui_slots
.. "list[nodemeta:" .. spos .. ";main;3,0.3;2,2;]"
.. "button_exit[7,1;1,1;eject;"..eject_button_text.."]"
.. "tooltip[eject;"..eject_button_tooltip.."]"
.. "list[current_player;main;0,2.85;8,1;]"
.. "list[current_player;main;0,4.08;8,3;8]"
.. "listring[nodemeta:" .. spos .. ";main]"
@ -491,7 +519,7 @@ minetest.register_node("hopper:chute", {
return
end
minetest.show_formspec(clicker:get_player_name(),
"hopper:chute", get_chute_formspec(pos))
"hopper_formspec:"..minetest.pos_to_string(pos), get_chute_formspec(pos))
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
@ -507,6 +535,7 @@ minetest.register_node("hopper:chute", {
on_timer = function(pos, elapsed)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
local eject_item = meta:get_string("eject") == "true"
local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2)
@ -523,6 +552,8 @@ minetest.register_node("hopper:chute", {
else
send_item_to(pos, destination_pos, destination_node, containers[destination_node.name]["bottom"])
end
else
send_item_to(pos, destination_pos, destination_node)
end
if not inv:is_empty("main") then
@ -531,6 +562,25 @@ minetest.register_node("hopper:chute", {
end,
})
-------------------------------------------------------------------------------------------
-- Formspec handling
minetest.register_on_player_receive_fields(function(player, formname, fields)
if "hopper_formspec:" == string.sub(formname, 1, 16) then
local pos = minetest.string_to_pos(string.sub(formname, 17, -1))
local meta = minetest.get_meta(pos)
local eject_setting = meta:get_string("eject") == "true"
if fields.eject then
if eject_setting then
meta:set_string("eject", nil)
else
meta:set_string("eject", "true")
end
end
end
end)
-------------------------------------------------------------------------------------------
-- ABMs
@ -650,6 +700,8 @@ minetest.register_abm({
else
send_item_to(pos, destination_pos, destination_node, containers[destination_node.name]["bottom"])
end
else
send_item_to(pos, destination_pos, destination_node)
end
end,
})

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-04 21:26-0700\n"
"POT-Creation-Date: 2017-02-23 20:30-0700\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@ -80,36 +80,62 @@ msgid ""
"removed or their destination becomes available."
msgstr ""
#: init.lua:255
#: init.lua:211
msgid ""
"Don't\n"
"Eject"
msgstr ""
#: init.lua:211
msgid ""
"This hopper is currently set to eject items from its output\n"
"even if there isn't a compatible block positioned to receive it.\n"
"Click this button to disable this feature."
msgstr ""
#: init.lua:213
msgid ""
"Eject\n"
"Items"
msgstr ""
#: init.lua:213
msgid ""
"This hopper is currently set to hold on to item if there\n"
"isn't a compatible block positioned to receive it.\n"
"Click this button to have it eject items instead."
msgstr ""
#: init.lua:280
msgid "Hopper"
msgstr "Trichter"
#: init.lua:316 init.lua:407
#: init.lua:341 init.lua:432
msgid "@1 moves stuff in hopper at @2"
msgstr "@1 bewegt Dinge in einem Trichter bei @2"
#: init.lua:321 init.lua:412
#: init.lua:346 init.lua:437
msgid "@1 moves stuff to hopper at @2"
msgstr "@1 verlagert Dinge in einen Trichter bei @2"
#: init.lua:326 init.lua:417
#: init.lua:351 init.lua:442
msgid "@1 moves stuff from hopper at @2"
msgstr "@1 nimmt Dinge aus einem Trichter bei @2"
#: init.lua:342
#: init.lua:367
msgid "Side Hopper"
msgstr "Seitentrichter"
#: init.lua:441
#: init.lua:469
#, fuzzy
msgid "Hopper Chute"
msgstr "Trichter"
#: init.lua:498
#: init.lua:526
#, fuzzy
msgid "@1 moves stuff to chute at @2"
msgstr "@1 verlagert Dinge in einen Trichter bei @2"
#: init.lua:705
#: init.lua:757
msgid "[MOD] Hopper loaded"
msgstr "[MOD] Trichter geladen"

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-04 21:26-0700\n"
"POT-Creation-Date: 2017-02-23 20:30-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -80,34 +80,60 @@ msgid ""
"removed or their destination becomes available."
msgstr ""
#: init.lua:255
#: init.lua:211
msgid ""
"Don't\n"
"Eject"
msgstr ""
#: init.lua:211
msgid ""
"This hopper is currently set to eject items from its output\n"
"even if there isn't a compatible block positioned to receive it.\n"
"Click this button to disable this feature."
msgstr ""
#: init.lua:213
msgid ""
"Eject\n"
"Items"
msgstr ""
#: init.lua:213
msgid ""
"This hopper is currently set to hold on to item if there\n"
"isn't a compatible block positioned to receive it.\n"
"Click this button to have it eject items instead."
msgstr ""
#: init.lua:280
msgid "Hopper"
msgstr ""
#: init.lua:316 init.lua:407
#: init.lua:341 init.lua:432
msgid "@1 moves stuff in hopper at @2"
msgstr ""
#: init.lua:321 init.lua:412
#: init.lua:346 init.lua:437
msgid "@1 moves stuff to hopper at @2"
msgstr ""
#: init.lua:326 init.lua:417
#: init.lua:351 init.lua:442
msgid "@1 moves stuff from hopper at @2"
msgstr ""
#: init.lua:342
#: init.lua:367
msgid "Side Hopper"
msgstr ""
#: init.lua:441
#: init.lua:469
msgid "Hopper Chute"
msgstr ""
#: init.lua:498
#: init.lua:526
msgid "@1 moves stuff to chute at @2"
msgstr ""
#: init.lua:705
#: init.lua:757
msgid "[MOD] Hopper loaded"
msgstr ""