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 -- 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) 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 return
end end
@ -169,25 +173,30 @@ local function send_item_to(hopper_pos, target_pos, target_node, target_inventor
--target inventory --target inventory
local target_inv = minetest.get_meta(target_pos):get_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 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 ~= "" then if item ~= "" then
if target_inv:room_for_item(target_inventory_name, item) then if target_inventory_name then
local stack_to_put = stack:take_item(1) if target_inv:room_for_item(target_inventory_name, item) then
if target_def.allow_metadata_inventory_put == nil local stack_to_put = stack:take_item(1)
or placer == nil -- backwards compatibility, older versions of this mod didn't record who placed the hopper if target_def.allow_metadata_inventory_put == nil
or target_def.allow_metadata_inventory_put(target_pos, target_inventory_name, i, stack_to_put, placer) > 0 then or placer == nil -- backwards compatibility, older versions of this mod didn't record who placed the hopper
hopper_inv:set_stack("main", i, stack) or target_def.allow_metadata_inventory_put(target_pos, target_inventory_name, i, stack_to_put, placer) > 0 then
--add to target node hopper_inv:set_stack("main", i, stack)
target_inv:add_item(target_inventory_name, item) --add to target node
if target_def.on_metadata_inventory_put ~= nil and placer ~= nil then target_inv:add_item(target_inventory_name, stack_to_put)
target_def.on_metadata_inventory_put(target_pos, target_inventory_name, i, stack_to_put, placer) 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
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
end end
@ -196,15 +205,31 @@ end
------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------
-- Nodes -- 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 -- formspec
local function get_hopper_formspec(pos) 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 = local formspec =
"size[8,9]" "size[8,9]"
.. default.gui_bg .. default.gui_bg
.. default.gui_bg_img .. default.gui_bg_img
.. default.gui_slots .. default.gui_slots
.. "list[nodemeta:" .. spos .. ";main;2,0.3;4,4;]" .. "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,4.85;8,1;]"
.. "list[current_player;main;0,6.08;8,3;8]" .. "list[current_player;main;0,6.08;8,3;8]"
.. "listring[nodemeta:" .. spos .. ";main]" .. "listring[nodemeta:" .. spos .. ";main]"
@ -309,7 +334,7 @@ minetest.register_node("hopper:hopper", {
return return
end end
minetest.show_formspec(clicker:get_player_name(), 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, end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) 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 return
end end
minetest.show_formspec(clicker:get_player_name(), 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, end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) 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 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 spos = pos.x .. "," .. pos.y .. "," ..pos.z
local formspec = local formspec =
"size[8,7]" "size[8,7]"
@ -427,6 +453,8 @@ local function get_chute_formspec(pos)
.. default.gui_bg_img .. default.gui_bg_img
.. default.gui_slots .. default.gui_slots
.. "list[nodemeta:" .. spos .. ";main;3,0.3;2,2;]" .. "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,2.85;8,1;]"
.. "list[current_player;main;0,4.08;8,3;8]" .. "list[current_player;main;0,4.08;8,3;8]"
.. "listring[nodemeta:" .. spos .. ";main]" .. "listring[nodemeta:" .. spos .. ";main]"
@ -491,7 +519,7 @@ minetest.register_node("hopper:chute", {
return return
end end
minetest.show_formspec(clicker:get_player_name(), 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, end,
on_metadata_inventory_put = function(pos, listname, index, stack, player) on_metadata_inventory_put = function(pos, listname, index, stack, player)
@ -507,6 +535,7 @@ minetest.register_node("hopper:chute", {
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()
local eject_item = meta:get_string("eject") == "true"
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)
@ -523,6 +552,8 @@ minetest.register_node("hopper:chute", {
else else
send_item_to(pos, destination_pos, destination_node, containers[destination_node.name]["bottom"]) send_item_to(pos, destination_pos, destination_node, containers[destination_node.name]["bottom"])
end end
else
send_item_to(pos, destination_pos, destination_node)
end end
if not inv:is_empty("main") then if not inv:is_empty("main") then
@ -531,6 +562,25 @@ minetest.register_node("hopper:chute", {
end, 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 -- ABMs
@ -650,6 +700,8 @@ minetest.register_abm({
else else
send_item_to(pos, destination_pos, destination_node, containers[destination_node.name]["bottom"]) send_item_to(pos, destination_pos, destination_node, containers[destination_node.name]["bottom"])
end end
else
send_item_to(pos, destination_pos, destination_node)
end end
end, end,
}) })

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \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" "PO-Revision-Date: \n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
@ -80,36 +80,62 @@ msgid ""
"removed or their destination becomes available." "removed or their destination becomes available."
msgstr "" 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" msgid "Hopper"
msgstr "Trichter" msgstr "Trichter"
#: init.lua:316 init.lua:407 #: init.lua:341 init.lua:432
msgid "@1 moves stuff in hopper at @2" msgid "@1 moves stuff in hopper at @2"
msgstr "@1 bewegt Dinge in einem Trichter bei @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" msgid "@1 moves stuff to hopper at @2"
msgstr "@1 verlagert Dinge in einen Trichter bei @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" msgid "@1 moves stuff from hopper at @2"
msgstr "@1 nimmt Dinge aus einem Trichter bei @2" msgstr "@1 nimmt Dinge aus einem Trichter bei @2"
#: init.lua:342 #: init.lua:367
msgid "Side Hopper" msgid "Side Hopper"
msgstr "Seitentrichter" msgstr "Seitentrichter"
#: init.lua:441 #: init.lua:469
#, fuzzy #, fuzzy
msgid "Hopper Chute" msgid "Hopper Chute"
msgstr "Trichter" msgstr "Trichter"
#: init.lua:498 #: init.lua:526
#, fuzzy #, fuzzy
msgid "@1 moves stuff to chute at @2" msgid "@1 moves stuff to chute at @2"
msgstr "@1 verlagert Dinge in einen Trichter bei @2" msgstr "@1 verlagert Dinge in einen Trichter bei @2"
#: init.lua:705 #: init.lua:757
msgid "[MOD] Hopper loaded" msgid "[MOD] Hopper loaded"
msgstr "[MOD] Trichter geladen" msgstr "[MOD] Trichter geladen"

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -80,34 +80,60 @@ msgid ""
"removed or their destination becomes available." "removed or their destination becomes available."
msgstr "" 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" msgid "Hopper"
msgstr "" msgstr ""
#: init.lua:316 init.lua:407 #: init.lua:341 init.lua:432
msgid "@1 moves stuff in hopper at @2" msgid "@1 moves stuff in hopper at @2"
msgstr "" msgstr ""
#: init.lua:321 init.lua:412 #: init.lua:346 init.lua:437
msgid "@1 moves stuff to hopper at @2" msgid "@1 moves stuff to hopper at @2"
msgstr "" msgstr ""
#: init.lua:326 init.lua:417 #: init.lua:351 init.lua:442
msgid "@1 moves stuff from hopper at @2" msgid "@1 moves stuff from hopper at @2"
msgstr "" msgstr ""
#: init.lua:342 #: init.lua:367
msgid "Side Hopper" msgid "Side Hopper"
msgstr "" msgstr ""
#: init.lua:441 #: init.lua:469
msgid "Hopper Chute" msgid "Hopper Chute"
msgstr "" msgstr ""
#: init.lua:498 #: init.lua:526
msgid "@1 moves stuff to chute at @2" msgid "@1 moves stuff to chute at @2"
msgstr "" msgstr ""
#: init.lua:705 #: init.lua:757
msgid "[MOD] Hopper loaded" msgid "[MOD] Hopper loaded"
msgstr "" msgstr ""