From e7d03626b4f997f1cdf387d4dfb185e0135fcb4b Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sun, 24 Dec 2023 12:18:40 +0100 Subject: [PATCH 01/10] Categories: fix error caused by inexistent ore names --- default-categories.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/default-categories.lua b/default-categories.lua index 57d3e88..cf39200 100644 --- a/default-categories.lua +++ b/default-categories.lua @@ -44,7 +44,10 @@ if unified_inventory.automatic_categorization then -- Add minable ores to minerals and everything else (pockets of stone & sand variations) to environment for _,item in pairs(minetest.registered_ores) do if item.ore_type == "scatter" then - local drop = minetest.registered_nodes[item.ore].drop + -- The NodeResolver is run *after* minetest.register_on_mods_loaded, thus the + -- existence of ore names were yet not checked or enforced. + local def = minetest.registered_nodes[item.ore] or {} + local drop = def.drop if drop and drop ~= "" then unified_inventory.add_category_item('minerals', item.ore) unified_inventory.add_category_item('minerals', drop) From eb3bb03ebf52dca9b2203faed5902f339b83d509 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sat, 6 Jan 2024 12:35:54 +0100 Subject: [PATCH 02/10] Option to hide uncraftable items (#240) This setting only applies to non-creative players. --- api.lua | 1 + init.lua | 3 ++- internal.lua | 41 ++++++++++++++++++++++++++--------------- settingtypes.txt | 4 ++++ 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/api.lua b/api.lua index 1c756d9..f2f40c2 100644 --- a/api.lua +++ b/api.lua @@ -51,6 +51,7 @@ minetest.after(0.01, function() end end end + table.sort(ui.items_list) ui.items_list_size = #ui.items_list print("Unified Inventory. Inventory size: "..ui.items_list_size) diff --git a/init.lua b/init.lua index 35a2e83..9c8ec35 100644 --- a/init.lua +++ b/init.lua @@ -53,8 +53,9 @@ unified_inventory = { standard_background = "bgcolor[#0000]background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]", hide_disabled_buttons = minetest.settings:get_bool("unified_inventory_hide_disabled_buttons", false), + hide_uncraftable_items = minetest.settings:get_bool("unified_inventory_hide_uncraftable_items", false), - version = 4 + version = 5 } local ui = unified_inventory diff --git a/internal.lua b/internal.lua index 0903d86..daa3ba1 100644 --- a/internal.lua +++ b/internal.lua @@ -270,8 +270,8 @@ local function formspec_add_item_browser(player, formspec, ui_peruser) button_name, minetest.formspec_escape(tooltip) ) n = n + 2 - list_index = list_index + 1 end + list_index = list_index + 1 end end formspec[n] = "style[page_number;content_offset=0]" @@ -349,12 +349,25 @@ function ui.apply_filter(player, filter, search_dir) end local player_name = player:get_player_name() + -- Whether to show uncraftable items + local fprefilter = function(_) + return true + end + if ui.hide_uncraftable_items and not ui.is_creative(player_name) then + fprefilter = function(name) + return ui.get_recipe_list(name) + end + end + + local registered_items = minetest.registered_items local lfilter = string.lower(filter) local ffilter + if lfilter:sub(1, 6) == "group:" then -- Group filter: all groups of the item must match local groups = lfilter:sub(7):split(",") - ffilter = function(name, def) + ffilter = function(name) + local def = registered_items[name] for _, group in ipairs(groups) do if not def.groups[group] or def.groups[group] <= 0 then @@ -368,7 +381,8 @@ function ui.apply_filter(player, filter, search_dir) local player_info = minetest.get_player_information(player_name) local lang = player_info and player_info.lang_code or "" - ffilter = function(name, def) + ffilter = function(name) + local def = registered_items[name] local lname = string.lower(name) local ldesc = string.lower(def.description) local llocaldesc = minetest.get_translated_string @@ -378,32 +392,29 @@ function ui.apply_filter(player, filter, search_dir) end end - local is_itemdef_listable = ui.is_itemdef_listable local filtered_items = {} local category = ui.current_category[player_name] or 'all' if category == 'all' then - for name, def in pairs(minetest.registered_items) do - if is_itemdef_listable(def) - and ffilter(name, def) then + for _, name in ipairs(ui.items_list) do + if fprefilter(name) and ffilter(name) then table.insert(filtered_items, name) end end elseif category == 'uncategorized' then - for name, def in pairs(minetest.registered_items) do - if is_itemdef_listable(def) - and not ui.find_category(name) - and ffilter(name, def) then + for _, name in ipairs(ui.items_list) do + if not ui.find_category(name) + and fprefilter(name) + and ffilter(name) then table.insert(filtered_items, name) end end else -- Any other category is selected for name, exists in pairs(ui.registered_category_items[category]) do - local def = minetest.registered_items[name] - if exists and def - and is_itemdef_listable(def) - and ffilter(name, def) then + if exists + and fprefilter(name) + and ffilter(name) then table.insert(filtered_items, name) end end diff --git a/settingtypes.txt b/settingtypes.txt index 4fabbe5..6f04aea 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -16,6 +16,10 @@ unified_inventory_waypoints (Enable waypoints) bool true # If enabled, disabled buttons will be hidden instead of grayed out. unified_inventory_hide_disabled_buttons (Hide disabled buttons) bool false +# Hides items with no known craft recipe from the category "all" (default). +# This setting has no effect on players in creative mode. +unified_inventory_hide_uncraftable_items (Hide uncraftable items) bool false + # Automatically categorizes registered items based on their # groups. This is based on a fuzzy match, thus is not 100% accurate. unified_inventory_automatic_categorization (Categories: add items automatically) bool true From 004a39aaf771aa94bfbcdd0834d61134d49249c7 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sat, 13 Jan 2024 10:40:25 +0100 Subject: [PATCH 03/10] Categories: Improve automatic ore categorization This function is now executed after registering all recipes within unified_inventory to properly register all item drops as ores. --- category.lua | 5 ++ default-categories.lua | 145 ++++++++++++++++++++--------------------- register.lua | 2 +- 3 files changed, 77 insertions(+), 75 deletions(-) diff --git a/category.lua b/category.lua index 46b3e02..f32a947 100644 --- a/category.lua +++ b/category.lua @@ -115,6 +115,11 @@ function unified_inventory.set_category_index(category_name, index) update_category_list() end function unified_inventory.add_category_item(category_name, item) + if type(item) ~= "string" then + minetest.log("warning", "[unified_inventory] Cannot register category item: " .. dump(item)) + return + end + ensure_category_exists(category_name) unified_inventory.registered_category_items[category_name][item] = true end diff --git a/default-categories.lua b/default-categories.lua index cf39200..1982527 100644 --- a/default-categories.lua +++ b/default-categories.lua @@ -1,4 +1,5 @@ local S = minetest.get_translator("unified_inventory") +local ui = unified_inventory unified_inventory.register_category('plants', { symbol = "flowers:tulip", @@ -25,74 +26,87 @@ unified_inventory.register_category('lighting', { label = S("Lighting") }) - -if unified_inventory.automatic_categorization then - minetest.register_on_mods_loaded(function() - - -- Add biome nodes to environment category - for _,def in pairs(minetest.registered_biomes) do - local env_nodes = { - def.node_riverbed, def.node_top, def.node_filler, def.node_dust, - } - for i,node in pairs(env_nodes) do - if node then - unified_inventory.add_category_item('environment', node) - end +local function register_automatic_categorization() + -- Add biome nodes to environment category + for _,def in pairs(minetest.registered_biomes) do + local env_nodes = { + def.node_riverbed, def.node_top, def.node_filler, def.node_dust, + } + for i,node in pairs(env_nodes) do + if node then + unified_inventory.add_category_item('environment', node) end end + end - -- Add minable ores to minerals and everything else (pockets of stone & sand variations) to environment - for _,item in pairs(minetest.registered_ores) do - if item.ore_type == "scatter" then - -- The NodeResolver is run *after* minetest.register_on_mods_loaded, thus the - -- existence of ore names were yet not checked or enforced. - local def = minetest.registered_nodes[item.ore] or {} - local drop = def.drop - if drop and drop ~= "" then - unified_inventory.add_category_item('minerals', item.ore) - unified_inventory.add_category_item('minerals', drop) - else - unified_inventory.add_category_item('environment', item.ore) + -- Preparation for ore registration: find all possible drops (digging) + local possible_node_dig_drops = { + -- ["default:stone_with_coal"] = { "default:coal_lump", "mymod:raregem" } + -- Ores may be contained multiple times, depending on drop chances. + } + for itemname, recipes in pairs(ui.crafts_for.usage) do + for _, recipe in ipairs(recipes) do + if recipe.type == "digging" or recipe.type == "digging_chance" then + if not possible_node_dig_drops[itemname] then + possible_node_dig_drops[itemname] = {} end - else - unified_inventory.add_category_item('environment', item.ore) + local stack = ItemStack(recipe.output) + table.insert(possible_node_dig_drops[itemname], stack:get_name()) end end + end - -- Add items by item definition - for name, def in pairs(minetest.registered_items) do - local group = def.groups or {} - if not group.not_in_creative_inventory then - if group.stair or - group.slab or - group.wall or - group.fence then - unified_inventory.add_category_item('building', name) - elseif group.flora or - group.flower or - group.seed or - group.leaves or - group.sapling or - group.tree then - unified_inventory.add_category_item('plants', name) - elseif def.type == 'tool' then - unified_inventory.add_category_item('tools', name) - elseif def.liquidtype == 'source' then - unified_inventory.add_category_item('environment', name) - elseif def.light_source and def.light_source > 0 then - unified_inventory.add_category_item('lighting', name) - elseif group.door or - minetest.global_exists("doors") and ( - doors.registered_doors and doors.registered_doors[name..'_a'] or - doors.registered_trapdoors and doors.registered_trapdoors[name] - ) then - unified_inventory.add_category_item('building', name) - end + -- Add minable ores to minerals and everything else (pockets of stone & sand variations) to environment + for _, odef in pairs(minetest.registered_ores) do + local drops = possible_node_dig_drops[odef.ore] + if drops and odef.ore_type == "scatter" then + ui.add_category_item('minerals', odef.ore) + -- Register all possible drops as "minerals" + ui.add_category_items('minerals', drops) + possible_node_dig_drops[odef.ore] = {} -- mask as handled + else + ui.add_category_item('environment', odef.ore) + end + end + + -- Add items by item definition + for name, def in pairs(minetest.registered_items) do + local group = def.groups or {} + if not group.not_in_creative_inventory then + if group.stair or + group.slab or + group.wall or + group.fence then + unified_inventory.add_category_item('building', name) + elseif group.flora or + group.flower or + group.seed or + group.leaves or + group.sapling or + group.tree then + unified_inventory.add_category_item('plants', name) + elseif def.type == 'tool' then + unified_inventory.add_category_item('tools', name) + elseif def.liquidtype == 'source' then + unified_inventory.add_category_item('environment', name) + elseif def.light_source and def.light_source > 0 then + unified_inventory.add_category_item('lighting', name) + elseif group.door or + minetest.global_exists("doors") and ( + doors.registered_doors and doors.registered_doors[name..'_a'] or + doors.registered_trapdoors and doors.registered_trapdoors[name] + ) then + unified_inventory.add_category_item('building', name) end end - end) + end end +if ui.automatic_categorization then + ui.register_on_initialized(register_automatic_categorization) +end + + -- [[ unified_inventory.add_category_items('plants', { "default:dry_grass_5", @@ -259,23 +273,6 @@ unified_inventory.add_category_items('minerals', { "default:coal_lump", "default:bronzeblock", "default:goldblock", - - "stairs:slab_bronzeblock", - "stairs:slab_copperblock", - "stairs:slab_steelblock", - "stairs:slab_tinblock", - "stairs:stair_bronzeblock", - "stairs:stair_copperblock", - "stairs:stair_inner_bronzeblock", - "stairs:stair_inner_copperblock", - "stairs:stair_inner_steelblock", - "stairs:stair_inner_tinblock", - "stairs:stair_outer_bronzeblock", - "stairs:stair_outer_copperblock", - "stairs:stair_outer_steelblock", - "stairs:stair_outer_tinblock", - "stairs:stair_steelblock", - "stairs:stair_tinblock", }) unified_inventory.add_category_items('building', { diff --git a/register.lua b/register.lua index 225a861..eedccb0 100644 --- a/register.lua +++ b/register.lua @@ -215,7 +215,7 @@ local function stack_image_button(x, y, w, h, buttonname_prefix, item) local group_name = name:sub(7) local group_item = ui.get_group_item(group_name) show_is_group = not group_item.sole - displayitem = group_item.item or "unknown" + displayitem = group_item.item or name selectitem = group_item.sole and displayitem or name end local label = show_is_group and "G" or "" From 921a6d76ee16f3633cf6122800da37776557b20a Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sat, 13 Jan 2024 10:47:05 +0100 Subject: [PATCH 04/10] Add dump function to luacheck --- .luacheckrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.luacheckrc b/.luacheckrc index e6fec97..a951e48 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -10,6 +10,7 @@ read_globals = { string = {fields = {"split", "trim"}}, table = {fields = {"copy", "getn"}}, + "dump", "minetest", "vector", "ItemStack", "datastorage", From b5de18b196c5ae0ba3d679f39af309be3ee64574 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sun, 17 Mar 2024 16:54:21 +0100 Subject: [PATCH 05/10] Categories: remove unknown items after start This avoids runtime errors caused by removed items or such that were not registered at all but listed by default in a pre-defined category. --- api.lua | 21 +++++++++++++++++++++ internal.lua | 8 ++++++++ 2 files changed, 29 insertions(+) diff --git a/api.lua b/api.lua index f2f40c2..7ab5d66 100644 --- a/api.lua +++ b/api.lua @@ -184,6 +184,27 @@ minetest.after(0.01, function() ui.crafts_for.recipe[outputitemname] = new_recipe_list end + -- Remove unknown items from all categories + local total_removed = 0 + for cat_name, cat_def in pairs(ui.registered_category_items) do + for itemname, exists in pairs(cat_def) do + if exists and not minetest.registered_items[itemname] then + total_removed = total_removed + 1 + --[[ + -- For analysis + minetest.log("warning", "[unified_inventory] Removed item '" + .. itemname .. "' from category '" .. cat_name + .. "'. Reason: item not registered") + ]] + cat_def[itemname] = nil + end + end + end + if total_removed > 0 then + minetest.log("info", "[unified_inventory] Removed " .. total_removed .. + " unknown items from the categories.") + end + for _, callback in ipairs(ui.initialized_callbacks) do callback() end diff --git a/internal.lua b/internal.lua index daa3ba1..3caa43a 100644 --- a/internal.lua +++ b/internal.lua @@ -368,6 +368,10 @@ function ui.apply_filter(player, filter, search_dir) local groups = lfilter:sub(7):split(",") ffilter = function(name) local def = registered_items[name] + if not def then + return false + end + for _, group in ipairs(groups) do if not def.groups[group] or def.groups[group] <= 0 then @@ -383,6 +387,10 @@ function ui.apply_filter(player, filter, search_dir) ffilter = function(name) local def = registered_items[name] + if not def then + return false + end + local lname = string.lower(name) local ldesc = string.lower(def.description) local llocaldesc = minetest.get_translated_string From 2c9449b6e796c5a4bcf832b10595c5a78e237dc6 Mon Sep 17 00:00:00 2001 From: Niklp Date: Mon, 18 Mar 2024 15:08:31 +0100 Subject: [PATCH 06/10] Categories: Remove `not_in_creative_inventory` items `unified_inventory.is_itemdef_listable` already prevents such items being listed. They are not needed, thus removing them from the categories in the first place does make sense. Co-authored-by: SmallJoker --- api.lua | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/api.lua b/api.lua index 7ab5d66..604d49e 100644 --- a/api.lua +++ b/api.lua @@ -187,8 +187,9 @@ minetest.after(0.01, function() -- Remove unknown items from all categories local total_removed = 0 for cat_name, cat_def in pairs(ui.registered_category_items) do - for itemname, exists in pairs(cat_def) do - if exists and not minetest.registered_items[itemname] then + for itemname, _ in pairs(cat_def) do + local idef = minetest.registered_items[itemname] + if not idef then total_removed = total_removed + 1 --[[ -- For analysis @@ -197,12 +198,21 @@ minetest.after(0.01, function() .. "'. Reason: item not registered") ]] cat_def[itemname] = nil + elseif not ui.is_itemdef_listable(idef) then + total_removed = total_removed + 1 + --[[ + -- For analysis + minetest.log("warning", "[unified_inventory] Removed item '" + .. itemname .. "' from category '" .. cat_name + .. "'. Reason: item is in 'not_in_creative_inventory' group") + ]] + cat_def[itemname] = nil end end end if total_removed > 0 then minetest.log("info", "[unified_inventory] Removed " .. total_removed .. - " unknown items from the categories.") + " items from the categories.") end for _, callback in ipairs(ui.initialized_callbacks) do From 235fa841dd558be5972e1ffa8bc858478a489bd4 Mon Sep 17 00:00:00 2001 From: Niklp Date: Sat, 29 Jun 2024 16:52:32 +0200 Subject: [PATCH 07/10] Replace deprecated `meta:set_string(*, nil)` call --- bags.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bags.lua b/bags.lua index f6d4da6..8563c2f 100644 --- a/bags.lua +++ b/bags.lua @@ -144,7 +144,7 @@ local function save_bags_metadata(player, bags_inv) end local meta = player:get_meta() if is_empty then - meta:set_string("unified_inventory:bags", nil) + meta:set_string("unified_inventory:bags", "") else meta:set_string("unified_inventory:bags", minetest.serialize(bags)) From 16265dca2dc2133fb9dd8bf31efd78077fa91a3d Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Thu, 18 Jul 2024 20:45:24 +0200 Subject: [PATCH 08/10] Item names: fix HUD deprecation warning --- item_names.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/item_names.lua b/item_names.lua index cb9f2a3..5eb0e40 100644 --- a/item_names.lua +++ b/item_names.lua @@ -18,7 +18,8 @@ local function set_hud(player) item_names[player_name] = { hud = player:hud_add({ - hud_elem_type = "text", + -- TODO: remove compatibility code when 5.8.0 is no longer used + [minetest.features.hud_def_type_field and "type" or "hud_elem_type"] = "text", position = {x=0.5, y=1}, offset = off, alignment = {x=0, y=-1}, From 1547ebcdd4a9fbd4cc62dcfdb1336960a51c6263 Mon Sep 17 00:00:00 2001 From: luk3yx Date: Wed, 14 Aug 2024 06:00:49 +1200 Subject: [PATCH 09/10] Make waypoints usable from lite mode (#251) --- waypoints.lua | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/waypoints.lua b/waypoints.lua index 8dbb175..8fdd801 100644 --- a/waypoints.lua +++ b/waypoints.lua @@ -103,7 +103,7 @@ local function get_waypoint_data(player) end ui.register_page("waypoints", { - get_formspec = function(player) + get_formspec = function(player, perplayer_formspec) local player_name = player:get_player_name() local wp_info_x = ui.style_full.form_header_x + 1.25 local wp_info_y = ui.style_full.form_header_y + 0.5 @@ -115,12 +115,16 @@ ui.register_page("waypoints", { local sel = waypoints.selected or 1 local formspec = { - ui.style_full.standard_inv_bg, string.format("label[%f,%f;%s]", ui.style_full.form_header_x, ui.style_full.form_header_y, F(S("Waypoints"))), "image["..wp_info_x..","..wp_info_y..";1,1;ui_waypoints_icon.png]" } - local n=4 + local n=3 + + if not perplayer_formspec.is_lite_mode then + formspec[n] = ui.style_full.standard_inv_bg + n = n + 1 + end -- Tabs buttons: for i = 1, COUNT do @@ -212,7 +216,10 @@ ui.register_page("waypoints", { formspec[n+2] = string.format("label[%f,%f;%s: %s]", wp_info_x, wp_info_y+2.60, F(S("HUD text color")), hud_colors[waypoint.color or 1][3]) - return {formspec=table.concat(formspec)} + return { + formspec = table.concat(formspec), + draw_inventory = not perplayer_formspec.is_lite_mode, + } end, }) @@ -220,7 +227,6 @@ ui.register_button("waypoints", { type = "image", image = "ui_waypoints_icon.png", tooltip = S("Waypoints"), - hide_lite=true }) local function update_hud(player, waypoints, temp, i) From e071a01372fe9151160af17d7f33c3277e119b5c Mon Sep 17 00:00:00 2001 From: 1F616EMO~nya Date: Sun, 25 Aug 2024 19:36:13 +0800 Subject: [PATCH 10/10] Giveme form: Respect `stack_max` (#250) --- register.lua | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/register.lua b/register.lua index eedccb0..f802a71 100644 --- a/register.lua +++ b/register.lua @@ -298,11 +298,10 @@ ui.register_page("craftguide", { local n = 4 + local item_def = minetest.registered_items[item_name] local item_name_shown - if minetest.registered_items[item_name] - and minetest.registered_items[item_name].description then - item_name_shown = S("@1 (@2)", - minetest.registered_items[item_name].description, item_name) + if item_def and item_def.description then + item_name_shown = S("@1 (@2)", item_def.description, item_name) else item_name_shown = item_name end @@ -327,12 +326,14 @@ ui.register_page("craftguide", { F(role_text[dir]), item_name_shown) n = n + 2 - local giveme_form = table.concat({ - "label[".. (give_x+0.1)..",".. (craftguidey + 2.7) .. ";" .. F(S("Give me:")) .. "]", - "button["..(give_x)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_1;1]", - "button["..(give_x+0.8)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_10;10]", - "button["..(give_x+1.6)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_99;99]" - }) + local giveme_form = + "label[" .. (give_x + 0.1) .. "," .. (craftguidey + 2.7) .. ";" .. F(S("Give me:")) .. "]" .. + "button[" .. (give_x) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_1;1]" + if item_def.type ~= "tool" then + giveme_form = giveme_form .. + "button[" .. (give_x + 0.8) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_10;10]" .. + "button[" .. (give_x + 1.6) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_99;99]" + end if not craft then -- No craft recipes available for this item.