local S = logistica.TRANSLATOR local NUM_REQUEST_SLOTS = 4 -- maybe at some point make this a param, but why? local PUSH_LIST_PICKER = "push_pick" local ON_OFF_BUTTON = "on_off_btn" local INF_CHECKBOX_PREFIX = "infchk" local FORMSPEC_NAME = "logistica_requester" local requesterForms = {} local function get_checkbox_name_from_index(index) return INF_CHECKBOX_PREFIX..tostring(index) end local function get_filter_list_inf_checkboxes(checkboxStates, x, y) local checkboxes = {} for i = 1, NUM_REQUEST_SLOTS do local checkboxName = get_checkbox_name_from_index(i) local ticked = "false" ; if checkboxStates[i] then ticked = "true" end checkboxes[i] = "checkbox["..(x + 0.1 + (i - 1) * 1.25)..","..y..";"..checkboxName..";Inf;"..ticked.."]".. "tooltip["..checkboxName..";"..S("Tick this to always try to insert the item above into the target inventory,\nregardless of how many of that item the target inventory contains.\nThe number of items put above is then requested every second.").."]" end return table.concat(checkboxes) end local function get_requester_formspec(pos) local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z local pushPos = logistica.get_requester_target(pos) local selectedList = logistica.get_requester_target_list(pos) local isOn = logistica.is_machine_on(pos) local checkboxStates = logistica.get_requester_inf_state(pos) return "formspec_version[4]" .. "size["..logistica.inv_size(10.6, 8.45).."]" .. logistica.ui.background.. logistica.ui.push_list_picker(PUSH_LIST_PICKER, 6.7, 1.5, pushPos, selectedList, S("Put items in:")).. logistica.ui.on_off_btn(isOn, 9.3, 1.3, ON_OFF_BUTTON, S("Enable")).. "label[0.5,0.4;"..S("Configure items and count to put, and keep a minimium of, in target's inventory").."]".. "label[0.5,0.7;"..S("Or tick the \"Inf\" (infinite) checkbox below a slot to always keep inserting the item.").."]".. "list["..posForm..";filter;0.5,1.2;"..NUM_REQUEST_SLOTS..",1;0]".. get_filter_list_inf_checkboxes(checkboxStates, 0.5, 2.5).. logistica.player_inv_formspec(0.5, 3.0).. "listring[current_player;main]".. "listring["..posForm..";filter]" end local function show_requester_formspec(playerName, pos) requesterForms[playerName] = {position = pos} minetest.show_formspec(playerName, FORMSPEC_NAME, get_requester_formspec(pos)) end local function on_player_receive_fields(player, formname, fields) if not player or not player:is_player() then return false end if formname ~= FORMSPEC_NAME then return false end local playerName = player:get_player_name() if not requesterForms[playerName] then return false end local pos = requesterForms[playerName].position if minetest.is_protected(pos, playerName) then return true end local reshow = false -- infinite checkboxes check for i = 1, NUM_REQUEST_SLOTS do local checkboxName = get_checkbox_name_from_index(i) if fields[checkboxName] ~= nil then logistica.requester_on_infinite_request_toggle(pos, i, fields[checkboxName] == "true") reshow = true end end if fields.quit then requesterForms[playerName] = nil elseif fields[ON_OFF_BUTTON] then if not pos then return false end logistica.toggle_machine_on_off(pos) show_requester_formspec(player:get_player_name(), pos) elseif fields[PUSH_LIST_PICKER] then local selected = fields[PUSH_LIST_PICKER] if logistica.is_allowed_push_list(selected) then local pos = requesterForms[playerName].position if not pos then return false end logistica.set_requester_target_list(pos, selected) end end if reshow then show_requester_formspec(player:get_player_name(), pos) end return true end local function on_requester_punch(pos, node, puncher, pointed_thing) local targetPos = logistica.get_requester_target(pos) if targetPos and puncher:is_player() and puncher:get_player_control().sneak then logistica.show_output_at(targetPos) end end local function on_requester_rightclick(pos, node, clicker, itemstack, pointed_thing) if not clicker or not clicker:is_player() then return end if minetest.is_protected(pos, clicker:get_player_name()) then return end show_requester_formspec(clicker:get_player_name(), pos) end local function after_place_requester(pos, placer, itemstack, numRequestSlots) local meta = minetest.get_meta(pos) if placer and placer:is_player() then meta:set_string("owner", placer:get_player_name()) end logistica.set_requester_target_list(pos, "main") local inv = meta:get_inventory() inv:set_size("filter", numRequestSlots) inv:set_size("actual", numRequestSlots) logistica.on_requester_change(pos) logistica.show_output_at(logistica.get_requester_target(pos)) logistica.set_node_tooltip_from_state(pos, nil, false) end local function allow_requester_storage_inv_put(pos, listname, index, stack, player) if listname ~= "filter" then return 0 end if minetest.is_protected(pos, player:get_player_name()) then return 0 end local inv = minetest.get_meta(pos):get_inventory() local slotStack = inv:get_stack(listname, index) slotStack:add_item(stack) inv:set_stack(listname, index, slotStack) logistica.update_cache_at_pos(pos, LOG_CACHE_REQUESTER) logistica.start_requester_timer(pos, 1) return 0 end local function allow_requester_inv_take(pos, listname, index, stack, player) if listname ~= "filter" then return 0 end if minetest.is_protected(pos, player:get_player_name()) then return 0 end local inv = minetest.get_meta(pos):get_inventory() local slotStack = inv:get_stack(listname, index) slotStack:take_item(stack:get_count()) inv:set_stack(listname, index, slotStack) logistica.update_cache_at_pos(pos, LOG_CACHE_REQUESTER) return 0 end local function allow_requester_inv_move(_, _, _, _, _, _, _) return 0 end ---------------------------------------------------------------- -- Minetest registration ---------------------------------------------------------------- minetest.register_on_player_receive_fields(on_player_receive_fields) minetest.register_on_leaveplayer(function(objRef, timed_out) if objRef:is_player() then requesterForms[objRef:get_player_name()] = nil end end) ---------------------------------------------------------------- -- Public Registration API ---------------------------------------------------------------- -- `simpleName` is used for the description and for the name (can contain spaces) -- transferRate is how many items per tick this requester can transfer, -1 for unlimited function logistica.register_requester(description, name, transferRate, tiles) local lname = string.lower(name:gsub(" ", "_")) local requester_name = "logistica:"..lname logistica.GROUPS.requesters.register(requester_name) local grps = {oddly_breakable_by_hand = 3, cracky = 3, handy = 1, pickaxey = 1, } grps[logistica.TIER_ALL] = 1 local def = { description = description, drawtype = "normal", tiles = tiles, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, groups = grps, drop = requester_name, sounds = logistica.node_sound_metallic(), on_timer = logistica.on_timer_powered(logistica.on_requester_timer), after_place_node = function (pos, placer, itemstack) after_place_requester(pos, placer, itemstack, NUM_REQUEST_SLOTS) end, after_dig_node = logistica.on_requester_change, on_punch = on_requester_punch, on_rightclick = on_requester_rightclick, allow_metadata_inventory_put = allow_requester_storage_inv_put, allow_metadata_inventory_take = allow_requester_inv_take, allow_metadata_inventory_move = allow_requester_inv_move, logistica = { requester_transfer_rate = transferRate, on_connect_to_network = function(pos, networkId) logistica.start_requester_timer(pos) end, on_power = function(pos, isPoweredOn) logistica.set_node_tooltip_from_state(pos, nil, isPoweredOn) if isPoweredOn then logistica.start_requester_timer(pos) end end, }, _mcl_hardness = 1.5, _mcl_blast_resistance = 10 } minetest.register_node(requester_name, def) logistica.register_non_pushable(requester_name) local def_disabled = table.copy(def) local tiles_disabled = {} for k, v in pairs(def.tiles) do tiles_disabled[k] = v.."^logistica_disabled.png" end def_disabled.tiles = tiles_disabled def_disabled.groups = { oddly_breakable_by_hand = 3, cracky = 3, choppy = 3, handy = 1, pickaxey = 1, axey = 1, not_in_creative_inventory = 1 } def_disabled.on_construct = nil def_disabled.after_dig_node = nil def_disabled.on_punch = nil def_disabled.on_rightclick = nil def_disabled.on_timer = nil def_disabled.logistica = nil minetest.register_node(requester_name.."_disabled", def_disabled) end