diff options
Diffstat (limited to 'nodes/node_item_ejector.lua')
-rw-r--r-- | nodes/node_item_ejector.lua | 172 |
1 files changed, 128 insertions, 44 deletions
diff --git a/nodes/node_item_ejector.lua b/nodes/node_item_ejector.lua index c29002f..6f9c64e 100644 --- a/nodes/node_item_ejector.lua +++ b/nodes/node_item_ejector.lua @@ -2,13 +2,111 @@ local MP = minetest.get_modpath(minetest.get_current_modname()) local S, NS = dofile(MP.."/intllib.lua") +--Build up the formspec, somewhat complicated due to multiple mod options local pipeworks_path = minetest.get_modpath("pipeworks") +local doc_path = minetest.get_modpath("doc") +local formspec_width = 1.5 + +local ejector_formspec_string = + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots + +if doc_path then + ejector_formspec_string = ejector_formspec_string .. + "button_exit[".. 0.2 + formspec_width ..",0.5;1,0.1;help;" .. S("Help") .. "]" .. + "tooltip[help;" .. S("Show documentation about this block") .. "]" + formspec_width = formspec_width + 1.5 +end + +local ejector_formspec_string = "size[".. formspec_width .. ",1]" .. ejector_formspec_string + +local ejector_formspec = function(pos, meta) + local return_string = ejector_formspec_string + if pipeworks_path then + return_string = return_string .. "checkbox[0,0.5;nonpipe;"..S("Eject into world")..";"..meta:get_string("nonpipe").."]" .. + "tooltip[nonpipe;" .. S("When checked, will eject items even if there's no pipe to accept it") .. "]" + end + return return_string .. "checkbox[0,0;autoeject;"..S("Automatic")..";"..meta:get_string("autoeject").."]" .. + "tooltip[autoeject;" .. S("When checked, will eject items automatically with every Digtron cycle.\nItem ejectors can always be operated manually by punching them.") .. "]" +end + +local function eject_items(pos, node, player, eject_even_without_pipeworks) + local dir = minetest.facedir_to_dir(node.param2) + local destination_pos = vector.add(pos, dir) + local destination_node_name = minetest.get_node(destination_pos).name + local destination_node_def = minetest.registered_nodes[destination_node_name] + + if not pipeworks_path then eject_even_without_pipeworks = true end -- if pipeworks is not installed, always eject into world (there's no other option) + + local insert_into_pipe = false + local eject_into_world = false + if pipeworks_path and minetest.get_node_group(destination_node_name, "tubedevice") > 0 then + insert_into_pipe = true + elseif eject_even_without_pipeworks then + if destination_node_def and not destination_node_def.walkable then + eject_into_world = true + else + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + return false + end + else + return false + end + + local layout = DigtronLayout.create(pos, player) + + -- Build a list of all the items that builder nodes want to use. + local filter_items = {} + for _, node_image in pairs(layout.builders) do + filter_items[node_image.meta.inventory.main[1]:get_name()] = true + end + + -- Look through the inventories and find an item that's not on that list. + local source_node = nil + local source_index = nil + local source_stack = nil + for _, node_image in pairs(layout.inventories) do + for index, item_stack in pairs(node_image.meta.inventory.main) do + if item_stack:get_count() > 0 and not filter_items[item_stack:get_name()] then + source_node = node_image + source_index = index + source_stack = item_stack + break + end + end + if source_node then break end + end + + if source_node then + local meta = minetest.get_meta(source_node.pos) + local inv = meta:get_inventory() + + if insert_into_pipe then + local from_pos = vector.add(pos, vector.multiply(dir, 0.5)) + local start_pos = pos + inv:set_stack("main", source_index, nil) + pipeworks.tube_inject_item(from_pos, start_pos, vector.multiply(dir, 1), source_stack, player:get_player_name()) + minetest.sound_play("steam_puff", {gain=0.5, pos=pos}) + return true + elseif eject_into_world then + minetest.add_item(destination_pos, source_stack) + inv:set_stack("main", source_index, nil) + minetest.sound_play("steam_puff", {gain=0.5, pos=pos}) + return true + end + end + + -- couldn't find an item to eject + return false +end minetest.register_node("digtron:inventory_ejector", { description = S("Digtron Inventory Ejector"), _doc_items_longdesc = digtron.doc.inventory_ejector_longdesc, _doc_items_usagehelp = digtron.doc.inventory_ejector_usagehelp, - groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1, tubedevice = 1}, + _digtron_formspec = ejector_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 9, tubedevice = 1}, tiles = {"digtron_plate.png", "digtron_plate.png", "digtron_plate.png", "digtron_plate.png", "digtron_plate.png^digtron_output.png", "digtron_plate.png^digtron_output_back.png"}, drawtype = "nodebox", sounds = digtron.metal_sounds, @@ -24,57 +122,43 @@ minetest.register_node("digtron:inventory_ejector", { } }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("autoeject", "true") + meta:set_string("formspec", ejector_formspec(pos, meta)) + end, + tube = (function() if pipeworks_path then return { connect_sides = {back = 1} } end end)(), - on_rightclick = function(pos, node, player) - local dir = minetest.facedir_to_dir(node.param2) - local destination_pos = vector.add(pos, dir) - local destination_node_name = minetest.get_node(destination_pos).name - local destination_node_def = minetest.registered_nodes[destination_node_name] - local layout = DigtronLayout.create(pos, player) - - -- Build a list of all the items that builder nodes want to use. - local filter_items = {} - for _, node_image in pairs(layout.builders) do - filter_items[node_image.meta.inventory.main[1]:get_name()] = true + on_punch = function(pos, node, player) + eject_items(pos, node, player, true) + end, + + execute_eject = function(pos, node, player) + local meta = minetest.get_meta(pos) + eject_items(pos, node, player, meta:get_string("nonpipe") == "true") + end, + + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + + if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built + local node_name = minetest.get_node(pos).name + minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", node_name, true) end - -- Look through the inventories and find an item that's not on that list. - local source_node = nil - local source_index = nil - local source_stack = nil - for _, node_image in pairs(layout.inventories) do - for index, item_stack in pairs(node_image.meta.inventory.main) do - if item_stack:get_count() > 0 and not filter_items[item_stack:get_name()] then - source_node = node_image - source_index = index - source_stack = item_stack - break - end - end - if source_node then break end + if fields.nonpipe then + meta:set_string("nonpipe", fields.nonpipe) end - if source_node then - local meta = minetest.get_meta(source_node.pos) - local inv = meta:get_inventory() - - if pipeworks_path and minetest.get_node_group(destination_node_name, "tubedevice") > 0 then - local from_pos = vector.add(pos, vector.multiply(dir, 0.5)) - local start_pos = pos--vector.add(pos, dir) - inv:set_stack("main", source_index, nil) - pipeworks.tube_inject_item(from_pos, start_pos, vector.multiply(dir, 1), source_stack, player:get_player_name()) - minetest.sound_play("steam_puff", {gain=0.5, pos=pos}) - elseif destination_node_def and not destination_node_def.walkable then - minetest.add_item(destination_pos, source_stack) - inv:set_stack("main", source_index, nil) - minetest.sound_play("steam_puff", {gain=0.5, pos=pos}) - else - minetest.sound_play("buzzer", {gain=0.5, pos=pos}) - end - end + if fields.autoeject then + meta:set_string("autoeject", fields.autoeject) + end + + meta:set_string("formspec", ejector_formspec(pos, meta)) + end, after_place_node = (function() if pipeworks_path then return pipeworks.after_place end end)(), |