diff --git a/ROADMAP.md b/ROADMAP.md index 782be47..7db34ab 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,7 +3,6 @@ Missing Features: - Crafting recipes High Priority: -- Storage Upgrades - Wirelss Network Extender - Mesecons compat @@ -17,10 +16,11 @@ Medium Priority Low Priority: - Liquid Storage - Improve node sounds +- Direct pipeworks compatibility +- Direct tubelib compatibility Maybe not needed, unless specific common usecase found to support: - Demander modes: AND/OR - Mode AND: supply target with "item 1 AND item 2..." - Mode OR: supply target with "item 1" OR (if not available) "item 2" -- Direct pipeworks compatibility -- Direct tubelib compatibility +- API improvements: The API isn't much of an API in most cases, it barely allows customization. May be worth generifiying some of it sometime. \ No newline at end of file diff --git a/api/access_point.lua b/api/access_point.lua new file mode 100644 index 0000000..b845921 --- /dev/null +++ b/api/access_point.lua @@ -0,0 +1,118 @@ + +local function after_place_access_point(pos, placer, itemstack, numSlots, numUpgradeSlots) + local meta = minetest.get_meta(pos) + if placer and placer:is_player() then + meta:set_string("owner", placer:get_player_name()) + end + logistica.access_point_after_place(pos, meta) + logistica.on_access_point_change(pos) +end + +local function allow_access_point_inv_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then return 0 end + return logistica.access_point_allow_put(pos, listname, index, stack, player) +end + +local function allow_access_point_inv_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then return 0 end + return logistica.access_point_allow_take(pos, listname, index, stack, player) +end + +local function allow_access_point_inv_move(pos, from_list, from_index, to_list, to_index, count, player) + if minetest.is_protected(pos, player:get_player_name()) then return 0 end + return logistica.access_point_allow_move(pos, from_list, from_index, to_list, to_index, count, player) +end + +local function on_access_point_inv_move(pos, from_list, from_index, to_list, to_index, count, player) + if minetest.is_protected(pos, player:get_player_name()) then return 0 end + logistica.access_point_on_inv_move(pos, from_list, from_index, to_list, to_index, count, player) +end + +local function on_access_point_inv_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then return 0 end + logistica.access_point_on_put(pos, listname, index, stack, player) +end + +local function on_access_point_inv_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then return 0 end + logistica.access_point_on_take(pos, listname, index, stack, player) +end + +local function on_access_point_rightclick(pos, node, clicker, itemstack, pointed_thing) + if minetest.is_protected(pos, clicker:get_player_name()) then return 0 end + logistica.access_point_on_rightclick(pos, node, clicker, itemstack, pointed_thing) +end + +---------------------------------------------------------------- +-- registration calls +---------------------------------------------------------------- + +minetest.register_on_leaveplayer(function(objRef, timed_out) + if objRef:is_player() then + logistica.access_point_on_player_close(objRef:get_player_name()) + end +end) + +minetest.register_on_player_receive_fields(logistica.on_receive_access_point_formspec) + +---------------------------------------------------------------- +-- public api +---------------------------------------------------------------- + +-- `simpleName` is used for the description and for the name (can contain spaces) +function logistica.register_access_point(desc, name, tiles) + local lname = string.lower(name:gsub(" ", "_")) + local access_point_name = "logistica:access_point_"..lname + logistica.misc_machines[access_point_name] = true + local grps = {oddly_breakable_by_hand = 3, cracky = 3 } + grps[logistica.TIER_ALL] = 1 + local def = { + description = desc, + drawtype = "normal", + tiles = tiles, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + groups = grps, + drop = access_point_name, + sounds = logistica.node_sound_metallic(), + connect_sides = {"top", "bottom", "left", "back", "right" }, + after_place_node = after_place_access_point, + after_destruct = logistica.on_access_point_change, + on_rightclick = on_access_point_rightclick, + on_metadata_inventory_move = on_access_point_inv_move, + on_metadata_inventory_put = on_access_point_inv_put, + on_metadata_inventory_take = on_access_point_inv_take, + allow_metadata_inventory_put = allow_access_point_inv_put, + allow_metadata_inventory_take = allow_access_point_inv_take, + allow_metadata_inventory_move = allow_access_point_inv_move, + logistica = {} + } + + minetest.register_node(access_point_name, def) + + 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, not_in_creative_inventory = 1 } + def_disabled.on_construct = nil + def_disabled.after_destruct = nil + def_disabled.on_punch = nil + def_disabled.on_rightclick = nil + def_disabled.on_timer = nil + def_disabled.logistica = nil + + minetest.register_node(access_point_name.."_disabled", def_disabled) + +end + +logistica.register_access_point("Access Point", "base", { + "logistica_access_point_top.png", + "logistica_access_point_bottom.png", + "logistica_access_point_side.png^[transformFX", + "logistica_access_point_side.png", + "logistica_access_point_back.png", + "logistica_access_point_front.png", +}) diff --git a/api/api.lua b/api/api.lua index 9f3b84e..667c6d5 100644 --- a/api/api.lua +++ b/api/api.lua @@ -7,3 +7,4 @@ dofile(path.."/supplier.lua") dofile(path.."/requester.lua") dofile(path.."/injector.lua") dofile(path.."/item_storage.lua") +dofile(path.."/access_point.lua") diff --git a/api/controller.lua b/api/controller.lua index bc61303..8edbea3 100644 --- a/api/controller.lua +++ b/api/controller.lua @@ -1,11 +1,12 @@ local SET_BUTTON = "logsetbtn" local NAME_FIELD = "namef" local FORMSPEC_NAME = "logconren" +local MAX_NETWORK_NAME_LENGTH = 20 local controllerForms = {} local function get_controller_formspec(pos) local name = logistica.get_network_name_or_nil(pos) or "" - return "formspec_version[6]" .. + return "formspec_version[4]" .. "size[10.5,2]" .. logistica.ui.background.. "field[2.5,0.6;3,0.8;"..NAME_FIELD..";Network Name;"..name.."]" .. @@ -28,6 +29,9 @@ local function on_controller_receive_fields(player, formname, fields) controllerForms[playerName] = nil elseif (fields[SET_BUTTON] or fields.key_enter_field) and fields[NAME_FIELD] then local newNetworkName = fields[NAME_FIELD] + if #newNetworkName > MAX_NETWORK_NAME_LENGTH then + newNetworkName = string.sub(newNetworkName, 1, MAX_NETWORK_NAME_LENGTH) + end logistica.rename_network(minetest.hash_node_position(pos), newNetworkName) local meta = minetest.get_meta(pos) meta:set_string("infotext", "Controller of Network: "..newNetworkName) diff --git a/api/injector.lua b/api/injector.lua index cd32a51..7b50090 100644 --- a/api/injector.lua +++ b/api/injector.lua @@ -61,6 +61,7 @@ end local function on_injector_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_injector_formspec(clicker:get_player_name(), pos) end diff --git a/api/item_storage.lua b/api/item_storage.lua index 72f8af7..274844a 100644 --- a/api/item_storage.lua +++ b/api/item_storage.lua @@ -55,6 +55,7 @@ end local function on_item_storage_rightclick(pos, _, clicker, _, _) if not clicker or not clicker:is_player() then return end + if minetest.is_protected(pos, clicker:get_player_name()) then return 0 end show_item_storage_formspec(clicker:get_player_name(), pos) end diff --git a/api/mass_storage.lua b/api/mass_storage.lua index 62f9da9..5b35d5c 100644 --- a/api/mass_storage.lua +++ b/api/mass_storage.lua @@ -272,12 +272,11 @@ end local function on_mass_storage_inv_move(pos, from_list, from_index, to_list, to_index, count, player) - if minetest.is_protected(pos, player) then return 0 end + if minetest.is_protected(pos, player:get_player_name()) then return 0 end return 0 end local function on_mass_storage_inv_put(pos, listname, index, stack, player) - if minetest.is_protected(pos, player) then return 0 end if listname == "main" then local remaining = logistica.try_to_add_item_to_storage(pos, stack) local taken = stack:get_count() - remaining @@ -298,7 +297,6 @@ local function on_mass_storage_inv_put(pos, listname, index, stack, player) end local function on_mass_storage_inv_take(pos, listname, index, stack, player) - if minetest.is_protected(pos, player) then return 0 end if listname == "upgrade" then logistica.on_mass_storage_upgrade_change(pos, stack:get_name(), false) end @@ -306,13 +304,14 @@ end local function on_mass_storage_punch(pos, node, puncher, pointed_thing) if not puncher and not puncher:is_player() then return end - if minetest.is_protected(pos, puncher) then return end + if minetest.is_protected(pos, puncher:get_player_name()) then return end logistica.try_to_add_player_wield_item_to_mass_storage(pos, puncher) end local function on_mass_storage_right_click(pos, node, clicker, itemstack, pointed_thing) - local name = clicker:get_player_name() - show_mass_storage_formspec(pos, name) + if not clicker or not clicker:is_player() then return end + if minetest.is_protected(pos, clicker:get_player_name()) then return end + show_mass_storage_formspec(pos, clicker:get_player_name()) end local function on_mass_storage_rotate(pos, node, player, mode, newParam2) diff --git a/api/requester.lua b/api/requester.lua index 4a3273e..d3fa5be 100644 --- a/api/requester.lua +++ b/api/requester.lua @@ -59,6 +59,7 @@ 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 diff --git a/api/supplier.lua b/api/supplier.lua index ff9295a..da58c41 100644 --- a/api/supplier.lua +++ b/api/supplier.lua @@ -42,6 +42,7 @@ end local function on_supplier_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_supplier_formspec(clicker:get_player_name(), pos) end diff --git a/entity/entity.lua b/entity/entity.lua index 5c24e4f..323c0df 100644 --- a/entity/entity.lua +++ b/entity/entity.lua @@ -1,4 +1,4 @@ local path = logistica.MODPATH .. "/entity" -dofile(path .. "/io_entity.lua") -dofile(path .. "/display_item.lua") \ No newline at end of file +dofile(path.."/io_entity.lua") +dofile(path.."/display_item.lua") \ No newline at end of file diff --git a/item/item.lua b/item/item.lua index 72242cb..c187057 100644 --- a/item/item.lua +++ b/item/item.lua @@ -1,4 +1,4 @@ local path = logistica.MODPATH .. "/item" logistica.craftitem = {} -dofile(path .. "/storage_upgrade.lua") +dofile(path.."/storage_upgrade.lua") diff --git a/logic/access_point.lua b/logic/access_point.lua new file mode 100644 index 0000000..f49c2da --- /dev/null +++ b/logic/access_point.lua @@ -0,0 +1,208 @@ +local META_CURR_PAGE = "ap_curr_p" +local META_SORT_TYPE = "ap_sort" +local META_FILTER_TYPE = "ap_fltr" +local META_CURR_SEARCH = "ap_curr_s" +local META_IGNORE_METADATA = "ap_usemd" + +local fakeInvMap = {} + +local SORT_NAME = 1 +local SORT_MOD = 2 +local SORT_COUNT = 3 +local SORT_WEAR = 4 +local sortMethodMap = { + [SORT_NAME] = function(list) return logistica.sort_list_by(list, LOG_SORT_NAME_AZ) end, + [SORT_MOD] = function(list) return logistica.sort_list_by(list, LOG_SORT_MOD_AZ) end, + [SORT_COUNT] = function(list) return logistica.sort_list_by(list, LOG_SORT_STACK_SIZE_REV) end, + [SORT_WEAR] = function(list) return logistica.sort_list_by(list, LOG_SORT_DURABILITY_FWD) end, +} + +local FILTER_ALL = 1 +local FILTER_NODES = 2 +local FILTER_ITEMS = 3 +local FILTER_TOOLS = 4 +local FILTER_LIGHTS = 5 + +local filterMethodMap = { + [FILTER_ALL] = function(list) return list end, + [FILTER_NODES] = function(list) return logistica.filter_list_by(list, LOG_FILTER_NODE) end, + [FILTER_ITEMS] = function(list) return logistica.filter_list_by(list, LOG_FILTER_CRAFTITEM) end, + [FILTER_TOOLS] = function(list) return logistica.filter_list_by(list, LOG_FILTER_TOOL) end, + [FILTER_LIGHTS] = function(list) return logistica.filter_list_by(list, LOG_FILTER_LIGHT) end, +} + +local h2p = minetest.get_position_from_hash +local pth = minetest.hash_node_position +local get_meta = minetest.get_meta + +local function get_curr_sort_method_int(meta) + local curr = meta:get_int(META_SORT_TYPE) + if curr <= 0 or curr >= 5 then return 1 else return curr end +end + +local function set_curr_sort_method_int(meta, methodIndex) + meta:set_int(META_SORT_TYPE, methodIndex) +end + +local function get_curr_filter_method_int(meta) + local curr = meta:get_int(META_FILTER_TYPE) + if curr <= 0 or curr >= 6 then return 1 else return curr end +end + +local function set_curr_filter_method_int(meta, methodIndex) + meta:set_int(META_FILTER_TYPE, methodIndex) +end + +local function add_list_to_itemmap(itemMap, list, useMetadata) + for _, stack in ipairs(list) do + if not stack:is_empty() then + local stackName = stack:get_name() + if useMetadata then stackName = stack:to_string() end + if itemMap[stackName] == nil then itemMap[stackName] = 0 end + itemMap[stackName] = itemMap[stackName] + stack:get_count() + end + end +end + +local function build_stack_list(pos) + local network = logistica.get_network_or_nil(pos) + if not network then return {stackList = {}, stackListSize = 0} end + local useMetadata = logistica.access_point_is_set_to_use_metadata(pos) + local meta = get_meta(pos) + + local itemMap = {} + -- we scan all supply chests and mass storage and item storage + for hash, _ in pairs(network.suppliers) do + local mPos = logistica.load_position(h2p(hash)) + local list = get_meta(mPos):get_inventory():get_list("main") or {} + add_list_to_itemmap(itemMap, list, useMetadata) + end + for hash, _ in pairs(network.mass_storage) do + local mPos = logistica.load_position(h2p(hash)) + local list = get_meta(mPos):get_inventory():get_list("storage") or {} + add_list_to_itemmap(itemMap, list, useMetadata) + end + for hash, _ in pairs(network.item_storage) do + local mPos = logistica.load_position(h2p(hash)) + local list = get_meta(mPos):get_inventory():get_list("main") or {} + add_list_to_itemmap(itemMap, list, useMetadata) + end + local itemList = {} + local listSize = 0 + for item, count in pairs(itemMap) do + local stack = ItemStack(item) + stack:set_count(count) + listSize = listSize + 1 + itemList[listSize] = stack + end + local filtered = filterMethodMap[get_curr_filter_method_int(meta)](itemList) + local sorted = sortMethodMap[get_curr_sort_method_int(meta)](filtered) + return { + stackList = sorted, + stackListSize = listSize, + } +end + + +-------------------------------- +-- public functions +-------------------------------- + +function logistica.access_point_on_player_close(playerName) + fakeInvMap[playerName] = nil +end + +function logistica.update_fake_inv(pos, listName, listSize, playerName) + local meta = get_meta(pos) + local inv = meta:get_inventory() + local pageInfo = logistica.access_point_get_current_page_info(pos, playerName, listSize, meta) + if pageInfo.max == 0 then inv:set_list(listName, {}) ; return end + local startingPos = (pageInfo.curr - 1) * listSize + 1 + local fullList = fakeInvMap[playerName].stackList + if not fullList then return end + local fakeInvList = {} + for i = startingPos, startingPos + listSize do + fakeInvList[i - startingPos + 1] = fullList[i] or ItemStack("") + end + inv:set_list(listName, fakeInvList) +end + +-- returns a table representing pages: {curr = #, max = #} +function logistica.access_point_get_current_page_info(pos, playerName, listSize, optMeta) + if not fakeInvMap[playerName] then return {curr = 0, max = 0} end + local meta = optMeta or get_meta(pos) + local storedPage = meta:get_int(META_CURR_PAGE) + if storedPage <= 0 then storedPage = 1 end + local fakeInv = fakeInvMap[playerName] + local maxPages = math.ceil(fakeInv.stackListSize / listSize) + if storedPage > maxPages then + storedPage = maxPages + meta:set_int(META_CURR_PAGE, storedPage) + end + return {curr = storedPage, max = maxPages} +end + +function logistica.access_point_is_set_to_use_metadata(pos) + local meta = get_meta(pos) + return meta:get_int(META_IGNORE_METADATA) == 0 +end + +-- toggles whether to use metadata and returns the new state +function logistica.access_point_toggle_use_metadata(pos) + local meta = get_meta(pos) + local curr = meta:get_int(META_IGNORE_METADATA) + local new = (curr + 1) % 2 + meta:set_int(META_IGNORE_METADATA, new) + return new == 0 +end + +-- returns true if page was changed, false if it wasn't +function logistica.access_point_change_page(pos, op, playerName, listSize) + local meta = get_meta(pos) + local currInfo = logistica.access_point_get_current_page_info(pos, playerName, listSize, meta) + if currInfo.max == 0 then return false end + local newPage = currInfo.curr + if op == 1 then newPage = newPage + 1 + elseif op > 1 then newPage = currInfo.max + elseif op == -1 then newPage = newPage - 1 + elseif op < -1 then newPage = 1 end + newPage = logistica.clamp(newPage, 1, currInfo.max) + if currInfo.curr == newPage then return false end + meta:set_int(META_CURR_PAGE, newPage) + return true +end + +function logistica.access_point_get_filter_highlight_images(meta, highlightImg, blankImg) + local method = get_curr_filter_method_int(meta) + return { + all = (method == FILTER_ALL and highlightImg) or blankImg, + node = (method == FILTER_NODES and highlightImg) or blankImg, + craftitem = (method == FILTER_ITEMS and highlightImg) or blankImg, + tools = (method == FILTER_TOOLS and highlightImg) or blankImg, + lights = (method == FILTER_LIGHTS and highlightImg) or blankImg, + } +end + +function logistica.access_point_get_sort_highlight_images(meta, highlightImg, blankImg) + local method = get_curr_sort_method_int(meta) + return { + name = (method == SORT_NAME and highlightImg) or blankImg, + mod = (method == SORT_MOD and highlightImg) or blankImg, + count = (method == SORT_COUNT and highlightImg) or blankImg, + wear = (method == SORT_WEAR and highlightImg) or blankImg, + } +end + +function logistica.access_point_refresh_fake_inv(pos, listName, listSize, playerName) + local listInfo = build_stack_list(pos) + fakeInvMap[playerName] = listInfo + logistica.update_fake_inv(pos, listName, listSize, playerName) +end + +function logistica.access_point_set_filter_method(pos, playerName, method) + set_curr_filter_method_int(get_meta(pos), method) +end + +function logistica.access_point_set_sort_method(pos, playerName, method) + set_curr_sort_method_int(get_meta(pos), method) +end diff --git a/logic/access_point_formspec.lua b/logic/access_point_formspec.lua new file mode 100644 index 0000000..fa58e6a --- /dev/null +++ b/logic/access_point_formspec.lua @@ -0,0 +1,239 @@ +local S = logistica.TRANSLATOR + +local FORMSPEC_NAME = "accesspoint_formspec" +-- local LOCK_BTN = "on_off" +local NEXT_BTN = "next" +local PREV_BTN = "prev" +local FRST_BTN = "frst" +local LAST_BTN = "last" +local SEARCH_BTN = "search" +local CLEAR_BTN = "clear" +local FILTER_ALL_BTN = "filter_all" +local FILTER_NODES_BTN = "filter_blk" +local FILTER_CRFTITM_BTN = "filter_cft" +local FILTER_TOOLS_BTN = "filter_tol" +local FILTER_LIGHTS_BTN = "filter_lig" +local SORT_NAME_BTN = "sort_name" +local SORT_MOD_BTN = "sort_mod" +local SORT_COUNT_BTN = "sort_cnt" +local SORT_WEAR_BTN = "sort_wer" +local SEARCH_FIELD = "srch_fld" +local USE_META_BTN = "tgl_meta" + +local INV_FAKE = "fake" +local INV_CRAFT = "craft" +local INV_CRAFT_OUTPUT = "output" +local INV_INSERT = "isert" +local FAKE_INV_W = 12 +local FAKE_INV_H = 4 +local FAKE_INV_SIZE = FAKE_INV_W * FAKE_INV_H + +local IMG_HIGHLGIHT = "logistica_icon_highlight.png" +local IMG_BLANK = "logistica_blank.png" +local IMG_SORT_NAME = "logistica_icon_sort_name_az.png" +local IMG_SORT_MOD = "logistica_icon_sort_mod_az.png" +local IMG_SORT_COUNT = "logistica_icon_sort_count_99_1.png" +local IMG_SORT_WEAR = "logistica_icon_sort_wear_0_100.png" +local IMG_FILT_ALL = "logistica_icon_all.png" +local IMG_FILT_NODE = "logistica_icon_node.png" +local IMG_FILT_ITEM = "logistica_icon_craftitem.png" +local IMG_FILT_TOOL = "logistica_icon_tool.png" +local IMG_FILT_LIGHT = "logistica_icon_torch.png" + +local ACCESS_POINT_TIMER = 1 + +local accessPointForms = {} + + + +---------------------------------------------------------------- +-- formspec +---------------------------------------------------------------- + +local function get_access_point_formspec(pos, optMeta, playerName) + local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z + local meta = optMeta or minetest.get_meta(pos) + local currentNetwork = logistica.get_network_name_or_nil(pos) or S("") + local filterHighImg = logistica.access_point_get_filter_highlight_images(meta, IMG_HIGHLGIHT, IMG_BLANK) + local sortHighImg = logistica.access_point_get_sort_highlight_images(meta, IMG_HIGHLGIHT, IMG_BLANK) + local pageInfo = logistica.access_point_get_current_page_info(pos, playerName, FAKE_INV_SIZE, meta) + local usesMetadata = logistica.access_point_is_set_to_use_metadata(pos) + local usesMetaStr = usesMetadata and S("Metadata: ON") or S("Metadata: OFF") + return "formspec_version[4]".. + "size[15.2,12.5]".. + logistica.ui.background.. + "list["..posForm..";"..INV_FAKE..";0.2,0.2;"..FAKE_INV_W..","..FAKE_INV_H..";0]".. + "image[2.8,6.4;1,1;logistica_icon_input.png]".. + "list["..posForm..";"..INV_INSERT..";3.8,6.4;1,1;0]".. + "list[current_player;main;5.2,7.5;8.0,4.0;0]".. + "listring[]".. + "label[1.4,12.2;"..S("Crafting").."]".. + "list["..posForm..";"..INV_CRAFT..";0.2,8.4;3,3;0]".. + "list["..posForm..";"..INV_CRAFT_OUTPUT..";3.9,8.4;1,1;0]".. + "button[1.4,5.2;2.6,0.6;"..USE_META_BTN..";"..usesMetaStr.."]".. + "label[4.3,5.5;"..S("Filter").."]".. + "image[5.1,5;1,1;"..filterHighImg.all.."]".. + "image[6.0,5;1,1;"..filterHighImg.node.."]".. + "image[6.9,5;1,1;"..filterHighImg.craftitem.."]".. + "image[7.8,5;1,1;"..filterHighImg.tools.."]".. + "image[8.7,5;1,1;"..filterHighImg.lights.."]".. + "image_button[5.2,5.1;0.8,0.8;"..IMG_FILT_ALL..";"..FILTER_ALL_BTN..";;false;false;]".. + "image_button[6.1,5.1;0.8,0.8;"..IMG_FILT_NODE..";"..FILTER_NODES_BTN..";;false;false;]".. + "image_button[7.0,5.1;0.8,0.8;"..IMG_FILT_ITEM..";"..FILTER_CRFTITM_BTN..";;false;false;]".. + "image_button[7.9,5.1;0.8,0.8;"..IMG_FILT_TOOL..";"..FILTER_TOOLS_BTN..";;false;false;]".. + "image_button[8.8,5.1;0.8,0.8;"..IMG_FILT_LIGHT..";"..FILTER_LIGHTS_BTN..";;false;false;]".. + "label[10.5,5.5;"..S("Sort").."]".. + "image[11.0,5;1,1;"..sortHighImg.name.."]".. + "image[11.9,5;1,1;"..sortHighImg.mod.."]".. + "image[12.8,5;1,1;"..sortHighImg.count.."]".. + "image[13.7,5;1,1;"..sortHighImg.wear.."]".. + "image_button[11.1,5.1;0.8,0.8;"..IMG_SORT_NAME..";"..SORT_NAME_BTN..";;false;false;]".. + "image_button[12.0,5.1;0.8,0.8;"..IMG_SORT_MOD..";"..SORT_MOD_BTN..";;false;false;]".. + "image_button[12.9,5.1;0.8,0.8;"..IMG_SORT_COUNT..";"..SORT_COUNT_BTN..";;false;false;]".. + "image_button[13.8,5.1;0.8,0.8;"..IMG_SORT_WEAR..";"..SORT_WEAR_BTN..";;false;false;]".. + "label[5.3,6.3;"..S("Network: ")..currentNetwork.."]".. + "field[5.2,6.5;2.8,0.8;"..SEARCH_FIELD..";;]".. + "image_button[8.1,6.5;0.8,0.8;logistica_icon_search.png;"..SEARCH_BTN..";;false;false;]".. + "image_button[9.2,6.5;0.8,0.8;logistica_icon_cancel.png;"..CLEAR_BTN..";;false;false;]".. + "label[12.0,6.3;"..S("Page")..": "..pageInfo.curr.." / "..pageInfo.max.."]".. + "image_button[10.6,6.5;0.8,0.8;logistica_icon_first.png;"..FRST_BTN..";;false;false;]".. + "image_button[11.7,6.5;0.8,0.8;logistica_icon_prev.png;"..PREV_BTN..";;false;false;]".. + "image_button[12.8,6.5;0.8,0.8;logistica_icon_next.png;"..NEXT_BTN..";;false;false;]".. + "image_button[13.9,6.5;0.8,0.8;logistica_icon_last.png;"..LAST_BTN..";;false;false;]" + -- TODO tooltips +end + +local function show_access_point_formspec(pos, playerName, optMeta) + local meta = optMeta or minetest.get_meta(pos) + accessPointForms[playerName] = { position = pos } + logistica.access_point_refresh_fake_inv(pos, INV_FAKE, FAKE_INV_SIZE, playerName) + minetest.show_formspec( + playerName, + FORMSPEC_NAME, + get_access_point_formspec(pos, meta, playerName) + ) +end + +---------------------------------------------------------------- +-- callbacks +---------------------------------------------------------------- + +function logistica.on_receive_access_point_formspec(player, formname, fields) + if formname ~= FORMSPEC_NAME then return end + local playerName = player:get_player_name() + if not accessPointForms[playerName] then return true end + local pos = accessPointForms[playerName].position + if minetest.is_protected(pos, playerName) or not pos then return true end + + if fields.quit and not fields.key_enter_field then + accessPointForms[playerName] = nil + logistica.access_point_on_player_close(playerName) + return true + elseif fields[FRST_BTN] then + if not logistica.access_point_change_page(pos, -2, playerName, FAKE_INV_SIZE) then return true end + elseif fields[PREV_BTN] then + if not logistica.access_point_change_page(pos, -1, playerName, FAKE_INV_SIZE) then return true end + elseif fields[NEXT_BTN] then + if not logistica.access_point_change_page(pos, 1, playerName, FAKE_INV_SIZE) then return true end + elseif fields[LAST_BTN] then + if not logistica.access_point_change_page(pos, 2, playerName, FAKE_INV_SIZE) then return true end + elseif fields[USE_META_BTN] then + logistica.access_point_toggle_use_metadata(pos) + elseif fields[FILTER_ALL_BTN] then + logistica.access_point_set_filter_method(pos, playerName, 1) + elseif fields[FILTER_NODES_BTN] then + logistica.access_point_set_filter_method(pos, playerName, 2) + elseif fields[FILTER_CRFTITM_BTN] then + logistica.access_point_set_filter_method(pos, playerName, 3) + elseif fields[FILTER_TOOLS_BTN] then + logistica.access_point_set_filter_method(pos, playerName, 4) + elseif fields[FILTER_LIGHTS_BTN] then + logistica.access_point_set_filter_method(pos, playerName, 5) + elseif fields[SORT_NAME_BTN] then + logistica.access_point_set_sort_method(pos, playerName, 1) + elseif fields[SORT_MOD_BTN] then + logistica.access_point_set_sort_method(pos, playerName, 2) + elseif fields[SORT_COUNT_BTN] then + logistica.access_point_set_sort_method(pos, playerName, 3) + elseif fields[SORT_WEAR_BTN] then + logistica.access_point_set_sort_method(pos, playerName, 4) + end + show_access_point_formspec(pos, playerName) + return true +end + +function logistica.access_point_after_place(pos, meta) + local inv = meta:get_inventory() + inv:set_size(INV_FAKE, FAKE_INV_SIZE) + inv:set_size(INV_CRAFT, 9) + inv:set_width(INV_CRAFT, 3) + inv:set_size(INV_CRAFT_OUTPUT, 1) + inv:set_size(INV_INSERT, 1) +end + +function logistica.access_point_allow_put(pos, listname, index, stack, player) + if listname == INV_FAKE or listname == INV_CRAFT_OUTPUT then return 0 end + return stack:get_count() +end + +function logistica.access_point_allow_take(pos, listname, index, _stack, player) + local stack = ItemStack(_stack) + if listname == INV_FAKE then + local network = logistica.get_network_or_nil(pos) + if not network then + show_access_point_formspec(pos, player:get_player_name()) + return 0 + end + -- either way, only allow taking up to stack max + stack:set_count(math.min(stack:get_count(), stack:get_stack_max())) + if stack:get_stack_max() > 1 then + local taken = nil + local acceptTaken = function(st) taken = st; return 0 end + logistica.take_stack_from_network(stack, network, acceptTaken) + if not taken or taken:is_empty() then return 0 end + return math.min(taken:get_count(), stack:get_stack_max()) + else -- individual items are trickier + -- we want to take the actual item, so place it in the slot before its taken + local useMetadata = logistica.access_point_is_set_to_use_metadata(pos) + local taken = nil + local acceptTaken = function(st) taken = st; return 0 end + logistica.take_stack_from_network(stack, network, acceptTaken, false, useMetadata) + if not taken or taken:is_empty() then return 0 end + local inv = minetest.get_meta(pos):get_inventory() + inv:set_stack(listname, index, taken) + return taken:get_count() + end + end + return stack:get_count() +end + +function logistica.access_point_allow_move(pos, from_list, from_index, to_list, to_index, count, player) + if from_list == INV_FAKE or to_list == INV_FAKE or to_list == INV_CRAFT_OUTPUT then return 0 end + return count +end + +function logistica.access_point_on_inv_move(pos, from_list, from_index, to_list, to_index, count, player) + +end + +function logistica.access_point_on_put(pos, listname, index, stack, player) + local networkId = logistica.get_network_id_or_nil(pos) + if not networkId then show_access_point_formspec(pos, player:get_player_name()) ; return end + if listname == INV_INSERT then + local leftover = logistica.insert_item_in_network(stack, networkId) + stack:set_count(leftover) + minetest.get_meta(pos):get_inventory():set_stack(listname, index, stack) + show_access_point_formspec(pos, player:get_player_name()) + end +end + +function logistica.access_point_on_take(pos, listname, index, stack, player) + if listname == INV_FAKE then + -- refresh the page in case we had to swap out a fake item or a stack is gone + logistica.access_point_refresh_fake_inv(pos, listname, FAKE_INV_SIZE, player:get_player_name()) + end +end + +function logistica.access_point_on_rightclick(pos, node, clicker, itemstack, pointed_thing) + show_access_point_formspec(pos, clicker:get_player_name()) +end \ No newline at end of file diff --git a/logic/logic.lua b/logic/logic.lua index b081cd4..da926b4 100644 --- a/logic/logic.lua +++ b/logic/logic.lua @@ -1,13 +1,15 @@ local path = logistica.MODPATH .. "/logic" -- once again, order is important -dofile(path .. "/processing_queue.lua") -dofile(path .. "/groups.lua") -dofile(path .. "/network_cache.lua") -dofile(path .. "/network_logic.lua") -dofile(path .. "/network_storage.lua") -dofile(path .. "/controller.lua") -dofile(path .. "/mass_storage.lua") -dofile(path .. "/supplier.lua") -dofile(path .. "/requester.lua") -dofile(path .. "/injector.lua") -dofile(path .. "/item_storage.lua") +dofile(path.."/processing_queue.lua") +dofile(path.."/groups.lua") +dofile(path.."/network_cache.lua") +dofile(path.."/network_logic.lua") +dofile(path.."/network_storage.lua") +dofile(path.."/controller.lua") +dofile(path.."/mass_storage.lua") +dofile(path.."/supplier.lua") +dofile(path.."/requester.lua") +dofile(path.."/injector.lua") +dofile(path.."/item_storage.lua") +dofile(path.."/access_point.lua") +dofile(path.."/access_point_formspec.lua") diff --git a/logic/network_logic.lua b/logic/network_logic.lua index 2ef8fee..fbbc659 100644 --- a/logic/network_logic.lua +++ b/logic/network_logic.lua @@ -1,5 +1,5 @@ local networks = {} -local HARD_NETWORK_NODE_LIMIT = 1000 -- A network cannot consist of more than this many nodes +local HARD_NETWORK_NODE_LIMIT = 4000 -- A network cannot consist of more than this many nodes local STATUS_OK = 0 local CREATE_NETWORK_STATUS_FAIL_OTHER_NETWORK = -1 local CREATE_NETWORK_STATUS_TOO_MANY_NODES = -2 @@ -10,12 +10,8 @@ local p2h = minetest.hash_node_position local h2p = minetest.get_position_from_hash local adjecent = { - vector.new( 1, 0, 0), - vector.new( 0, 1, 0), - vector.new( 0, 0, 1), - vector.new(-1, 0, 0), - vector.new( 0, -1, 0), - vector.new( 0, 0, -1), + vector.new( 1, 0, 0), vector.new( 0, 1, 0), vector.new( 0, 0, 1), + vector.new(-1, 0, 0), vector.new( 0, -1, 0), vector.new( 0, 0, -1), } local function has_machine(network, id) @@ -25,6 +21,7 @@ local function has_machine(network, id) or network.mass_storage[id] or network.item_storage[id] or network.injectors[id] + or network.misc[id] then return true else @@ -192,10 +189,10 @@ local function create_network(controllerPosition, oldNetworkName) network.suppliers = {} network.mass_storage = {} network.item_storage = {} + network.misc = {} network.storage_cache = {} network.supplier_cache = {} network.requester_cache = {} - network.misc = {} local startPos = {} startPos[controllerHash] = true local status = recursive_scan_for_nodes_for_controller(network, startPos) @@ -280,6 +277,15 @@ local function remove_from_network(pos, ops) ops.get_list(network)[hash] = nil end +local function on_node_change(pos, oldNode, ops) + local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one + if placed == true then + try_to_add_to_network(pos, ops) + else + remove_from_network(pos, ops) + end +end + local MASS_STORAGE_OPS = { get_list = function(network) return network.mass_storage end, update_cache_node_added = function(pos) logistica.update_cache_at_pos(pos, LOG_CACHE_MASS_STORAGE) end, @@ -304,13 +310,18 @@ local INJECTOR_OPS = { update_cache_node_removed = function(_) end, } - local ITEM_STORAGE_OPS = { get_list = function(network) return network.item_storage end, update_cache_node_added = function(_) end, update_cache_node_removed = function(_) end, } +local ACCESS_POINT_OPS = { + get_list = function(network) return network.misc end, + update_cache_node_added = function(_) end, + update_cache_node_removed = function(_) end, +} + local function cable_can_extend_network_from(pos) local node = minetest.get_node_or_nil(pos) if not node then return false end @@ -379,46 +390,25 @@ function logistica.on_controller_change(pos, oldNode) end function logistica.on_mass_storage_change(pos, oldNode) - local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one - if placed == true then - try_to_add_to_network(pos, MASS_STORAGE_OPS) - else - remove_from_network(pos, MASS_STORAGE_OPS) - end + on_node_change(pos, oldNode, MASS_STORAGE_OPS) end function logistica.on_requester_change(pos, oldNode) - local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one - if placed == true then - try_to_add_to_network(pos, REQUESTER_OPS) - else - remove_from_network(pos, REQUESTER_OPS) - end + on_node_change(pos, oldNode, REQUESTER_OPS) end function logistica.on_supplier_change(pos, oldNode) - local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one - if placed == true then - try_to_add_to_network(pos, SUPPLIER_OPS) - else - remove_from_network(pos, SUPPLIER_OPS) - end + on_node_change(pos, oldNode, SUPPLIER_OPS) end function logistica.on_injector_change(pos, oldNode) - local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one - if placed == true then - try_to_add_to_network(pos, INJECTOR_OPS) - else - remove_from_network(pos, INJECTOR_OPS) - end + on_node_change(pos, oldNode, INJECTOR_OPS) end function logistica.on_item_storage_change(pos, oldNode) - local placed = (oldNode == nil) -- if oldNode is nil, we placed a new one - if placed == true then - try_to_add_to_network(pos, ITEM_STORAGE_OPS) - else - remove_from_network(pos, ITEM_STORAGE_OPS) - end + on_node_change(pos, oldNode, ITEM_STORAGE_OPS) +end + +function logistica.on_access_point_change(pos, oldNode) + on_node_change(pos, oldNode, ACCESS_POINT_OPS) end diff --git a/logic/network_storage.lua b/logic/network_storage.lua index 3e0c3e0..68b61c8 100644 --- a/logic/network_storage.lua +++ b/logic/network_storage.lua @@ -18,15 +18,17 @@ end -- calls the collectorFunc with the stack - collectorFunc needs to return how many were left-over
-- `collectorFunc = function(stackToInsert)`
-- note that it may be called multiple times as the itemstack is gathered from mass storage -function logistica.take_stack_from_network(stackToTake, network, collectorFunc, isAutomatedRequest) +-- `isAutomatedRequest` is optional, assumed to be false if not set +-- `useMetaData` is optional, assume false if not set - only applies to items with stack_max = 1 +function logistica.take_stack_from_network(stackToTake, network, collectorFunc, isAutomatedRequest, useMetadata) if not network then return false end -- first check suppliers - if logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc, isAutomatedRequest) then + if logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc, isAutomatedRequest, useMetadata) then return end -- then check storages if stackToTake:get_stack_max() <= 1 then - logistica.take_stack_from_item_storage(stackToTake, network, collectorFunc, isAutomatedRequest) + logistica.take_stack_from_item_storage(stackToTake, network, collectorFunc, isAutomatedRequest, useMetadata) else logistica.take_stack_from_mass_storage(stackToTake, network, collectorFunc, isAutomatedRequest) end @@ -35,7 +37,9 @@ end -- tries to take the given stack from the passive suppliers on the network -- calls the collectorFunc with the stack when necessary -- note that it may be called multiple times as the itemstack is gathered from mass storage -function logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc, isAutomatedRequest) +function logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc, isAutomatedRequest, useMetadata) + local eq = function(s1, s2) return s1:get_name() == s2:get_name() end + if stackToTake:get_stack_max() == 1 and useMetadata then eq = function(s1, s2) return s1:equals(s2) end end local requestedAmount = stackToTake:get_count() local remaining = requestedAmount local stackName = stackToTake:get_name() @@ -46,7 +50,7 @@ function logistica.take_stack_from_suppliers(stackToTake, network, collectorFunc local supplierInv = get_meta(supplierPos):get_inventory() local supplyList = supplierInv:get_list(SUPPLIER_LIST_NAME) for i, supplyStack in ipairs(supplyList) do - if supplyStack:get_name() == stackName then + if eq(supplyStack, stackToTake) then table.insert(modifiedPos, supplierPos) local supplyCount = supplyStack:get_count() if supplyCount >= remaining then -- enough to fulfil requested @@ -82,15 +86,17 @@ end -- calls the collectorFunc with the stack - collectorFunc needs to return how many were left-over
-- `collectorFunc = function(stackToInsert)`
-- returns true if item successfully found and given to collector, false otherwise -function logistica.take_stack_from_item_storage(stack, network, collectorFunc, isAutomatedRequest) - local stackName = stack:get_name() +function logistica.take_stack_from_item_storage(stack, network, collectorFunc, isAutomatedRequest, useMetadata) + local eq = function(s1, s2) return s1:get_name() == s2:get_name() end + if useMetadata then eq = function(s1, s2) return s1:equals(s2) end end + for storageHash, _ in pairs(network.item_storage) do local storagePos = minetest.get_position_from_hash(storageHash) local storageInv = get_meta(storagePos):get_inventory() if logistica.is_machine_on(storagePos) then local storageList = storageInv:get_list(ITEM_STORAGE_LIST_NAME) or {} for i, storedStack in ipairs(storageList) do - if storedStack:get_name() == stackName then + if (not storedStack:is_empty()) and eq(storedStack, stack) then local leftover = collectorFunc(storedStack) if leftover == 0 then -- stack max is 1, so just take the whole itemstack out storageList[i] = ItemStack("") diff --git a/textures/logistica_access_point_back.png b/textures/logistica_access_point_back.png new file mode 100644 index 0000000..2207c34 Binary files /dev/null and b/textures/logistica_access_point_back.png differ diff --git a/textures/logistica_access_point_bottom.png b/textures/logistica_access_point_bottom.png new file mode 100644 index 0000000..5582058 Binary files /dev/null and b/textures/logistica_access_point_bottom.png differ diff --git a/textures/logistica_access_point_front.png b/textures/logistica_access_point_front.png new file mode 100644 index 0000000..29fd810 Binary files /dev/null and b/textures/logistica_access_point_front.png differ diff --git a/textures/logistica_access_point_side.png b/textures/logistica_access_point_side.png new file mode 100644 index 0000000..a4d67fe Binary files /dev/null and b/textures/logistica_access_point_side.png differ diff --git a/textures/logistica_access_point_top.png b/textures/logistica_access_point_top.png new file mode 100644 index 0000000..8d998fa Binary files /dev/null and b/textures/logistica_access_point_top.png differ diff --git a/textures/logistica_blank.png b/textures/logistica_blank.png new file mode 100644 index 0000000..8901855 Binary files /dev/null and b/textures/logistica_blank.png differ diff --git a/textures/logistica_icon_all.png b/textures/logistica_icon_all.png new file mode 100644 index 0000000..a34bf14 Binary files /dev/null and b/textures/logistica_icon_all.png differ diff --git a/textures/logistica_icon_cancel.png b/textures/logistica_icon_cancel.png new file mode 100644 index 0000000..71186cd Binary files /dev/null and b/textures/logistica_icon_cancel.png differ diff --git a/textures/logistica_icon_craftitem.png b/textures/logistica_icon_craftitem.png new file mode 100644 index 0000000..dd01b70 Binary files /dev/null and b/textures/logistica_icon_craftitem.png differ diff --git a/textures/logistica_icon_first.png b/textures/logistica_icon_first.png new file mode 100644 index 0000000..67b671a Binary files /dev/null and b/textures/logistica_icon_first.png differ diff --git a/textures/logistica_icon_highlight.png b/textures/logistica_icon_highlight.png new file mode 100644 index 0000000..a5b01ca Binary files /dev/null and b/textures/logistica_icon_highlight.png differ diff --git a/textures/logistica_icon_last.png b/textures/logistica_icon_last.png new file mode 100644 index 0000000..d369a9b Binary files /dev/null and b/textures/logistica_icon_last.png differ diff --git a/textures/logistica_icon_next.png b/textures/logistica_icon_next.png new file mode 100644 index 0000000..04f6382 Binary files /dev/null and b/textures/logistica_icon_next.png differ diff --git a/textures/logistica_icon_node.png b/textures/logistica_icon_node.png new file mode 100644 index 0000000..cc2e750 Binary files /dev/null and b/textures/logistica_icon_node.png differ diff --git a/textures/logistica_icon_prev.png b/textures/logistica_icon_prev.png new file mode 100644 index 0000000..7f9bd8f Binary files /dev/null and b/textures/logistica_icon_prev.png differ diff --git a/textures/logistica_icon_search.png b/textures/logistica_icon_search.png new file mode 100644 index 0000000..a716fb8 Binary files /dev/null and b/textures/logistica_icon_search.png differ diff --git a/textures/logistica_icon_sort_count_99_1.png b/textures/logistica_icon_sort_count_99_1.png new file mode 100644 index 0000000..2f6d585 Binary files /dev/null and b/textures/logistica_icon_sort_count_99_1.png differ diff --git a/textures/logistica_icon_sort_mod_az.png b/textures/logistica_icon_sort_mod_az.png new file mode 100644 index 0000000..a355b0a Binary files /dev/null and b/textures/logistica_icon_sort_mod_az.png differ diff --git a/textures/logistica_icon_sort_name_az.png b/textures/logistica_icon_sort_name_az.png new file mode 100644 index 0000000..a0fbfb1 Binary files /dev/null and b/textures/logistica_icon_sort_name_az.png differ diff --git a/textures/logistica_icon_sort_wear_0_100.png b/textures/logistica_icon_sort_wear_0_100.png new file mode 100644 index 0000000..4ee51ea Binary files /dev/null and b/textures/logistica_icon_sort_wear_0_100.png differ diff --git a/textures/logistica_icon_tool.png b/textures/logistica_icon_tool.png new file mode 100644 index 0000000..ef4b9a3 Binary files /dev/null and b/textures/logistica_icon_tool.png differ diff --git a/textures/logistica_icon_torch.png b/textures/logistica_icon_torch.png new file mode 100644 index 0000000..74e3f02 Binary files /dev/null and b/textures/logistica_icon_torch.png differ diff --git a/util/common.lua b/util/common.lua index 22000f9..aa19af4 100644 --- a/util/common.lua +++ b/util/common.lua @@ -20,12 +20,14 @@ end -- global namespaced functions ---------------------------------------------------------------- +-- Loads and returns the given position, or nil if its outisde the current bounds function logistica.load_position(pos) if pos.x < -30912 or pos.y < -30912 or pos.z < -30912 or pos.x > 30927 or pos.y > 30927 or pos.z > 30927 then return end - if minetest.get_node_or_nil(pos) then return end + if minetest.get_node_or_nil(pos) then return pos end local vm = minetest.get_voxel_manip() vm:read_from_map(pos, pos) + return pos end function logistica.swap_node(pos, newName) diff --git a/util/inv_list_filtering.lua b/util/inv_list_filtering.lua new file mode 100644 index 0000000..da63f2d --- /dev/null +++ b/util/inv_list_filtering.lua @@ -0,0 +1,63 @@ + +local lights_map = {} + +-- all these get initialized after loadtime + +LOG_FILTER_NODE = function(_) return true end +LOG_FILTER_CRAFTITEM = function(_) return true end +LOG_FILTER_TOOL = function(_) return true end +LOG_FILTER_LIGHT = function(_) return true end + +local function load_lights() + for name, def in pairs(minetest.registered_items) do + if def.light_source and def.light_source > 0 then + lights_map[name] = true + end + end +end + +local function create_filter(lookupTable) + return function(name) + return lookupTable[name] ~= nil + end +end + +local function load_filters() + LOG_FILTER_NODE = create_filter(minetest.registered_nodes) + LOG_FILTER_CRAFTITEM = create_filter(minetest.registered_craftitems) + LOG_FILTER_TOOL = create_filter(minetest.registered_tools) + LOG_FILTER_LIGHT = create_filter(lights_map) +end + +local function do_filter(stackList, filterMethod) + local res = {} + local idx = 1 + for _, stack in ipairs(stackList) do + if filterMethod(stack:get_name()) then + res[idx] = stack + idx = idx + 1 + end + end + return res +end + +-------------------------------- +-- public funcs +-------------------------------- + +-- returns a new list that cotains only matching items +-- or return just the same list immediately for convenience if `filterMethod` is nil +-- filterMethod should be one of LOG_FILTER_NODE, LOG_FILTER_CRAFTITEM, LOG_FILTER_TOOL, LOG_FILTER_LIGHT +function logistica.filter_list_by(stackList, filterMethod) + if not filterMethod then return stackList end + return do_filter(stackList, filterMethod) +end + +-------------------------------- +-- registration +-------------------------------- + +minetest.register_on_mods_loaded(function() + load_lights() + load_filters() +end) diff --git a/util/inv_list_sorting.lua b/util/inv_list_sorting.lua index 2abf826..bc63f79 100644 --- a/util/inv_list_sorting.lua +++ b/util/inv_list_sorting.lua @@ -5,7 +5,7 @@ local LANG_EN = "en" -------------------------------- local function get_description(st) return minetest.get_translated_string(LANG_EN, st:get_short_description()) end -local function get_name(st) d.log(st:get_name()) ; return st:get_name() end +local function get_name(st) return st:get_name() end local function get_stack_size(st) return st:get_count() end local function get_wear(st) return st:get_wear() end diff --git a/util/util.lua b/util/util.lua index 7649328..7388c62 100644 --- a/util/util.lua +++ b/util/util.lua @@ -7,6 +7,7 @@ dofile(path.."/ui_logic.lua") dofile(path.."/ui.lua") dofile(path.."/sound.lua") dofile(path.."/inv_list_sorting.lua") +dofile(path.."/inv_list_filtering.lua") -- bad debug d = {}