local utils = ... local S = utils.S local function unit_after_place_node (pos, placer, itemstack, pointed_thing) local meta = minetest.get_meta (pos) local spec = "formspec_version[3]".. "size[11.75,12.25,false]".. "list[context;main;1.0,1.0;8,4;]".. "list[current_player;main;1.0,6.5;8,4;]".. "listring[]" meta:set_string ("inventory", "{ main = { } }") meta:set_string ("formspec", spec) local inv = meta:get_inventory () inv:set_size ("main", 32) inv:set_width ("main", 8) -- If return true no item is taken from itemstack return false end local function unit_after_place_node_locked (pos, placer, itemstack, pointed_thing) unit_after_place_node (pos, placer, itemstack, pointed_thing) if placer and placer:is_player () then local meta = minetest.get_meta (pos) meta:set_string ("owner", placer:get_player_name ()) meta:set_string ("infotext", "Storage Unit (owned by "..placer:get_player_name ()..")") end -- If return true no item is taken from itemstack return false end local function unit_can_dig (pos, player) if not utils.can_interact_with_node (pos, player) then return false end local meta = minetest.get_meta (pos) if meta then local inv = meta:get_inventory () if inv then if not inv:is_empty ("main") then return false end end end return true end local function unit_on_blast (pos, intensity) local meta = minetest.get_meta (pos) if meta then if intensity >= 1.0 then local inv = meta:get_inventory () if inv then local slots = inv:get_size ("main") for slot = 1, slots do local stack = inv:get_stack ("main", slot) if stack and not stack:is_empty () then if math.floor (math.random (0, 5)) == 3 then utils.item_drop (stack, nil, pos) else utils.on_destroy (stack) end end end end minetest.remove_node (pos) else -- intensity < 1.0 local inv = meta:get_inventory () if inv then local slots = inv:get_size ("main") for slot = 1, slots do local stack = inv:get_stack ("main", slot) if stack and not stack:is_empty () then utils.item_drop (stack, nil, pos) end end end local node = minetest.get_node_or_nil (pos) if node then local items = minetest.get_node_drops (node, nil) if items and #items > 0 then local stack = ItemStack (items[1]) if stack then utils.item_drop (stack, nil, pos) minetest.remove_node (pos) end end end end end end local function unit_on_rightclick (pos, node, clicker, itemstack, pointed_thing) if not utils.can_interact_with_node (pos, clicker) then if clicker and clicker:is_player () then local owner = "" local meta = minetest.get_meta (pos) if meta then owner = meta:get_string ("owner") end local spec = "formspec_version[3]".. "size[8.0,4.0,false]".. "label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]".. "button_exit[3.0,2.0;2.0,1.0;close;Close]" minetest.show_formspec (clicker:get_player_name (), "lwcomponents:component_privately_owned", spec) end end return itemstack end minetest.register_node("lwcomponents:storage_unit", { description = S("Storage Unit"), drawtype = "glasslike_framed", tiles = { "lwcomponents_storage_framed.png", "lwcomponents_storage.png" }, is_ground_content = false, groups = { choppy = 2 }, paramtype = "none", param1 = 0, paramtype2 = "none", param2 = 0, floodable = false, after_place_node = unit_after_place_node, can_dig = unit_can_dig, on_blast = unit_on_blast, on_rightclick = unit_on_rightclick }) minetest.register_node("lwcomponents:storage_unit_locked", { description = S("Storage Unit (locked)"), drawtype = "glasslike_framed", tiles = { "lwcomponents_storage_framed.png", "lwcomponents_storage.png" }, is_ground_content = false, groups = { choppy = 2 }, paramtype = "none", param1 = 0, paramtype2 = "none", param2 = 0, floodable = false, after_place_node = unit_after_place_node_locked, can_dig = unit_can_dig, on_blast = unit_on_blast, on_rightclick = unit_on_rightclick }) local consolidation_interval = 20 local function unit_inventory (pos, owner, inv_list) local node = utils.get_far_node (pos) if node and (node.name == "lwcomponents:storage_unit" or node.name == "lwcomponents:storage_unit_locked") then local meta = minetest.get_meta (pos) local uowner = meta:get_string ("owner") if meta and (owner == uowner or uowner == "") then local inv = meta:get_inventory () if inv then local slots = inv:get_size ("main") for slot = 1, slots, 1 do local stack = inv:get_stack ("main", slot) if stack and not stack:is_empty () then local copy = ItemStack (stack) copy:set_count (1) local name = copy:to_string () local item = inv_list[name] if not item then inv_list[name] = { count = 0 } item = inv_list[name] end item[#item + 1] = { pos = vector.new (pos), count = stack:get_count (), slot = slot } item.count = item.count + stack:get_count () end end end return true end end return false end local function inventory_searcher (pos, owner, coords, inv_list, check_list) local spos = minetest.pos_to_string (pos, 0) if not check_list[spos] then check_list[spos] = true if unit_inventory (pos, owner, inv_list) then for _, c in ipairs (coords) do inventory_searcher (vector.add (pos, c), owner, coords, inv_list, check_list) end end end end local function get_inventory_list (pos) local inv_list = { } local meta = minetest.get_meta (pos) if meta then local owner = meta:get_string ("owner") local check_list = { [minetest.pos_to_string (pos, 0)] = true } local coords = { { x = 1, y = 0, z = 0 }, { x = -1, y = 0, z = 0 }, { x = 0, y = 1, z = 0 }, { x = 0, y = -1, z = 0 }, { x = 0, y = 0, z = 1 }, { x = 0, y = 0, z = -1 } } for _, c in ipairs (coords) do inventory_searcher (vector.add (pos, c), owner, coords, inv_list, check_list) end end return inv_list end local function count_table_keys (t) local count = 0 for k, v in pairs (t) do count = count + 1 end return count end local function get_stock_list (pos) local inv_list = get_inventory_list (pos) local list = { } for k, v in pairs (inv_list) do local stack = ItemStack (k) local name = stack:get_name () local description local custom = false local pallet_index = nil local tstack = stack:to_table () if tstack and tstack.meta and count_table_keys (tstack.meta) > 0 then custom = true pallet_index = tstack.meta.palette_index end if stack:get_short_description () ~= "" then description = stack:get_short_description () elseif stack:get_description () ~= "" then description = stack:get_description () else description = name local def = utils.find_item_def (name) if def then if def.short_description then description = def.short_description elseif def.description then description = def.description end end end list[#list + 1] = { name = stack:get_name (), description = utils.unescape_description (description), id = k, count = v.count, custom = custom, pallet_index = pallet_index, } end return list end local function output_items (pos, name, count) if count < 1 then return 0 end local meta = minetest.get_meta (pos) if not meta then return 0 end local inv = meta:get_inventory () if not inv then return 0 end local stack = ItemStack (name) if stack:get_stack_max () < count then count = stack:get_stack_max () end stack:set_count (count) while stack:get_count () > 0 do if inv:room_for_item ("output", stack) then break else stack:set_count (stack:get_count () - 1) end end if stack:get_count () < 1 then return 0 end local inv_list = get_inventory_list (pos) local item = inv_list[name] local left = stack:get_count () if item then for i = #item, 1, -1 do local tmeta = minetest.get_meta (item[i].pos) local tinv = (tmeta and tmeta:get_inventory ()) or nil if tinv then local s = tinv:get_stack ("main", item[i].slot) if utils.is_same_item (name, s) then if s:get_count () > left then s:set_count (s:get_count () - left) tinv:set_stack ("main", item[i].slot, s) left = 0 else tinv:set_stack ("main", item[i].slot, nil) left = left - s:get_count () end end if left == 0 then break end end end end if left < count then local output = ItemStack (name) output:set_count (count - left) inv:add_item ("output", output) return count - left end return 0 end local function consolidate_itemstacks (item1, item2) local copy1 = ItemStack (item1) local copy2 = ItemStack (item2) if utils.is_same_item (copy1, copy2) then local count = copy1:get_stack_max () - copy1:get_count () if count > copy2:get_count () then count = copy2:get_count () end if count > 0 then copy1:set_count (copy1:get_count () + count) copy2:set_count (copy2:get_count () - count) if copy2:get_count () < 1 then copy2 = nil end end end return copy1, copy2 end local function consolidate_stock (pos) local inv_list = get_inventory_list (pos) for k, v in pairs (inv_list) do if #v > 1 then for i = #v, 2, -1 do local smeta = minetest.get_meta (v[i].pos) local sinv = (smeta and smeta:get_inventory ()) or nil if sinv then local src = sinv:get_stack ("main", v[i].slot) if src and not src:is_empty () then for j = 1, i - 1, 1 do local dmeta = minetest.get_meta (v[j].pos) local dinv = (dmeta and dmeta:get_inventory ()) or nil if dinv then local dest = dinv:get_stack ("main", v[j].slot) dest, src = consolidate_itemstacks (dest, src) dinv:set_stack ("main", v[j].slot, dest) end if not src or src:is_empty () then break end end end sinv:set_stack ("main", v[i].slot, src) end end end end end local function check_consolidation (pos) local meta = minetest.get_meta (pos) if meta then local count = meta:get_int ("input_count") + 1 if count >= consolidation_interval then meta:set_int ("input_count", 0) minetest.after (0.1, consolidate_stock, vector.new (pos)) else meta:set_int ("input_count", count) end end end local function check_filter (pos, itemstack) local stack = ItemStack (itemstack) if stack and not stack:is_empty () then local meta = minetest.get_meta (pos) if meta then local inv = meta:get_inventory () if inv then if inv:is_empty ("filter") then return true end local slots = inv:get_size ("filter") for i = 1, slots, 1 do local s = inv:get_stack ("filter", i) if s and not s:is_empty () and s:get_name () == stack:get_name () then return true end end end end end return false end local function unit_placer (pos, owner, stack) local node = utils.get_far_node (pos) if node and (node.name == "lwcomponents:storage_unit" or node.name == "lwcomponents:storage_unit_locked") then local meta = minetest.get_meta (pos) local uowner = meta:get_string ("owner") if meta and (owner == uowner or uowner == "") then local inv = meta:get_inventory () if inv then local left = inv:add_item ("main", stack) if not left or left:is_empty () or left:get_count () == 0 then return false, nil end return true, left end end end return false, stack end local function inventory_placer (pos, owner, coords, stack, check_list) local spos = minetest.pos_to_string (pos, 0) if not check_list[spos] then check_list[spos] = true local continue, left = unit_placer (pos, owner, stack) if continue and left then for _, c in ipairs (coords) do left = inventory_placer (vector.add (pos, c), owner, coords, left, check_list) if not left then break end end end return left end return stack end local function input_item (pos, itemstack) local stack = ItemStack (itemstack) if stack and not stack:is_empty () and check_filter (pos, itemstack) then local meta = minetest.get_meta (pos) if meta then local owner = meta:get_string ("owner") local check_list = { [minetest.pos_to_string (pos, 0)] = true } local coords = { { x = 1, y = 0, z = 0 }, { x = -1, y = 0, z = 0 }, { x = 0, y = 1, z = 0 }, { x = 0, y = -1, z = 0 }, { x = 0, y = 0, z = 1 }, { x = 0, y = 0, z = -1 } } for _, c in ipairs (coords) do stack = inventory_placer (vector.add (pos, c), owner, coords, stack, check_list) if not stack then break end end end check_consolidation (pos) end return stack end local function store_input (pos) local meta = minetest.get_meta (pos) if meta then local inv = meta:get_inventory () if inv then local slots = inv:get_size ("input") for slot = 1, slots, 1 do local stack = inv:get_stack ("input", slot) if stack and not stack:is_empty () then local left = input_item (pos, stack) if left then left = inv:add_item ("output", left) end inv:set_stack ("input", slot, left) end end end end end local function store_input_delayed (pos) minetest.after (0.1, store_input, pos) end local function search_filter (name, terms) if terms then for _, t in ipairs (terms) do if (name:lower ():find (t, 1, true)) then return true end end return false end return true end local function get_formspec_list (pos) local inv_list = get_inventory_list (pos) local list = { } for k, v in pairs (inv_list) do local description = k local stack = ItemStack (k) if stack:get_short_description () ~= "" then description = stack:get_short_description () elseif stack:get_description () ~= "" then description = stack:get_description () else local def = utils.find_item_def (stack:get_name ()) if def then if def.short_description then description = def.short_description elseif def.description then description = def.description end end end list[#list + 1] = { item = k, description = utils.unescape_description (description), count = v.count } end table.sort (list , function (e1, e2) return (e1.description:lower () < e2.description:lower ()) end) return list end local function indexer_get_formspec (pos, search) local inv_list = get_formspec_list (pos) search = search or "" local terms = { } for w in string.gmatch(search, "[^%s]+") do terms[#terms + 1] = string.lower (w) end if #terms < 1 then terms = nil end local index = "" local count = 0 local top = 0 for _, v in ipairs (inv_list) do if search_filter (v.description, terms) then local stack = ItemStack (v.item) local max_stack = stack:get_stack_max () local descr_esc = minetest.formspec_escape (v.description) local item = string.format ("item_image_button[0.0,%0.2f;1.0,1.0;%s;01_%s;]", top, v.item, v.item) if max_stack >= 10 then item = item.. string.format ("button[1.0,%0.2f;1.0,1.0;10_%s;10]", top, v.item) end if max_stack > 1 then item = item.. string.format ("button[2.0,%0.2f;1.0,1.0;ST_%d_%s;%d]", top, max_stack, v.item, max_stack) end item = item.. string.format ("label[3.1,%0.2f;%d]".. "label[4.4,%0.2f;%s]", top + 0.5, v.count, top + 0.5, descr_esc) index = index..item top = top + 1.0 count = count + 1 end end local scroll_height = ((count < 12 and 0) or (count - 11)) * 10 local thumb_size = (count < 12 and 11) or (scroll_height * (11 / count)) if thumb_size < (scroll_height / 10) then thumb_size = scroll_height / 10 end local spec = string.format ("formspec_version[3]".. "size[21.75,14.5,false]".. "field[1.0,1.21;7.5,0.8;search_field;;%s]\n".. "field_close_on_enter[search_field;false]".. "button[8.5,1.21;2.0,0.8;search;Search]\n".. "scrollbaroptions[min=0;max=%d;smallstep=10;largestep=100;thumbsize=%d;arrows=default]".. "scrollbar[10.0,2.5;0.5,11.0;vertical;index_scrollbar;0-%d]".. "scroll_container[1.0,2.5;9.0,11.0;index_scrollbar;vertical;0.1]".. "%s".. "scroll_container_end[]".. "field[11.0,1.21;3.0,0.8;channel;Channel;${channel}]\n".. "field_close_on_enter[channel;false]".. "button[14.0,1.21;1.5,0.8;setchannel;Set]\n".. "label[11.0,3.6;Input]".. "list[context;input;11.0,3.8;2,2;]".. "listring[context;output]".. "label[16.0,1.0;Output]".. "list[context;output;16.0,1.25;4,4;]".. "listring[current_player;main]".. "label[11.0,6.75;Filter]".. "list[context;filter;11.0,7.0;8,1;]".. "list[current_player;main;11.0,8.75;8,4;]".. "listring[context;input]", search, scroll_height, thumb_size, scroll_height, index) return spec end local function indexer_after_place_base (pos, placer, itemstack, pointed_thing) local meta = minetest.get_meta (pos) meta:set_string ("inventory", "{ input = { }, output = { }, filter = { } }") meta:set_string ("formspec", indexer_get_formspec (pos)) local inv = meta:get_inventory () inv:set_size ("input", 4) inv:set_width ("input", 2) inv:set_size ("output", 16) inv:set_width ("output", 4) inv:set_size ("filter", 8) inv:set_width ("filter", 2) end local function indexer_after_place_node (pos, placer, itemstack, pointed_thing) indexer_after_place_base (pos, placer, itemstack, pointed_thing) utils.pipeworks_after_place (pos) -- If return true no item is taken from itemstack return false end local function indexer_after_place_node_locked (pos, placer, itemstack, pointed_thing) indexer_after_place_base (pos, placer, itemstack, pointed_thing) if placer and placer:is_player () then local meta = minetest.get_meta (pos) meta:set_string ("owner", placer:get_player_name ()) meta:set_string ("infotext", "Storage Indexer (owned by "..placer:get_player_name ()..")") end utils.pipeworks_after_place (pos) -- If return true no item is taken from itemstack return false end local function indexer_can_dig (pos, player) if not utils.can_interact_with_node (pos, player) then return false end local meta = minetest.get_meta (pos) if meta then local inv = meta:get_inventory () if inv then if not inv:is_empty ("input") then return false end if not inv:is_empty ("output") then return false end end end return true end local function indexer_on_blast (pos, intensity) local meta = minetest.get_meta (pos) if meta then if intensity >= 1.0 then local inv = meta:get_inventory () if inv then local slots = inv:get_size ("input") for slot = 1, slots do local stack = inv:get_stack ("input", slot) if stack and not stack:is_empty () then if math.floor (math.random (0, 5)) == 3 then utils.item_drop (stack, nil, pos) else utils.on_destroy (stack) end end end slots = inv:get_size ("output") for slot = 1, slots do local stack = inv:get_stack ("output", slot) if stack and not stack:is_empty () then if math.floor (math.random (0, 5)) == 3 then utils.item_drop (stack, nil, pos) else utils.on_destroy (stack) end end end end minetest.remove_node (pos) else -- intensity < 1.0 local inv = meta:get_inventory () if inv then local slots = inv:get_size ("input") for slot = 1, slots do local stack = inv:get_stack ("input", slot) if stack and not stack:is_empty () then utils.item_drop (stack, nil, pos) end end slots = inv:get_size ("output") for slot = 1, slots do local stack = inv:get_stack ("output", slot) if stack and not stack:is_empty () then utils.item_drop (stack, nil, pos) end end end local node = minetest.get_node_or_nil (pos) if node then local items = minetest.get_node_drops (node, nil) if items and #items > 0 then local stack = ItemStack (items[1]) if stack then utils.item_drop (stack, nil, pos) minetest.remove_node (pos) end end end end end end local function indexer_on_rightclick (pos, node, clicker, itemstack, pointed_thing) local meta = minetest.get_meta (pos) if meta then if not utils.can_interact_with_node (pos, clicker) then if clicker and clicker:is_player () then local owner = meta:get_string ("owner") local spec = "formspec_version[3]".. "size[8.0,4.0,false]".. "label[1.0,1.0;Owned by "..minetest.formspec_escape (owner).."]".. "button_exit[3.0,2.0;2.0,1.0;close;Close]" minetest.show_formspec (clicker:get_player_name (), "lwcomponents:component_privately_owned", spec) end return itemstack end meta:set_string ("formspec", indexer_get_formspec (pos)) end return itemstack end local function indexer_on_receive_fields (pos, formname, fields, sender) if not utils.can_interact_with_node (pos, sender) then return end if fields.setchannel or (fields.key_enter_field and fields.key_enter_field == "channel") then local meta = minetest.get_meta (pos) if meta then meta:set_string ("channel", fields.channel) end elseif fields.search or (fields.key_enter_field and fields.key_enter_field == "search_field") then local meta = minetest.get_meta (pos) if meta then meta:set_string ("formspec", indexer_get_formspec (pos, fields.search_field)) end else for k, v in pairs (fields) do if k:sub (1, 3) == "01_" then local item = k:sub (4, -1) output_items (pos, item, 1) break elseif k:sub (1, 3) == "10_" then local item = k:sub (4, -1) output_items (pos, item, 10) break elseif k:sub (1, 3) == "ST_" then local marker = k:find ("_", 4, true) if marker then local qty = tonumber (k:sub (4, marker - 1) or 1) local item = k:sub (marker + 1, -1) output_items (pos, item, qty) end end end end end local function indexer_on_metadata_inventory_put (pos, listname, index, stack, player) if listname == "input" then store_input_delayed (pos) end end local function indexer_on_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player) if from_list == "output" and to_list == "input" then store_input_delayed (pos) end end local function indexer_allow_metadata_inventory_put (pos, listname, index, stack, player) if listname == "filter" then local meta = minetest.get_meta (pos) if meta then local inv = meta:get_inventory () if inv then inv:set_stack ("filter", index, ItemStack (stack:get_name ())) end end return 0 end return stack:get_stack_max () end local function indexer_allow_metadata_inventory_take (pos, listname, index, stack, player) if listname == "filter" then local meta = minetest.get_meta (pos) if meta then local inv = meta:get_inventory () if inv then inv:set_stack ("filter", index, nil) end end return 0 end return stack:get_stack_max () end local function indexer_allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player) local meta = minetest.get_meta (pos) if meta then local inv = meta:get_inventory () if inv then if from_list == "filter" then if to_list == "filter" then return 1 end inv:set_stack ("filter", from_index, nil) return 0 elseif to_list == "filter" then local stack = inv:get_stack (from_list, from_index) if stack and not stack:is_empty () then inv:set_stack ("filter", to_index, ItemStack (stack:get_name ())) end return 0 else local stack = inv:get_stack (from_list, from_index) if stack and not stack:is_empty () then return stack:get_stack_max () end end end end return utils.settings.default_stack_max end local function send_stock_message (pos) if utils.digilines_supported then local meta = minetest.get_meta (pos) if meta then local channel = meta:get_string ("channel") if channel:len () > 0 then local msg = { action = "inventory", inventory = get_stock_list (pos) } utils.digilines_receptor_send (pos, utils.digilines_default_rules, channel, msg) end end end end local function digilines_support () if utils.digilines_supported then return { wire = { rules = utils.digilines_default_rules, }, effector = { action = function (pos, node, channel, msg) local meta = minetest.get_meta(pos) if meta then local this_channel = meta:get_string ("channel") if this_channel ~= "" then if type (msg) == "string" then local m = { } for w in string.gmatch(msg, "[^%s]+") do m[#m + 1] = w end if this_channel == channel then if m[1] == "output" then if m[2] then output_items (pos, m[2], tonumber (m[3] or 1) or 1) end elseif m[1] == "inventory" then send_stock_message (pos) end end elseif type (msg) == "table" then if this_channel == channel then if msg.action and msg.action == "output" and type (msg.item) == "string" then output_items (pos, msg.item, tonumber (msg.count or 1) or 1) end end end end end end, } } end return nil end local function pipeworks_support () if utils.pipeworks_supported then return { priority = 100, input_inventory = "output", connect_sides = { left = 1, right = 1, front = 1, back = 1, bottom = 1, top = 1 }, insert_object = function (pos, node, stack, direction) local meta = minetest.get_meta (pos) local inv = (meta and meta:get_inventory ()) or nil if inv then store_input_delayed (pos) return inv:add_item ("input", stack) end return stack end, can_insert = function (pos, node, stack, direction) local meta = minetest.get_meta (pos) local inv = (meta and meta:get_inventory ()) or nil if inv then return inv:room_for_item ("input", stack) end return false end, can_remove = function (pos, node, stack, dir) -- returns the maximum number of items of that stack that can be removed local meta = minetest.get_meta (pos) local inv = (meta and meta:get_inventory ()) or nil if inv then local slots = inv:get_size ("output") for i = 1, slots, 1 do local s = inv:get_stack ("output", i) if s and not s:is_empty () and utils.is_same_item (stack, s) then return s:get_count () end end end return 0 end, remove_items = function (pos, node, stack, dir, count) -- removes count items and returns them local meta = minetest.get_meta (pos) local inv = (meta and meta:get_inventory ()) or nil local left = count if inv then local slots = inv:get_size ("output") for i = 1, slots, 1 do local s = inv:get_stack ("output", i) if s and not s:is_empty () and utils.is_same_item (s, stack) then if s:get_count () > left then s:set_count (s:get_count () - left) inv:set_stack ("output", i, s) left = 0 else left = left - s:get_count () inv:set_stack ("output", i, nil) end end if left == 0 then break end end end local result = ItemStack (stack) result:set_count (count - left) return result end } end return nil end local indexer_groups = { choppy = 2 } if utils.pipeworks_supported then indexer_groups.tubedevice = 1 indexer_groups.tubedevice_receiver = 1 end minetest.register_node("lwcomponents:storage_indexer", { description = S("Storage Indexer"), drawtype = "normal", tiles = { "lwcomponents_storage_framed.png", "lwcomponents_storage_framed.png", "lwcomponents_storage_indexer.png", "lwcomponents_storage_indexer.png", "lwcomponents_storage_indexer.png", "lwcomponents_storage_indexer.png",}, is_ground_content = false, groups = table.copy (indexer_groups), paramtype = "none", param1 = 0, paramtype2 = "none", param2 = 0, floodable = false, _digistuff_channelcopier_fieldname = "channel", digiline = digilines_support (), tube = pipeworks_support (), on_receive_fields = indexer_on_receive_fields, after_place_node = indexer_after_place_node, can_dig = indexer_can_dig, after_dig_node = utils.pipeworks_after_dig, on_blast = indexer_on_blast, on_rightclick = indexer_on_rightclick, on_metadata_inventory_put = indexer_on_metadata_inventory_put, on_metadata_inventory_move = indexer_on_metadata_inventory_move, allow_metadata_inventory_take = indexer_allow_metadata_inventory_take, allow_metadata_inventory_put = indexer_allow_metadata_inventory_put, allow_metadata_inventory_move = indexer_allow_metadata_inventory_move }) minetest.register_node("lwcomponents:storage_indexer_locked", { description = S("Storage Indexer (locked)"), drawtype = "normal", tiles = { "lwcomponents_storage_framed.png", "lwcomponents_storage_framed.png", "lwcomponents_storage_indexer.png", "lwcomponents_storage_indexer.png", "lwcomponents_storage_indexer.png", "lwcomponents_storage_indexer.png",}, is_ground_content = false, groups = table.copy (indexer_groups), paramtype = "none", param1 = 0, paramtype2 = "none", param2 = 0, floodable = false, _digistuff_channelcopier_fieldname = "channel", digiline = digilines_support (), tube = pipeworks_support (), on_receive_fields = indexer_on_receive_fields, after_place_node = indexer_after_place_node_locked, can_dig = indexer_can_dig, after_dig_node = utils.pipeworks_after_dig, on_blast = indexer_on_blast, on_rightclick = indexer_on_rightclick, on_metadata_inventory_put = indexer_on_metadata_inventory_put, on_metadata_inventory_move = indexer_on_metadata_inventory_move, allow_metadata_inventory_take = indexer_allow_metadata_inventory_take, allow_metadata_inventory_put = indexer_allow_metadata_inventory_put, allow_metadata_inventory_move = indexer_allow_metadata_inventory_move }) utils.hopper_add_container({ {"top", "lwcomponents:storage_indexer", "output"}, -- take items from above into hopper below {"bottom", "lwcomponents:storage_indexer", "input"}, -- insert items below from hopper above {"side", "lwcomponents:storage_indexer", "input"}, -- insert items from hopper at side }) utils.hopper_add_container({ {"top", "lwcomponents:storage_indexer_locked", "output"}, -- take items from above into hopper below {"bottom", "lwcomponents:storage_indexer_locked", "input"}, -- insert items below from hopper above {"side", "lwcomponents:storage_indexer_locked", "input"}, -- insert items from hopper at side }) --