From 897fc3a21de8ced57dee72d722e3d8ee0f4d2464 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 30 Dec 2018 20:25:28 +0100 Subject: [PATCH 001/188] Show usages for fuel-able items with no recipes --- init.lua | 154 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 84 insertions(+), 70 deletions(-) diff --git a/init.lua b/init.lua index f6c7153..8c9af57 100644 --- a/init.lua +++ b/init.lua @@ -83,7 +83,7 @@ local function reset_datas(data) data.item = nil data.pagenum = 1 data.rnum = 1 - data.fuel = nil + data.items = progressive_mode and data.init_filter_items or datas.init_items end local function in_table(T) @@ -166,13 +166,15 @@ local function get_tooltip(item, recipe_type, cooktime, groups) return has_extras and tooltip .. "]" or "" end -local function _get_recipe(iX, iY, xoffset, recipe_num, recipes, show_usage) +local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) local fs, recipes_total = {}, #recipes - if recipes_total > 1 then - fs[#fs + 1] = "button[" .. (iX - (sfinv_only and 2.2 or 2.6)) .. "," .. - (iY + (sfinv_only and 3.9 or 3.3)) .. ";2.2,1;alternate;" .. - (show_usage and S("Usage") or S("Recipe")) .. " " .. - S("@1 of @2", recipe_num, recipes_total) .. "]" + fs[#fs + 1] = "button[" .. (iX - (sfinv_only and 2.2 or 2.6)) .. "," .. + (iY + (sfinv_only and 3.9 or 3.3)) .. ";2.2,1;alternate;" .. + (show_usage and S("Usage") or S("Recipe")) .. " " .. + S("@1 of @2", recipe_num, recipes_total) .. "]" + + if not recipes[1] then + return "" end local recipe_type = recipes[recipe_num].type @@ -226,8 +228,9 @@ local function _get_recipe(iX, iY, xoffset, recipe_num, recipes, show_usage) end local custom_recipe = craftguide.craft_types[recipe_type] - if recipe_type == "cooking" or (recipe_type == "normal" and width == 0) or - custom_recipe then + if recipe_type == "cooking" or custom_recipe or + (recipe_type == "normal" and width == 0) then + local icon = recipe_type == "cooking" and "furnace" or "shapeless" local coords = (rightest + 1.2) .. "," .. (iY + (sfinv_only and 2.2 or 1.7)) .. @@ -242,9 +245,8 @@ local function _get_recipe(iX, iY, xoffset, recipe_num, recipes, show_usage) recipe_type:gsub("^%l", string.upper)) .. "]" end - local output = recipes[recipe_num].output + local output = recipes[recipe_num].output local output_s = output:match("%S+") - local output_is_fuel = get_fueltime(output) > 0 local arrow_X = rightest + (s_btn_size or BUTTON_SIZE) local output_X = arrow_X + 0.9 @@ -253,13 +255,20 @@ local function _get_recipe(iX, iY, xoffset, recipe_num, recipes, show_usage) (iY + (sfinv_only and 2.85 or 2.35)) .. ";0.9,0.7;craftguide_arrow.png]" - fs[#fs + 1] = "item_image_button[" .. output_X .. "," .. - (iY + (sfinv_only and 2.7 or 2.2)) .. ";" .. - BUTTON_SIZE .. "," .. BUTTON_SIZE .. ";" .. - output .. ";" .. output_s .. ";]" + if output == "BURN" then + fs[#fs + 1] = "image[" .. output_X .. "," .. + (iY + (sfinv_only and 2.68 or 2.18)) .. + ";1.1,1.1;craftguide_fire.png]" + else + fs[#fs + 1] = "item_image_button[" .. output_X .. "," .. + (iY + (sfinv_only and 2.7 or 2.2)) .. ";" .. + BUTTON_SIZE .. "," .. BUTTON_SIZE .. ";" .. + output .. ";" .. output_s .. ";]" + end fs[#fs + 1] = get_tooltip(output_s) + local output_is_fuel = get_fueltime(output) > 0 if output_is_fuel then fs[#fs + 1] = "image[" .. (output_X + 1) .. "," .. (iY + (sfinv_only and 2.83 or 2.33)) .. @@ -336,32 +345,13 @@ local function get_formspec(player_name) end if data.item and reg_items[data.item] then - if not data.recipes_item or (data.fuel and not get_recipe(data.item).items) then - local X = floor(xoffset) - (sfinv_only and 0 or 0.2) - - fs[#fs + 1] = "item_image_button[" .. X .. "," .. - (iY + (sfinv_only and 2.7 or 2.2)) .. - ";" .. BUTTON_SIZE .. "," .. BUTTON_SIZE .. - ";" .. data.item .. ";" .. data.item .. ";]" - - fs[#fs + 1] = "image[" .. (X + 1.1) .. "," .. - (iY + (sfinv_only and 2.85 or 2.35)) .. - ";0.9,0.7;craftguide_arrow.png]" - - fs[#fs + 1] = get_tooltip(data.item) - - fs[#fs + 1] = "image[" .. (X + 2.1) .. "," .. - (iY + (sfinv_only and 2.68 or 2.18)) .. - ";1.1,1.1;craftguide_fire.png]" - else - local usage = data.show_usage - fs[#fs + 1] = _get_recipe(data.iX, - iY, - xoffset, - data.rnum, - (usage and data.usages or data.recipes_item), - usage) - end + local usage = data.show_usage + fs[#fs + 1] = get_recipe_fs(data.iX, + iY, + xoffset, + data.rnum, + (usage and data.usages or data.recipes_item), + usage) end fs = concat(fs) @@ -568,7 +558,6 @@ local function get_fields(player, ...) if fields.clear then reset_datas(data) - data.items = progressive_mode and data.init_filter_items or datas.init_items show_fs(player, player_name) elseif fields.alternate then @@ -591,7 +580,6 @@ local function get_fields(player, ...) elseif fields.prev or fields.next then data.pagenum = data.pagenum - (fields.prev and 1 or -1) - if data.pagenum > data.pagemax then data.pagenum = 1 elseif data.pagenum == 0 then @@ -617,32 +605,44 @@ local function get_fields(player, ...) local is_fuel = get_fueltime(item) > 0 local recipes = get_recipes(item) or {} recipes = add_custom_recipes(item, recipes) - if not next(recipes) and not is_fuel then return end - if not data.show_usage and item == data.item and not progressive_mode then + local no_recipes = not next(recipes) + if no_recipes and not is_fuel then return end + + if item ~= data.item then + data.show_usage = nil + end + + if not progressive_mode and (is_fuel and no_recipes) or + (not data.show_usage and item == data.item) then data.usages = get_item_usages(item) + + if is_fuel then + data.usages[#data.usages + 1] = { + width = 1, + type = "normal", + items = {item}, + output = "BURN", + } + end + if next(data.usages) then data.show_usage = true - data.rnum = 1 end - show_fs(player, player_name) - else - if progressive_mode then - local inv = player:get_inventory() - local has_item - recipes, has_item = recipe_in_inv(inv, item, recipes) - if not has_item then return end - end - - data.item = item - data.recipes_item = recipes - data.rnum = 1 - data.show_usage = nil - data.fuel = is_fuel - - show_fs(player, player_name) + elseif progressive_mode then + local inv = player:get_inventory() + local has_item + recipes, has_item = recipe_in_inv(inv, item, recipes) + if not has_item then return end end + + data.item = item + data.recipes_item = recipes + data.rnum = 1 + data.show_usage = data.show_usage + + show_fs(player, player_name) end end end @@ -784,25 +784,39 @@ if not progressive_mode then init_datas(player, name) end - local data = datas[name] + local data = datas[name] + reset_datas(data) + local is_fuel = get_fueltime(node_name) > 0 local recipes = get_recipes(node_name) or {} recipes = add_custom_recipes(node_name, recipes) + local no_recipes = not next(recipes) - if not next(recipes) and not is_fuel then + if no_recipes and not is_fuel then return false, colorize("[craftguide] ") .. S("No recipe for this node:") .. " " .. colorize(node_name) end - data.show_usage = nil - data.filter = "" + if is_fuel and no_recipes then + data.usages = get_item_usages(node_name) + if is_fuel then + data.usages[#data.usages + 1] = { + width = 1, + type = "normal", + items = {node_name}, + output = "BURN", + } + end + + if next(data.usages) then + data.show_usage = true + end + end + + data.show_usage = data.show_usage data.item = node_name - data.pagenum = 1 - data.rnum = 1 data.recipes_item = recipes - data.items = datas.init_items - data.fuel = is_fuel return true, show_fs(player, name) end, From 65b51ad3e557f83dd41151906b081d6509586df4 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 30 Dec 2018 21:00:04 +0100 Subject: [PATCH 002/188] Do not alternate if X > 1 --- init.lua | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/init.lua b/init.lua index 8c9af57..c961a66 100644 --- a/init.lua +++ b/init.lua @@ -43,7 +43,10 @@ local group_stereotypes = { } local function extract_groups(str) - if str:sub(1,6) ~= "group:" then return end + if str:sub(1,6) ~= "group:" then + return + end + return str:sub(7):split(",") end @@ -552,7 +555,10 @@ local function get_fields(player, ...) formname, fields = args[1], args[2] end - if not sfinv_only and formname ~= "craftguide" then return end + if not sfinv_only and formname ~= "craftguide" then + return + end + local player_name = player:get_player_name() local data = datas[player_name] @@ -561,14 +567,18 @@ local function get_fields(player, ...) show_fs(player, player_name) elseif fields.alternate then - local num - if data.show_usage then - num = data.usages[data.rnum + 1] - else - num = data.recipes_item[data.rnum + 1] + if (data.usages and #data.usages == 1) or #data.recipes_item == 1 then + return end - data.rnum = num and data.rnum + 1 or 1 + local next_i + if data.show_usage then + next_i = data.usages[data.rnum + 1] + else + next_i = data.recipes_item[data.rnum + 1] + end + + data.rnum = next_i and data.rnum + 1 or 1 show_fs(player, player_name) elseif (fields.key_enter_field == "filter" or fields.search) and @@ -607,7 +617,9 @@ local function get_fields(player, ...) recipes = add_custom_recipes(item, recipes) local no_recipes = not next(recipes) - if no_recipes and not is_fuel then return end + if no_recipes and not is_fuel then + return + end if item ~= data.item then data.show_usage = nil @@ -634,7 +646,10 @@ local function get_fields(player, ...) local inv = player:get_inventory() local has_item recipes, has_item = recipe_in_inv(inv, item, recipes) - if not has_item then return end + + if not has_item then + return + end end data.item = item From 7745ccd863ddab8986f1fa6e08204168aab3f1f0 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 30 Dec 2018 21:10:39 +0100 Subject: [PATCH 003/188] Not really important --- init.lua | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/init.lua b/init.lua index c961a66..67500ae 100644 --- a/init.lua +++ b/init.lua @@ -72,8 +72,14 @@ craftguide.register_craft({ items = {"default:stone"}, }) -local function colorize(str) - return mt.colorize("#FFFF00", str) +local color_codes = { + red = "#FF0000", + yellow = "#FFFF00", +} + +local function colorize(str, color) + color = color or "yellow" + return mt.colorize(color_codes[color], str) end local function get_fueltime(item) @@ -794,7 +800,7 @@ if not progressive_mode then end if not node_name then - return false, colorize("[craftguide] ") .. S("No node pointed") + return false, colorize("[craftguide] ", "red") .. S("No node pointed") elseif not datas[name] then init_datas(player, name) end @@ -808,7 +814,7 @@ if not progressive_mode then local no_recipes = not next(recipes) if no_recipes and not is_fuel then - return false, colorize("[craftguide] ") .. + return false, colorize("[craftguide] ", "red") .. S("No recipe for this node:") .. " " .. colorize(node_name) end From 4b97b08aa7f47f4bebd3c23d50c1c7b7cf299462 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 30 Dec 2018 21:17:21 +0100 Subject: [PATCH 004/188] Variable naming --- init.lua | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/init.lua b/init.lua index 67500ae..5efc1f3 100644 --- a/init.lua +++ b/init.lua @@ -89,7 +89,7 @@ end local function reset_datas(data) data.show_usage = nil data.filter = "" - data.item = nil + data.input = nil data.pagenum = 1 data.rnum = 1 data.items = progressive_mode and data.init_filter_items or datas.init_items @@ -176,16 +176,17 @@ local function get_tooltip(item, recipe_type, cooktime, groups) end local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) - local fs, recipes_total = {}, #recipes - fs[#fs + 1] = "button[" .. (iX - (sfinv_only and 2.2 or 2.6)) .. "," .. - (iY + (sfinv_only and 3.9 or 3.3)) .. ";2.2,1;alternate;" .. - (show_usage and S("Usage") or S("Recipe")) .. " " .. - S("@1 of @2", recipe_num, recipes_total) .. "]" - if not recipes[1] then return "" end + local fs = {} + + fs[#fs + 1] = "button[" .. (iX - (sfinv_only and 2.2 or 2.6)) .. "," .. + (iY + (sfinv_only and 3.9 or 3.3)) .. ";2.2,1;alternate;" .. + (show_usage and S("Usage") or S("Recipe")) .. " " .. + S("@1 of @2", recipe_num, #recipes) .. "]" + local recipe_type = recipes[recipe_num].type local items = recipes[recipe_num].items local width = recipes[recipe_num].width @@ -343,7 +344,10 @@ local function get_formspec(player_name) local first_item = (data.pagenum - 1) * ipp for i = first_item, first_item + ipp - 1 do local name = data.items[i + 1] - if not name then break end + if not name then + break + end + local X = i % data.iX local Y = (i % ipp - X) / data.iX + 1 @@ -353,7 +357,7 @@ local function get_formspec(player_name) name .. ";" .. name .. "_inv;]" end - if data.item and reg_items[data.item] then + if data.input and reg_items[data.input] then local usage = data.show_usage fs[#fs + 1] = get_recipe_fs(data.iX, iY, @@ -627,12 +631,12 @@ local function get_fields(player, ...) return end - if item ~= data.item then + if item ~= data.input then data.show_usage = nil end if not progressive_mode and (is_fuel and no_recipes) or - (not data.show_usage and item == data.item) then + (not data.show_usage and item == data.input) then data.usages = get_item_usages(item) if is_fuel then @@ -658,7 +662,7 @@ local function get_fields(player, ...) end end - data.item = item + data.input = item data.recipes_item = recipes data.rnum = 1 data.show_usage = data.show_usage @@ -836,7 +840,7 @@ if not progressive_mode then end data.show_usage = data.show_usage - data.item = node_name + data.input = node_name data.recipes_item = recipes return true, show_fs(player, name) From 4bca02f0dbaa63eb0f87795786c2287931d6fc73 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 30 Dec 2018 21:32:36 +0100 Subject: [PATCH 005/188] Add assertions --- init.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/init.lua b/init.lua index 5efc1f3..a3d3fc8 100644 --- a/init.lua +++ b/init.lua @@ -50,7 +50,16 @@ local function extract_groups(str) return str:sub(7):split(",") end +local function __func() + return debug.getinfo(2, "n").name +end + function craftguide.register_craft_type(name, def) + local func = "craftguide." .. __func() .. "(): " + assert(name, func .. "'name' field missing") + assert(def.description, func .. "'description' field missing") + assert(def.icon, func .. "'icon' field missing") + if not craftguide.craft_types[name] then craftguide.craft_types[name] = def end @@ -62,6 +71,12 @@ craftguide.register_craft_type("digging", { }) function craftguide.register_craft(def) + local func = "craftguide." .. __func() .. "(): " + assert(def.type, func .. "'type' field missing") + assert(def.width, func .. "'width' field missing") + assert(def.output, func .. "'output' field missing") + assert(def.items, func .. "'items' field missing") + craftguide.custom_crafts[#craftguide.custom_crafts + 1] = def end From 1034fd7c0e09214a5b98afd222b504f9ff030038 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 2 Jan 2019 00:35:21 -0500 Subject: [PATCH 006/188] Fix repeated clicks of same item not toggling usages mode --- init.lua | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/init.lua b/init.lua index a3d3fc8..654f609 100644 --- a/init.lua +++ b/init.lua @@ -102,7 +102,7 @@ local function get_fueltime(item) end local function reset_datas(data) - data.show_usage = nil + data.show_usage = false data.filter = "" data.input = nil data.pagenum = 1 @@ -647,11 +647,16 @@ local function get_fields(player, ...) end if item ~= data.input then - data.show_usage = nil + data.show_usage = false + else + data.show_usage = not data.show_usage end - if not progressive_mode and (is_fuel and no_recipes) or - (not data.show_usage and item == data.input) then + if not progressive_mode and (is_fuel and no_recipes) then + data.show_usage = true + end + + if data.show_usage then data.usages = get_item_usages(item) if is_fuel then @@ -663,8 +668,8 @@ local function get_fields(player, ...) } end - if next(data.usages) then - data.show_usage = true + if not next(data.usages) then + data.show_usage = false end elseif progressive_mode then @@ -680,7 +685,6 @@ local function get_fields(player, ...) data.input = item data.recipes_item = recipes data.rnum = 1 - data.show_usage = data.show_usage show_fs(player, player_name) end @@ -854,7 +858,6 @@ if not progressive_mode then end end - data.show_usage = data.show_usage data.input = node_name data.recipes_item = recipes @@ -884,4 +887,4 @@ for x = 1, 6 do recipe = cr[x] }) end -]] \ No newline at end of file +]] From f8b7a72635eaa640317a8ffa7816c35021836d96 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 2 Jan 2019 00:39:05 -0500 Subject: [PATCH 007/188] Fix alternate button not working in some cases --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 654f609..d2ab60e 100644 --- a/init.lua +++ b/init.lua @@ -592,7 +592,7 @@ local function get_fields(player, ...) show_fs(player, player_name) elseif fields.alternate then - if (data.usages and #data.usages == 1) or #data.recipes_item == 1 then + if #(data.show_usage and data.usages or data.recipes_item) == 1 then return end From b980dccaeeb06f962cc30a9c58c0b43128814eff Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 2 Jan 2019 18:57:35 +0100 Subject: [PATCH 008/188] Use of string.format instead of concat --- init.lua | 159 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 57 deletions(-) diff --git a/init.lua b/init.lua index d2ab60e..74377b4 100644 --- a/init.lua +++ b/init.lua @@ -24,6 +24,7 @@ craftguide.intllib = S local remove, maxn, sort, concat = table.remove, table.maxn, table.sort, table.concat local vector_add, vector_mul = vector.add, vector.multiply local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil +local fmt = string.format local DEFAULT_SIZE = 10 local MIN_LIMIT, MAX_LIMIT = 10, 12 @@ -74,7 +75,7 @@ function craftguide.register_craft(def) local func = "craftguide." .. __func() .. "(): " assert(def.type, func .. "'type' field missing") assert(def.width, func .. "'width' field missing") - assert(def.output, func .. "'output' field missing") + assert(def.output, func .. "'output' field missing") assert(def.items, func .. "'items' field missing") craftguide.custom_crafts[#craftguide.custom_crafts + 1] = def @@ -102,7 +103,7 @@ local function get_fueltime(item) end local function reset_datas(data) - data.show_usage = false + data.show_usage = nil data.filter = "" data.input = nil data.pagenum = 1 @@ -197,10 +198,16 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) local fs = {} - fs[#fs + 1] = "button[" .. (iX - (sfinv_only and 2.2 or 2.6)) .. "," .. - (iY + (sfinv_only and 3.9 or 3.3)) .. ";2.2,1;alternate;" .. - (show_usage and S("Usage") or S("Recipe")) .. " " .. - S("@1 of @2", recipe_num, #recipes) .. "]" + fs[#fs + 1] = fmt("button[%f,%f;%f,%f;%s;%s %u %s %u]", + iX - (sfinv_only and 2.2 or 2.6), + iY + (sfinv_only and 3.9 or 3.3), + 2.2, + 1, + "alternate", + show_usage and S("Usage") or S("Recipe"), + recipe_num, + S("of"), + #recipes) local recipe_type = recipes[recipe_num].type local items = recipes[recipe_num].items @@ -217,8 +224,10 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) local rightest, s_btn_size = 0 if recipe_type ~= "cooking" and (width > GRID_LIMIT or rows > GRID_LIMIT) then - fs[#fs + 1] = "label[" .. ((iX / 2) - 2) .. "," .. (iY + 2.2) .. ";" .. - S("Recipe is too big to be displayed (@1x@2)", width, rows) .. "]" + fs[#fs + 1] = fmt("label[%f,%f;%s]", + (iX / 2) - 2, + iY + 2.2, + S("Recipe is too big to be displayed (@1x@2)", width, rows)) return concat(fs) else @@ -241,12 +250,18 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) local groups = extract_groups(v) local label = groups and "\nG" or "" local item_r = group_to_item(v) - local tltip = get_tooltip(item_r, recipe_type, cooktime, groups) + local tltp = get_tooltip(item_r, recipe_type, cooktime, groups) - fs[#fs + 1] = "item_image_button[" .. X .. "," .. - (Y + (sfinv_only and 0.7 or 0.2)) .. ";" .. - BUTTON_SIZE .. "," .. BUTTON_SIZE .. ";" .. item_r .. - ";" .. item_r:match("%S*") .. ";" .. label .. "]" .. tltip + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]", + X, + Y + (sfinv_only and 0.7 or 0.2), + BUTTON_SIZE, + BUTTON_SIZE, + item_r, + item_r:match("%S*"), + label) + + fs[#fs + 1] = tltp end BUTTON_SIZE = 1.1 @@ -256,18 +271,23 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) if recipe_type == "cooking" or custom_recipe or (recipe_type == "normal" and width == 0) then - local icon = recipe_type == "cooking" and "furnace" or "shapeless" - local coords = (rightest + 1.2) .. "," .. - (iY + (sfinv_only and 2.2 or 1.7)) .. - ";0.5,0.5;" + local icon = recipe_type == "cooking" and "furnace" or "shapeless" - fs[#fs + 1] = "image[" .. coords .. - (custom_recipe and custom_recipe.icon or - "craftguide_" .. icon .. ".png^[resize:16x16") .. "]" + fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + rightest + 1.2, + iY + (sfinv_only and 2.2 or 1.7), + 0.5, + 0.5, + custom_recipe and custom_recipe.icon or + "craftguide_" .. icon .. ".png^[resize:16x16") - fs[#fs + 1] = "tooltip[" .. coords .. - (custom_recipe and custom_recipe.description or - recipe_type:gsub("^%l", string.upper)) .. "]" + fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", + rightest + 1.2, + iY + (sfinv_only and 2.2 or 1.7), + 0.5, + 0.5, + custom_recipe and custom_recipe.description or + recipe_type:gsub("^%l", string.upper)) end local output = recipes[recipe_num].output @@ -276,32 +296,47 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) local arrow_X = rightest + (s_btn_size or BUTTON_SIZE) local output_X = arrow_X + 0.9 - fs[#fs + 1] = "image[" .. arrow_X .. "," .. - (iY + (sfinv_only and 2.85 or 2.35)) .. - ";0.9,0.7;craftguide_arrow.png]" + fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + arrow_X, + iY + (sfinv_only and 2.85 or 2.35), + 0.9, + 0.7, + "craftguide_arrow.png") if output == "BURN" then - fs[#fs + 1] = "image[" .. output_X .. "," .. - (iY + (sfinv_only and 2.68 or 2.18)) .. - ";1.1,1.1;craftguide_fire.png]" + fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + output_X, + iY + (sfinv_only and 2.68 or 2.18), + 1.1, + 1.1, + "craftguide_fire.png") else - fs[#fs + 1] = "item_image_button[" .. output_X .. "," .. - (iY + (sfinv_only and 2.7 or 2.2)) .. ";" .. - BUTTON_SIZE .. "," .. BUTTON_SIZE .. ";" .. - output .. ";" .. output_s .. ";]" + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]", + output_X, + iY + (sfinv_only and 2.7 or 2.2), + BUTTON_SIZE, + BUTTON_SIZE, + output, + output_s) end fs[#fs + 1] = get_tooltip(output_s) local output_is_fuel = get_fueltime(output) > 0 if output_is_fuel then - fs[#fs + 1] = "image[" .. (output_X + 1) .. "," .. - (iY + (sfinv_only and 2.83 or 2.33)) .. - ";0.6,0.4;craftguide_arrow.png]" + fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + output_X + 1, + iY + (sfinv_only and 2.83 or 2.33), + 0.6, + 0.4, + "craftguide_arrow.png") - fs[#fs + 1] = "image[" .. (output_X + 1.6) .. "," .. - (iY + (sfinv_only and 2.68 or 2.18)) .. - ";0.6,0.6;craftguide_fire.png]" + fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + output_X + 1.6, + iY + (sfinv_only and 2.68 or 2.18), + 0.6, + 0.6, + "craftguide_fire.png") end return concat(fs) @@ -321,7 +356,6 @@ local function get_formspec(player_name) local fs = {} if not sfinv_only then fs[#fs + 1] = "size[" .. (data.iX - 0.35) .. "," .. (iY + 4) .. ";]" - fs[#fs + 1] = "background[1,1;1,1;craftguide_bg.png;true]" fs[#fs + 1] = "tooltip[size_inc;" .. S("Increase window size") .. "]" fs[#fs + 1] = "tooltip[size_dec;" .. S("Decrease window size") .. "]" fs[#fs + 1] = "image_button[" .. (data.iX * 0.47) .. @@ -331,6 +365,7 @@ local function get_formspec(player_name) end fs[#fs + 1] = [[ + "background[1,1;1,1;craftguide_bg.png;true]" image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] field_close_on_enter[filter;false] @@ -342,8 +377,8 @@ local function get_formspec(player_name) fs[#fs + 1] = "tooltip[next;" .. S("Next page") .. "]" fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 2.6 or 3.1)) .. ",0.12;0.8,0.8;craftguide_prev_icon.png;prev;]" - fs[#fs + 1] = "label[" .. (data.iX - (sfinv_only and 1.7 or 2.2)) .. ",0.22;" .. - colorize(data.pagenum) .. " / " .. data.pagemax .. "]" + fs[#fs + 1] = "label[" .. (data.iX - (sfinv_only and 1.7 or 2.2)) .. + ",0.22;" .. colorize(data.pagenum) .. " / " .. data.pagemax .. "]" fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 0.7 or 1.2) - (data.iX >= 11 and 0.08 or 0)) .. ",0.12;0.8,0.8;craftguide_next_icon.png;next;]" @@ -352,8 +387,10 @@ local function get_formspec(player_name) local xoffset = data.iX / 2.15 if not next(data.items) then - fs[#fs + 1] = "label[" .. ((data.iX / 2) - 1) .. - ",2;" .. S("No item to show") .. "]" + fs[#fs + 1] = fmt("label[%f,%f;%s]", + (data.iX / 2) - 1, + 2, + S("No item to show")) end local first_item = (data.pagenum - 1) * ipp @@ -366,10 +403,13 @@ local function get_formspec(player_name) local X = i % data.iX local Y = (i % ipp - X) / data.iX + 1 - fs[#fs + 1] = "item_image_button[" .. - (X - (sfinv_only and 0 or (X * 0.05))) .. "," .. - Y .. ";" .. BUTTON_SIZE .. "," .. BUTTON_SIZE .. ";" .. - name .. ";" .. name .. "_inv;]" + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]", + X - (sfinv_only and 0 or (X * 0.05)), + Y, + BUTTON_SIZE, + BUTTON_SIZE, + name, + name) end if data.input and reg_items[data.input] then @@ -417,6 +457,7 @@ local function recipe_in_inv(inv, item_name, recipes_f) end end end + if not group_in_inv and not item_in_inv(inv, item) then show_item_recipes[i] = false end @@ -631,9 +672,7 @@ local function get_fields(player, ...) else for item in pairs(fields) do if item:find(":") then - if item:sub(-4) == "_inv" then - item = item:sub(1,-5) - elseif item:find("%s") then + if item:find("%s") then item = item:match("%S*") end @@ -647,12 +686,12 @@ local function get_fields(player, ...) end if item ~= data.input then - data.show_usage = false + data.show_usage = nil else data.show_usage = not data.show_usage end - if not progressive_mode and (is_fuel and no_recipes) then + if not progressive_mode and is_fuel and no_recipes then data.show_usage = true end @@ -669,7 +708,7 @@ local function get_fields(player, ...) end if not next(data.usages) then - data.show_usage = false + data.show_usage = nil end elseif progressive_mode then @@ -695,6 +734,7 @@ end if sfinv_only then sfinv.register_page("craftguide:craftguide", { title = "Craft Guide", + get = function(self, player, context) local player_name = player:get_player_name() return sfinv.make_formspec( @@ -703,6 +743,7 @@ if sfinv_only then get_formspec(player_name) ) end, + on_enter = function(self, player, context) local player_name = player:get_player_name() local data = datas[player_name] @@ -711,6 +752,7 @@ if sfinv_only then init_datas(player, player_name) end end, + on_player_receive_fields = function(self, player, context, fields) get_fields(player, fields) end, @@ -757,10 +799,12 @@ else wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375} }, + on_construct = function(pos) local meta = mt.get_meta(pos) meta:set_string("infotext", S("Crafting Guide Sign")) end, + on_rightclick = function(pos, node, user, itemstack) on_use(itemstack, user) end @@ -794,10 +838,10 @@ else sfinv_buttons.register_button("craftguide", { title = S("Crafting Guide"), tooltip = S("Shows a list of available crafting recipes, cooking recipes and fuels"), + image = "craftguide_book.png", action = function(player) on_use(nil, player) end, - image = "craftguide_book.png", }) end end @@ -823,7 +867,8 @@ if not progressive_mode then end if not node_name then - return false, colorize("[craftguide] ", "red") .. S("No node pointed") + return false, colorize("[craftguide] ", "red") .. + S("No node pointed") elseif not datas[name] then init_datas(player, name) end @@ -858,7 +903,7 @@ if not progressive_mode then end end - data.input = node_name + data.input = node_name data.recipes_item = recipes return true, show_fs(player, name) From d1ee125a1a7b0a7c325284699729070c145178da Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Jan 2019 02:19:29 +0100 Subject: [PATCH 009/188] Remove erroneous quotation marks --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 74377b4..083c1dd 100644 --- a/init.lua +++ b/init.lua @@ -365,7 +365,7 @@ local function get_formspec(player_name) end fs[#fs + 1] = [[ - "background[1,1;1,1;craftguide_bg.png;true]" + background[1,1;1,1;craftguide_bg.png;true] image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] field_close_on_enter[filter;false] From 7f6dd430ce59ef749324413ffc908dec43b7331e Mon Sep 17 00:00:00 2001 From: pauloue Date: Tue, 8 Jan 2019 01:25:22 +0100 Subject: [PATCH 010/188] Various fixes - Include recipes with matching groups in usages - Fix group_to_item() - Fix custom recipes not showing in usages --- init.lua | 271 +++++++++++++++++++++++++++---------------------------- 1 file changed, 134 insertions(+), 137 deletions(-) diff --git a/init.lua b/init.lua index 083c1dd..4bbfcd6 100644 --- a/init.lua +++ b/init.lua @@ -9,15 +9,12 @@ local datas = {searches = {}} local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode") local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") -local get_recipe, get_recipes = mt.get_craft_recipe, mt.get_all_craft_recipes -local get_result, show_formspec = mt.get_craft_result, mt.show_formspec local reg_items = mt.registered_items - -craftguide.path = mt.get_modpath("craftguide") +local get_result = mt.get_craft_result +local show_formspec = mt.show_formspec -- Intllib -local S = dofile(craftguide.path .. "/intllib.lua") -craftguide.intllib = S +local S = dofile(mt.get_modpath("craftguide") .. "/intllib.lua") -- Lua 5.3 removed `table.maxn`, use this alternative in case of breakage: -- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1 @@ -34,23 +31,15 @@ local GRID_LIMIT = 5 local BUTTON_SIZE = 1.1 local group_stereotypes = { - wool = "wool:white", - dye = "dye:white", + wool = "wool:white", + dye = "dye:white", water_bucket = "bucket:bucket_water", - vessel = "vessels:glass_bottle", - coal = "default:coal_lump", - flower = "flowers:dandelion_yellow", + vessel = "vessels:glass_bottle", + coal = "default:coal_lump", + flower = "flowers:dandelion_yellow", mesecon_conductor_craftable = "mesecons:wire_00000000_off", } -local function extract_groups(str) - if str:sub(1,6) ~= "group:" then - return - end - - return str:sub(7):split(",") -end - local function __func() return debug.getinfo(2, "n").name end @@ -88,6 +77,34 @@ craftguide.register_craft({ items = {"default:stone"}, }) +local function get_recipe(output) + local recipe = mt.get_craft_recipe(output) + if recipe.items then + return recipe + end + + for i = 1, #craftguide.custom_crafts do + local custom_craft = craftguide.custom_crafts[i] + if custom_craft.output:match("%S*") == output then + return custom_craft + end + end + + return {} +end + +local function get_recipes(output) + local recipes = mt.get_all_craft_recipes(output) or {} + for i = 1, #craftguide.custom_crafts do + local custom_craft = craftguide.custom_crafts[i] + if custom_craft.output:match("%S*") == output then + recipes[#recipes + 1] = custom_craft + end + end + + return recipes +end + local color_codes = { red = "#FF0000", yellow = "#FFFF00", @@ -120,11 +137,11 @@ local function in_table(T) end local function group_to_items(group) - local items_with_group, counter = {}, 0 + local items_with_group, c = {}, 0 for name, def in pairs(reg_items) do if def.groups[group:sub(7)] then - counter = counter + 1 - items_with_group[counter] = name + c = c + 1 + items_with_group[c] = name end end @@ -135,23 +152,38 @@ local function item_in_inv(inv, item) return inv:contains_item("main", item) end -local function group_to_item(item) - if item:sub(1,6) == "group:" then - local itemsub = item:sub(7) - if group_stereotypes[itemsub] then - item = group_stereotypes[itemsub] - elseif reg_items["default:" .. itemsub] then - item = item:gsub("group:", "default:") - else - for name, def in pairs(reg_items) do - if def.groups[item:match("[^,:]+$")] then - item = name - end - end +local function extract_groups(str) + return str:sub(7):split(",") +end + +local function item_has_groups(item_groups, groups) + for i = 1, #groups do + local group = groups[i] + if not item_groups[group] then + return end end - return item:sub(1,6) == "group:" and "" or item + return true +end + +local function groups_to_item(groups) + if #groups == 1 then + local group = groups[1] + if group_stereotypes[group] then + return group_stereotypes[group] + elseif reg_items["default:" .. group] then + return "default:" .. group + end + end + + for name, def in pairs(reg_items) do + if item_has_groups(def.groups, groups) then + return name + end + end + + return "" end local function get_tooltip(item, recipe_type, cooktime, groups) @@ -223,50 +255,54 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) local rows = ceil(maxn(items) / width) local rightest, s_btn_size = 0 - if recipe_type ~= "cooking" and (width > GRID_LIMIT or rows > GRID_LIMIT) then + if width > GRID_LIMIT or rows > GRID_LIMIT then fs[#fs + 1] = fmt("label[%f,%f;%s]", (iX / 2) - 2, iY + 2.2, S("Recipe is too big to be displayed (@1x@2)", width, rows)) return concat(fs) - else - for i, v in pairs(items) do - local X = ceil((i - 1) % width + xoffset - width) - - (sfinv_only and 0 or 0.2) - local Y = ceil(i / width + (iY + 2) - min(2, rows)) + end - if recipe_type ~= "cooking" and (width > 3 or rows > 3) then - BUTTON_SIZE = width > 3 and 3 / width or 3 / rows - s_btn_size = BUTTON_SIZE - X = BUTTON_SIZE * (i % width) + xoffset - 2.65 - Y = BUTTON_SIZE * floor((i - 1) / width) + (iY + 3) - min(2, rows) - end + for i, item in pairs(items) do + local X = ceil((i - 1) % width + xoffset - width) - + (sfinv_only and 0 or 0.2) + local Y = ceil(i / width + (iY + 2) - min(2, rows)) - if X > rightest then - rightest = X - end - - local groups = extract_groups(v) - local label = groups and "\nG" or "" - local item_r = group_to_item(v) - local tltp = get_tooltip(item_r, recipe_type, cooktime, groups) - - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]", - X, - Y + (sfinv_only and 0.7 or 0.2), - BUTTON_SIZE, - BUTTON_SIZE, - item_r, - item_r:match("%S*"), - label) - - fs[#fs + 1] = tltp + if width > 3 or rows > 3 then + BUTTON_SIZE = width > 3 and 3 / width or 3 / rows + s_btn_size = BUTTON_SIZE + X = BUTTON_SIZE * (i % width) + xoffset - 2.65 + Y = BUTTON_SIZE * floor((i - 1) / width) + (iY + 3) - min(2, rows) end - BUTTON_SIZE = 1.1 + if X > rightest then + rightest = X + end + + local groups + if item:sub(1,6) == "group:" then + groups = extract_groups(item) + item = groups_to_item(groups) + end + + local label = groups and "\nG" or "" + local tltp = get_tooltip(item, recipe_type, cooktime, groups) + + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]", + X, + Y + (sfinv_only and 0.7 or 0.2), + BUTTON_SIZE, + BUTTON_SIZE, + item, + item:match("%S*"), + label) + + fs[#fs + 1] = tltp end + BUTTON_SIZE = 1.1 + local custom_recipe = craftguide.craft_types[recipe_type] if recipe_type == "cooking" or custom_recipe or (recipe_type == "normal" and width == 0) then @@ -442,7 +478,7 @@ local show_fs = function(player, player_name) end local function recipe_in_inv(inv, item_name, recipes_f) - local recipes = recipes_f or get_recipes(item_name) or {} + local recipes = recipes_f or get_recipes(item_name) local show_item_recipes = {} for i = 1, #recipes do @@ -525,54 +561,17 @@ local function init_datas(user, name) end end -local function add_custom_recipes(item, recipes) - for j = 1, #craftguide.custom_crafts do - local craft = craftguide.custom_crafts[j] - if craft.output:match("%S*") == item then - recipes[#recipes + 1] = { - type = craft.type, - width = craft.width, - items = craft.items, - output = craft.output, - } - end - end - - return recipes -end - local function get_init_items() local items_list, c = {}, 0 - local function list(name) - c = c + 1 - items_list[c] = name - end for name, def in pairs(reg_items) do local is_fuel = get_fueltime(name) > 0 - if (not (def.groups.not_in_craft_guide == 1 or - def.groups.not_in_creative_inventory == 1)) and - (get_recipe(name).items or is_fuel) and - def.description and def.description ~= "" then - list(name) - end - end - - for i = 1, #craftguide.custom_crafts do - local craft = craftguide.custom_crafts[i] - local output = craft.output:match("%S*") - local listed - - for j = 1, #items_list do - local listed_item = items_list[j] - if output == listed_item then - listed = true - break - end - end - - if not listed then - list(output) + if not (def.groups.not_in_craft_guide == 1 or + def.groups.not_in_creative_inventory == 1) and + (get_recipe(name).items or is_fuel) and + def.description and def.description ~= "" then + c = c + 1 + items_list[c] = name end end @@ -580,31 +579,35 @@ local function get_init_items() datas.init_items = items_list end -mt.register_on_mods_loaded(function() - get_init_items() -end) +mt.register_on_mods_loaded(get_init_items) + +local function item_in_recipe(item, recipe) + local item_groups = reg_items[item].groups + for _, recipe_item in pairs(recipe.items) do + if recipe_item == item then + return true + elseif recipe_item:sub(1,6) == "group:" then + local groups = extract_groups(recipe_item) + if item_has_groups(item_groups, groups) then + return true + end + end + end +end local function get_item_usages(item) local usages = {} for name, def in pairs(reg_items) do if not (def.groups.not_in_craft_guide == 1 or - def.groups.not_in_creative_inventory == 1) and - get_recipe(name).items and def.description and def.description ~= "" then + def.groups.not_in_creative_inventory == 1) and + get_recipe(name).items and + def.description and def.description ~= "" then + local recipes = get_recipes(name) for i = 1, #recipes do local recipe = recipes[i] - local items = recipe.items - - for j = 1, #items do - if items[j] == item then - usages[#usages + 1] = { - type = recipe.type, - items = items, - width = recipe.width, - output = recipe.output, - } - break - end + if item_in_recipe(item, recipe) then + usages[#usages + 1] = recipe end end end @@ -672,13 +675,8 @@ local function get_fields(player, ...) else for item in pairs(fields) do if item:find(":") then - if item:find("%s") then - item = item:match("%S*") - end - local is_fuel = get_fueltime(item) > 0 - local recipes = get_recipes(item) or {} - recipes = add_custom_recipes(item, recipes) + local recipes = get_recipes(item) local no_recipes = not next(recipes) if no_recipes and not is_fuel then @@ -877,8 +875,7 @@ if not progressive_mode then reset_datas(data) local is_fuel = get_fueltime(node_name) > 0 - local recipes = get_recipes(node_name) or {} - recipes = add_custom_recipes(node_name, recipes) + local recipes = get_recipes(node_name) local no_recipes = not next(recipes) if no_recipes and not is_fuel then From e0db5834b34708231d05631cf6734dfa89f685c8 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Tue, 8 Jan 2019 14:28:53 -0500 Subject: [PATCH 011/188] Separate player data --- init.lua | 59 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/init.lua b/init.lua index 4bbfcd6..4050ad9 100644 --- a/init.lua +++ b/init.lua @@ -4,7 +4,9 @@ craftguide = { } local mt = minetest -local datas = {searches = {}} +local player_data = {} +local init_items = {} +local searches = {} local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode") local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") @@ -119,13 +121,13 @@ local function get_fueltime(item) return get_result({method = "fuel", width = 1, items = {item}}).time end -local function reset_datas(data) +local function reset_data(data) data.show_usage = nil data.filter = "" data.input = nil data.pagenum = 1 data.rnum = 1 - data.items = progressive_mode and data.init_filter_items or datas.init_items + data.items = progressive_mode and data.init_filter_items or init_items end local function in_table(T) @@ -379,12 +381,12 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) end local function get_formspec(player_name) - local data = datas[player_name] + local data = player_data[player_name] local iY = sfinv_only and 4 or data.iX - 5 local ipp = data.iX * iY if not data.items then - data.items = datas.init_items + data.items = init_items end data.pagemax = max(1, ceil(#data.items / ipp)) @@ -511,12 +513,12 @@ end local function get_filter_items(data, player) local filter = data.filter - if datas.searches[filter] then - data.items = datas.searches[filter] + if searches[filter] then + data.items = searches[filter] return end - local items_list = progressive_mode and data.init_filter_items or datas.init_items + local items_list = progressive_mode and data.init_filter_items or init_items local inv = player:get_inventory() local filtered_list, counter = {}, 0 @@ -544,26 +546,25 @@ local function get_filter_items(data, player) end elseif filter ~= "" then -- Cache the results only if searched 2 times - if datas.searches[filter] == nil then - datas.searches[filter] = false + if searches[filter] == nil then + searches[filter] = false else - datas.searches[filter] = filtered_list + searches[filter] = filtered_list end end data.items = filtered_list end -local function init_datas(user, name) - datas[name] = {filter = "", pagenum = 1, iX = sfinv_only and 8 or DEFAULT_SIZE} +local function init_data(user, name) + player_data[name] = {filter = "", pagenum = 1, iX = sfinv_only and 8 or DEFAULT_SIZE} if progressive_mode then - get_filter_items(datas[name], user) + get_filter_items(player_data[name], user) end end local function get_init_items() - local items_list, c = {}, 0 - + local c = 0 for name, def in pairs(reg_items) do local is_fuel = get_fueltime(name) > 0 if not (def.groups.not_in_craft_guide == 1 or @@ -571,12 +572,10 @@ local function get_init_items() (get_recipe(name).items or is_fuel) and def.description and def.description ~= "" then c = c + 1 - items_list[c] = name + init_items[c] = name end end - - sort(items_list) - datas.init_items = items_list + sort(init_items) end mt.register_on_mods_loaded(get_init_items) @@ -629,10 +628,10 @@ local function get_fields(player, ...) end local player_name = player:get_player_name() - local data = datas[player_name] + local data = player_data[player_name] if fields.clear then - reset_datas(data) + reset_data(data) show_fs(player, player_name) elseif fields.alternate then @@ -744,10 +743,10 @@ if sfinv_only then on_enter = function(self, player, context) local player_name = player:get_player_name() - local data = datas[player_name] + local data = player_data[player_name] if progressive_mode or not data then - init_datas(player, player_name) + init_data(player, player_name) end end, @@ -760,10 +759,10 @@ else local function on_use(itemstack, user) local player_name = user:get_player_name() - local data = datas[player_name] + local data = player_data[player_name] if progressive_mode or not data then - init_datas(user, player_name) + init_data(user, player_name) get_formspec(player_name) else show_formspec(player_name, "craftguide", data.formspec) @@ -867,12 +866,12 @@ if not progressive_mode then if not node_name then return false, colorize("[craftguide] ", "red") .. S("No node pointed") - elseif not datas[name] then - init_datas(player, name) + elseif not player_data[name] then + init_data(player, name) end - local data = datas[name] - reset_datas(data) + local data = player_data[name] + reset_data(data) local is_fuel = get_fueltime(node_name) > 0 local recipes = get_recipes(node_name) From 70682b230bb9f0a5fa37be95aeff55835b10ddd2 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 9 Jan 2019 21:11:06 +0100 Subject: [PATCH 012/188] Hardset button size to 1.1 --- init.lua | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/init.lua b/init.lua index 4050ad9..c790012 100644 --- a/init.lua +++ b/init.lua @@ -30,7 +30,6 @@ local MIN_LIMIT, MAX_LIMIT = 10, 12 DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) local GRID_LIMIT = 5 -local BUTTON_SIZE = 1.1 local group_stereotypes = { wool = "wool:white", @@ -255,7 +254,7 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) end local rows = ceil(maxn(items) / width) - local rightest, s_btn_size = 0 + local rightest, btn_size, s_btn_size = 0, 1.1 if width > GRID_LIMIT or rows > GRID_LIMIT then fs[#fs + 1] = fmt("label[%f,%f;%s]", @@ -272,10 +271,10 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) local Y = ceil(i / width + (iY + 2) - min(2, rows)) if width > 3 or rows > 3 then - BUTTON_SIZE = width > 3 and 3 / width or 3 / rows - s_btn_size = BUTTON_SIZE - X = BUTTON_SIZE * (i % width) + xoffset - 2.65 - Y = BUTTON_SIZE * floor((i - 1) / width) + (iY + 3) - min(2, rows) + btn_size = width > 3 and 3 / width or 3 / rows + s_btn_size = btn_size + X = btn_size * (i % width) + xoffset - 2.65 + Y = btn_size * floor((i - 1) / width) + (iY + 3) - min(2, rows) end if X > rightest then @@ -294,8 +293,8 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]", X, Y + (sfinv_only and 0.7 or 0.2), - BUTTON_SIZE, - BUTTON_SIZE, + btn_size, + btn_size, item, item:match("%S*"), label) @@ -303,8 +302,6 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) fs[#fs + 1] = tltp end - BUTTON_SIZE = 1.1 - local custom_recipe = craftguide.craft_types[recipe_type] if recipe_type == "cooking" or custom_recipe or (recipe_type == "normal" and width == 0) then @@ -331,7 +328,7 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) local output = recipes[recipe_num].output local output_s = output:match("%S+") - local arrow_X = rightest + (s_btn_size or BUTTON_SIZE) + local arrow_X = rightest + (s_btn_size or 1.1) local output_X = arrow_X + 0.9 fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", @@ -352,8 +349,8 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]", output_X, iY + (sfinv_only and 2.7 or 2.2), - BUTTON_SIZE, - BUTTON_SIZE, + 1.1, + 1.1, output, output_s) end @@ -444,8 +441,8 @@ local function get_formspec(player_name) fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]", X - (sfinv_only and 0 or (X * 0.05)), Y, - BUTTON_SIZE, - BUTTON_SIZE, + 1.1, + 1.1, name, name) end From 134fbf382d824a168f2d8f3f4e22ffbd80f3ceed Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 11 Jan 2019 01:54:17 +0100 Subject: [PATCH 013/188] Do not search again for same string --- init.lua | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index c790012..eb3c07a 100644 --- a/init.lua +++ b/init.lua @@ -517,7 +517,7 @@ local function get_filter_items(data, player) local items_list = progressive_mode and data.init_filter_items or init_items local inv = player:get_inventory() - local filtered_list, counter = {}, 0 + local filtered_list, c = {}, 0 for i = 1, #items_list do local item = items_list[i] @@ -525,14 +525,14 @@ local function get_filter_items(data, player) if filter ~= "" then if item:find(filter, 1, true) or item_desc:find(filter, 1, true) then - counter = counter + 1 - filtered_list[counter] = item + c = c + 1 + filtered_list[c] = item end elseif progressive_mode then local _, has_item = recipe_in_inv(inv, item) if has_item then - counter = counter + 1 - filtered_list[counter] = item + c = c + 1 + filtered_list[c] = item end end end @@ -572,6 +572,7 @@ local function get_init_items() init_items[c] = name end end + sort(init_items) end @@ -648,7 +649,12 @@ local function get_fields(player, ...) elseif (fields.key_enter_field == "filter" or fields.search) and fields.filter ~= "" then - data.filter = fields.filter:lower() + local fltr = fields.filter:lower() + if data.filter == fltr then + return + end + + data.filter = fltr data.pagenum = 1 get_filter_items(data, player) show_fs(player, player_name) From 1def071029f3eacf09e93721dceb822afe0d472e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 13 Jan 2019 01:18:41 +0100 Subject: [PATCH 014/188] Fix background --- init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/init.lua b/init.lua index eb3c07a..adbf603 100644 --- a/init.lua +++ b/init.lua @@ -391,6 +391,7 @@ local function get_formspec(player_name) local fs = {} if not sfinv_only then fs[#fs + 1] = "size[" .. (data.iX - 0.35) .. "," .. (iY + 4) .. ";]" + fs[#fs + 1] = "no_prepend[]" fs[#fs + 1] = "tooltip[size_inc;" .. S("Increase window size") .. "]" fs[#fs + 1] = "tooltip[size_dec;" .. S("Decrease window size") .. "]" fs[#fs + 1] = "image_button[" .. (data.iX * 0.47) .. From 50317cc20eee3d04805f03f8f3a9532fc1fd0a3e Mon Sep 17 00:00:00 2001 From: pauloue Date: Sun, 13 Jan 2019 01:36:38 +0100 Subject: [PATCH 015/188] Progressive: refactor, fix some bugs, add API function --- README.md | 44 +++++++-- init.lua | 276 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 182 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index 00e6054..6be78cc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -## ![Preview1](http://i.imgur.com/fIPNYkb.png) Crafting Guide ## +# ![Preview1](http://i.imgur.com/fIPNYkb.png) Crafting Guide -#### `craftguide` is the most comprehensive crafting guide on Minetest. #### -#### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details. #### +#### `craftguide` is the most comprehensive crafting guide on Minetest. +#### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details. This crafting guide is a blue book named *"Crafting Guide"* or a wooden sign. @@ -14,10 +14,16 @@ The progressive mode can be enabled with `craftguide_progressive_mode = true` in Use the command `/craft` to show the recipe(s) of the pointed node. +![Preview2](https://i.imgur.com/bToFH38.png) + --- -`craftguide` has an API to register **custom recipes**. Demos: -#### Registering a custom crafting type #### +## API + +### Custom recipes + +#### Registering a custom crafting type + ```Lua craftguide.register_craft_type("digging", { description = "Digging", @@ -25,7 +31,8 @@ craftguide.register_craft_type("digging", { }) ``` -#### Registering a custom crafting recipe #### +#### Registering a custom crafting recipe + ```Lua craftguide.register_craft({ type = "digging", @@ -35,4 +42,27 @@ craftguide.register_craft({ }) ``` -![Preview2](https://i.imgur.com/bToFH38.png) +### Progressive mode + +#### `craftguide.progressive_filter_recipes(recipes, player)` + +This function is used to filter recipes when progressive mode is enabled. It can +be overridden to change the recipes that are normally displayed. + +The function should return the recipes to be displayed, given the available +recipes and an `ObjectRef` to the craft guide user. Each recipe is a table of +the form returned by `minetest.get_craft_recipe`. + +Example function to hide recipes for items from a mod called "secretstuff": + +```lua +function craftguide.progressive_filter_recipes(recipes, player) + local filtered = {} + for _, recipe in ipairs(recipes) do + if recipe.output:sub(1, 12) ~= "secretstuff:" then + filtered[#filtered + 1] = recipe + end + end + return filtered +end +``` diff --git a/init.lua b/init.lua index adbf603..35db5e8 100644 --- a/init.lua +++ b/init.lua @@ -20,7 +20,7 @@ local S = dofile(mt.get_modpath("craftguide") .. "/intllib.lua") -- Lua 5.3 removed `table.maxn`, use this alternative in case of breakage: -- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1 -local remove, maxn, sort, concat = table.remove, table.maxn, table.sort, table.concat +local maxn, sort, concat = table.maxn, table.sort, table.concat local vector_add, vector_mul = vector.add, vector.multiply local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local fmt = string.format @@ -120,39 +120,6 @@ local function get_fueltime(item) return get_result({method = "fuel", width = 1, items = {item}}).time end -local function reset_data(data) - data.show_usage = nil - data.filter = "" - data.input = nil - data.pagenum = 1 - data.rnum = 1 - data.items = progressive_mode and data.init_filter_items or init_items -end - -local function in_table(T) - for i = 1, #T do - if T[i] then - return true - end - end -end - -local function group_to_items(group) - local items_with_group, c = {}, 0 - for name, def in pairs(reg_items) do - if def.groups[group:sub(7)] then - c = c + 1 - items_with_group[c] = name - end - end - - return items_with_group -end - -local function item_in_inv(inv, item) - return inv:contains_item("main", item) -end - local function extract_groups(str) return str:sub(7):split(",") end @@ -382,10 +349,6 @@ local function get_formspec(player_name) local iY = sfinv_only and 4 or data.iX - 5 local ipp = data.iX * iY - if not data.items then - data.items = init_items - end - data.pagemax = max(1, ceil(#data.items / ipp)) local fs = {} @@ -459,12 +422,11 @@ local function get_formspec(player_name) end fs = concat(fs) - data.formspec = fs if sfinv_only then return fs else - show_formspec(player_name, "craftguide", fs) + data.formspec = fs end end @@ -474,75 +436,32 @@ local show_fs = function(player, player_name) sfinv.set_player_inventory_formspec(player, context) else get_formspec(player_name) + local data = player_data[player_name] + show_formspec(player_name, "craftguide", data.formspec) end end -local function recipe_in_inv(inv, item_name, recipes_f) - local recipes = recipes_f or get_recipes(item_name) - local show_item_recipes = {} - - for i = 1, #recipes do - show_item_recipes[i] = true - for _, item in pairs(recipes[i].items) do - local group_in_inv = false - if item:sub(1,6) == "group:" then - local groups = group_to_items(item) - for j = 1, #groups do - if item_in_inv(inv, groups[j]) then - group_in_inv = true - end - end - end - - if not group_in_inv and not item_in_inv(inv, item) then - show_item_recipes[i] = false - end - end - end - - for i = #show_item_recipes, 1, -1 do - if not show_item_recipes[i] then - remove(recipes, i) - end - end - - return recipes, in_table(show_item_recipes) -end - -local function get_filter_items(data, player) +local function filter_items(data) local filter = data.filter if searches[filter] then data.items = searches[filter] return end - local items_list = progressive_mode and data.init_filter_items or init_items - local inv = player:get_inventory() + local items_list = progressive_mode and data.progressive_items or init_items local filtered_list, c = {}, 0 for i = 1, #items_list do local item = items_list[i] local item_desc = reg_items[item].description:lower() - if filter ~= "" then - if item:find(filter, 1, true) or item_desc:find(filter, 1, true) then - c = c + 1 - filtered_list[c] = item - end - elseif progressive_mode then - local _, has_item = recipe_in_inv(inv, item) - if has_item then - c = c + 1 - filtered_list[c] = item - end + if item:find(filter, 1, true) or item_desc:find(filter, 1, true) then + c = c + 1 + filtered_list[c] = item end end - if progressive_mode then - if not data.items then - data.init_filter_items = filtered_list - end - elseif filter ~= "" then + if not progressive_mode then -- Cache the results only if searched 2 times if searches[filter] == nil then searches[filter] = false @@ -554,31 +473,6 @@ local function get_filter_items(data, player) data.items = filtered_list end -local function init_data(user, name) - player_data[name] = {filter = "", pagenum = 1, iX = sfinv_only and 8 or DEFAULT_SIZE} - if progressive_mode then - get_filter_items(player_data[name], user) - end -end - -local function get_init_items() - local c = 0 - for name, def in pairs(reg_items) do - local is_fuel = get_fueltime(name) > 0 - if not (def.groups.not_in_craft_guide == 1 or - def.groups.not_in_creative_inventory == 1) and - (get_recipe(name).items or is_fuel) and - def.description and def.description ~= "" then - c = c + 1 - init_items[c] = name - end - end - - sort(init_items) -end - -mt.register_on_mods_loaded(get_init_items) - local function item_in_recipe(item, recipe) local item_groups = reg_items[item].groups for _, recipe_item in pairs(recipe.items) do @@ -614,6 +508,120 @@ local function get_item_usages(item) return usages end +local function get_inv_items(player) + local invlist = player:get_inventory():get_list("main") + local inv_items = {} + + for i = 1, #invlist do + local stack = invlist[i] + if not stack:is_empty() then + inv_items[#inv_items + 1] = stack:get_name() + end + end + + return inv_items +end + +local function progressive_show_recipe(recipe, inv_items) + for _, item in pairs(recipe.items) do + local item_in_inv + if item:sub(1,6) == "group:" then + local groups = extract_groups(item) + for i = 1, #inv_items do + local item_def = reg_items[inv_items[i]] + if item_def then + local item_groups = item_def.groups + if item_has_groups(item_groups, groups) then + item_in_inv = true + end + end + end + else + for i = 1, #inv_items do + if inv_items[i] == item then + item_in_inv = true + end + end + end + + if not item_in_inv then + return + end + end + + return true +end + +function craftguide.progressive_filter_recipes(recipes, player) + local inv_items = get_inv_items(player) + if #inv_items == 0 then + return {} + end + + local filtered = {} + for i = 1, #recipes do + local recipe = recipes[i] + if progressive_show_recipe(recipe, inv_items) then + filtered[#filtered + 1] = recipe + end + end + + return filtered +end + +local function get_progressive_items(player) + local items = {} + for i = 1, #init_items do + local item = init_items[i] + local recipes = get_recipes(item) + recipes = craftguide.progressive_filter_recipes(recipes, player) + + if #recipes > 0 then + items[#items + 1] = item + end + end + + return items +end + +local function init_data(player, name) + local p_items = progressive_mode and get_progressive_items(player) or nil + player_data[name] = { + filter = "", + pagenum = 1, + iX = sfinv_only and 8 or DEFAULT_SIZE, + items = p_items or init_items, + progressive_items = p_items, + } +end + +local function reset_data(data) + data.show_usage = nil + data.filter = "" + data.input = nil + data.pagenum = 1 + data.rnum = 1 + data.items = progressive_mode and data.progressive_items or init_items +end + +local function get_init_items() + local c = 0 + for name, def in pairs(reg_items) do + local is_fuel = get_fueltime(name) > 0 + if not (def.groups.not_in_craft_guide == 1 or + def.groups.not_in_creative_inventory == 1) and + (get_recipe(name).items or is_fuel) and + def.description and def.description ~= "" then + c = c + 1 + init_items[c] = name + end + end + + sort(init_items) +end + +mt.register_on_mods_loaded(get_init_items) + local function get_fields(player, ...) local args, formname, fields = {...} if sfinv_only then @@ -657,7 +665,7 @@ local function get_fields(player, ...) data.filter = fltr data.pagenum = 1 - get_filter_items(data, player) + filter_items(data) show_fs(player, player_name) elseif fields.prev or fields.next then @@ -680,9 +688,12 @@ local function get_fields(player, ...) if item:find(":") then local is_fuel = get_fueltime(item) > 0 local recipes = get_recipes(item) + if progressive_mode then + recipes = craftguide.progressive_filter_recipes(recipes, player) + end local no_recipes = not next(recipes) - if no_recipes and not is_fuel then + if no_recipes and (progressive_mode or not is_fuel) then return end @@ -708,17 +719,12 @@ local function get_fields(player, ...) } end - if not next(data.usages) then - data.show_usage = nil + if progressive_mode then + data.usages = craftguide.progressive_filter_recipes(data.usages, player) end - elseif progressive_mode then - local inv = player:get_inventory() - local has_item - recipes, has_item = recipe_in_inv(inv, item, recipes) - - if not has_item then - return + if not next(data.usages) then + data.show_usage = nil end end @@ -749,8 +755,11 @@ if sfinv_only then local player_name = player:get_player_name() local data = player_data[player_name] - if progressive_mode or not data then + if not data then init_data(player, player_name) + elseif progressive_mode then + data.progressive_items = get_progressive_items(player) + filter_items(data) end end, @@ -765,12 +774,17 @@ else local player_name = user:get_player_name() local data = player_data[player_name] - if progressive_mode or not data then + if not data then init_data(user, player_name) get_formspec(player_name) - else - show_formspec(player_name, "craftguide", data.formspec) + data = player_data[player_name] + elseif progressive_mode then + data.progressive_items = get_progressive_items(user) + filter_items(data) + get_formspec(player_name) end + + show_formspec(player_name, "craftguide", data.formspec) end mt.register_craftitem("craftguide:book", { From 157c6e5004898d58039d5408172e03126021d8cd Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 13 Jan 2019 01:48:14 +0100 Subject: [PATCH 016/188] get_formspec -> make_formspec --- init.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/init.lua b/init.lua index 35db5e8..29f8d75 100644 --- a/init.lua +++ b/init.lua @@ -344,7 +344,7 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) return concat(fs) end -local function get_formspec(player_name) +local function make_formspec(player_name) local data = player_data[player_name] local iY = sfinv_only and 4 or data.iX - 5 local ipp = data.iX * iY @@ -435,7 +435,7 @@ local show_fs = function(player, player_name) local context = sfinv.get_or_create_context(player) sfinv.set_player_inventory_formspec(player, context) else - get_formspec(player_name) + make_formspec(player_name) local data = player_data[player_name] show_formspec(player_name, "craftguide", data.formspec) end @@ -747,7 +747,7 @@ if sfinv_only then return sfinv.make_formspec( player, context, - get_formspec(player_name) + make_formspec(player_name) ) end, @@ -776,12 +776,12 @@ else if not data then init_data(user, player_name) - get_formspec(player_name) + make_formspec(player_name) data = player_data[player_name] elseif progressive_mode then data.progressive_items = get_progressive_items(user) filter_items(data) - get_formspec(player_name) + make_formspec(player_name) end show_formspec(player_name, "craftguide", data.formspec) From 0959eaef0bd7799d052855fd6ab13723553e5d08 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 13 Jan 2019 01:50:26 +0100 Subject: [PATCH 017/188] Update License --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 7854fd0..6d1eb81 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ License of source code ---------------------- -« Copyright © 2015-2018, Jean-Patrick Guerrero +« Copyright © 2015-2019, Jean-Patrick Guerrero and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: From fa8d602a64376c75aa89430d216d69d3437cbf56 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 13 Jan 2019 02:31:55 +0100 Subject: [PATCH 018/188] Fix sfinv mode bg --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 29f8d75..5a8d0d1 100644 --- a/init.lua +++ b/init.lua @@ -355,6 +355,7 @@ local function make_formspec(player_name) if not sfinv_only then fs[#fs + 1] = "size[" .. (data.iX - 0.35) .. "," .. (iY + 4) .. ";]" fs[#fs + 1] = "no_prepend[]" + fs[#fs + 1] = "background[1,1;1,1;craftguide_bg.png;true]" fs[#fs + 1] = "tooltip[size_inc;" .. S("Increase window size") .. "]" fs[#fs + 1] = "tooltip[size_dec;" .. S("Decrease window size") .. "]" fs[#fs + 1] = "image_button[" .. (data.iX * 0.47) .. @@ -364,7 +365,6 @@ local function make_formspec(player_name) end fs[#fs + 1] = [[ - background[1,1;1,1;craftguide_bg.png;true] image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] field_close_on_enter[filter;false] From 18affcb00e68d27291d83949ccfab29011437a32 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 13 Jan 2019 18:30:21 +0100 Subject: [PATCH 019/188] Allow searching same string again in progressive mode --- init.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index 5a8d0d1..7126d22 100644 --- a/init.lua +++ b/init.lua @@ -523,11 +523,12 @@ local function get_inv_items(player) end local function progressive_show_recipe(recipe, inv_items) + local inv_items_size = #inv_items for _, item in pairs(recipe.items) do local item_in_inv if item:sub(1,6) == "group:" then local groups = extract_groups(item) - for i = 1, #inv_items do + for i = 1, inv_items_size do local item_def = reg_items[inv_items[i]] if item_def then local item_groups = item_def.groups @@ -537,7 +538,7 @@ local function progressive_show_recipe(recipe, inv_items) end end else - for i = 1, #inv_items do + for i = 1, inv_items_size do if inv_items[i] == item then item_in_inv = true end @@ -659,7 +660,7 @@ local function get_fields(player, ...) elseif (fields.key_enter_field == "filter" or fields.search) and fields.filter ~= "" then local fltr = fields.filter:lower() - if data.filter == fltr then + if not progressive_mode and data.filter == fltr then return end From ed11bf3281f753f5269ea25e900842f276f2cf2e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 15 Jan 2019 14:38:15 +0100 Subject: [PATCH 020/188] Fix tooltip --- init.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 7126d22..593e5d1 100644 --- a/init.lua +++ b/init.lua @@ -402,7 +402,7 @@ local function make_formspec(player_name) local X = i % data.iX local Y = (i % ipp - X) / data.iX + 1 - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]", + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s_inv;]", X - (sfinv_only and 0 or (X * 0.05)), Y, 1.1, @@ -687,8 +687,13 @@ local function get_fields(player, ...) else for item in pairs(fields) do if item:find(":") then + if item:sub(-4) == "_inv" then + item = item:sub(1,-5) + end + local is_fuel = get_fueltime(item) > 0 local recipes = get_recipes(item) + if progressive_mode then recipes = craftguide.progressive_filter_recipes(recipes, player) end From c4fe467e6fd446fd195623308f613185bbf73ef9 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 18 Jan 2019 15:56:52 +0100 Subject: [PATCH 021/188] Remove wood group --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 593e5d1..48241d4 100644 --- a/init.lua +++ b/init.lua @@ -813,7 +813,7 @@ else paramtype = "light", paramtype2 = "wallmounted", sunlight_propagates = true, - groups = {wood = 1, oddly_breakable_by_hand = 1, flammable = 3}, + groups = {oddly_breakable_by_hand = 1, flammable = 3}, node_box = { type = "wallmounted", wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}, From 61ae85a09cf818e3cc9a95cbcb7ab9932dc990c4 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 18 Jan 2019 17:15:25 +0100 Subject: [PATCH 022/188] Progressive mode: Add functions in API to add/set/get filters --- README.md | 26 ++++++++++++++++---------- init.lua | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 6be78cc..f9a2972 100644 --- a/README.md +++ b/README.md @@ -44,25 +44,31 @@ craftguide.register_craft({ ### Progressive mode -#### `craftguide.progressive_filter_recipes(recipes, player)` +#### `craftguide.add_progressive_filter(function(recipes, player))` -This function is used to filter recipes when progressive mode is enabled. It can -be overridden to change the recipes that are normally displayed. - -The function should return the recipes to be displayed, given the available -recipes and an `ObjectRef` to the craft guide user. Each recipe is a table of -the form returned by `minetest.get_craft_recipe`. +This function adds a recipe filter when progressive mode is enabled. +The default `craftguide` filter will still be used. Example function to hide recipes for items from a mod called "secretstuff": ```lua -function craftguide.progressive_filter_recipes(recipes, player) +craftguide.add_progressive_filter(function(recipes) local filtered = {} for _, recipe in ipairs(recipes) do - if recipe.output:sub(1, 12) ~= "secretstuff:" then + if recipe.output:sub(1,12) ~= "secretstuff:" then filtered[#filtered + 1] = recipe end end + return filtered -end +end) ``` + +#### `craftguide.set_progressive_filter(function(recipes, player))` + +This function sets an unique recipes filter when progressive mode is enabled. +The default `craftguide` progressive filter will be overridden. + +#### `craftguide.get_progressive_filters()` + +This function returns all progressive filters that are applied to recipes in progressive mode. diff --git a/init.lua b/init.lua index 48241d4..7ec8a44 100644 --- a/init.lua +++ b/init.lua @@ -553,7 +553,7 @@ local function progressive_show_recipe(recipe, inv_items) return true end -function craftguide.progressive_filter_recipes(recipes, player) +local function progressive_default_filter(recipes, player) local inv_items = get_inv_items(player) if #inv_items == 0 then return {} @@ -570,12 +570,35 @@ function craftguide.progressive_filter_recipes(recipes, player) return filtered end +local progressive_filters = {progressive_default_filter} + +function craftguide.add_progressive_filter(func) + progressive_filters[#progressive_filters + 1] = func +end + +function craftguide.set_progressive_filter(func) + progressive_filters = {func} +end + +function craftguide.get_progressive_filters() + return progressive_filters +end + +local function apply_progressive_filters(recipes, player) + for i = 1, #progressive_filters do + local func = progressive_filters[i] + recipes = func(recipes, player) + end + + return recipes +end + local function get_progressive_items(player) local items = {} for i = 1, #init_items do local item = init_items[i] local recipes = get_recipes(item) - recipes = craftguide.progressive_filter_recipes(recipes, player) + recipes = apply_progressive_filters(recipes, player) if #recipes > 0 then items[#items + 1] = item @@ -695,7 +718,7 @@ local function get_fields(player, ...) local recipes = get_recipes(item) if progressive_mode then - recipes = craftguide.progressive_filter_recipes(recipes, player) + recipes = apply_progressive_filters(recipes, player) end local no_recipes = not next(recipes) @@ -725,8 +748,9 @@ local function get_fields(player, ...) } end - if progressive_mode then - data.usages = craftguide.progressive_filter_recipes(data.usages, player) + if progressive_mode and next(data.usages) then + data.usages = + apply_progressive_filters(data.usages, player) end if not next(data.usages) then @@ -933,7 +957,7 @@ end --[[ Custom recipes (>3x3) test code -mt.register_craftitem("craftguide:custom_recipe_test", { +mt.register_craftitem(":secretstuff:custom_recipe_test", { description = "Custom Recipe Test", }) @@ -943,12 +967,12 @@ for x = 1, 6 do for i = 1, 10 - x do cr[x][i] = {} for j = 1, 10 - x do - cr[x][i][j] = "group:wood" + cr[x][i][j] = "group:sand" end end mt.register_craft({ - output = "craftguide:custom_recipe_test", + output = "secretstuff:custom_recipe_test", recipe = cr[x] }) end From 5ee1bea4ce0b7c0a63f65f240712af2e4c46396e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 20 Jan 2019 02:12:14 +0100 Subject: [PATCH 023/188] Progressive mode: Add a name to filters --- README.md | 2 +- init.lua | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f9a2972..d6cd536 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ end) #### `craftguide.set_progressive_filter(function(recipes, player))` -This function sets an unique recipes filter when progressive mode is enabled. +This function sets an unique recipe filter when progressive mode is enabled. The default `craftguide` progressive filter will be overridden. #### `craftguide.get_progressive_filters()` diff --git a/init.lua b/init.lua index 7ec8a44..313e9b4 100644 --- a/init.lua +++ b/init.lua @@ -63,10 +63,10 @@ craftguide.register_craft_type("digging", { function craftguide.register_craft(def) local func = "craftguide." .. __func() .. "(): " - assert(def.type, func .. "'type' field missing") + assert(def.type, func .. "'type' field missing") assert(def.width, func .. "'width' field missing") assert(def.output, func .. "'output' field missing") - assert(def.items, func .. "'items' field missing") + assert(def.items, func .. "'items' field missing") craftguide.custom_crafts[#craftguide.custom_crafts + 1] = def end @@ -570,14 +570,23 @@ local function progressive_default_filter(recipes, player) return filtered end -local progressive_filters = {progressive_default_filter} +local progressive_filters = {{ + name = "Default filter", + func = progressive_default_filter, +}} -function craftguide.add_progressive_filter(func) - progressive_filters[#progressive_filters + 1] = func +function craftguide.add_progressive_filter(name, func) + progressive_filters[#progressive_filters + 1] = { + name = name, + func = func, + } end -function craftguide.set_progressive_filter(func) - progressive_filters = {func} +function craftguide.set_progressive_filter(name, func) + progressive_filters = {{ + name = name, + func = func, + }} end function craftguide.get_progressive_filters() @@ -586,7 +595,7 @@ end local function apply_progressive_filters(recipes, player) for i = 1, #progressive_filters do - local func = progressive_filters[i] + local func = progressive_filters[i].func recipes = func(recipes, player) end From d950c71dbc8ba05abef44f8a553e65e2a7b4157f Mon Sep 17 00:00:00 2001 From: pauloue Date: Tue, 22 Jan 2019 01:44:36 +0100 Subject: [PATCH 024/188] Refactors, optimizations and fixes --- init.lua | 531 +++++++++++++++++++++++++------------------------------ 1 file changed, 237 insertions(+), 294 deletions(-) diff --git a/init.lua b/init.lua index 313e9b4..b446cba 100644 --- a/init.lua +++ b/init.lua @@ -6,6 +6,8 @@ craftguide = { local mt = minetest local player_data = {} local init_items = {} +local recipes_cache = {} +local fuel_cache = {} local searches = {} local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode") @@ -78,23 +80,7 @@ craftguide.register_craft({ items = {"default:stone"}, }) -local function get_recipe(output) - local recipe = mt.get_craft_recipe(output) - if recipe.items then - return recipe - end - - for i = 1, #craftguide.custom_crafts do - local custom_craft = craftguide.custom_crafts[i] - if custom_craft.output:match("%S*") == output then - return custom_craft - end - end - - return {} -end - -local function get_recipes(output) +local function cache_recipes(output) local recipes = mt.get_all_craft_recipes(output) or {} for i = 1, #craftguide.custom_crafts do local custom_craft = craftguide.custom_crafts[i] @@ -103,23 +89,24 @@ local function get_recipes(output) end end - return recipes + if #recipes > 0 then + recipes_cache[output] = recipes + return true + end end -local color_codes = { - red = "#FF0000", - yellow = "#FFFF00", -} - -local function colorize(str, color) - color = color or "yellow" - return mt.colorize(color_codes[color], str) -end - -local function get_fueltime(item) +local function get_burntime(item) return get_result({method = "fuel", width = 1, items = {item}}).time end +local function cache_fuel(item) + local burntime = get_burntime(item) + if burntime > 0 then + fuel_cache[item] = burntime + return true + end +end + local function extract_groups(str) return str:sub(7):split(",") end @@ -154,85 +141,61 @@ local function groups_to_item(groups) return "" end -local function get_tooltip(item, recipe_type, cooktime, groups) - local tooltip, item_desc = "tooltip[" .. item .. ";", "" - local fueltime = get_fueltime(item) - local has_extras = groups or recipe_type == "cooking" or fueltime > 0 - - if reg_items[item] then - if not groups then - item_desc = reg_items[item].description - end - else - return tooltip .. S("Unknown Item (@1)", item) .. "]" - end +local function get_tooltip(item, groups, cooktime, burntime) + local tooltip if groups then - local groupstr = "" + local groupstr = {} for i = 1, #groups do - groupstr = groupstr .. - colorize(groups[i]) .. (groups[i + 1] and ", " or "") + groupstr[#groupstr + 1] = mt.colorize("yellow", groups[i]) end - tooltip = tooltip .. - S("Any item belonging to the group(s)") .. ": " .. groupstr + groupstr = concat(groupstr, ", ") + tooltip = S("Any item belonging to the group(s):") .. " " .. groupstr + else + tooltip = reg_items[item].description end - if recipe_type == "cooking" then - tooltip = tooltip .. item_desc .. "\n" .. - S("Cooking time") .. ": " .. colorize(cooktime) + if cooktime then + tooltip = tooltip .. "\n" .. S("Cooking time:") .. " " .. + mt.colorize("yellow", cooktime) end - if fueltime > 0 then - tooltip = tooltip .. item_desc .. "\n" .. - S("Burning time") .. ": " .. colorize(fueltime) + if burntime then + tooltip = tooltip .. "\n" .. S("Burning time:") .. " " .. + mt.colorize("yellow", burntime) end - return has_extras and tooltip .. "]" or "" + return "tooltip[" .. item .. ";" .. tooltip .. "]" end -local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) - if not recipes[1] then - return "" - end - +local function get_recipe_fs(data, iY) local fs = {} + local recipe = data.recipes[data.rnum] + local width = recipe.width + local xoffset = data.iX / 2.15 + local cooktime, shapeless - fs[#fs + 1] = fmt("button[%f,%f;%f,%f;%s;%s %u %s %u]", - iX - (sfinv_only and 2.2 or 2.6), - iY + (sfinv_only and 3.9 or 3.3), - 2.2, - 1, - "alternate", - show_usage and S("Usage") or S("Recipe"), - recipe_num, - S("of"), - #recipes) - - local recipe_type = recipes[recipe_num].type - local items = recipes[recipe_num].items - local width = recipes[recipe_num].width - - local cooktime = width - if recipe_type == "cooking" then - width = 1 + if recipe.type == "cooking" then + cooktime, width = width, 1 elseif width == 0 then - width = min(3, #items) + shapeless = true + width = min(3, #recipe.items) end - local rows = ceil(maxn(items) / width) + local rows = ceil(maxn(recipe.items) / width) local rightest, btn_size, s_btn_size = 0, 1.1 if width > GRID_LIMIT or rows > GRID_LIMIT then fs[#fs + 1] = fmt("label[%f,%f;%s]", - (iX / 2) - 2, + (data.iX / 2) - 2, iY + 2.2, S("Recipe is too big to be displayed (@1x@2)", width, rows)) return concat(fs) end - for i, item in pairs(items) do + for i, item in pairs(recipe.items) do local X = ceil((i - 1) % width + xoffset - width) - (sfinv_only and 0 or 0.2) local Y = ceil(i / width + (iY + 2) - min(2, rows)) @@ -255,7 +218,6 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) end local label = groups and "\nG" or "" - local tltp = get_tooltip(item, recipe_type, cooktime, groups) fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]", X, @@ -266,35 +228,40 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) item:match("%S*"), label) - fs[#fs + 1] = tltp + local burntime = fuel_cache[item] + + if groups or cooktime or burntime then + fs[#fs + 1] = get_tooltip(item, groups, cooktime, burntime) + end end - local custom_recipe = craftguide.craft_types[recipe_type] - if recipe_type == "cooking" or custom_recipe or - (recipe_type == "normal" and width == 0) then + local custom_recipe = craftguide.craft_types[recipe.type] - local icon = recipe_type == "cooking" and "furnace" or "shapeless" + if custom_recipe or shapeless or recipe.type == "cooking" then + local icon = custom_recipe and custom_recipe.icon or + shapeless and "shapeless" or "furnace" + if not custom_recipe then + icon = "craftguide_" .. icon .. ".png^[resize:16x16" + end fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", rightest + 1.2, iY + (sfinv_only and 2.2 or 1.7), 0.5, 0.5, - custom_recipe and custom_recipe.icon or - "craftguide_" .. icon .. ".png^[resize:16x16") + icon) + + local tooltip = custom_recipe and custom_recipe.description or + shapeless and S("Shapeless") or S("Cooking") fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", rightest + 1.2, iY + (sfinv_only and 2.2 or 1.7), 0.5, 0.5, - custom_recipe and custom_recipe.description or - recipe_type:gsub("^%l", string.upper)) + tooltip) end - local output = recipes[recipe_num].output - local output_s = output:match("%S+") - local arrow_X = rightest + (s_btn_size or 1.1) local output_X = arrow_X + 0.9 @@ -305,7 +272,7 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) 0.7, "craftguide_arrow.png") - if output == "BURN" then + if recipe.type == "fuel" then fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", output_X, iY + (sfinv_only and 2.68 or 2.18), @@ -313,33 +280,46 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage) 1.1, "craftguide_fire.png") else + local output_name = recipe.output:match("%S+") + local burntime = fuel_cache[output_name] + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]", output_X, iY + (sfinv_only and 2.7 or 2.2), 1.1, 1.1, - output, - output_s) + recipe.output, + output_name) + + if burntime then + fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime) + + fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + output_X + 1, + iY + (sfinv_only and 2.83 or 2.33), + 0.6, + 0.4, + "craftguide_arrow.png") + + fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + output_X + 1.6, + iY + (sfinv_only and 2.68 or 2.18), + 0.6, + 0.6, + "craftguide_fire.png") + end end - fs[#fs + 1] = get_tooltip(output_s) - - local output_is_fuel = get_fueltime(output) > 0 - if output_is_fuel then - fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", - output_X + 1, - iY + (sfinv_only and 2.83 or 2.33), - 0.6, - 0.4, - "craftguide_arrow.png") - - fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", - output_X + 1.6, - iY + (sfinv_only and 2.68 or 2.18), - 0.6, - 0.6, - "craftguide_fire.png") - end + fs[#fs + 1] = fmt("button[%f,%f;%f,%f;%s;%s %u %s %u]", + data.iX - (sfinv_only and 2.2 or 2.6), + iY + (sfinv_only and 3.9 or 3.3), + 2.2, + 1, + "alternate", + data.show_usages and S("Usage") or S("Recipe"), + data.rnum, + S("of"), + #data.recipes) return concat(fs) end @@ -376,16 +356,14 @@ local function make_formspec(player_name) fs[#fs + 1] = "tooltip[next;" .. S("Next page") .. "]" fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 2.6 or 3.1)) .. ",0.12;0.8,0.8;craftguide_prev_icon.png;prev;]" - fs[#fs + 1] = "label[" .. (data.iX - (sfinv_only and 1.7 or 2.2)) .. - ",0.22;" .. colorize(data.pagenum) .. " / " .. data.pagemax .. "]" + fs[#fs + 1] = "label[" .. (data.iX - (sfinv_only and 1.7 or 2.2)) .. ",0.22;" .. + mt.colorize("yellow", data.pagenum) .. " / " .. data.pagemax .. "]" fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 0.7 or 1.2) - (data.iX >= 11 and 0.08 or 0)) .. ",0.12;0.8,0.8;craftguide_next_icon.png;next;]" fs[#fs + 1] = "field[0.3,0.32;2.5,1;filter;;" .. mt.formspec_escape(data.filter) .. "]" - local xoffset = data.iX / 2.15 - - if not next(data.items) then + if #data.items == 0 then fs[#fs + 1] = fmt("label[%f,%f;%s]", (data.iX / 2) - 1, 2, @@ -411,32 +389,19 @@ local function make_formspec(player_name) name) end - if data.input and reg_items[data.input] then - local usage = data.show_usage - fs[#fs + 1] = get_recipe_fs(data.iX, - iY, - xoffset, - data.rnum, - (usage and data.usages or data.recipes_item), - usage) + if data.recipes and #data.recipes > 0 then + fs[#fs + 1] = get_recipe_fs(data, iY) end - fs = concat(fs) - - if sfinv_only then - return fs - else - data.formspec = fs - end + return concat(fs) end local show_fs = function(player, player_name) if sfinv_only then - local context = sfinv.get_or_create_context(player) - sfinv.set_player_inventory_formspec(player, context) + sfinv.set_player_inventory_formspec(player) else - make_formspec(player_name) local data = player_data[player_name] + data.formspec = make_formspec(player_name) show_formspec(player_name, "craftguide", data.formspec) end end @@ -489,68 +454,61 @@ end local function get_item_usages(item) local usages = {} - for name, def in pairs(reg_items) do - if not (def.groups.not_in_craft_guide == 1 or - def.groups.not_in_creative_inventory == 1) and - get_recipe(name).items and - def.description and def.description ~= "" then - - local recipes = get_recipes(name) - for i = 1, #recipes do - local recipe = recipes[i] - if item_in_recipe(item, recipe) then - usages[#usages + 1] = recipe - end + for _, recipes in pairs(recipes_cache) do + for i = 1, #recipes do + local recipe = recipes[i] + if item_in_recipe(item, recipe) then + usages[#usages + 1] = recipe end end end + if fuel_cache[item] then + usages[#usages + 1] = {type = "fuel", width = 1, items = {item}} + end + return usages end local function get_inv_items(player) - local invlist = player:get_inventory():get_list("main") - local inv_items = {} + local inv = player:get_inventory() + local stacks = inv:get_list("main") + local craftlist = inv:get_list("craft") - for i = 1, #invlist do - local stack = invlist[i] + for i = 1, #craftlist do + stacks[#stacks + 1] = craftlist[i] + end + + local inv_items = {} + for i = 1, #stacks do + local stack = stacks[i] if not stack:is_empty() then - inv_items[#inv_items + 1] = stack:get_name() + local name = stack:get_name() + if not inv_items[name] and reg_items[name] then + inv_items[#inv_items + 1] = name + end end end return inv_items end -local function progressive_show_recipe(recipe, inv_items) - local inv_items_size = #inv_items - for _, item in pairs(recipe.items) do - local item_in_inv - if item:sub(1,6) == "group:" then - local groups = extract_groups(item) - for i = 1, inv_items_size do - local item_def = reg_items[inv_items[i]] - if item_def then - local item_groups = item_def.groups - if item_has_groups(item_groups, groups) then - item_in_inv = true - end - end - end - else - for i = 1, inv_items_size do - if inv_items[i] == item then - item_in_inv = true - end +local function item_in_inv(item, inv_items) + if item:sub(1,6) == "group:" then + local groups = extract_groups(item) + for i = 1, #inv_items do + local item_groups = reg_items[inv_items[i]].groups + if item_has_groups(item_groups, groups) then + return true end end - - if not item_in_inv then - return + else + for i = 1, #inv_items do + if inv_items[i] == item then + return true + end end end - - return true end local function progressive_default_filter(recipes, player) @@ -562,7 +520,14 @@ local function progressive_default_filter(recipes, player) local filtered = {} for i = 1, #recipes do local recipe = recipes[i] - if progressive_show_recipe(recipe, inv_items) then + local recipe_in_inv = true + for _, item in pairs(recipe.items) do + if not item_in_inv(item, inv_items) then + recipe_in_inv = false + end + end + + if recipe_in_inv then filtered[#filtered + 1] = recipe end end @@ -606,11 +571,13 @@ local function get_progressive_items(player) local items = {} for i = 1, #init_items do local item = init_items[i] - local recipes = get_recipes(item) - recipes = apply_progressive_filters(recipes, player) + local recipes = recipes_cache[item] - if #recipes > 0 then - items[#items + 1] = item + if recipes then + recipes = apply_progressive_filters(recipes, player) + if #recipes > 0 then + items[#items + 1] = item + end end end @@ -629,22 +596,22 @@ local function init_data(player, name) end local function reset_data(data) - data.show_usage = nil - data.filter = "" - data.input = nil - data.pagenum = 1 - data.rnum = 1 - data.items = progressive_mode and data.progressive_items or init_items + data.filter = "" + data.pagenum = 1 + data.query_item = nil + data.show_usages = nil + data.recipes = nil + data.items = progressive_mode and data.progressive_items or init_items end local function get_init_items() local c = 0 for name, def in pairs(reg_items) do - local is_fuel = get_fueltime(name) > 0 + local is_fuel = cache_fuel(name) if not (def.groups.not_in_craft_guide == 1 or def.groups.not_in_creative_inventory == 1) and - (get_recipe(name).items or is_fuel) and - def.description and def.description ~= "" then + def.description and def.description ~= "" and + (cache_recipes(name) or is_fuel) then c = c + 1 init_items[c] = name end @@ -655,18 +622,7 @@ end mt.register_on_mods_loaded(get_init_items) -local function get_fields(player, ...) - local args, formname, fields = {...} - if sfinv_only then - fields = args[1] - else - formname, fields = args[1], args[2] - end - - if not sfinv_only and formname ~= "craftguide" then - return - end - +local function on_receive_fields(player, fields) local player_name = player:get_player_name() local data = player_data[player_name] @@ -675,18 +631,12 @@ local function get_fields(player, ...) show_fs(player, player_name) elseif fields.alternate then - if #(data.show_usage and data.usages or data.recipes_item) == 1 then + if #data.recipes == 1 then return end - local next_i - if data.show_usage then - next_i = data.usages[data.rnum + 1] - else - next_i = data.recipes_item[data.rnum + 1] - end - - data.rnum = next_i and data.rnum + 1 or 1 + local num_next = data.rnum + 1 + data.rnum = data.recipes[num_next] and num_next or 1 show_fs(player, player_name) elseif (fields.key_enter_field == "filter" or fields.search) and @@ -702,6 +652,10 @@ local function get_fields(player, ...) show_fs(player, player_name) elseif fields.prev or fields.next then + if data.pagemax == 1 then + return + end + data.pagenum = data.pagenum - (fields.prev and 1 or -1) if data.pagenum > data.pagemax then data.pagenum = 1 @@ -714,66 +668,63 @@ local function get_fields(player, ...) elseif (fields.size_inc and data.iX < MAX_LIMIT) or (fields.size_dec and data.iX > MIN_LIMIT) then data.pagenum = 1 - data.iX = data.iX - (fields.size_dec and 1 or -1) + data.iX = data.iX + (fields.size_inc and 1 or -1) show_fs(player, player_name) - else for item in pairs(fields) do - if item:find(":") then - if item:sub(-4) == "_inv" then - item = item:sub(1,-5) + else + local item + for field in pairs(fields) do + if field:find(":") then + item = field + break end + end - local is_fuel = get_fueltime(item) > 0 - local recipes = get_recipes(item) + if not item then + return + elseif item:sub(-4) == "_inv" then + item = item:sub(1,-5) + end + + local is_fuel = fuel_cache[item] + local recipes = recipes_cache[item] + + if progressive_mode and recipes then + recipes = apply_progressive_filters(recipes, player) + end + + local no_recipes = not recipes or #recipes == 0 + if no_recipes and not is_fuel then + return + end + + if item ~= data.query_item then + data.show_usages = nil + else + data.show_usages = not data.show_usages + end + + if is_fuel and no_recipes then + data.show_usages = true + end + + if data.show_usages then + recipes = get_item_usages(item) if progressive_mode then recipes = apply_progressive_filters(recipes, player) end - local no_recipes = not next(recipes) - if no_recipes and (progressive_mode or not is_fuel) then + if #recipes == 0 then return end - - if item ~= data.input then - data.show_usage = nil - else - data.show_usage = not data.show_usage - end - - if not progressive_mode and is_fuel and no_recipes then - data.show_usage = true - end - - if data.show_usage then - data.usages = get_item_usages(item) - - if is_fuel then - data.usages[#data.usages + 1] = { - width = 1, - type = "normal", - items = {item}, - output = "BURN", - } - end - - if progressive_mode and next(data.usages) then - data.usages = - apply_progressive_filters(data.usages, player) - end - - if not next(data.usages) then - data.show_usage = nil - end - end - - data.input = item - data.recipes_item = recipes - data.rnum = 1 - - show_fs(player, player_name) end - end + + data.query_item = item + data.recipes = recipes + data.rnum = 1 + + show_fs(player, player_name) end end @@ -782,12 +733,8 @@ if sfinv_only then title = "Craft Guide", get = function(self, player, context) - local player_name = player:get_player_name() - return sfinv.make_formspec( - player, - context, - make_formspec(player_name) - ) + local formspec = make_formspec(player:get_player_name()) + return sfinv.make_formspec(player, context, formspec) end, on_enter = function(self, player, context) @@ -803,24 +750,28 @@ if sfinv_only then end, on_player_receive_fields = function(self, player, context, fields) - get_fields(player, fields) + on_receive_fields(player, fields) end, }) else - mt.register_on_player_receive_fields(get_fields) + mt.register_on_player_receive_fields(function(player, formname, fields) + if formname == "craftguide" then + on_receive_fields(player, fields) + end + end) - local function on_use(itemstack, user) + local function on_use(user) local player_name = user:get_player_name() local data = player_data[player_name] if not data then init_data(user, player_name) - make_formspec(player_name) data = player_data[player_name] + data.formspec = make_formspec(player_name) elseif progressive_mode then data.progressive_items = get_progressive_items(user) filter_items(data) - make_formspec(player_name) + data.formspec = make_formspec(player_name) end show_formspec(player_name, "craftguide", data.formspec) @@ -833,7 +784,7 @@ else stack_max = 1, groups = {book = 1}, on_use = function(itemstack, user) - on_use(itemstack, user) + on_use(user) end }) @@ -860,7 +811,7 @@ else end, on_rightclick = function(pos, node, user, itemstack) - on_use(itemstack, user) + on_use(user) end }) @@ -894,7 +845,7 @@ else tooltip = S("Shows a list of available crafting recipes, cooking recipes and fuels"), image = "craftguide_book.png", action = function(player) - on_use(nil, player) + on_use(player) end, }) end @@ -921,7 +872,7 @@ if not progressive_mode then end if not node_name then - return false, colorize("[craftguide] ", "red") .. + return false, mt.colorize("red", "[craftguide] ") .. S("No node pointed") elseif not player_data[name] then init_data(player, name) @@ -930,34 +881,26 @@ if not progressive_mode then local data = player_data[name] reset_data(data) - local is_fuel = get_fueltime(node_name) > 0 - local recipes = get_recipes(node_name) + local recipes = recipes_cache[node_name] local no_recipes = not next(recipes) + local is_fuel = fuel_cache[node_name] if no_recipes and not is_fuel then - return false, colorize("[craftguide] ", "red") .. + return false, mt.colorize("red", "[craftguide] ") .. S("No recipe for this node:") .. " " .. - colorize(node_name) + mt.colorize("yellow", node_name) end if is_fuel and no_recipes then - data.usages = get_item_usages(node_name) - if is_fuel then - data.usages[#data.usages + 1] = { - width = 1, - type = "normal", - items = {node_name}, - output = "BURN", - } - end + recipes = get_item_usages(node_name) - if next(data.usages) then - data.show_usage = true + if #recipes > 0 then + data.show_usages = true end end - data.input = node_name - data.recipes_item = recipes + data.query_item = node_name + data.recipes = recipes return true, show_fs(player, name) end, From 8a9f8572044c45ad1c55c30e0a3637e7fa8aeb92 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 22 Jan 2019 01:51:17 +0100 Subject: [PATCH 025/188] Fix API doc --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d6cd536..4f41e06 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ craftguide.register_craft({ ### Progressive mode -#### `craftguide.add_progressive_filter(function(recipes, player))` +#### `craftguide.add_progressive_filter(name, function(recipes, player))` This function adds a recipe filter when progressive mode is enabled. The default `craftguide` filter will still be used. @@ -52,7 +52,7 @@ The default `craftguide` filter will still be used. Example function to hide recipes for items from a mod called "secretstuff": ```lua -craftguide.add_progressive_filter(function(recipes) +craftguide.add_progressive_filter("Hide secretstuff", function(recipes) local filtered = {} for _, recipe in ipairs(recipes) do if recipe.output:sub(1,12) ~= "secretstuff:" then @@ -64,7 +64,7 @@ craftguide.add_progressive_filter(function(recipes) end) ``` -#### `craftguide.set_progressive_filter(function(recipes, player))` +#### `craftguide.set_progressive_filter(name, function(recipes, player))` This function sets an unique recipe filter when progressive mode is enabled. The default `craftguide` progressive filter will be overridden. From 5d7379409642efc760ca9de1f67ae276f10c3541 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 22 Jan 2019 01:59:54 +0100 Subject: [PATCH 026/188] Localize formspec string formats --- init.lua | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/init.lua b/init.lua index b446cba..06563dd 100644 --- a/init.lua +++ b/init.lua @@ -33,6 +33,10 @@ DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) local GRID_LIMIT = 5 +local fmt_label = "label[%f,%f;%s]" +local fmt_image = "image[%f,%f;%f,%f;%s]" +local fmt_tooltip = "tooltip[%f,%f;%f,%f;%s]" + local group_stereotypes = { wool = "wool:white", dye = "dye:white", @@ -187,7 +191,7 @@ local function get_recipe_fs(data, iY) local rightest, btn_size, s_btn_size = 0, 1.1 if width > GRID_LIMIT or rows > GRID_LIMIT then - fs[#fs + 1] = fmt("label[%f,%f;%s]", + fs[#fs + 1] = fmt(fmt_label, (data.iX / 2) - 2, iY + 2.2, S("Recipe is too big to be displayed (@1x@2)", width, rows)) @@ -244,7 +248,7 @@ local function get_recipe_fs(data, iY) icon = "craftguide_" .. icon .. ".png^[resize:16x16" end - fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + fs[#fs + 1] = fmt(fmt_image, rightest + 1.2, iY + (sfinv_only and 2.2 or 1.7), 0.5, @@ -254,7 +258,7 @@ local function get_recipe_fs(data, iY) local tooltip = custom_recipe and custom_recipe.description or shapeless and S("Shapeless") or S("Cooking") - fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", + fs[#fs + 1] = fmt(fmt_tooltip, rightest + 1.2, iY + (sfinv_only and 2.2 or 1.7), 0.5, @@ -265,7 +269,7 @@ local function get_recipe_fs(data, iY) local arrow_X = rightest + (s_btn_size or 1.1) local output_X = arrow_X + 0.9 - fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + fs[#fs + 1] = fmt(fmt_image, arrow_X, iY + (sfinv_only and 2.85 or 2.35), 0.9, @@ -273,7 +277,7 @@ local function get_recipe_fs(data, iY) "craftguide_arrow.png") if recipe.type == "fuel" then - fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + fs[#fs + 1] = fmt(fmt_image, output_X, iY + (sfinv_only and 2.68 or 2.18), 1.1, @@ -294,14 +298,14 @@ local function get_recipe_fs(data, iY) if burntime then fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime) - fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + fs[#fs + 1] = fmt(fmt_image, output_X + 1, iY + (sfinv_only and 2.83 or 2.33), 0.6, 0.4, "craftguide_arrow.png") - fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]", + fs[#fs + 1] = fmt(fmt_image, output_X + 1.6, iY + (sfinv_only and 2.68 or 2.18), 0.6, @@ -364,7 +368,7 @@ local function make_formspec(player_name) fs[#fs + 1] = "field[0.3,0.32;2.5,1;filter;;" .. mt.formspec_escape(data.filter) .. "]" if #data.items == 0 then - fs[#fs + 1] = fmt("label[%f,%f;%s]", + fs[#fs + 1] = fmt(fmt_label, (data.iX / 2) - 1, 2, S("No item to show")) From e6268a395f7309a2bd16fd3ad8f59fa92b202ad4 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 22 Jan 2019 02:03:01 +0100 Subject: [PATCH 027/188] Empty data when player leaves --- init.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/init.lua b/init.lua index 06563dd..d7fa1ab 100644 --- a/init.lua +++ b/init.lua @@ -911,6 +911,13 @@ if not progressive_mode then }) end +mt.register_on_leaveplayer(function(player) + if player then + local name = player:get_player_name() + player_data[name] = nil + end +end) + --[[ Custom recipes (>3x3) test code mt.register_craftitem(":secretstuff:custom_recipe_test", { From c1b1bef263f8f8889e1303b0678f17ec263d942b Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 23 Jan 2019 02:15:26 +0100 Subject: [PATCH 028/188] Progressive mode: Remember discovered recipes --- README.md | 10 +++- init.lua | 173 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 130 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 4f41e06..4816c02 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ This crafting guide is a blue book named *"Crafting Guide"* or a wooden sign. This crafting guide features a **progressive mode**. -The progressive mode is a Terraria-like system that only shows recipes you can craft from items in inventory. -The progressive mode can be enabled with `craftguide_progressive_mode = true` in `minetest.conf`. +The progressive mode is a Terraria-like system that only shows recipes you can craft +from items you ever had in your inventory. To enable it: `craftguide_progressive_mode = true` in `minetest.conf`. -`craftguide` is also integrated in `sfinv` (Minetest Game inventory) when you enable it with +`craftguide` is also integrated in `sfinv` (Minetest Game inventory). To enable it: `craftguide_sfinv_only = true` in `minetest.conf`. Use the command `/craft` to show the recipe(s) of the pointed node. @@ -49,6 +49,10 @@ craftguide.register_craft({ This function adds a recipe filter when progressive mode is enabled. The default `craftguide` filter will still be used. +The function should return the recipes to be displayed, given the available +recipes and an `ObjectRef` to the user. Each recipe is a table of the form +returned by `minetest.get_craft_recipe`. + Example function to hide recipes for items from a mod called "secretstuff": ```lua diff --git a/init.lua b/init.lua index d7fa1ab..70116cc 100644 --- a/init.lua +++ b/init.lua @@ -16,6 +16,7 @@ local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") local reg_items = mt.registered_items local get_result = mt.get_craft_result local show_formspec = mt.show_formspec +local serialize, deserialize = mt.serialize, mt.deserialize -- Intllib local S = dofile(mt.get_modpath("craftguide") .. "/intllib.lua") @@ -47,6 +48,28 @@ local group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } +local function table_merge(t, t2) + for i = 1, #t2 do + t[#t + 1] = t2[i] + end + + return t +end + +local function table_clean(t) + local hash, ct = {}, {} + for i = 1, #t do + local v = t[i] + if not hash[v] then + ct[#ct + 1] = v + hash[v] = true + end + end + + sort(ct) + return ct +end + local function __func() return debug.getinfo(2, "n").name end @@ -328,8 +351,8 @@ local function get_recipe_fs(data, iY) return concat(fs) end -local function make_formspec(player_name) - local data = player_data[player_name] +local function make_formspec(name) + local data = player_data[name] local iY = sfinv_only and 4 or data.iX - 5 local ipp = data.iX * iY @@ -376,8 +399,8 @@ local function make_formspec(player_name) local first_item = (data.pagenum - 1) * ipp for i = first_item, first_item + ipp - 1 do - local name = data.items[i + 1] - if not name then + local item = data.items[i + 1] + if not item then break end @@ -389,8 +412,8 @@ local function make_formspec(player_name) Y, 1.1, 1.1, - name, - name) + item, + item) end if data.recipes and #data.recipes > 0 then @@ -400,13 +423,13 @@ local function make_formspec(player_name) return concat(fs) end -local show_fs = function(player, player_name) +local show_fs = function(player, name) if sfinv_only then sfinv.set_player_inventory_formspec(player) else - local data = player_data[player_name] - data.formspec = make_formspec(player_name) - show_formspec(player_name, "craftguide", data.formspec) + local data = player_data[name] + data.formspec = make_formspec(name) + show_formspec(name, "craftguide", data.formspec) end end @@ -417,7 +440,7 @@ local function filter_items(data) return end - local items_list = progressive_mode and data.progressive_items or init_items + local items_list = progressive_mode and data.p_items or init_items local filtered_list, c = {}, 0 for i = 1, #items_list do @@ -478,17 +501,14 @@ local function get_inv_items(player) local inv = player:get_inventory() local stacks = inv:get_list("main") local craftlist = inv:get_list("craft") - - for i = 1, #craftlist do - stacks[#stacks + 1] = craftlist[i] - end + stacks = table_merge(stacks, craftlist) local inv_items = {} for i = 1, #stacks do local stack = stacks[i] if not stack:is_empty() then local name = stack:get_name() - if not inv_items[name] and reg_items[name] then + if reg_items[name] then inv_items[#inv_items + 1] = name end end @@ -498,16 +518,17 @@ local function get_inv_items(player) end local function item_in_inv(item, inv_items) + local inv_items_size = #inv_items if item:sub(1,6) == "group:" then local groups = extract_groups(item) - for i = 1, #inv_items do + for i = 1, inv_items_size do local item_groups = reg_items[inv_items[i]].groups if item_has_groups(item_groups, groups) then return true end end else - for i = 1, #inv_items do + for i = 1, inv_items_size do if inv_items[i] == item then return true end @@ -516,15 +537,25 @@ local function item_in_inv(item, inv_items) end local function progressive_default_filter(recipes, player) + local name = player:get_player_name() + local data = player_data[name] local inv_items = get_inv_items(player) + + if data.inv_items then + inv_items = table_merge(data.inv_items, inv_items) + end + if #inv_items == 0 then return {} end + data.inv_items = inv_items + local filtered = {} for i = 1, #recipes do local recipe = recipes[i] local recipe_in_inv = true + for _, item in pairs(recipe.items) do if not item_in_inv(item, inv_items) then recipe_in_inv = false @@ -571,8 +602,10 @@ local function apply_progressive_filters(recipes, player) return recipes end -local function get_progressive_items(player) - local items = {} +local function get_progressive_items(player, name) + local data = player_data[name] + local items = data and data.p_items or {} + for i = 1, #init_items do local item = init_items[i] local recipes = recipes_cache[item] @@ -585,18 +618,35 @@ local function get_progressive_items(player) end end + items = table_clean(items) return items end local function init_data(player, name) - local p_items = progressive_mode and get_progressive_items(player) or nil player_data[name] = { filter = "", pagenum = 1, iX = sfinv_only and 8 or DEFAULT_SIZE, - items = p_items or init_items, - progressive_items = p_items, } + + local p_items + if progressive_mode then + local meta = player:get_meta() + player_data[name].inv_items = deserialize(meta:get_string("inv_items")) + p_items = get_progressive_items(player, name) + + if p_items then + local old_items = deserialize(meta:get_string("p_items")) + if old_items then + p_items = table_merge(p_items, old_items) + p_items = table_clean(p_items) + end + end + + player_data[name].p_items = p_items + end + + player_data[name].items = p_items or init_items end local function reset_data(data) @@ -605,7 +655,7 @@ local function reset_data(data) data.query_item = nil data.show_usages = nil data.recipes = nil - data.items = progressive_mode and data.progressive_items or init_items + data.items = progressive_mode and data.p_items or init_items end local function get_init_items() @@ -624,15 +674,13 @@ local function get_init_items() sort(init_items) end -mt.register_on_mods_loaded(get_init_items) - local function on_receive_fields(player, fields) - local player_name = player:get_player_name() - local data = player_data[player_name] + local name = player:get_player_name() + local data = player_data[name] if fields.clear then reset_data(data) - show_fs(player, player_name) + show_fs(player, name) elseif fields.alternate then if #data.recipes == 1 then @@ -641,7 +689,7 @@ local function on_receive_fields(player, fields) local num_next = data.rnum + 1 data.rnum = data.recipes[num_next] and num_next or 1 - show_fs(player, player_name) + show_fs(player, name) elseif (fields.key_enter_field == "filter" or fields.search) and fields.filter ~= "" then @@ -653,7 +701,7 @@ local function on_receive_fields(player, fields) data.filter = fltr data.pagenum = 1 filter_items(data) - show_fs(player, player_name) + show_fs(player, name) elseif fields.prev or fields.next then if data.pagemax == 1 then @@ -667,13 +715,13 @@ local function on_receive_fields(player, fields) data.pagenum = data.pagemax end - show_fs(player, player_name) + show_fs(player, name) elseif (fields.size_inc and data.iX < MAX_LIMIT) or (fields.size_dec and data.iX > MIN_LIMIT) then data.pagenum = 1 data.iX = data.iX + (fields.size_inc and 1 or -1) - show_fs(player, player_name) + show_fs(player, name) else local item @@ -728,7 +776,7 @@ local function on_receive_fields(player, fields) data.recipes = recipes data.rnum = 1 - show_fs(player, player_name) + show_fs(player, name) end end @@ -737,18 +785,20 @@ if sfinv_only then title = "Craft Guide", get = function(self, player, context) - local formspec = make_formspec(player:get_player_name()) + local name = player:get_player_name() + local formspec = make_formspec(name) + return sfinv.make_formspec(player, context, formspec) end, on_enter = function(self, player, context) - local player_name = player:get_player_name() - local data = player_data[player_name] + local name = player:get_player_name() + local data = player_data[name] if not data then - init_data(player, player_name) + init_data(player, name) elseif progressive_mode then - data.progressive_items = get_progressive_items(player) + data.p_items = get_progressive_items(player, name) filter_items(data) end end, @@ -765,20 +815,20 @@ else end) local function on_use(user) - local player_name = user:get_player_name() - local data = player_data[player_name] + local name = user:get_player_name() + local data = player_data[name] if not data then - init_data(user, player_name) - data = player_data[player_name] - data.formspec = make_formspec(player_name) + init_data(user, name) + data = player_data[name] + data.formspec = make_formspec(name) elseif progressive_mode then - data.progressive_items = get_progressive_items(user) + data.p_items = get_progressive_items(user, name) filter_items(data) - data.formspec = make_formspec(player_name) + data.formspec = make_formspec(name) end - show_formspec(player_name, "craftguide", data.formspec) + show_formspec(name, "craftguide", data.formspec) end mt.register_craftitem("craftguide:book", { @@ -911,13 +961,36 @@ if not progressive_mode then }) end +mt.register_on_mods_loaded(get_init_items) + +local function save_meta(player, data) + local meta = player:get_meta() + meta:set_string("p_items", serialize(data.p_items)) + meta:set_string("inv_items", serialize(data.inv_items)) +end + mt.register_on_leaveplayer(function(player) - if player then - local name = player:get_player_name() - player_data[name] = nil + local name = player:get_player_name() + if progressive_mode then + save_meta(player, player_data[name]) end + + player_data[name] = nil end) +if progressive_mode then + mt.register_on_shutdown(function() + local players = mt.get_connected_players() + for i = 1, #players do + local player = players[i] + if player then + local name = player:get_player_name() + save_meta(player, player_data[name]) + end + end + end) +end + --[[ Custom recipes (>3x3) test code mt.register_craftitem(":secretstuff:custom_recipe_test", { From 7fc2d3a96af70f8554824d1e14d8d696a4259220 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 27 Jan 2019 16:32:48 +0100 Subject: [PATCH 029/188] Ensure sfinv is loaded --- depends.txt | 1 + init.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/depends.txt b/depends.txt index f91ea34..91106bf 100644 --- a/depends.txt +++ b/depends.txt @@ -1,3 +1,4 @@ sfinv? sfinv_buttons? intllib? +display_api? \ No newline at end of file diff --git a/init.lua b/init.lua index 70116cc..1aa566c 100644 --- a/init.lua +++ b/init.lua @@ -11,7 +11,7 @@ local fuel_cache = {} local searches = {} local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode") -local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") +local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") local reg_items = mt.registered_items local get_result = mt.get_craft_result From fd375c92b3cb87ca3b65fc13b14e024bc9d167c0 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 30 Jan 2019 01:53:32 +0100 Subject: [PATCH 030/188] Init data when player joins --- depends.txt | 3 +-- init.lua | 19 ++++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/depends.txt b/depends.txt index 91106bf..87c6271 100644 --- a/depends.txt +++ b/depends.txt @@ -1,4 +1,3 @@ sfinv? sfinv_buttons? -intllib? -display_api? \ No newline at end of file +intllib? \ No newline at end of file diff --git a/init.lua b/init.lua index 1aa566c..ddcf3da 100644 --- a/init.lua +++ b/init.lua @@ -795,9 +795,7 @@ if sfinv_only then local name = player:get_player_name() local data = player_data[name] - if not data then - init_data(player, name) - elseif progressive_mode then + if progressive_mode then data.p_items = get_progressive_items(player, name) filter_items(data) end @@ -818,16 +816,12 @@ else local name = user:get_player_name() local data = player_data[name] - if not data then - init_data(user, name) - data = player_data[name] - data.formspec = make_formspec(name) - elseif progressive_mode then + if progressive_mode then data.p_items = get_progressive_items(user, name) filter_items(data) - data.formspec = make_formspec(name) end + data.formspec = make_formspec(name) show_formspec(name, "craftguide", data.formspec) end @@ -928,8 +922,6 @@ if not progressive_mode then if not node_name then return false, mt.colorize("red", "[craftguide] ") .. S("No node pointed") - elseif not player_data[name] then - init_data(player, name) end local data = player_data[name] @@ -963,6 +955,11 @@ end mt.register_on_mods_loaded(get_init_items) +mt.register_on_joinplayer(function(player) + local name = player:get_player_name() + init_data(player, name) +end) + local function save_meta(player, data) local meta = player:get_meta() meta:set_string("p_items", serialize(data.p_items)) From 5e8079b2e831fffe5caac0ae435c938c6036301e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 30 Jan 2019 02:14:11 +0100 Subject: [PATCH 031/188] Saving p_items not necessary --- init.lua | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/init.lua b/init.lua index ddcf3da..74fa867 100644 --- a/init.lua +++ b/init.lua @@ -633,16 +633,8 @@ local function init_data(player, name) if progressive_mode then local meta = player:get_meta() player_data[name].inv_items = deserialize(meta:get_string("inv_items")) + p_items = get_progressive_items(player, name) - - if p_items then - local old_items = deserialize(meta:get_string("p_items")) - if old_items then - p_items = table_merge(p_items, old_items) - p_items = table_clean(p_items) - end - end - player_data[name].p_items = p_items end @@ -962,7 +954,6 @@ end) local function save_meta(player, data) local meta = player:get_meta() - meta:set_string("p_items", serialize(data.p_items)) meta:set_string("inv_items", serialize(data.inv_items)) end From 5625a0cb1c6f605b912c59fad108d1666e71238f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 31 Jan 2019 01:10:09 +0100 Subject: [PATCH 032/188] Remove superfluous call --- init.lua | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/init.lua b/init.lua index 74fa867..183d2ad 100644 --- a/init.lua +++ b/init.lua @@ -627,18 +627,13 @@ local function init_data(player, name) filter = "", pagenum = 1, iX = sfinv_only and 8 or DEFAULT_SIZE, + items = init_items, } - local p_items if progressive_mode then local meta = player:get_meta() player_data[name].inv_items = deserialize(meta:get_string("inv_items")) - - p_items = get_progressive_items(player, name) - player_data[name].p_items = p_items end - - player_data[name].items = p_items or init_items end local function reset_data(data) From 4289dea10898acb9bce2325d63276dd2547b4545 Mon Sep 17 00:00:00 2001 From: pauloue Date: Sun, 3 Feb 2019 16:15:28 +0100 Subject: [PATCH 033/188] Separate recipe filters and progressive mode --- README.md | 30 ++++--- init.lua | 251 +++++++++++++++++++++++++----------------------------- 2 files changed, 132 insertions(+), 149 deletions(-) diff --git a/README.md b/README.md index 4816c02..e060ec7 100644 --- a/README.md +++ b/README.md @@ -42,21 +42,22 @@ craftguide.register_craft({ }) ``` -### Progressive mode +### Recipe filters -#### `craftguide.add_progressive_filter(name, function(recipes, player))` +Recipe filters can be used to filter the recipes shown to players. Progressive +mode is implemented as a recipe filter. -This function adds a recipe filter when progressive mode is enabled. -The default `craftguide` filter will still be used. +#### `craftguide.add_recipe_filter(name, function(recipes, player))` -The function should return the recipes to be displayed, given the available -recipes and an `ObjectRef` to the user. Each recipe is a table of the form -returned by `minetest.get_craft_recipe`. +Adds a recipe filter with the given name. The filter function should return the +recipes to be displayed, given the available recipes and an `ObjectRef` to the +user. Each recipe is a table of the form returned by +`minetest.get_craft_recipe`. Example function to hide recipes for items from a mod called "secretstuff": ```lua -craftguide.add_progressive_filter("Hide secretstuff", function(recipes) +craftguide.add_recipe_filter("Hide secretstuff", function(recipes) local filtered = {} for _, recipe in ipairs(recipes) do if recipe.output:sub(1,12) ~= "secretstuff:" then @@ -68,11 +69,14 @@ craftguide.add_progressive_filter("Hide secretstuff", function(recipes) end) ``` -#### `craftguide.set_progressive_filter(name, function(recipes, player))` +#### `craftguide.remove_recipe_filter(name)` -This function sets an unique recipe filter when progressive mode is enabled. -The default `craftguide` progressive filter will be overridden. +Removes the recipe filter with the given name. -#### `craftguide.get_progressive_filters()` +#### `craftguide.set_recipe_filter(name, function(recipe, player))` -This function returns all progressive filters that are applied to recipes in progressive mode. +Removes all recipe filters and adds a new one. + +#### `craftguide.get_recipe_filters()` + +Returns a map of recipe filters, indexed by name. diff --git a/init.lua b/init.lua index 183d2ad..b59ce68 100644 --- a/init.lua +++ b/init.lua @@ -66,7 +66,6 @@ local function table_clean(t) end end - sort(ct) return ct end @@ -107,6 +106,50 @@ craftguide.register_craft({ items = {"default:stone"}, }) +local recipe_filters = {} + +function craftguide.add_recipe_filter(name, func) + recipe_filters[name] = func +end + +function craftguide.remove_recipe_filter(name) + recipe_filters[name] = nil +end + +function craftguide.set_recipe_filter(name, func) + recipe_filters = {[name] = func} +end + +function craftguide.get_recipe_filters() + return recipe_filters +end + +local function apply_recipe_filters(recipes, player) + for _, filter in pairs(recipe_filters) do + recipes = filter(recipes, player) + end + + return recipes +end + +local function get_filtered_items(player) + local items = {} + + for i = 1, #init_items do + local item = init_items[i] + local recipes = recipes_cache[item] + + if recipes then + recipes = apply_recipe_filters(recipes, player) + if #recipes > 0 then + items[#items + 1] = item + end + end + end + + return items +end + local function cache_recipes(output) local recipes = mt.get_all_craft_recipes(output) or {} for i = 1, #craftguide.custom_crafts do @@ -427,24 +470,21 @@ local show_fs = function(player, name) if sfinv_only then sfinv.set_player_inventory_formspec(player) else - local data = player_data[name] - data.formspec = make_formspec(name) - show_formspec(name, "craftguide", data.formspec) + show_formspec(name, "craftguide", make_formspec(name)) end end -local function filter_items(data) +local function search(data) local filter = data.filter if searches[filter] then data.items = searches[filter] return end - local items_list = progressive_mode and data.p_items or init_items local filtered_list, c = {}, 0 - for i = 1, #items_list do - local item = items_list[i] + for i = 1, #data.items_raw do + local item = data.items_raw[i] local item_desc = reg_items[item].description:lower() if item:find(filter, 1, true) or item_desc:find(filter, 1, true) then @@ -453,7 +493,7 @@ local function filter_items(data) end end - if not progressive_mode then + if not next(recipe_filters) then -- Cache the results only if searched 2 times if searches[filter] == nil then searches[filter] = false @@ -499,9 +539,8 @@ end local function get_inv_items(player) local inv = player:get_inventory() - local stacks = inv:get_list("main") - local craftlist = inv:get_list("craft") - stacks = table_merge(stacks, craftlist) + local main, craft = inv:get_list("main"), inv:get_list("craft") + local stacks = table_merge(main, craft) local inv_items = {} for i = 1, #stacks do @@ -536,104 +575,14 @@ local function item_in_inv(item, inv_items) end end -local function progressive_default_filter(recipes, player) - local name = player:get_player_name() - local data = player_data[name] - local inv_items = get_inv_items(player) - - if data.inv_items then - inv_items = table_merge(data.inv_items, inv_items) - end - - if #inv_items == 0 then - return {} - end - - data.inv_items = inv_items - - local filtered = {} - for i = 1, #recipes do - local recipe = recipes[i] - local recipe_in_inv = true - - for _, item in pairs(recipe.items) do - if not item_in_inv(item, inv_items) then - recipe_in_inv = false - end - end - - if recipe_in_inv then - filtered[#filtered + 1] = recipe - end - end - - return filtered -end - -local progressive_filters = {{ - name = "Default filter", - func = progressive_default_filter, -}} - -function craftguide.add_progressive_filter(name, func) - progressive_filters[#progressive_filters + 1] = { - name = name, - func = func, - } -end - -function craftguide.set_progressive_filter(name, func) - progressive_filters = {{ - name = name, - func = func, - }} -end - -function craftguide.get_progressive_filters() - return progressive_filters -end - -local function apply_progressive_filters(recipes, player) - for i = 1, #progressive_filters do - local func = progressive_filters[i].func - recipes = func(recipes, player) - end - - return recipes -end - -local function get_progressive_items(player, name) - local data = player_data[name] - local items = data and data.p_items or {} - - for i = 1, #init_items do - local item = init_items[i] - local recipes = recipes_cache[item] - - if recipes then - recipes = apply_progressive_filters(recipes, player) - if #recipes > 0 then - items[#items + 1] = item - end - end - end - - items = table_clean(items) - return items -end - local function init_data(player, name) player_data[name] = { filter = "", pagenum = 1, iX = sfinv_only and 8 or DEFAULT_SIZE, items = init_items, + items_raw = init_items, } - - if progressive_mode then - local meta = player:get_meta() - player_data[name].inv_items = deserialize(meta:get_string("inv_items")) - end end local function reset_data(data) @@ -642,7 +591,7 @@ local function reset_data(data) data.query_item = nil data.show_usages = nil data.recipes = nil - data.items = progressive_mode and data.p_items or init_items + data.items = data.items_raw end local function get_init_items() @@ -681,13 +630,13 @@ local function on_receive_fields(player, fields) elseif (fields.key_enter_field == "filter" or fields.search) and fields.filter ~= "" then local fltr = fields.filter:lower() - if not progressive_mode and data.filter == fltr then + if data.filter == fltr then return end data.filter = fltr data.pagenum = 1 - filter_items(data) + search(data) show_fs(player, name) elseif fields.prev or fields.next then @@ -728,8 +677,8 @@ local function on_receive_fields(player, fields) local is_fuel = fuel_cache[item] local recipes = recipes_cache[item] - if progressive_mode and recipes then - recipes = apply_progressive_filters(recipes, player) + if recipes then + recipes = apply_recipe_filters(recipes, player) end local no_recipes = not recipes or #recipes == 0 @@ -748,11 +697,7 @@ local function on_receive_fields(player, fields) end if data.show_usages then - recipes = get_item_usages(item) - - if progressive_mode then - recipes = apply_progressive_filters(recipes, player) - end + recipes = apply_recipe_filters(get_item_usages(item), player) if #recipes == 0 then return @@ -782,9 +727,9 @@ if sfinv_only then local name = player:get_player_name() local data = player_data[name] - if progressive_mode then - data.p_items = get_progressive_items(player, name) - filter_items(data) + if next(recipe_filters) then + data.items_raw = get_filtered_items(player) + search(data) end end, @@ -803,13 +748,12 @@ else local name = user:get_player_name() local data = player_data[name] - if progressive_mode then - data.p_items = get_progressive_items(user, name) - filter_items(data) + if next(recipe_filters) then + data.items_raw = get_filtered_items(user) + search(data) end - data.formspec = make_formspec(name) - show_formspec(name, "craftguide", data.formspec) + show_formspec(name, "craftguide", make_formspec(name)) end mt.register_craftitem("craftguide:book", { @@ -886,7 +830,7 @@ else end end -if not progressive_mode then +if not next(recipe_filters) then mt.register_chatcommand("craft", { description = S("Show recipe(s) of the pointed node"), func = function(name) @@ -947,29 +891,64 @@ mt.register_on_joinplayer(function(player) init_data(player, name) end) -local function save_meta(player, data) - local meta = player:get_meta() - meta:set_string("inv_items", serialize(data.inv_items)) -end - mt.register_on_leaveplayer(function(player) local name = player:get_player_name() - if progressive_mode then - save_meta(player, player_data[name]) - end - player_data[name] = nil end) if progressive_mode then + local function recipe_in_inv(recipe, inv_items) + for _, item in pairs(recipe.items) do + if not item_in_inv(item, inv_items) then + return + end + end + + return true + end + + local function progressive_filter(recipes, player) + local name = player:get_player_name() + local discovered = player_data[name].inv_items + local inv_items = get_inv_items(player) + discovered = table_clean(table_merge(discovered, inv_items)) + + if #discovered == 0 then + return {} + end + + local filtered = {} + for i = 1, #recipes do + local recipe = recipes[i] + if recipe_in_inv(recipe, discovered) then + filtered[#filtered + 1] = recipe + end + end + + return filtered + end + + craftguide.add_recipe_filter("Default progressive filter", progressive_filter) + + mt.register_on_joinplayer(function(player) + local meta = player:get_meta() + local inv_items = deserialize(meta:get_string("inv_items")) or {} + local name = player:get_player_name() + player_data[name].inv_items = inv_items + end) + + local function save_meta(player) + local meta = player:get_meta() + local name = player:get_player_name() + meta:set_string("inv_items", serialize(player_data[name].inv_items)) + end + + mt.register_on_leaveplayer(save_meta) + mt.register_on_shutdown(function() local players = mt.get_connected_players() for i = 1, #players do - local player = players[i] - if player then - local name = player:get_player_name() - save_meta(player, player_data[name]) - end + save_meta(players[i]) end end) end From 3e9e16b66186fbb3889babfe8af72193dad4df63 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 5 Feb 2019 14:45:57 +0100 Subject: [PATCH 034/188] Minor cleaning --- init.lua | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/init.lua b/init.lua index b59ce68..b84a872 100644 --- a/init.lua +++ b/init.lua @@ -26,7 +26,7 @@ local S = dofile(mt.get_modpath("craftguide") .. "/intllib.lua") local maxn, sort, concat = table.maxn, table.sort, table.concat local vector_add, vector_mul = vector.add, vector.multiply local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil -local fmt = string.format +local fmt, pairs, next = string.format, pairs, next local DEFAULT_SIZE = 10 local MIN_LIMIT, MAX_LIMIT = 10, 12 @@ -152,6 +152,7 @@ end local function cache_recipes(output) local recipes = mt.get_all_craft_recipes(output) or {} + for i = 1, #craftguide.custom_crafts do local custom_craft = craftguide.custom_crafts[i] if custom_craft.output:match("%S*") == output then @@ -309,7 +310,8 @@ local function get_recipe_fs(data, iY) if custom_recipe or shapeless or recipe.type == "cooking" then local icon = custom_recipe and custom_recipe.icon or - shapeless and "shapeless" or "furnace" + shapeless and "shapeless" or "furnace" + if not custom_recipe then icon = "craftguide_" .. icon .. ".png^[resize:16x16" end @@ -402,35 +404,43 @@ local function make_formspec(name) data.pagemax = max(1, ceil(#data.items / ipp)) local fs = {} + if not sfinv_only then - fs[#fs + 1] = "size[" .. (data.iX - 0.35) .. "," .. (iY + 4) .. ";]" - fs[#fs + 1] = "no_prepend[]" - fs[#fs + 1] = "background[1,1;1,1;craftguide_bg.png;true]" + fs[#fs + 1] = fmt("size[%f,%f;]", data.iX - 0.35, iY + 4) + fs[#fs + 1] = [[ + no_prepend[] + background[1,1;1,1;craftguide_bg.png;true] + image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] + image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] + field_close_on_enter[filter;false] + ]] + fs[#fs + 1] = "tooltip[size_inc;" .. S("Increase window size") .. "]" fs[#fs + 1] = "tooltip[size_dec;" .. S("Decrease window size") .. "]" + fs[#fs + 1] = "image_button[" .. (data.iX * 0.47) .. ",0.12;0.8,0.8;craftguide_zoomin_icon.png;size_inc;]" fs[#fs + 1] = "image_button[" .. ((data.iX * 0.47) + 0.6) .. ",0.12;0.8,0.8;craftguide_zoomout_icon.png;size_dec;]" end - fs[#fs + 1] = [[ - image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] - image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] - field_close_on_enter[filter;false] - ]] - fs[#fs + 1] = "tooltip[search;" .. S("Search") .. "]" fs[#fs + 1] = "tooltip[clear;" .. S("Reset") .. "]" fs[#fs + 1] = "tooltip[prev;" .. S("Previous page") .. "]" fs[#fs + 1] = "tooltip[next;" .. S("Next page") .. "]" + fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 2.6 or 3.1)) .. ",0.12;0.8,0.8;craftguide_prev_icon.png;prev;]" - fs[#fs + 1] = "label[" .. (data.iX - (sfinv_only and 1.7 or 2.2)) .. ",0.22;" .. - mt.colorize("yellow", data.pagenum) .. " / " .. data.pagemax .. "]" - fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 0.7 or 1.2) - - (data.iX >= 11 and 0.08 or 0)) .. + + fs[#fs + 1] = fmt(fmt_label, + data.iX - (sfinv_only and 1.7 or 2.2), + 0.22, + mt.colorize("yellow", data.pagenum) .. " / " .. data.pagemax) + + fs[#fs + 1] = "image_button[" .. (data.iX - + (sfinv_only and 0.7 or 1.2) - (data.iX >= 11 and 0.08 or 0)) .. ",0.12;0.8,0.8;craftguide_next_icon.png;next;]" + fs[#fs + 1] = "field[0.3,0.32;2.5,1;filter;;" .. mt.formspec_escape(data.filter) .. "]" if #data.items == 0 then @@ -476,6 +486,7 @@ end local function search(data) local filter = data.filter + if searches[filter] then data.items = searches[filter] return @@ -521,14 +532,15 @@ end local function get_item_usages(item) local usages = {} + for _, recipes in pairs(recipes_cache) do - for i = 1, #recipes do - local recipe = recipes[i] - if item_in_recipe(item, recipe) then - usages[#usages + 1] = recipe - end + for i = 1, #recipes do + local recipe = recipes[i] + if item_in_recipe(item, recipe) then + usages[#usages + 1] = recipe end end + end if fuel_cache[item] then usages[#usages + 1] = {type = "fuel", width = 1, items = {item}} From 65a8707a691e25029512c193bea45569a95d1469 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 6 Feb 2019 01:51:09 +0100 Subject: [PATCH 035/188] Repair the /craft command --- init.lua | 111 +++++++++++++++++++++++++++---------------------------- 1 file changed, 54 insertions(+), 57 deletions(-) diff --git a/init.lua b/init.lua index b84a872..65ab96a 100644 --- a/init.lua +++ b/init.lua @@ -600,6 +600,7 @@ end local function reset_data(data) data.filter = "" data.pagenum = 1 + data.rnum = 1 data.query_item = nil data.show_usages = nil data.recipes = nil @@ -657,6 +658,7 @@ local function on_receive_fields(player, fields) end data.pagenum = data.pagenum - (fields.prev and 1 or -1) + if data.pagenum > data.pagemax then data.pagenum = 1 elseif data.pagenum == 0 then @@ -710,15 +712,14 @@ local function on_receive_fields(player, fields) if data.show_usages then recipes = apply_recipe_filters(get_item_usages(item), player) - if #recipes == 0 then return end end data.query_item = item - data.recipes = recipes - data.rnum = 1 + data.recipes = recipes + data.rnum = 1 show_fs(player, name) end @@ -842,60 +843,6 @@ else end end -if not next(recipe_filters) then - mt.register_chatcommand("craft", { - description = S("Show recipe(s) of the pointed node"), - func = function(name) - local player = mt.get_player_by_name(name) - local ppos = player:get_pos() - local dir = player:get_look_dir() - local eye_h = {x = ppos.x, y = ppos.y + 1.625, z = ppos.z} - local node_name - - for i = 1, 10 do - local look_at = vector_add(eye_h, vector_mul(dir, i)) - local node = mt.get_node(look_at) - - if node.name ~= "air" then - node_name = node.name - break - end - end - - if not node_name then - return false, mt.colorize("red", "[craftguide] ") .. - S("No node pointed") - end - - local data = player_data[name] - reset_data(data) - - local recipes = recipes_cache[node_name] - local no_recipes = not next(recipes) - local is_fuel = fuel_cache[node_name] - - if no_recipes and not is_fuel then - return false, mt.colorize("red", "[craftguide] ") .. - S("No recipe for this node:") .. " " .. - mt.colorize("yellow", node_name) - end - - if is_fuel and no_recipes then - recipes = get_item_usages(node_name) - - if #recipes > 0 then - data.show_usages = true - end - end - - data.query_item = node_name - data.recipes = recipes - - return true, show_fs(player, name) - end, - }) -end - mt.register_on_mods_loaded(get_init_items) mt.register_on_joinplayer(function(player) @@ -963,6 +910,56 @@ if progressive_mode then save_meta(players[i]) end end) +else + mt.register_chatcommand("craft", { + description = S("Show recipe(s) of the pointed node"), + func = function(name) + local player = mt.get_player_by_name(name) + local ppos = player:get_pos() + local dir = player:get_look_dir() + local eye_h = {x = ppos.x, y = ppos.y + 1.625, z = ppos.z} + local node_name + + for i = 1, 10 do + local look_at = vector_add(eye_h, vector_mul(dir, i)) + local node = mt.get_node(look_at) + + if node.name ~= "air" then + node_name = node.name + break + end + end + + if not node_name then + return false, mt.colorize("red", "[craftguide] ") .. + S("No node pointed") + end + + local data = player_data[name] + reset_data(data) + + local recipes = recipes_cache[node_name] + local is_fuel = fuel_cache[node_name] + + if not recipes then + if is_fuel then + recipes = get_item_usages(node_name) + if #recipes > 0 then + data.show_usages = true + end + else + return false, mt.colorize("red", "[craftguide] ") .. + S("No recipe for this node:") .. " " .. + mt.colorize("yellow", node_name) + end + end + + data.query_item = node_name + data.recipes = recipes + + return true, show_fs(player, name) + end, + }) end --[[ Custom recipes (>3x3) test code From 85ece2c8b917b88d39ccba4caf46468071081ac9 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 6 Feb 2019 14:37:43 -0500 Subject: [PATCH 036/188] filter /craft recipes, fix crash, fix sfinv form --- init.lua | 151 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 79 insertions(+), 72 deletions(-) diff --git a/init.lua b/init.lua index 65ab96a..b862e10 100644 --- a/init.lua +++ b/init.lua @@ -56,13 +56,13 @@ local function table_merge(t, t2) return t end -local function table_clean(t) +local function clean_items(items) local hash, ct = {}, {} - for i = 1, #t do - local v = t[i] - if not hash[v] then - ct[#ct + 1] = v - hash[v] = true + for i = 1, #items do + local item = items[i] + if not hash[item] and reg_items[item] then + ct[#ct + 1] = item + hash[item] = true end end @@ -410,9 +410,6 @@ local function make_formspec(name) fs[#fs + 1] = [[ no_prepend[] background[1,1;1,1;craftguide_bg.png;true] - image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] - image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] - field_close_on_enter[filter;false] ]] fs[#fs + 1] = "tooltip[size_inc;" .. S("Increase window size") .. "]" @@ -424,6 +421,12 @@ local function make_formspec(name) ",0.12;0.8,0.8;craftguide_zoomout_icon.png;size_dec;]" end + fs[#fs + 1] = [[ + image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] + image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] + field_close_on_enter[filter;false] + ]] + fs[#fs + 1] = "tooltip[search;" .. S("Search") .. "]" fs[#fs + 1] = "tooltip[clear;" .. S("Reset") .. "]" fs[#fs + 1] = "tooltip[prev;" .. S("Previous page") .. "]" @@ -725,6 +728,18 @@ local function on_receive_fields(player, fields) end end +mt.register_on_mods_loaded(get_init_items) + +mt.register_on_joinplayer(function(player) + local name = player:get_player_name() + init_data(player, name) +end) + +mt.register_on_leaveplayer(function(player) + local name = player:get_player_name() + player_data[name] = nil +end) + if sfinv_only then sfinv.register_page("craftguide:craftguide", { title = "Craft Guide", @@ -843,18 +858,6 @@ else end end -mt.register_on_mods_loaded(get_init_items) - -mt.register_on_joinplayer(function(player) - local name = player:get_player_name() - init_data(player, name) -end) - -mt.register_on_leaveplayer(function(player) - local name = player:get_player_name() - player_data[name] = nil -end) - if progressive_mode then local function recipe_in_inv(recipe, inv_items) for _, item in pairs(recipe.items) do @@ -870,7 +873,7 @@ if progressive_mode then local name = player:get_player_name() local discovered = player_data[name].inv_items local inv_items = get_inv_items(player) - discovered = table_clean(table_merge(discovered, inv_items)) + discovered = clean_items(table_merge(discovered, inv_items)) if #discovered == 0 then return {} @@ -910,58 +913,62 @@ if progressive_mode then save_meta(players[i]) end end) -else - mt.register_chatcommand("craft", { - description = S("Show recipe(s) of the pointed node"), - func = function(name) - local player = mt.get_player_by_name(name) - local ppos = player:get_pos() - local dir = player:get_look_dir() - local eye_h = {x = ppos.x, y = ppos.y + 1.625, z = ppos.z} - local node_name - - for i = 1, 10 do - local look_at = vector_add(eye_h, vector_mul(dir, i)) - local node = mt.get_node(look_at) - - if node.name ~= "air" then - node_name = node.name - break - end - end - - if not node_name then - return false, mt.colorize("red", "[craftguide] ") .. - S("No node pointed") - end - - local data = player_data[name] - reset_data(data) - - local recipes = recipes_cache[node_name] - local is_fuel = fuel_cache[node_name] - - if not recipes then - if is_fuel then - recipes = get_item_usages(node_name) - if #recipes > 0 then - data.show_usages = true - end - else - return false, mt.colorize("red", "[craftguide] ") .. - S("No recipe for this node:") .. " " .. - mt.colorize("yellow", node_name) - end - end - - data.query_item = node_name - data.recipes = recipes - - return true, show_fs(player, name) - end, - }) end +mt.register_chatcommand("craft", { + description = S("Show recipe(s) of the pointed node"), + func = function(name) + local player = mt.get_player_by_name(name) + local ppos = player:get_pos() + local dir = player:get_look_dir() + local eye_h = {x = ppos.x, y = ppos.y + 1.625, z = ppos.z} + local node_name + + for i = 1, 10 do + local look_at = vector_add(eye_h, vector_mul(dir, i)) + local node = mt.get_node(look_at) + + if node.name ~= "air" then + node_name = node.name + break + end + end + + if not node_name then + return false, mt.colorize("red", "[craftguide] ") .. + S("No node pointed") + end + + local data = player_data[name] + reset_data(data) + + local recipes = recipes_cache[node_name] + local is_fuel = fuel_cache[node_name] + + if recipes then + recipes = apply_recipe_filters(recipes, player) + end + + if not recipes or #recipes == 0 then + if is_fuel then + recipes = get_item_usages(node_name) + if #recipes > 0 then + data.show_usages = true + end + else + return false, mt.colorize("red", "[craftguide] ") .. + S("No recipe for this node:") .. " " .. + mt.colorize("yellow", node_name) + end + end + + data.query_item = node_name + data.recipes = recipes + + return true, show_fs(player, name) + end, +}) + --[[ Custom recipes (>3x3) test code mt.register_craftitem(":secretstuff:custom_recipe_test", { From a7dd13994fd10969431edb8dd26ae34d1833c304 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 6 Feb 2019 22:59:38 -0500 Subject: [PATCH 037/188] remove shapeless, minor refactors --- init.lua | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/init.lua b/init.lua index b862e10..fec553c 100644 --- a/init.lua +++ b/init.lua @@ -590,7 +590,7 @@ local function item_in_inv(item, inv_items) end end -local function init_data(player, name) +local function init_data(name) player_data[name] = { filter = "", pagenum = 1, @@ -732,7 +732,7 @@ mt.register_on_mods_loaded(get_init_items) mt.register_on_joinplayer(function(player) local name = player:get_player_name() - init_data(player, name) + init_data(name) end) mt.register_on_leaveplayer(function(player) @@ -752,10 +752,9 @@ if sfinv_only then end, on_enter = function(self, player, context) - local name = player:get_player_name() - local data = player_data[name] - if next(recipe_filters) then + local name = player:get_player_name() + local data = player_data[name] data.items_raw = get_filtered_items(player) search(data) end @@ -774,9 +773,9 @@ else local function on_use(user) local name = user:get_player_name() - local data = player_data[name] if next(recipe_filters) then + local data = player_data[name] data.items_raw = get_filtered_items(user) search(data) end @@ -824,8 +823,9 @@ else mt.register_craft({ output = "craftguide:book", - type = "shapeless", - recipe = {"default:book"} + recipe = { + {"default:book"} + } }) mt.register_craft({ @@ -836,8 +836,9 @@ else mt.register_craft({ output = "craftguide:sign", - type = "shapeless", - recipe = {"default:sign_wall_wood"} + recipe = { + {"default:sign_wall_wood"} + } }) mt.register_craft({ From 3498cf3f8688ef11ba9ec3d53e36f6c5bb40ee2f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 7 Feb 2019 15:53:40 +0100 Subject: [PATCH 038/188] Update license file --- LICENSE => license.txt | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) rename LICENSE => license.txt (56%) diff --git a/LICENSE b/license.txt similarity index 56% rename from LICENSE rename to license.txt index 6d1eb81..57174d4 100644 --- a/LICENSE +++ b/license.txt @@ -1,15 +1,28 @@ License of source code ---------------------- -« Copyright © 2015-2019, Jean-Patrick Guerrero and contributors. +The MIT License (MIT) -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2015-2019 Jean-Patrick Guerrero and contributors. -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders X be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. -Except as contained in this notice, the name of the shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the . » Licenses of media (textures) ---------------------------- From 6e744b44b1e64d67dedbfada44a4946bc119fc1d Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 7 Feb 2019 16:08:50 +0100 Subject: [PATCH 039/188] Few minor optimizations --- init.lua | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/init.lua b/init.lua index fec553c..7dc8411 100644 --- a/init.lua +++ b/init.lua @@ -133,7 +133,7 @@ local function apply_recipe_filters(recipes, player) end local function get_filtered_items(player) - local items = {} + local items, c = {}, 0 for i = 1, #init_items do local item = init_items[i] @@ -142,7 +142,8 @@ local function get_filtered_items(player) if recipes then recipes = apply_recipe_filters(recipes, player) if #recipes > 0 then - items[#items + 1] = item + c = c + 1 + items[c] = item end end end @@ -152,11 +153,13 @@ end local function cache_recipes(output) local recipes = mt.get_all_craft_recipes(output) or {} + local c = 0 for i = 1, #craftguide.custom_crafts do local custom_craft = craftguide.custom_crafts[i] if custom_craft.output:match("%S*") == output then - recipes[#recipes + 1] = custom_craft + c = c + 1 + recipes[c] = custom_craft end end @@ -499,9 +502,9 @@ local function search(data) for i = 1, #data.items_raw do local item = data.items_raw[i] - local item_desc = reg_items[item].description:lower() + local desc = reg_items[item].description:lower() - if item:find(filter, 1, true) or item_desc:find(filter, 1, true) then + if (item .. desc):find(filter, 1, true) then c = c + 1 filtered_list[c] = item end @@ -534,13 +537,14 @@ local function item_in_recipe(item, recipe) end local function get_item_usages(item) - local usages = {} + local usages, c = {}, 0 for _, recipes in pairs(recipes_cache) do for i = 1, #recipes do local recipe = recipes[i] if item_in_recipe(item, recipe) then - usages[#usages + 1] = recipe + c = c + 1 + usages[c] = recipe end end end @@ -556,14 +560,15 @@ local function get_inv_items(player) local inv = player:get_inventory() local main, craft = inv:get_list("main"), inv:get_list("craft") local stacks = table_merge(main, craft) + local inv_items, c = {}, 0 - local inv_items = {} for i = 1, #stacks do local stack = stacks[i] if not stack:is_empty() then local name = stack:get_name() if reg_items[name] then - inv_items[#inv_items + 1] = name + c = c + 1 + inv_items[c] = name end end end @@ -880,11 +885,12 @@ if progressive_mode then return {} end - local filtered = {} + local filtered, c = {}, 0 for i = 1, #recipes do local recipe = recipes[i] if recipe_in_inv(recipe, discovered) then - filtered[#filtered + 1] = recipe + c = c + 1 + filtered[c] = recipe end end From e37f1df6d3442c882ffa5d0deac86cb810a6b823 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 10 Feb 2019 20:37:24 +0100 Subject: [PATCH 040/188] Fix error message in progressive mode --- init.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/init.lua b/init.lua index 7dc8411..26577f0 100644 --- a/init.lua +++ b/init.lua @@ -941,9 +941,10 @@ mt.register_chatcommand("craft", { end end + local red = mt.colorize("red", "[craftguide] ") + if not node_name then - return false, mt.colorize("red", "[craftguide] ") .. - S("No node pointed") + return false, red .. S("No node pointed") end local data = player_data[name] @@ -957,15 +958,18 @@ mt.register_chatcommand("craft", { end if not recipes or #recipes == 0 then + local ylw = mt.colorize("yellow", node_name) + local msg = red .. "%s: " .. ylw + if is_fuel then recipes = get_item_usages(node_name) if #recipes > 0 then data.show_usages = true end + elseif recipes_cache[node_name] then + return false, fmt(msg, S("You don't know a recipe for this node")) else - return false, mt.colorize("red", "[craftguide] ") .. - S("No recipe for this node:") .. " " .. - mt.colorize("yellow", node_name) + return false, fmt(msg, S("No recipe for this node")) end end From fc2d2e585c464fe1892cb778c0bd83b04deae2dd Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 10 Feb 2019 23:07:28 +0100 Subject: [PATCH 041/188] Fix issue #60 --- init.lua | 145 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 76 insertions(+), 69 deletions(-) diff --git a/init.lua b/init.lua index 26577f0..56351ef 100644 --- a/init.lua +++ b/init.lua @@ -49,6 +49,8 @@ local group_stereotypes = { } local function table_merge(t, t2) + t, t2 = t or {}, t2 or {} + for i = 1, #t2 do t[#t + 1] = t2[i] end @@ -132,6 +134,55 @@ local function apply_recipe_filters(recipes, player) return recipes end +local function item_has_groups(item_groups, groups) + for i = 1, #groups do + local group = groups[i] + if not item_groups[group] then + return + end + end + + return true +end + +local function extract_groups(str) + return str:sub(7):split(",") +end + +local function item_in_recipe(item, recipe) + local item_groups = reg_items[item].groups + for _, recipe_item in pairs(recipe.items) do + if recipe_item == item then + return true + elseif recipe_item:sub(1,6) == "group:" then + local groups = extract_groups(recipe_item) + if item_has_groups(item_groups, groups) then + return true + end + end + end +end + +local function get_item_usages(item) + local usages, c = {}, 0 + + for _, recipes in pairs(recipes_cache) do + for i = 1, #recipes do + local recipe = recipes[i] + if item_in_recipe(item, recipe) then + c = c + 1 + usages[c] = recipe + end + end + end + + if fuel_cache[item] then + usages[#usages + 1] = {type = "fuel", width = 1, items = {item}} + end + + return usages +end + local function get_filtered_items(player) local items, c = {}, 0 @@ -139,6 +190,10 @@ local function get_filtered_items(player) local item = init_items[i] local recipes = recipes_cache[item] + if fuel_cache[item] then + recipes = table_merge(get_item_usages(item), recipes) + end + if recipes then recipes = apply_recipe_filters(recipes, player) if #recipes > 0 then @@ -181,21 +236,6 @@ local function cache_fuel(item) end end -local function extract_groups(str) - return str:sub(7):split(",") -end - -local function item_has_groups(item_groups, groups) - for i = 1, #groups do - local group = groups[i] - if not item_groups[group] then - return - end - end - - return true -end - local function groups_to_item(groups) if #groups == 1 then local group = groups[1] @@ -522,40 +562,6 @@ local function search(data) data.items = filtered_list end -local function item_in_recipe(item, recipe) - local item_groups = reg_items[item].groups - for _, recipe_item in pairs(recipe.items) do - if recipe_item == item then - return true - elseif recipe_item:sub(1,6) == "group:" then - local groups = extract_groups(recipe_item) - if item_has_groups(item_groups, groups) then - return true - end - end - end -end - -local function get_item_usages(item) - local usages, c = {}, 0 - - for _, recipes in pairs(recipes_cache) do - for i = 1, #recipes do - local recipe = recipes[i] - if item_in_recipe(item, recipe) then - c = c + 1 - usages[c] = recipe - end - end - end - - if fuel_cache[item] then - usages[#usages + 1] = {type = "fuel", width = 1, items = {item}} - end - - return usages -end - local function get_inv_items(player) local inv = player:get_inventory() local main, craft = inv:get_list("main"), inv:get_list("craft") @@ -576,25 +582,6 @@ local function get_inv_items(player) return inv_items end -local function item_in_inv(item, inv_items) - local inv_items_size = #inv_items - if item:sub(1,6) == "group:" then - local groups = extract_groups(item) - for i = 1, inv_items_size do - local item_groups = reg_items[inv_items[i]].groups - if item_has_groups(item_groups, groups) then - return true - end - end - else - for i = 1, inv_items_size do - if inv_items[i] == item then - return true - end - end - end -end - local function init_data(name) player_data[name] = { filter = "", @@ -865,6 +852,26 @@ else end if progressive_mode then + local function item_in_inv(item, inv_items) + local inv_items_size = #inv_items + + if item:sub(1,6) == "group:" then + local groups = extract_groups(item) + for i = 1, inv_items_size do + local item_groups = reg_items[inv_items[i]].groups + if item_has_groups(item_groups, groups) then + return true + end + end + else + for i = 1, inv_items_size do + if inv_items[i] == item then + return true + end + end + end + end + local function recipe_in_inv(recipe, inv_items) for _, item in pairs(recipe.items) do if not item_in_inv(item, inv_items) then @@ -969,7 +976,7 @@ mt.register_chatcommand("craft", { elseif recipes_cache[node_name] then return false, fmt(msg, S("You don't know a recipe for this node")) else - return false, fmt(msg, S("No recipe for this node")) + return false, fmt(msg, S("No recipe for this node")) end end From aac3e3f693d082171122508ea7e561db1f46091e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 11 Feb 2019 00:01:32 +0100 Subject: [PATCH 042/188] Add API call to open crafting guide (#59) --- README.md | 11 +++++++++ init.lua | 74 ++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index e060ec7..b093611 100644 --- a/README.md +++ b/README.md @@ -80,3 +80,14 @@ Removes all recipe filters and adds a new one. #### `craftguide.get_recipe_filters()` Returns a map of recipe filters, indexed by name. + +### Miscellaneous + +#### `craftguide.show(player_name, item, show_usages)` + +Opens the craft guide with the current filter applied. + + * `player_name`: string param. + * `item`: optional, string param. If set, this item is pre-selected. If the item does not exist or has no recipe, use the player's previous selection. By default, player's previous selection is used + * `show_usages`: optional, boolean param. If true, show item usages. + diff --git a/init.lua b/init.lua index 56351ef..1821164 100644 --- a/init.lua +++ b/init.lua @@ -16,6 +16,7 @@ local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") and rawget(_G, local reg_items = mt.registered_items local get_result = mt.get_craft_result local show_formspec = mt.show_formspec +local get_player_by_name = mt.get_player_by_name local serialize, deserialize = mt.serialize, mt.deserialize -- Intllib @@ -224,6 +225,33 @@ local function cache_recipes(output) end end +local function get_recipes(item, data, player) + local is_fuel = fuel_cache[item] + local recipes = recipes_cache[item] + + if recipes then + recipes = apply_recipe_filters(recipes, player) + end + + local no_recipes = not recipes or #recipes == 0 + if no_recipes and not is_fuel then + return + end + + if is_fuel and no_recipes then + data.show_usages = true + end + + if data.show_usages then + recipes = apply_recipe_filters(get_item_usages(item), player) + if #recipes == 0 then + return + end + end + + return recipes +end + local function get_burntime(item) return get_result({method = "fuel", width = 1, items = {item}}).time end @@ -683,37 +711,14 @@ local function on_receive_fields(player, fields) item = item:sub(1,-5) end - local is_fuel = fuel_cache[item] - local recipes = recipes_cache[item] - - if recipes then - recipes = apply_recipe_filters(recipes, player) - end - - local no_recipes = not recipes or #recipes == 0 - if no_recipes and not is_fuel then - return - end - if item ~= data.query_item then data.show_usages = nil else data.show_usages = not data.show_usages end - if is_fuel and no_recipes then - data.show_usages = true - end - - if data.show_usages then - recipes = apply_recipe_filters(get_item_usages(item), player) - if #recipes == 0 then - return - end - end - data.query_item = item - data.recipes = recipes + data.recipes = get_recipes(item, data, player) data.rnum = 1 show_fs(player, name) @@ -932,7 +937,7 @@ end mt.register_chatcommand("craft", { description = S("Show recipe(s) of the pointed node"), func = function(name) - local player = mt.get_player_by_name(name) + local player = get_player_by_name(name) local ppos = player:get_pos() local dir = player:get_look_dir() local eye_h = {x = ppos.x, y = ppos.y + 1.625, z = ppos.z} @@ -987,6 +992,25 @@ mt.register_chatcommand("craft", { end, }) +function craftguide.show(name, item, show_usages) + local func = "craftguide." .. __func() .. "(): " + assert(name, func .. "player name missing") + + local data = player_data[name] + local player = get_player_by_name(name) + local query_item = data.query_item + + reset_data(data) + + item = reg_items[item] and item or query_item + + data.query_item = item + data.show_usages = show_usages + data.recipes = get_recipes(item, data, player) + + show_fs(player, name) +end + --[[ Custom recipes (>3x3) test code mt.register_craftitem(":secretstuff:custom_recipe_test", { From c4272d8d248769f1a8efe2d9a1077904eff64f13 Mon Sep 17 00:00:00 2001 From: Wuzzy2 Date: Mon, 11 Feb 2019 00:18:10 +0100 Subject: [PATCH 043/188] Add formspec escape, apply proper format strings --- init.lua | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/init.lua b/init.lua index 1821164..d2aa6e6 100644 --- a/init.lua +++ b/init.lua @@ -13,6 +13,7 @@ local searches = {} local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode") local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") +local fs_esc = mt.formspec_escape local reg_items = mt.registered_items local get_result = mt.get_craft_result local show_formspec = mt.show_formspec @@ -293,22 +294,22 @@ local function get_tooltip(item, groups, cooktime, burntime) end groupstr = concat(groupstr, ", ") - tooltip = S("Any item belonging to the group(s):") .. " " .. groupstr + tooltip = S("Any item belonging to the group(s): @1", groupstr) else tooltip = reg_items[item].description end if cooktime then - tooltip = tooltip .. "\n" .. S("Cooking time:") .. " " .. - mt.colorize("yellow", cooktime) + tooltip = tooltip .. "\n" .. S("Cooking time: @1", + mt.colorize("yellow", cooktime)) end if burntime then - tooltip = tooltip .. "\n" .. S("Burning time:") .. " " .. - mt.colorize("yellow", burntime) + tooltip = tooltip .. "\n" .. S("Burning time: @1", + mt.colorize("yellow", burntime)) end - return "tooltip[" .. item .. ";" .. tooltip .. "]" + return "tooltip[" .. item .. ";" .. fs_esc(tooltip) .. "]" end local function get_recipe_fs(data, iY) @@ -332,7 +333,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(fmt_label, (data.iX / 2) - 2, iY + 2.2, - S("Recipe is too big to be displayed (@1x@2)", width, rows)) + fs_esc(S("Recipe is too big to be displayed (@1x@2)", width, rows))) return concat(fs) end @@ -368,7 +369,7 @@ local function get_recipe_fs(data, iY) btn_size, item, item:match("%S*"), - label) + fs_esc(label)) local burntime = fuel_cache[item] @@ -402,7 +403,7 @@ local function get_recipe_fs(data, iY) iY + (sfinv_only and 2.2 or 1.7), 0.5, 0.5, - tooltip) + fs_esc(tooltip)) end local arrow_X = rightest + (s_btn_size or 1.1) @@ -432,7 +433,7 @@ local function get_recipe_fs(data, iY) 1.1, 1.1, recipe.output, - output_name) + fs_esc(output_name)) if burntime then fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime) @@ -459,9 +460,9 @@ local function get_recipe_fs(data, iY) 2.2, 1, "alternate", - data.show_usages and S("Usage") or S("Recipe"), + data.show_usages and fs_esc(S("Usage")) or fs_esc(S("Recipe")), data.rnum, - S("of"), + fs_esc(S("of")), #data.recipes) return concat(fs) @@ -483,8 +484,8 @@ local function make_formspec(name) background[1,1;1,1;craftguide_bg.png;true] ]] - fs[#fs + 1] = "tooltip[size_inc;" .. S("Increase window size") .. "]" - fs[#fs + 1] = "tooltip[size_dec;" .. S("Decrease window size") .. "]" + fs[#fs + 1] = "tooltip[size_inc;" .. fs_esc(S("Increase window size")) .. "]" + fs[#fs + 1] = "tooltip[size_dec;" .. fs_esc(S("Decrease window size")) .. "]" fs[#fs + 1] = "image_button[" .. (data.iX * 0.47) .. ",0.12;0.8,0.8;craftguide_zoomin_icon.png;size_inc;]" @@ -498,10 +499,10 @@ local function make_formspec(name) field_close_on_enter[filter;false] ]] - fs[#fs + 1] = "tooltip[search;" .. S("Search") .. "]" - fs[#fs + 1] = "tooltip[clear;" .. S("Reset") .. "]" - fs[#fs + 1] = "tooltip[prev;" .. S("Previous page") .. "]" - fs[#fs + 1] = "tooltip[next;" .. S("Next page") .. "]" + fs[#fs + 1] = "tooltip[search;" .. fs_esc(S("Search")) .. "]" + fs[#fs + 1] = "tooltip[clear;" .. fs_esc(S("Reset")) .. "]" + fs[#fs + 1] = "tooltip[prev;" .. fs_esc(S("Previous page")) .. "]" + fs[#fs + 1] = "tooltip[next;" .. fs_esc(S("Next page")) .. "]" fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 2.6 or 3.1)) .. ",0.12;0.8,0.8;craftguide_prev_icon.png;prev;]" @@ -515,13 +516,13 @@ local function make_formspec(name) (sfinv_only and 0.7 or 1.2) - (data.iX >= 11 and 0.08 or 0)) .. ",0.12;0.8,0.8;craftguide_next_icon.png;next;]" - fs[#fs + 1] = "field[0.3,0.32;2.5,1;filter;;" .. mt.formspec_escape(data.filter) .. "]" + fs[#fs + 1] = "field[0.3,0.32;2.5,1;filter;;" .. fs_esc(data.filter) .. "]" if #data.items == 0 then fs[#fs + 1] = fmt(fmt_label, (data.iX / 2) - 1, 2, - S("No item to show")) + fs_esc(S("No item to show"))) end local first_item = (data.pagenum - 1) * ipp @@ -739,7 +740,7 @@ end) if sfinv_only then sfinv.register_page("craftguide:craftguide", { - title = "Craft Guide", + title = S("Craft Guide"), get = function(self, player, context) local name = player:get_player_name() From 3cf4bef83a738c0da37b525abe4828191d92032b Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 11 Feb 2019 00:22:00 +0100 Subject: [PATCH 044/188] Shorten function name --- init.lua | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/init.lua b/init.lua index d2aa6e6..6986265 100644 --- a/init.lua +++ b/init.lua @@ -13,6 +13,7 @@ local searches = {} local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode") local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") +local colorize = mt.colorize local fs_esc = mt.formspec_escape local reg_items = mt.registered_items local get_result = mt.get_craft_result @@ -290,7 +291,7 @@ local function get_tooltip(item, groups, cooktime, burntime) if groups then local groupstr = {} for i = 1, #groups do - groupstr[#groupstr + 1] = mt.colorize("yellow", groups[i]) + groupstr[#groupstr + 1] = colorize("yellow", groups[i]) end groupstr = concat(groupstr, ", ") @@ -300,13 +301,13 @@ local function get_tooltip(item, groups, cooktime, burntime) end if cooktime then - tooltip = tooltip .. "\n" .. S("Cooking time: @1", - mt.colorize("yellow", cooktime)) + tooltip = tooltip .. "\n" .. + S("Cooking time: @1", colorize("yellow", cooktime)) end if burntime then - tooltip = tooltip .. "\n" .. S("Burning time: @1", - mt.colorize("yellow", burntime)) + tooltip = tooltip .. "\n" .. + S("Burning time: @1", colorize("yellow", burntime)) end return "tooltip[" .. item .. ";" .. fs_esc(tooltip) .. "]" @@ -510,7 +511,7 @@ local function make_formspec(name) fs[#fs + 1] = fmt(fmt_label, data.iX - (sfinv_only and 1.7 or 2.2), 0.22, - mt.colorize("yellow", data.pagenum) .. " / " .. data.pagemax) + colorize("yellow", data.pagenum) .. " / " .. data.pagemax) fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 0.7 or 1.2) - (data.iX >= 11 and 0.08 or 0)) .. @@ -954,7 +955,7 @@ mt.register_chatcommand("craft", { end end - local red = mt.colorize("red", "[craftguide] ") + local red = colorize("red", "[craftguide] ") if not node_name then return false, red .. S("No node pointed") @@ -971,7 +972,7 @@ mt.register_chatcommand("craft", { end if not recipes or #recipes == 0 then - local ylw = mt.colorize("yellow", node_name) + local ylw = colorize("yellow", node_name) local msg = red .. "%s: " .. ylw if is_fuel then From 1ba1e41dcd89576208570bea82e3d6b6c982e1ed Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 11 Feb 2019 00:30:06 +0100 Subject: [PATCH 045/188] Progressive: Add a better error message for empty items list --- init.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/init.lua b/init.lua index 6986265..3000398 100644 --- a/init.lua +++ b/init.lua @@ -520,10 +520,15 @@ local function make_formspec(name) fs[#fs + 1] = "field[0.3,0.32;2.5,1;filter;;" .. fs_esc(data.filter) .. "]" if #data.items == 0 then - fs[#fs + 1] = fmt(fmt_label, - (data.iX / 2) - 1, - 2, - fs_esc(S("No item to show"))) + local no_item = S("No item to show") + local pos = (data.iX / 2) - 1 + + if next(recipe_filters) and #init_items > 0 and data.filter == "" then + no_item = S("Collect items to reveal more recipes") + pos = pos - 1 + end + + fs[#fs + 1] = fmt(fmt_label, pos, 2, fs_esc(no_item)) end local first_item = (data.pagenum - 1) * ipp From 3f44ae00d20b7056718ee840ef76b62487bd5724 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 11 Feb 2019 01:03:48 +0100 Subject: [PATCH 046/188] Remove demo custom recipe --- README.md | 4 ++-- init.lua | 16 +--------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index b093611..7dbbec5 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Use the command `/craft` to show the recipe(s) of the pointed node. ### Custom recipes -#### Registering a custom crafting type +#### Registering a custom crafting type (example) ```Lua craftguide.register_craft_type("digging", { @@ -31,7 +31,7 @@ craftguide.register_craft_type("digging", { }) ``` -#### Registering a custom crafting recipe +#### Registering a custom crafting recipe (example) ```Lua craftguide.register_craft({ diff --git a/init.lua b/init.lua index 3000398..26c0c5e 100644 --- a/init.lua +++ b/init.lua @@ -89,11 +89,6 @@ function craftguide.register_craft_type(name, def) end end -craftguide.register_craft_type("digging", { - description = S("Digging"), - icon = "default_tool_steelpick.png", -}) - function craftguide.register_craft(def) local func = "craftguide." .. __func() .. "(): " assert(def.type, func .. "'type' field missing") @@ -104,13 +99,6 @@ function craftguide.register_craft(def) craftguide.custom_crafts[#craftguide.custom_crafts + 1] = def end -craftguide.register_craft({ - type = "digging", - width = 1, - output = "default:cobble", - items = {"default:stone"}, -}) - local recipe_filters = {} function craftguide.add_recipe_filter(name, func) @@ -238,9 +226,7 @@ local function get_recipes(item, data, player) local no_recipes = not recipes or #recipes == 0 if no_recipes and not is_fuel then return - end - - if is_fuel and no_recipes then + elseif is_fuel and no_recipes then data.show_usages = true end From 4560457504a377fc84f5435a38fcc99eb87e4372 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 11 Feb 2019 23:52:31 +0100 Subject: [PATCH 047/188] Mitigate the performance regression since fc2d2e5 --- README.md | 2 +- init.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7dbbec5..203f717 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ Returns a map of recipe filters, indexed by name. #### `craftguide.show(player_name, item, show_usages)` -Opens the craft guide with the current filter applied. +Opens the Crafting Guide with the current filter applied. * `player_name`: string param. * `item`: optional, string param. If set, this item is pre-selected. If the item does not exist or has no recipe, use the player's previous selection. By default, player's previous selection is used diff --git a/init.lua b/init.lua index 26c0c5e..b3b2b8d 100644 --- a/init.lua +++ b/init.lua @@ -181,7 +181,7 @@ local function get_filtered_items(player) local item = init_items[i] local recipes = recipes_cache[item] - if fuel_cache[item] then + if not recipes and fuel_cache[item] then recipes = table_merge(get_item_usages(item), recipes) end From b3bba5c2ff437991a4db7670c41dcc2ce14ee41e Mon Sep 17 00:00:00 2001 From: pauloue Date: Wed, 13 Feb 2019 00:50:26 +0100 Subject: [PATCH 048/188] Fix get_filtered_items() --- init.lua | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/init.lua b/init.lua index b3b2b8d..74cb26f 100644 --- a/init.lua +++ b/init.lua @@ -180,17 +180,12 @@ local function get_filtered_items(player) for i = 1, #init_items do local item = init_items[i] local recipes = recipes_cache[item] + local fuel = fuel_cache[item] - if not recipes and fuel_cache[item] then - recipes = table_merge(get_item_usages(item), recipes) - end - - if recipes then - recipes = apply_recipe_filters(recipes, player) - if #recipes > 0 then - c = c + 1 - items[c] = item - end + if recipes and #apply_recipe_filters(recipes, player) > 0 or + fuel and #apply_recipe_filters(get_item_usages(item), player) > 0 then + c = c + 1 + items[c] = item end end From 07bc14e516f0b17cac00b5526a37419e145932a3 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 13 Feb 2019 00:45:06 +0100 Subject: [PATCH 049/188] Track new discovered items all the time --- init.lua | 69 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/init.lua b/init.lua index 74cb26f..23c6f08 100644 --- a/init.lua +++ b/init.lua @@ -53,25 +53,40 @@ local group_stereotypes = { local function table_merge(t, t2) t, t2 = t or {}, t2 or {} + local c = #t for i = 1, #t2 do - t[#t + 1] = t2[i] + c = c + 1 + t[c] = t2[i] end return t end -local function clean_items(items) - local hash, ct = {}, {} - for i = 1, #items do - local item = items[i] - if not hash[item] and reg_items[item] then - ct[#ct + 1] = item - hash[item] = true +local function table_diff(t, t2) + local t3 = {} + + for i = 1, #t do + local v = t[i] + t3[v] = true + end + + for i = 1, #t2 do + local v = t2[i] + t3[v] = nil + end + + local ret, c = {}, 0 + + for i = 1, #t do + local v = t[i] + if t3[v] then + c = c + 1 + ret[c] = v end end - return ct + return ret end local function __func() @@ -740,6 +755,7 @@ if sfinv_only then if next(recipe_filters) then local name = player:get_player_name() local data = player_data[name] + data.items_raw = get_filtered_items(player) search(data) end @@ -877,18 +893,16 @@ if progressive_mode then local function progressive_filter(recipes, player) local name = player:get_player_name() - local discovered = player_data[name].inv_items - local inv_items = get_inv_items(player) - discovered = clean_items(table_merge(discovered, inv_items)) + local data = player_data[name] - if #discovered == 0 then + if #data.inv_items == 0 then return {} end local filtered, c = {}, 0 for i = 1, #recipes do local recipe = recipes[i] - if recipe_in_inv(recipe, discovered) then + if recipe_in_inv(recipe, data.inv_items) then c = c + 1 filtered[c] = recipe end @@ -897,19 +911,37 @@ if progressive_mode then return filtered end + mt.register_globalstep(function() + local players = mt.get_connected_players() + for i = 1, #players do + local player = players[i] + local name = player:get_player_name() + local data = player_data[name] + local inv_items = get_inv_items(player) + local diff = table_diff(inv_items, data.inv_items) + + if #diff > 0 then + data.inv_items = table_merge(diff, data.inv_items) + end + end + end) + craftguide.add_recipe_filter("Default progressive filter", progressive_filter) mt.register_on_joinplayer(function(player) local meta = player:get_meta() - local inv_items = deserialize(meta:get_string("inv_items")) or {} local name = player:get_player_name() - player_data[name].inv_items = inv_items + local data = player_data[name] + + data.inv_items = deserialize(meta:get_string("inv_items")) or {} end) local function save_meta(player) local meta = player:get_meta() local name = player:get_player_name() - meta:set_string("inv_items", serialize(player_data[name].inv_items)) + local data = player_data[name] + + meta:set_string("inv_items", serialize(data.inv_items)) end mt.register_on_leaveplayer(save_meta) @@ -917,7 +949,8 @@ if progressive_mode then mt.register_on_shutdown(function() local players = mt.get_connected_players() for i = 1, #players do - save_meta(players[i]) + local player = players[i] + save_meta(player) end end) end From 0956e86d733e052d401f3c8d5ec382b6740f7109 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 13 Feb 2019 01:30:34 +0100 Subject: [PATCH 050/188] Check also the 'craftpreview' list --- init.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index 23c6f08..a69051f 100644 --- a/init.lua +++ b/init.lua @@ -51,6 +51,12 @@ local group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } +local item_lists = { + "main", + "craft", + "craftpreview", +} + local function table_merge(t, t2) t, t2 = t or {}, t2 or {} local c = #t @@ -595,8 +601,12 @@ end local function get_inv_items(player) local inv = player:get_inventory() - local main, craft = inv:get_list("main"), inv:get_list("craft") - local stacks = table_merge(main, craft) + local stacks = {} + + for i = 1, #item_lists do + stacks = table_merge(stacks, inv:get_list(item_lists[i])) + end + local inv_items, c = {}, 0 for i = 1, #stacks do From 40b5f8725ad34d0e287af116f20739ec577fdd1f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 13 Feb 2019 14:04:13 +0100 Subject: [PATCH 051/188] Fix some glitch --- init.lua | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/init.lua b/init.lua index a69051f..65dd37e 100644 --- a/init.lua +++ b/init.lua @@ -70,23 +70,23 @@ local function table_merge(t, t2) end local function table_diff(t, t2) - local t3 = {} + local hash = {} for i = 1, #t do local v = t[i] - t3[v] = true + hash[v] = true end for i = 1, #t2 do local v = t2[i] - t3[v] = nil + hash[v] = nil end local ret, c = {}, 0 for i = 1, #t do local v = t[i] - if t3[v] then + if hash[v] then c = c + 1 ret[c] = v end @@ -730,8 +730,13 @@ local function on_receive_fields(player, fields) data.show_usages = not data.show_usages end + local recipes = get_recipes(item, data, player) + if not recipes then + return + end + data.query_item = item - data.recipes = get_recipes(item, data, player) + data.recipes = recipes data.rnum = 1 show_fs(player, name) From 8f6f8dda7e07ceb1a8b751de2efada929c0de362 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 13 Feb 2019 14:15:29 +0100 Subject: [PATCH 052/188] Use engine translator, ditch intllib --- depends.txt | 3 +- init.lua | 3 +- intllib.lua | 45 ------------------------------ locale/{de.po => craftguide.de.tr} | 0 locale/{ms.po => craftguide.ms.tr} | 0 locale/{ru.po => craftguide.ru.tr} | 0 6 files changed, 2 insertions(+), 49 deletions(-) delete mode 100644 intllib.lua rename locale/{de.po => craftguide.de.tr} (100%) rename locale/{ms.po => craftguide.ms.tr} (100%) rename locale/{ru.po => craftguide.ru.tr} (100%) diff --git a/depends.txt b/depends.txt index 87c6271..ad29828 100644 --- a/depends.txt +++ b/depends.txt @@ -1,3 +1,2 @@ sfinv? -sfinv_buttons? -intllib? \ No newline at end of file +sfinv_buttons? \ No newline at end of file diff --git a/init.lua b/init.lua index 65dd37e..cf5b18a 100644 --- a/init.lua +++ b/init.lua @@ -21,8 +21,7 @@ local show_formspec = mt.show_formspec local get_player_by_name = mt.get_player_by_name local serialize, deserialize = mt.serialize, mt.deserialize --- Intllib -local S = dofile(mt.get_modpath("craftguide") .. "/intllib.lua") +local S = mt.get_translator("craftguide") -- Lua 5.3 removed `table.maxn`, use this alternative in case of breakage: -- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1 diff --git a/intllib.lua b/intllib.lua deleted file mode 100644 index 6669d72..0000000 --- a/intllib.lua +++ /dev/null @@ -1,45 +0,0 @@ - --- Fallback functions for when `intllib` is not installed. --- Code released under Unlicense . - --- Get the latest version of this file at: --- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua - -local function format(str, ...) - local args = { ... } - local function repl(escape, open, num, close) - if escape == "" then - local replacement = tostring(args[tonumber(num)]) - if open == "" then - replacement = replacement..close - end - return replacement - else - return "@"..open..num..close - end - end - return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) -end - -local gettext, ngettext -if minetest.get_modpath("intllib") then - if intllib.make_gettext_pair then - -- New method using gettext. - gettext, ngettext = intllib.make_gettext_pair() - else - -- Old method using text files. - gettext = intllib.Getter() - end -end - --- Fill in missing functions. - -gettext = gettext or function(msgid, ...) - return format(msgid, ...) -end - -ngettext = ngettext or function(msgid, msgid_plural, n, ...) - return format(n==1 and msgid or msgid_plural, ...) -end - -return gettext, ngettext diff --git a/locale/de.po b/locale/craftguide.de.tr similarity index 100% rename from locale/de.po rename to locale/craftguide.de.tr diff --git a/locale/ms.po b/locale/craftguide.ms.tr similarity index 100% rename from locale/ms.po rename to locale/craftguide.ms.tr diff --git a/locale/ru.po b/locale/craftguide.ru.tr similarity index 100% rename from locale/ru.po rename to locale/craftguide.ru.tr From c62994f9af73e8cb40d4f7623af3bb44015445ea Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 13 Feb 2019 14:24:13 +0100 Subject: [PATCH 053/188] Split API doc in separate file --- API.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 80 +++---------------------------------------------------- 2 files changed, 76 insertions(+), 76 deletions(-) create mode 100644 API.md diff --git a/API.md b/API.md new file mode 100644 index 0000000..b73893d --- /dev/null +++ b/API.md @@ -0,0 +1,72 @@ +## API + +### Custom recipes + +#### Registering a custom crafting type (example) + +```Lua +craftguide.register_craft_type("digging", { + description = "Digging", + icon = "default_tool_steelpick.png", +}) +``` + +#### Registering a custom crafting recipe (example) + +```Lua +craftguide.register_craft({ + type = "digging", + width = 1, + output = "default:cobble 2", + items = {"default:stone"}, +}) +``` + +### Recipe filters + +Recipe filters can be used to filter the recipes shown to players. Progressive +mode is implemented as a recipe filter. + +#### `craftguide.add_recipe_filter(name, function(recipes, player))` + +Adds a recipe filter with the given name. The filter function should return the +recipes to be displayed, given the available recipes and an `ObjectRef` to the +user. Each recipe is a table of the form returned by +`minetest.get_craft_recipe`. + +Example function to hide recipes for items from a mod called "secretstuff": + +```lua +craftguide.add_recipe_filter("Hide secretstuff", function(recipes) + local filtered = {} + for _, recipe in ipairs(recipes) do + if recipe.output:sub(1,12) ~= "secretstuff:" then + filtered[#filtered + 1] = recipe + end + end + + return filtered +end) +``` + +#### `craftguide.remove_recipe_filter(name)` + +Removes the recipe filter with the given name. + +#### `craftguide.set_recipe_filter(name, function(recipe, player))` + +Removes all recipe filters and adds a new one. + +#### `craftguide.get_recipe_filters()` + +Returns a map of recipe filters, indexed by name. + +### Miscellaneous + +#### `craftguide.show(player_name, item, show_usages)` + +Opens the Crafting Guide with the current filter applied. + + * `player_name`: string param. + * `item`: optional, string param. If set, this item is pre-selected. If the item does not exist or has no recipe, use the player's previous selection. By default, player's previous selection is used + * `show_usages`: optional, boolean param. If true, show item usages. diff --git a/README.md b/README.md index 203f717..00f7e8e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This crafting guide is a blue book named *"Crafting Guide"* or a wooden sign. This crafting guide features a **progressive mode**. -The progressive mode is a Terraria-like system that only shows recipes you can craft +The progressive mode is a Terraria-like system that shows recipes you can craft from items you ever had in your inventory. To enable it: `craftguide_progressive_mode = true` in `minetest.conf`. `craftguide` is also integrated in `sfinv` (Minetest Game inventory). To enable it: @@ -14,80 +14,8 @@ from items you ever had in your inventory. To enable it: `craftguide_progressive Use the command `/craft` to show the recipe(s) of the pointed node. +For developers, `craftguide` also has a [modding API](https://github.com/minetest-mods/craftguide/blob/master/API.md). + + ![Preview2](https://i.imgur.com/bToFH38.png) ---- - -## API - -### Custom recipes - -#### Registering a custom crafting type (example) - -```Lua -craftguide.register_craft_type("digging", { - description = "Digging", - icon = "default_tool_steelpick.png", -}) -``` - -#### Registering a custom crafting recipe (example) - -```Lua -craftguide.register_craft({ - type = "digging", - width = 1, - output = "default:cobble 2", - items = {"default:stone"}, -}) -``` - -### Recipe filters - -Recipe filters can be used to filter the recipes shown to players. Progressive -mode is implemented as a recipe filter. - -#### `craftguide.add_recipe_filter(name, function(recipes, player))` - -Adds a recipe filter with the given name. The filter function should return the -recipes to be displayed, given the available recipes and an `ObjectRef` to the -user. Each recipe is a table of the form returned by -`minetest.get_craft_recipe`. - -Example function to hide recipes for items from a mod called "secretstuff": - -```lua -craftguide.add_recipe_filter("Hide secretstuff", function(recipes) - local filtered = {} - for _, recipe in ipairs(recipes) do - if recipe.output:sub(1,12) ~= "secretstuff:" then - filtered[#filtered + 1] = recipe - end - end - - return filtered -end) -``` - -#### `craftguide.remove_recipe_filter(name)` - -Removes the recipe filter with the given name. - -#### `craftguide.set_recipe_filter(name, function(recipe, player))` - -Removes all recipe filters and adds a new one. - -#### `craftguide.get_recipe_filters()` - -Returns a map of recipe filters, indexed by name. - -### Miscellaneous - -#### `craftguide.show(player_name, item, show_usages)` - -Opens the Crafting Guide with the current filter applied. - - * `player_name`: string param. - * `item`: optional, string param. If set, this item is pre-selected. If the item does not exist or has no recipe, use the player's previous selection. By default, player's previous selection is used - * `show_usages`: optional, boolean param. If true, show item usages. - From d6432f53bb4db1cfb37ddf19155588bb654aaba0 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 13 Feb 2019 14:32:36 +0100 Subject: [PATCH 054/188] Add a comment on the item polling --- init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/init.lua b/init.lua index cf5b18a..7fe6a92 100644 --- a/init.lua +++ b/init.lua @@ -925,6 +925,8 @@ if progressive_mode then return filtered end + -- Workaround. Need an engine call to detect when the contents + -- of the player inventory changed, instead. mt.register_globalstep(function() local players = mt.get_connected_players() for i = 1, #players do From 97e6eceb755b12480290c94fcc6fb9df37580f0d Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sat, 16 Feb 2019 01:52:01 +0100 Subject: [PATCH 055/188] Progressive: Poll new items every 0.5s --- init.lua | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/init.lua b/init.lua index 7fe6a92..4738a86 100644 --- a/init.lua +++ b/init.lua @@ -35,10 +35,11 @@ local MIN_LIMIT, MAX_LIMIT = 10, 12 DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) local GRID_LIMIT = 5 +local POLL_FREQ = 0.5 -local fmt_label = "label[%f,%f;%s]" -local fmt_image = "image[%f,%f;%f,%f;%s]" -local fmt_tooltip = "tooltip[%f,%f;%f,%f;%s]" +local FMT_label = "label[%f,%f;%s]" +local FMT_image = "image[%f,%f;%f,%f;%s]" +local FMT_tooltip = "tooltip[%f,%f;%f,%f;%s]" local group_stereotypes = { wool = "wool:white", @@ -332,7 +333,7 @@ local function get_recipe_fs(data, iY) local rightest, btn_size, s_btn_size = 0, 1.1 if width > GRID_LIMIT or rows > GRID_LIMIT then - fs[#fs + 1] = fmt(fmt_label, + fs[#fs + 1] = fmt(FMT_label, (data.iX / 2) - 2, iY + 2.2, fs_esc(S("Recipe is too big to be displayed (@1x@2)", width, rows))) @@ -390,7 +391,7 @@ local function get_recipe_fs(data, iY) icon = "craftguide_" .. icon .. ".png^[resize:16x16" end - fs[#fs + 1] = fmt(fmt_image, + fs[#fs + 1] = fmt(FMT_image, rightest + 1.2, iY + (sfinv_only and 2.2 or 1.7), 0.5, @@ -400,7 +401,7 @@ local function get_recipe_fs(data, iY) local tooltip = custom_recipe and custom_recipe.description or shapeless and S("Shapeless") or S("Cooking") - fs[#fs + 1] = fmt(fmt_tooltip, + fs[#fs + 1] = fmt(FMT_tooltip, rightest + 1.2, iY + (sfinv_only and 2.2 or 1.7), 0.5, @@ -411,7 +412,7 @@ local function get_recipe_fs(data, iY) local arrow_X = rightest + (s_btn_size or 1.1) local output_X = arrow_X + 0.9 - fs[#fs + 1] = fmt(fmt_image, + fs[#fs + 1] = fmt(FMT_image, arrow_X, iY + (sfinv_only and 2.85 or 2.35), 0.9, @@ -419,7 +420,7 @@ local function get_recipe_fs(data, iY) "craftguide_arrow.png") if recipe.type == "fuel" then - fs[#fs + 1] = fmt(fmt_image, + fs[#fs + 1] = fmt(FMT_image, output_X, iY + (sfinv_only and 2.68 or 2.18), 1.1, @@ -440,14 +441,14 @@ local function get_recipe_fs(data, iY) if burntime then fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime) - fs[#fs + 1] = fmt(fmt_image, + fs[#fs + 1] = fmt(FMT_image, output_X + 1, iY + (sfinv_only and 2.83 or 2.33), 0.6, 0.4, "craftguide_arrow.png") - fs[#fs + 1] = fmt(fmt_image, + fs[#fs + 1] = fmt(FMT_image, output_X + 1.6, iY + (sfinv_only and 2.68 or 2.18), 0.6, @@ -509,7 +510,7 @@ local function make_formspec(name) fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 2.6 or 3.1)) .. ",0.12;0.8,0.8;craftguide_prev_icon.png;prev;]" - fs[#fs + 1] = fmt(fmt_label, + fs[#fs + 1] = fmt(FMT_label, data.iX - (sfinv_only and 1.7 or 2.2), 0.22, colorize("yellow", data.pagenum) .. " / " .. data.pagemax) @@ -529,7 +530,7 @@ local function make_formspec(name) pos = pos - 1 end - fs[#fs + 1] = fmt(fmt_label, pos, 2, fs_esc(no_item)) + fs[#fs + 1] = fmt(FMT_label, pos, 2, fs_esc(no_item)) end local first_item = (data.pagenum - 1) * ipp @@ -927,7 +928,7 @@ if progressive_mode then -- Workaround. Need an engine call to detect when the contents -- of the player inventory changed, instead. - mt.register_globalstep(function() + local function poll_new_items() local players = mt.get_connected_players() for i = 1, #players do local player = players[i] @@ -940,7 +941,11 @@ if progressive_mode then data.inv_items = table_merge(diff, data.inv_items) end end - end) + + mt.after(POLL_FREQ, poll_new_items) + end + + poll_new_items() craftguide.add_recipe_filter("Default progressive filter", progressive_filter) From bfe99092db236386bc7838bb8ed187e4212a631c Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 17 Feb 2019 15:04:01 +0100 Subject: [PATCH 056/188] Cleanup and optimizations --- init.lua | 200 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 117 insertions(+), 83 deletions(-) diff --git a/init.lua b/init.lua index 4738a86..ca98831 100644 --- a/init.lua +++ b/init.lua @@ -3,39 +3,43 @@ craftguide = { craft_types = {}, } -local mt = minetest +local M = minetest local player_data = {} -local init_items = {} + +-- Caches +local init_items = {} +local searches = {} local recipes_cache = {} -local fuel_cache = {} -local searches = {} +local usages_cache = {} +local fuel_cache = {} -local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode") -local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") +local progressive_mode = M.settings:get_bool("craftguide_progressive_mode") +local sfinv_only = M.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") -local colorize = mt.colorize -local fs_esc = mt.formspec_escape -local reg_items = mt.registered_items -local get_result = mt.get_craft_result -local show_formspec = mt.show_formspec -local get_player_by_name = mt.get_player_by_name -local serialize, deserialize = mt.serialize, mt.deserialize +local colorize = M.colorize +local reg_items = M.registered_items +local get_result = M.get_craft_result +local show_formspec = M.show_formspec +local get_player_by_name = M.get_player_by_name +local serialize, deserialize = M.serialize, M.deserialize -local S = mt.get_translator("craftguide") +local ESC = M.formspec_escape +local S = M.get_translator("craftguide") -- Lua 5.3 removed `table.maxn`, use this alternative in case of breakage: -- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1 local maxn, sort, concat = table.maxn, table.sort, table.concat local vector_add, vector_mul = vector.add, vector.multiply local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil -local fmt, pairs, next = string.format, pairs, next +local fmt, find, sub, gmatch = string.format, string.find, string.sub, string.gmatch +local pairs, next = pairs, next local DEFAULT_SIZE = 10 local MIN_LIMIT, MAX_LIMIT = 10, 12 DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) local GRID_LIMIT = 5 -local POLL_FREQ = 0.5 +local POLL_FREQ = 0.25 local FMT_label = "label[%f,%f;%s]" local FMT_image = "image[%f,%f;%f,%f;%s]" @@ -157,8 +161,18 @@ local function item_has_groups(item_groups, groups) return true end +local function split(str) + local t, c = {}, 0 + for s in gmatch(str, "([^,]+)") do + c = c + 1 + t[c] = s + end + + return t +end + local function extract_groups(str) - return str:sub(7):split(",") + return split(sub(str, 7)) end local function item_in_recipe(item, recipe) @@ -166,7 +180,7 @@ local function item_in_recipe(item, recipe) for _, recipe_item in pairs(recipe.items) do if recipe_item == item then return true - elseif recipe_item:sub(1,6) == "group:" then + elseif sub(recipe_item, 1, 6) == "group:" then local groups = extract_groups(recipe_item) if item_has_groups(item_groups, groups) then return true @@ -204,7 +218,7 @@ local function get_filtered_items(player) local fuel = fuel_cache[item] if recipes and #apply_recipe_filters(recipes, player) > 0 or - fuel and #apply_recipe_filters(get_item_usages(item), player) > 0 then + fuel and #apply_recipe_filters(usages_cache[item], player) > 0 then c = c + 1 items[c] = item end @@ -214,7 +228,7 @@ local function get_filtered_items(player) end local function cache_recipes(output) - local recipes = mt.get_all_craft_recipes(output) or {} + local recipes = M.get_all_craft_recipes(output) or {} local c = 0 for i = 1, #craftguide.custom_crafts do @@ -247,7 +261,7 @@ local function get_recipes(item, data, player) end if data.show_usages then - recipes = apply_recipe_filters(get_item_usages(item), player) + recipes = apply_recipe_filters(usages_cache[item], player) if #recipes == 0 then return end @@ -271,10 +285,12 @@ end local function groups_to_item(groups) if #groups == 1 then local group = groups[1] + local def_gr = "default:" .. group + if group_stereotypes[group] then return group_stereotypes[group] - elseif reg_items["default:" .. group] then - return "default:" .. group + elseif reg_items[def_gr] then + return def_gr end end @@ -291,9 +307,11 @@ local function get_tooltip(item, groups, cooktime, burntime) local tooltip if groups then - local groupstr = {} + local groupstr, c = {}, 0 + for i = 1, #groups do - groupstr[#groupstr + 1] = colorize("yellow", groups[i]) + c = c + 1 + groupstr[c] = colorize("yellow", groups[i]) end groupstr = concat(groupstr, ", ") @@ -312,7 +330,7 @@ local function get_tooltip(item, groups, cooktime, burntime) S("Burning time: @1", colorize("yellow", burntime)) end - return "tooltip[" .. item .. ";" .. fs_esc(tooltip) .. "]" + return fmt("tooltip[%s;%s]", item, ESC(tooltip)) end local function get_recipe_fs(data, iY) @@ -336,7 +354,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT_label, (data.iX / 2) - 2, iY + 2.2, - fs_esc(S("Recipe is too big to be displayed (@1x@2)", width, rows))) + ESC(S("Recipe is too big to be displayed (@1x@2)", width, rows))) return concat(fs) end @@ -358,7 +376,7 @@ local function get_recipe_fs(data, iY) end local groups - if item:sub(1,6) == "group:" then + if sub(item, 1, 6) == "group:" then groups = extract_groups(item) item = groups_to_item(groups) end @@ -372,7 +390,7 @@ local function get_recipe_fs(data, iY) btn_size, item, item:match("%S*"), - fs_esc(label)) + ESC(label)) local burntime = fuel_cache[item] @@ -388,7 +406,7 @@ local function get_recipe_fs(data, iY) shapeless and "shapeless" or "furnace" if not custom_recipe then - icon = "craftguide_" .. icon .. ".png^[resize:16x16" + icon = fmt("craftguide_%s.png^[resize:16x16", icon) end fs[#fs + 1] = fmt(FMT_image, @@ -406,7 +424,7 @@ local function get_recipe_fs(data, iY) iY + (sfinv_only and 2.2 or 1.7), 0.5, 0.5, - fs_esc(tooltip)) + ESC(tooltip)) end local arrow_X = rightest + (s_btn_size or 1.1) @@ -436,7 +454,7 @@ local function get_recipe_fs(data, iY) 1.1, 1.1, recipe.output, - fs_esc(output_name)) + ESC(output_name)) if burntime then fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime) @@ -463,9 +481,9 @@ local function get_recipe_fs(data, iY) 2.2, 1, "alternate", - data.show_usages and fs_esc(S("Usage")) or fs_esc(S("Recipe")), + data.show_usages and ESC(S("Usage")) or ESC(S("Recipe")), data.rnum, - fs_esc(S("of")), + ESC(S("of")), #data.recipes) return concat(fs) @@ -482,18 +500,22 @@ local function make_formspec(name) if not sfinv_only then fs[#fs + 1] = fmt("size[%f,%f;]", data.iX - 0.35, iY + 4) + fs[#fs + 1] = [[ no_prepend[] background[1,1;1,1;craftguide_bg.png;true] ]] - fs[#fs + 1] = "tooltip[size_inc;" .. fs_esc(S("Increase window size")) .. "]" - fs[#fs + 1] = "tooltip[size_dec;" .. fs_esc(S("Decrease window size")) .. "]" + fs[#fs + 1] = fmt([[ tooltip[size_inc;%s] + tooltip[size_dec;%s] ]], + ESC(S("Increase window size")), + ESC(S("Decrease window size"))) - fs[#fs + 1] = "image_button[" .. (data.iX * 0.47) .. - ",0.12;0.8,0.8;craftguide_zoomin_icon.png;size_inc;]" - fs[#fs + 1] = "image_button[" .. ((data.iX * 0.47) + 0.6) .. - ",0.12;0.8,0.8;craftguide_zoomout_icon.png;size_dec;]" + fs[#fs + 1] = fmt([[ + image_button[%f,0.12;0.8,0.8;craftguide_zoomin_icon.png;size_inc;] + image_button[%f,0.12;0.8,0.8;craftguide_zoomout_icon.png;size_dec;] ]], + data.iX * 0.47, + data.iX * 0.47 + 0.6) end fs[#fs + 1] = [[ @@ -502,24 +524,28 @@ local function make_formspec(name) field_close_on_enter[filter;false] ]] - fs[#fs + 1] = "tooltip[search;" .. fs_esc(S("Search")) .. "]" - fs[#fs + 1] = "tooltip[clear;" .. fs_esc(S("Reset")) .. "]" - fs[#fs + 1] = "tooltip[prev;" .. fs_esc(S("Previous page")) .. "]" - fs[#fs + 1] = "tooltip[next;" .. fs_esc(S("Next page")) .. "]" + fs[#fs + 1] = fmt([[ tooltip[search;%s] + tooltip[clear;%s] + tooltip[prev;%s] + tooltip[next;%s] ]], + ESC(S("Search")), + ESC(S("Reset")), + ESC(S("Previous page")), + ESC(S("Next page"))) - fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 2.6 or 3.1)) .. - ",0.12;0.8,0.8;craftguide_prev_icon.png;prev;]" + fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", + data.iX - (sfinv_only and 1.7 or 2.2), + 0.22, + colorize("yellow", data.pagenum), + data.pagemax) - fs[#fs + 1] = fmt(FMT_label, - data.iX - (sfinv_only and 1.7 or 2.2), - 0.22, - colorize("yellow", data.pagenum) .. " / " .. data.pagemax) + fs[#fs + 1] = fmt([[ + image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;] + image_button[%f,0.12;0.8,0.8;craftguide_next_icon.png;next;] ]], + data.iX - (sfinv_only and 2.6 or 3.1), + data.iX - (sfinv_only and 0.7 or 1.2) - (data.iX >= 11 and 0.08 or 0)) - fs[#fs + 1] = "image_button[" .. (data.iX - - (sfinv_only and 0.7 or 1.2) - (data.iX >= 11 and 0.08 or 0)) .. - ",0.12;0.8,0.8;craftguide_next_icon.png;next;]" - - fs[#fs + 1] = "field[0.3,0.32;2.5,1;filter;;" .. fs_esc(data.filter) .. "]" + fs[#fs + 1] = fmt("field[0.3,0.32;2.5,1;filter;;%s]", ESC(data.filter)) if #data.items == 0 then local no_item = S("No item to show") @@ -530,7 +556,7 @@ local function make_formspec(name) pos = pos - 1 end - fs[#fs + 1] = fmt(FMT_label, pos, 2, fs_esc(no_item)) + fs[#fs + 1] = fmt(FMT_label, pos, 2, ESC(no_item)) end local first_item = (data.pagenum - 1) * ipp @@ -581,7 +607,7 @@ local function search(data) local item = data.items_raw[i] local desc = reg_items[item].description:lower() - if (item .. desc):find(filter, 1, true) then + if find(item .. desc, filter, 1, true) then c = c + 1 filtered_list[c] = item end @@ -643,6 +669,13 @@ local function reset_data(data) data.items = data.items_raw end +local function cache_usages() + for i = 1, #init_items do + local item = init_items[i] + usages_cache[item] = get_item_usages(item) + end +end + local function get_init_items() local c = 0 for name, def in pairs(reg_items) do @@ -657,6 +690,7 @@ local function get_init_items() end sort(init_items) + cache_usages() end local function on_receive_fields(player, fields) @@ -712,7 +746,7 @@ local function on_receive_fields(player, fields) else local item for field in pairs(fields) do - if field:find(":") then + if find(field, ":") then item = field break end @@ -720,8 +754,8 @@ local function on_receive_fields(player, fields) if not item then return - elseif item:sub(-4) == "_inv" then - item = item:sub(1,-5) + elseif sub(item, -4) == "_inv" then + item = sub(item, 1, -5) end if item ~= data.query_item then @@ -743,14 +777,14 @@ local function on_receive_fields(player, fields) end end -mt.register_on_mods_loaded(get_init_items) +M.register_on_mods_loaded(get_init_items) -mt.register_on_joinplayer(function(player) +M.register_on_joinplayer(function(player) local name = player:get_player_name() init_data(name) end) -mt.register_on_leaveplayer(function(player) +M.register_on_leaveplayer(function(player) local name = player:get_player_name() player_data[name] = nil end) @@ -781,7 +815,7 @@ if sfinv_only then end, }) else - mt.register_on_player_receive_fields(function(player, formname, fields) + M.register_on_player_receive_fields(function(player, formname, fields) if formname == "craftguide" then on_receive_fields(player, fields) end @@ -799,7 +833,7 @@ else show_formspec(name, "craftguide", make_formspec(name)) end - mt.register_craftitem("craftguide:book", { + M.register_craftitem("craftguide:book", { description = S("Crafting Guide"), inventory_image = "craftguide_book.png", wield_image = "craftguide_book.png", @@ -810,7 +844,7 @@ else end }) - mt.register_node("craftguide:sign", { + M.register_node("craftguide:sign", { description = S("Crafting Guide Sign"), drawtype = "nodebox", tiles = {"craftguide_sign.png"}, @@ -828,7 +862,7 @@ else }, on_construct = function(pos) - local meta = mt.get_meta(pos) + local meta = M.get_meta(pos) meta:set_string("infotext", S("Crafting Guide Sign")) end, @@ -837,27 +871,27 @@ else end }) - mt.register_craft({ + M.register_craft({ output = "craftguide:book", recipe = { {"default:book"} } }) - mt.register_craft({ + M.register_craft({ type = "fuel", recipe = "craftguide:book", burntime = 3 }) - mt.register_craft({ + M.register_craft({ output = "craftguide:sign", recipe = { {"default:sign_wall_wood"} } }) - mt.register_craft({ + M.register_craft({ type = "fuel", recipe = "craftguide:sign", burntime = 10 @@ -879,7 +913,7 @@ if progressive_mode then local function item_in_inv(item, inv_items) local inv_items_size = #inv_items - if item:sub(1,6) == "group:" then + if sub(item, 1, 6) == "group:" then local groups = extract_groups(item) for i = 1, inv_items_size do local item_groups = reg_items[inv_items[i]].groups @@ -929,7 +963,7 @@ if progressive_mode then -- Workaround. Need an engine call to detect when the contents -- of the player inventory changed, instead. local function poll_new_items() - local players = mt.get_connected_players() + local players = M.get_connected_players() for i = 1, #players do local player = players[i] local name = player:get_player_name() @@ -942,14 +976,14 @@ if progressive_mode then end end - mt.after(POLL_FREQ, poll_new_items) + M.after(POLL_FREQ, poll_new_items) end poll_new_items() craftguide.add_recipe_filter("Default progressive filter", progressive_filter) - mt.register_on_joinplayer(function(player) + M.register_on_joinplayer(function(player) local meta = player:get_meta() local name = player:get_player_name() local data = player_data[name] @@ -965,10 +999,10 @@ if progressive_mode then meta:set_string("inv_items", serialize(data.inv_items)) end - mt.register_on_leaveplayer(save_meta) + M.register_on_leaveplayer(save_meta) - mt.register_on_shutdown(function() - local players = mt.get_connected_players() + M.register_on_shutdown(function() + local players = M.get_connected_players() for i = 1, #players do local player = players[i] save_meta(player) @@ -976,7 +1010,7 @@ if progressive_mode then end) end -mt.register_chatcommand("craft", { +M.register_chatcommand("craft", { description = S("Show recipe(s) of the pointed node"), func = function(name) local player = get_player_by_name(name) @@ -987,7 +1021,7 @@ mt.register_chatcommand("craft", { for i = 1, 10 do local look_at = vector_add(eye_h, vector_mul(dir, i)) - local node = mt.get_node(look_at) + local node = M.get_node(look_at) if node.name ~= "air" then node_name = node.name @@ -1016,7 +1050,7 @@ mt.register_chatcommand("craft", { local msg = red .. "%s: " .. ylw if is_fuel then - recipes = get_item_usages(node_name) + recipes = usages_cache[node_name] if #recipes > 0 then data.show_usages = true end @@ -1055,7 +1089,7 @@ end --[[ Custom recipes (>3x3) test code -mt.register_craftitem(":secretstuff:custom_recipe_test", { +M.register_craftitem(":secretstuff:custom_recipe_test", { description = "Custom Recipe Test", }) @@ -1069,7 +1103,7 @@ for x = 1, 6 do end end - mt.register_craft({ + M.register_craft({ output = "secretstuff:custom_recipe_test", recipe = cr[x] }) From 92cf2307dbecb41e51432e9fb91bae0d636612ca Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 20 Feb 2019 18:11:59 +0100 Subject: [PATCH 057/188] Progressive: do not show items that you didn't get --- init.lua | 60 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/init.lua b/init.lua index ca98831..630fecd 100644 --- a/init.lua +++ b/init.lua @@ -209,16 +209,42 @@ local function get_item_usages(item) return usages end +local function item_in_inv(item, inv_items) + local inv_items_size = #inv_items + + if sub(item, 1, 6) == "group:" then + local groups = extract_groups(item) + for i = 1, inv_items_size do + local inv_item = reg_items[inv_items[i]] + if inv_item then + local item_groups = inv_item.groups + if item_has_groups(item_groups, groups) then + return true + end + end + end + else + for i = 1, inv_items_size do + if inv_items[i] == item then + return true + end + end + end +end + local function get_filtered_items(player) + local name = player:get_player_name() + local data = player_data[name] local items, c = {}, 0 for i = 1, #init_items do local item = init_items[i] local recipes = recipes_cache[item] - local fuel = fuel_cache[item] + local usages = usages_cache[item] if recipes and #apply_recipe_filters(recipes, player) > 0 or - fuel and #apply_recipe_filters(usages_cache[item], player) > 0 then + (usages and item_in_inv(item, data.inv_items) and + #apply_recipe_filters(usages_cache[item], player) > 0) then c = c + 1 items[c] = item end @@ -246,17 +272,17 @@ local function cache_recipes(output) end local function get_recipes(item, data, player) - local is_fuel = fuel_cache[item] local recipes = recipes_cache[item] + local usages = usages_cache[item] if recipes then recipes = apply_recipe_filters(recipes, player) end local no_recipes = not recipes or #recipes == 0 - if no_recipes and not is_fuel then + if no_recipes and not usages then return - elseif is_fuel and no_recipes then + elseif usages and no_recipes then data.show_usages = true end @@ -910,26 +936,6 @@ else end if progressive_mode then - local function item_in_inv(item, inv_items) - local inv_items_size = #inv_items - - if sub(item, 1, 6) == "group:" then - local groups = extract_groups(item) - for i = 1, inv_items_size do - local item_groups = reg_items[inv_items[i]].groups - if item_has_groups(item_groups, groups) then - return true - end - end - else - for i = 1, inv_items_size do - if inv_items[i] == item then - return true - end - end - end - end - local function recipe_in_inv(recipe, inv_items) for _, item in pairs(recipe.items) do if not item_in_inv(item, inv_items) then @@ -1039,7 +1045,7 @@ M.register_chatcommand("craft", { reset_data(data) local recipes = recipes_cache[node_name] - local is_fuel = fuel_cache[node_name] + local usages = usages_cache[node_name] if recipes then recipes = apply_recipe_filters(recipes, player) @@ -1049,7 +1055,7 @@ M.register_chatcommand("craft", { local ylw = colorize("yellow", node_name) local msg = red .. "%s: " .. ylw - if is_fuel then + if usages then recipes = usages_cache[node_name] if #recipes > 0 then data.show_usages = true From fa30a0d07669a8d470ce52c589fb1275633b5b60 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Feb 2019 00:26:14 +0100 Subject: [PATCH 058/188] Add an API for custom formspec elements --- .luacheckrc | 1 + API.md | 41 +++++++++++++++++++ init.lua | 112 +++++++++++++++++++++++++++++++++++----------------- 3 files changed, 117 insertions(+), 37 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 6ade552..0e8162f 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -7,4 +7,5 @@ read_globals = { "sfinv", "sfinv_buttons", "vector", + "string", } diff --git a/API.md b/API.md index b73893d..76fe70b 100644 --- a/API.md +++ b/API.md @@ -61,6 +61,47 @@ Removes all recipe filters and adds a new one. Returns a map of recipe filters, indexed by name. +### Custom formspec elements + +#### `craftguide.add_formspec_element(name, def)` + +Adds a formspec element to the current formspec. +Supported types: `box`, `label`, `image`, `button`, `tooltip`, `item_image`, `image_button`, `item_image_button` + +Example: + +```lua +craftguide.add_formspec_element("export", { + type = "button", + element = function(data) + -- Should return a table of parameters according to the formspec element type. + -- Note: for all buttons, the 'name' parameter *must not* be specified! + if data.recipes then + return { + data.iX - 3.7, -- X + sfinv_only and 7.9 or 8, -- Y + 1.6, -- W + 1, -- H + ESC(S("Export")) -- label + } + end + end, + -- Optional. + action = function(player, data) + -- When the button is pressed. + print("Exported!") + end +}) +``` + +#### `craftguide.remove_formspec_element(name)` + +Removes the formspec element with the given name. + +#### `craftguide.get_formspec_elements()` + +Returns a map of formspec elements, indexed by name. + ### Miscellaneous #### `craftguide.show(player_name, item, show_usages)` diff --git a/init.lua b/init.lua index 630fecd..78b5d5b 100644 --- a/init.lua +++ b/init.lua @@ -26,13 +26,12 @@ local serialize, deserialize = M.serialize, M.deserialize local ESC = M.formspec_escape local S = M.get_translator("craftguide") --- Lua 5.3 removed `table.maxn`, use this alternative in case of breakage: --- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1 -local maxn, sort, concat = table.maxn, table.sort, table.concat -local vector_add, vector_mul = vector.add, vector.multiply +local maxn, sort, concat, insert = table.maxn, table.sort, table.concat, table.insert local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil -local fmt, find, sub, gmatch = string.format, string.find, string.sub, string.gmatch -local pairs, next = pairs, next +local fmt, find, match, sub, split = + string.format, string.find, string.match, string.sub, string.split +local pairs, next, unpack = pairs, next, unpack +local vec_add, vec_mul = vector.add, vector.multiply local DEFAULT_SIZE = 10 local MIN_LIMIT, MAX_LIMIT = 10, 12 @@ -41,9 +40,16 @@ DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) local GRID_LIMIT = 5 local POLL_FREQ = 0.25 -local FMT_label = "label[%f,%f;%s]" -local FMT_image = "image[%f,%f;%f,%f;%s]" -local FMT_tooltip = "tooltip[%f,%f;%f,%f;%s]" +local FMT = { + box = "box[%f,%f;%f,%f;%s]", + label = "label[%f,%f;%s]", + image = "image[%f,%f;%f,%f;%s]", + button = "button[%f,%f;%f,%f;%s;%s]", + tooltip = "tooltip[%s;%s]", + item_image = "item_image[%f,%f;%f,%f;%s]", + image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", + item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]", +} local group_stereotypes = { wool = "wool:white", @@ -150,6 +156,29 @@ local function apply_recipe_filters(recipes, player) return recipes end +local formspec_elements = {} + +function craftguide.add_formspec_element(name, def) + local func = "craftguide." .. __func() .. "(): " + assert(def.element, func .. "'element' field not defined") + assert(def.type, func .. "'type' field not defined") + assert(FMT[def.type], func .. "'" .. def.type .. "' type not supported by the API") + + formspec_elements[name] = { + type = def.type, + element = def.element, + action = def.action, + } +end + +function craftguide.remove_formspec_element(name) + formspec_elements[name] = nil +end + +function craftguide.get_formspec_elements() + return formspec_elements +end + local function item_has_groups(item_groups, groups) for i = 1, #groups do local group = groups[i] @@ -161,18 +190,8 @@ local function item_has_groups(item_groups, groups) return true end -local function split(str) - local t, c = {}, 0 - for s in gmatch(str, "([^,]+)") do - c = c + 1 - t[c] = s - end - - return t -end - local function extract_groups(str) - return split(sub(str, 7)) + return split(sub(str, 7), ",") end local function item_in_recipe(item, recipe) @@ -259,7 +278,7 @@ local function cache_recipes(output) for i = 1, #craftguide.custom_crafts do local custom_craft = craftguide.custom_crafts[i] - if custom_craft.output:match("%S*") == output then + if match(custom_craft.output, "%S*") == output then c = c + 1 recipes[c] = custom_craft end @@ -356,7 +375,7 @@ local function get_tooltip(item, groups, cooktime, burntime) S("Burning time: @1", colorize("yellow", burntime)) end - return fmt("tooltip[%s;%s]", item, ESC(tooltip)) + return fmt(FMT.tooltip, item, ESC(tooltip)) end local function get_recipe_fs(data, iY) @@ -377,7 +396,7 @@ local function get_recipe_fs(data, iY) local rightest, btn_size, s_btn_size = 0, 1.1 if width > GRID_LIMIT or rows > GRID_LIMIT then - fs[#fs + 1] = fmt(FMT_label, + fs[#fs + 1] = fmt(FMT.label, (data.iX / 2) - 2, iY + 2.2, ESC(S("Recipe is too big to be displayed (@1x@2)", width, rows))) @@ -409,13 +428,13 @@ local function get_recipe_fs(data, iY) local label = groups and "\nG" or "" - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]", + fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0.2), btn_size, btn_size, item, - item:match("%S*"), + match(item, "%S*"), ESC(label)) local burntime = fuel_cache[item] @@ -435,7 +454,7 @@ local function get_recipe_fs(data, iY) icon = fmt("craftguide_%s.png^[resize:16x16", icon) end - fs[#fs + 1] = fmt(FMT_image, + fs[#fs + 1] = fmt(FMT.image, rightest + 1.2, iY + (sfinv_only and 2.2 or 1.7), 0.5, @@ -445,7 +464,7 @@ local function get_recipe_fs(data, iY) local tooltip = custom_recipe and custom_recipe.description or shapeless and S("Shapeless") or S("Cooking") - fs[#fs + 1] = fmt(FMT_tooltip, + fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", rightest + 1.2, iY + (sfinv_only and 2.2 or 1.7), 0.5, @@ -456,7 +475,7 @@ local function get_recipe_fs(data, iY) local arrow_X = rightest + (s_btn_size or 1.1) local output_X = arrow_X + 0.9 - fs[#fs + 1] = fmt(FMT_image, + fs[#fs + 1] = fmt(FMT.image, arrow_X, iY + (sfinv_only and 2.85 or 2.35), 0.9, @@ -464,35 +483,36 @@ local function get_recipe_fs(data, iY) "craftguide_arrow.png") if recipe.type == "fuel" then - fs[#fs + 1] = fmt(FMT_image, + fs[#fs + 1] = fmt(FMT.image, output_X, iY + (sfinv_only and 2.68 or 2.18), 1.1, 1.1, "craftguide_fire.png") else - local output_name = recipe.output:match("%S+") + local output_name = match(recipe.output, "%S+") local burntime = fuel_cache[output_name] - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]", + fs[#fs + 1] = fmt(FMT.item_image_button, output_X, iY + (sfinv_only and 2.7 or 2.2), 1.1, 1.1, recipe.output, - ESC(output_name)) + ESC(output_name), + "") if burntime then fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime) - fs[#fs + 1] = fmt(FMT_image, + fs[#fs + 1] = fmt(FMT.image, output_X + 1, iY + (sfinv_only and 2.83 or 2.33), 0.6, 0.4, "craftguide_arrow.png") - fs[#fs + 1] = fmt(FMT_image, + fs[#fs + 1] = fmt(FMT.image, output_X + 1.6, iY + (sfinv_only and 2.68 or 2.18), 0.6, @@ -582,7 +602,7 @@ local function make_formspec(name) pos = pos - 1 end - fs[#fs + 1] = fmt(FMT_label, pos, 2, ESC(no_item)) + fs[#fs + 1] = fmt(FMT.label, pos, 2, ESC(no_item)) end local first_item = (data.pagenum - 1) * ipp @@ -608,6 +628,17 @@ local function make_formspec(name) fs[#fs + 1] = get_recipe_fs(data, iY) end + for elem_name, def in pairs(formspec_elements) do + local element = def.element(data) + if element then + if find(def.type, "button") then + insert(element, #element, elem_name) + end + + fs[#fs + 1] = fmt(FMT[def.type], unpack(element)) + end + end + return concat(fs) end @@ -656,7 +687,8 @@ local function get_inv_items(player) local stacks = {} for i = 1, #item_lists do - stacks = table_merge(stacks, inv:get_list(item_lists[i])) + local l = inv:get_list(item_lists[i]) + stacks = table_merge(stacks, l) end local inv_items, c = {}, 0 @@ -723,6 +755,12 @@ local function on_receive_fields(player, fields) local name = player:get_player_name() local data = player_data[name] + for elem_name, def in pairs(formspec_elements) do + if fields[elem_name] and def.action then + return def.action(player, data) + end + end + if fields.clear then reset_data(data) show_fs(player, name) @@ -1026,7 +1064,7 @@ M.register_chatcommand("craft", { local node_name for i = 1, 10 do - local look_at = vector_add(eye_h, vector_mul(dir, i)) + local look_at = vec_add(eye_h, vec_mul(dir, i)) local node = M.get_node(look_at) if node.name ~= "air" then From 058cd05ed71ea96ef5a4cc63eda77c0aaed74112 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Feb 2019 01:08:37 +0100 Subject: [PATCH 059/188] Separate custom_crafts tables from main table --- init.lua | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/init.lua b/init.lua index 78b5d5b..32932e6 100644 --- a/init.lua +++ b/init.lua @@ -1,7 +1,4 @@ -craftguide = { - custom_crafts = {}, - craft_types = {}, -} +craftguide = {} local M = minetest local player_data = {} @@ -109,15 +106,15 @@ local function __func() return debug.getinfo(2, "n").name end +local custom_crafts, craft_types = {}, {} + function craftguide.register_craft_type(name, def) local func = "craftguide." .. __func() .. "(): " assert(name, func .. "'name' field missing") assert(def.description, func .. "'description' field missing") assert(def.icon, func .. "'icon' field missing") - if not craftguide.craft_types[name] then - craftguide.craft_types[name] = def - end + craft_types[name] = def end function craftguide.register_craft(def) @@ -127,7 +124,7 @@ function craftguide.register_craft(def) assert(def.output, func .. "'output' field missing") assert(def.items, func .. "'items' field missing") - craftguide.custom_crafts[#craftguide.custom_crafts + 1] = def + custom_crafts[#custom_crafts + 1] = def end local recipe_filters = {} @@ -276,8 +273,8 @@ local function cache_recipes(output) local recipes = M.get_all_craft_recipes(output) or {} local c = 0 - for i = 1, #craftguide.custom_crafts do - local custom_craft = craftguide.custom_crafts[i] + for i = 1, #custom_crafts do + local custom_craft = custom_crafts[i] if match(custom_craft.output, "%S*") == output then c = c + 1 recipes[c] = custom_craft @@ -444,7 +441,7 @@ local function get_recipe_fs(data, iY) end end - local custom_recipe = craftguide.craft_types[recipe.type] + local custom_recipe = craft_types[recipe.type] if custom_recipe or shapeless or recipe.type == "cooking" then local icon = custom_recipe and custom_recipe.icon or From 5e4a362a15279129595aa8fad8746f4483a517a3 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Feb 2019 01:44:09 +0100 Subject: [PATCH 060/188] Fix some crash --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 32932e6..2d97acd 100644 --- a/init.lua +++ b/init.lua @@ -259,7 +259,7 @@ local function get_filtered_items(player) local usages = usages_cache[item] if recipes and #apply_recipe_filters(recipes, player) > 0 or - (usages and item_in_inv(item, data.inv_items) and + (usages and (progressive_mode and item_in_inv(item, data.inv_items)) and #apply_recipe_filters(usages_cache[item], player) > 0) then c = c + 1 items[c] = item From 7f44517701677af9dbaa33726e393b743f913db0 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Feb 2019 01:54:15 +0100 Subject: [PATCH 061/188] Fix alternate button not shown for too large recipes --- init.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/init.lua b/init.lua index 2d97acd..9fb770d 100644 --- a/init.lua +++ b/init.lua @@ -392,6 +392,17 @@ local function get_recipe_fs(data, iY) local rows = ceil(maxn(recipe.items) / width) local rightest, btn_size, s_btn_size = 0, 1.1 + fs[#fs + 1] = fmt("button[%f,%f;%f,%f;%s;%s %u %s %u]", + data.iX - (sfinv_only and 2.2 or 2.6), + iY + (sfinv_only and 3.9 or 3.3), + 2.2, + 1, + "alternate", + data.show_usages and ESC(S("Usage")) or ESC(S("Recipe")), + data.rnum, + ESC(S("of")), + #data.recipes) + if width > GRID_LIMIT or rows > GRID_LIMIT then fs[#fs + 1] = fmt(FMT.label, (data.iX / 2) - 2, @@ -518,17 +529,6 @@ local function get_recipe_fs(data, iY) end end - fs[#fs + 1] = fmt("button[%f,%f;%f,%f;%s;%s %u %s %u]", - data.iX - (sfinv_only and 2.2 or 2.6), - iY + (sfinv_only and 3.9 or 3.3), - 2.2, - 1, - "alternate", - data.show_usages and ESC(S("Usage")) or ESC(S("Recipe")), - data.rnum, - ESC(S("of")), - #data.recipes) - return concat(fs) end @@ -1140,7 +1140,7 @@ for x = 1, 6 do for i = 1, 10 - x do cr[x][i] = {} for j = 1, 10 - x do - cr[x][i][j] = "group:sand" + cr[x][i][j] = "group:wood" end end From 7219a6096bbc4480221398bd168506fba1d28ab2 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Feb 2019 15:31:28 +0100 Subject: [PATCH 062/188] Minor cleanup --- init.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/init.lua b/init.lua index 9fb770d..3a095aa 100644 --- a/init.lua +++ b/init.lua @@ -393,8 +393,8 @@ local function get_recipe_fs(data, iY) local rightest, btn_size, s_btn_size = 0, 1.1 fs[#fs + 1] = fmt("button[%f,%f;%f,%f;%s;%s %u %s %u]", - data.iX - (sfinv_only and 2.2 or 2.6), - iY + (sfinv_only and 3.9 or 3.3), + sfinv_only and 5.8 or data.iX - 2.6, + sfinv_only and 7.9 or iY + 3.3, 2.2, 1, "alternate", @@ -464,7 +464,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.image, rightest + 1.2, - iY + (sfinv_only and 2.2 or 1.7), + sfinv_only and 6.2 or iY + 1.7, 0.5, 0.5, icon) @@ -474,7 +474,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", rightest + 1.2, - iY + (sfinv_only and 2.2 or 1.7), + sfinv_only and 6.2 or iY + 1.7, 0.5, 0.5, ESC(tooltip)) @@ -485,7 +485,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.image, arrow_X, - iY + (sfinv_only and 2.85 or 2.35), + sfinv_only and 6.85 or iY + 2.35, 0.9, 0.7, "craftguide_arrow.png") @@ -493,7 +493,7 @@ local function get_recipe_fs(data, iY) if recipe.type == "fuel" then fs[#fs + 1] = fmt(FMT.image, output_X, - iY + (sfinv_only and 2.68 or 2.18), + sfinv_only and 6.68 or iY + 2.18, 1.1, 1.1, "craftguide_fire.png") @@ -503,7 +503,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.item_image_button, output_X, - iY + (sfinv_only and 2.7 or 2.2), + sfinv_only and 6.7 or iY + 2.2, 1.1, 1.1, recipe.output, @@ -515,14 +515,14 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.image, output_X + 1, - iY + (sfinv_only and 2.83 or 2.33), + sfinv_only and 6.83 or iY + 2.33, 0.6, 0.4, "craftguide_arrow.png") fs[#fs + 1] = fmt(FMT.image, output_X + 1.6, - iY + (sfinv_only and 2.68 or 2.18), + sfinv_only and 6.68 or iY + 2.18, 0.6, 0.6, "craftguide_fire.png") @@ -577,7 +577,7 @@ local function make_formspec(name) ESC(S("Next page"))) fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", - data.iX - (sfinv_only and 1.7 or 2.2), + sfinv_only and 5.7 or data.iX - 2.2, 0.22, colorize("yellow", data.pagenum), data.pagemax) @@ -585,8 +585,8 @@ local function make_formspec(name) fs[#fs + 1] = fmt([[ image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;] image_button[%f,0.12;0.8,0.8;craftguide_next_icon.png;next;] ]], - data.iX - (sfinv_only and 2.6 or 3.1), - data.iX - (sfinv_only and 0.7 or 1.2) - (data.iX >= 11 and 0.08 or 0)) + sfinv_only and 6.6 or data.iX - 3.1, + sfinv_only and 7.3 or (data.iX - 1.2) - (data.iX >= 11 and 0.08 or 0)) fs[#fs + 1] = fmt("field[0.3,0.32;2.5,1;filter;;%s]", ESC(data.filter)) From cdc8e410b6d289054bb05da15c54850228b6ef7d Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Feb 2019 16:59:07 +0100 Subject: [PATCH 063/188] Add french translations, revise others --- init.lua | 17 +++--- locale/craftguide.de.tr | 113 +++++++++------------------------------- locale/craftguide.fr.tr | 25 +++++++++ locale/craftguide.ms.tr | 91 -------------------------------- locale/craftguide.ru.tr | 113 +++++++++------------------------------- locale/template | 25 +++++++++ locale/template.pot | 88 ------------------------------- 7 files changed, 107 insertions(+), 365 deletions(-) create mode 100644 locale/craftguide.fr.tr delete mode 100644 locale/craftguide.ms.tr create mode 100644 locale/template delete mode 100644 locale/template.pot diff --git a/init.lua b/init.lua index 3a095aa..d921808 100644 --- a/init.lua +++ b/init.lua @@ -392,16 +392,17 @@ local function get_recipe_fs(data, iY) local rows = ceil(maxn(recipe.items) / width) local rightest, btn_size, s_btn_size = 0, 1.1 - fs[#fs + 1] = fmt("button[%f,%f;%f,%f;%s;%s %u %s %u]", + local btn_lab = data.show_usages and + ESC(S("Usage @1 of @2", data.rnum, #data.recipes)) or + ESC(S("Recipe @1 of @2", data.rnum, #data.recipes)) + + fs[#fs + 1] = fmt(FMT.button, sfinv_only and 5.8 or data.iX - 2.6, sfinv_only and 7.9 or iY + 3.3, 2.2, 1, "alternate", - data.show_usages and ESC(S("Usage")) or ESC(S("Recipe")), - data.rnum, - ESC(S("of")), - #data.recipes) + btn_lab) if width > GRID_LIMIT or rows > GRID_LIMIT then fs[#fs + 1] = fmt(FMT.label, @@ -577,7 +578,7 @@ local function make_formspec(name) ESC(S("Next page"))) fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", - sfinv_only and 5.7 or data.iX - 2.2, + sfinv_only and 6.3 or data.iX - 2.2, 0.22, colorize("yellow", data.pagenum), data.pagemax) @@ -585,7 +586,7 @@ local function make_formspec(name) fs[#fs + 1] = fmt([[ image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;] image_button[%f,0.12;0.8,0.8;craftguide_next_icon.png;next;] ]], - sfinv_only and 6.6 or data.iX - 3.1, + sfinv_only and 5.5 or data.iX - 3.1, sfinv_only and 7.3 or (data.iX - 1.2) - (data.iX >= 11 and 0.08 or 0)) fs[#fs + 1] = fmt("field[0.3,0.32;2.5,1;filter;;%s]", ESC(data.filter)) @@ -924,7 +925,7 @@ else on_construct = function(pos) local meta = M.get_meta(pos) - meta:set_string("infotext", S("Crafting Guide Sign")) + meta:set_string("infotext", "Crafting Guide Sign") end, on_rightclick = function(pos, node, user, itemstack) diff --git a/locale/craftguide.de.tr b/locale/craftguide.de.tr index 8e5a8de..b630835 100644 --- a/locale/craftguide.de.tr +++ b/locale/craftguide.de.tr @@ -1,90 +1,25 @@ -# German translation for craftguide mod. -# Copyright (C) 2018 -# This file is distributed under the same license as the craftguide package. -# codexp , 2018. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: 1.27\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-03-23 00:17+0100\n" -"PO-Revision-Date: \n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: German\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" +# textdomain: craftguide -#: init.lua -msgid "Unknown Item (@1)" -msgstr "Unbekannter Gegenstand (@1)" - -#: init.lua -msgid "Any item belonging to the group(s)" -msgstr "Beliebiger Gegenstand aus der Gruppe" - -#: init.lua -msgid "Cooking time" -msgstr "Kochzeit" - -#: init.lua -msgid "Burning time" -msgstr "Brennzeit" - -#: init.lua -msgid "Alternate" -msgstr "Andere" - -#: init.lua -msgid "Recipe @1 of @2" -msgstr "Rezept @1 von @2" - -#: init.lua -msgid "" -"Recipe is too big to\n" -"be displayed (@1x@2)" -msgstr "" -"Rezept ist zu groß\n" -"für die Anzeige (@1x@2)" - -#: init.lua -msgid "Search" -msgstr "Suche" - -#: init.lua -msgid "Reset" -msgstr "Zurücksetzen" - -#: init.lua -msgid "Increase window size" -msgstr "Fenster vergrößern" - -#: init.lua -msgid "Decrease window size" -msgstr "Fenster verkleinern" - -#: init.lua -msgid "Previous page" -msgstr "Vorherige Seite" - -#: init.lua -msgid "Next page" -msgstr "Nächste Seite" - -#: init.lua -msgid "No item to show" -msgstr "Nichts anzuzeigen" - -#: init.lua -msgid "Crafting Guide" -msgstr "Rezeptbuch" - -#: init.lua -msgid "Crafting Guide Sign" -msgstr "Rezepttafel" - -#: init.lua -msgid "Shows a list of available crafting recipes, cooking recipes and fuels" -msgstr "Zeigt eine Liste von verfügbaren Rezepten, Kochrezepten und Brennmaterialien" +Craft Guide=Rezeptbuch +Crafting Guide=Rezeptbuch +Crafting Guide Sign=Rezepttafel +Search=Suche +Reset=Zurücksetzen +Previous page=Vorherige Seite +Next page=Nächste Seite +Usage @1 of @2=Verwendung @1 von @2 +Recipe @1 of @2=Rezept @1 von @2 +Burning time: @1=Brennzeit: @1 +Cooking time: @1=Kochzeit: @1 +Any item belonging to the group(s): @1=Beliebiger Gegenstand aus der Gruppe: @1 +Recipe is too big to be displayed (@1x@2)=Rezept ist zu groß für die Anzeige (@1x@2) +Shapeless= +Cooking=Kochen +Increase window size=Fenster vergrößern +Decrease window size=Fenster verkleinern +No item to show=Nichts anzuzeigen +Collect items to reveal more recipes= +Show recipe(s) of the pointed node= +No node pointed= +You don't know a recipe for this node= +No recipe for this node= diff --git a/locale/craftguide.fr.tr b/locale/craftguide.fr.tr new file mode 100644 index 0000000..2bdbf9d --- /dev/null +++ b/locale/craftguide.fr.tr @@ -0,0 +1,25 @@ +# textdomain: craftguide + +Craft Guide=Guide de recettes +Crafting Guide=Guide de recettes +Crafting Guide Sign=Guide de recettes (panneau) +Search=Rechercher +Reset=Réinitialiser +Previous page=Page précédente +Next page=Page suivante +Usage @1 of @2=Usage @1 de @2 +Recipe @1 of @2=Recette @1 de @2 +Burning time: @1=Temps de combustion : @1 +Cooking time: @1=Temps de cuisson : @1 +Any item belonging to the group(s): @1=Tout item appartenant au(x) groupe(s) : @1 +Recipe is too big to be displayed (@1x@2)=La recette est trop grande pour être affichée (@1x@2) +Shapeless=Sans forme +Cooking=Cuisson +Increase window size=Agrandir la fenêtre +Decrease window size=Réduire la fenêtre +No item to show=Aucun item à afficher +Collect items to reveal more recipes=Collecte des items pour révéler plus de recettes +Show recipe(s) of the pointed node=Affiche les recettes du bloc visé +No node pointed=Aucun bloc visé +You don't know a recipe for this node=Tu ne connais aucune recette pour ce bloc +No recipe for this node=Aucune recette pour ce bloc diff --git a/locale/craftguide.ms.tr b/locale/craftguide.ms.tr deleted file mode 100644 index 56a1c20..0000000 --- a/locale/craftguide.ms.tr +++ /dev/null @@ -1,91 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: craftguide\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-03-23 18:35+0100\n" -"PO-Revision-Date: 2018-04-18 02:02+0800\n" -"Language-Team: muhdnurhidayat \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.6\n" -"Last-Translator: MuhdNurHidayat (MNH48) \n" -"Plural-Forms: nplurals=1; plural=0;\n" -"Language: ms\n" - -#: init.lua -msgid "Unknown Item (@1)" -msgstr "Item Tidak Diketahui (@1)" - -#: init.lua -msgid "Any item belonging to the group(s)" -msgstr "Sebarang item dari kumpulan" - -#: init.lua -msgid "Cooking time" -msgstr "Tempoh memasak" - -#: init.lua -msgid "Burning time" -msgstr "Tempoh pembakaran" - -#: init.lua -msgid "Alternate" -msgstr "Resipi lain" - -#: init.lua -msgid "Recipe @1 of @2" -msgstr "Resipi @1 dari @2" - -#: init.lua -msgid "" -"Recipe is too big to\n" -"be displayed (@1x@2)" -msgstr "" -"Resipi terlalu besar\n" -"untuk paparan (@1x@2)" - -#: init.lua -msgid "Search" -msgstr "Cari" - -#: init.lua -msgid "Reset" -msgstr "Set semula" - -#: init.lua -msgid "Increase window size" -msgstr "Besarkan saiz tetingkap" - -#: init.lua -msgid "Decrease window size" -msgstr "Kecilkan saiz tetingkap" - -#: init.lua -msgid "Previous page" -msgstr "Halaman sebelumnya" - -#: init.lua -msgid "Next page" -msgstr "Halaman seterusnya" - -#: init.lua -msgid "No item to show" -msgstr "Tiada item untuk dipaparkan" - -#: init.lua -msgid "Crafting Guide" -msgstr "Panduan Pertukangan" - -#: init.lua -msgid "Crafting Guide Sign" -msgstr "Papan Tanda Panduan Pertukangan" - -#: init.lua -msgid "Shows a list of available crafting recipes, cooking recipes and fuels" -msgstr "Menunjukkan senarai resipi pertukangan, resipi memasak dan bahan api yang ada" diff --git a/locale/craftguide.ru.tr b/locale/craftguide.ru.tr index e99d0c6..cd92378 100644 --- a/locale/craftguide.ru.tr +++ b/locale/craftguide.ru.tr @@ -1,90 +1,25 @@ -# Russian translation for craftguide mod. -# Copyright (C) 2018 -# This file is distributed under the same license as the craftguide package. -# codexp , 2018. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: 1.27\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-03-23 00:17+0100\n" -"PO-Revision-Date: \n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: Russian\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" +# textdomain: craftguide -#: init.lua -msgid "Unknown Item (@1)" -msgstr "Неизвестный элемент (@1)" - -#: init.lua -msgid "Any item belonging to the group(s)" -msgstr "Любой элемент из группы" - -#: init.lua -msgid "Cooking time" -msgstr "Время преготовления" - -#: init.lua -msgid "Burning time" -msgstr "Время горения" - -#: init.lua -msgid "Alternate" -msgstr "Другой" - -#: init.lua -msgid "Recipe @1 of @2" -msgstr "Рецепт @1 из @2" - -#: init.lua -msgid "" -"Recipe is too big to\n" -"be displayed (@1x@2)" -msgstr "" -"Рецепт слишком большой\n" -"для показа (@1x@2)" - -#: init.lua -msgid "Search" -msgstr "Поиск" - -#: init.lua -msgid "Reset" -msgstr "Сброс" - -#: init.lua -msgid "Increase window size" -msgstr "Увеличить окно" - -#: init.lua -msgid "Decrease window size" -msgstr "Уменьшить окно" - -#: init.lua -msgid "Previous page" -msgstr "Предыдущая страница" - -#: init.lua -msgid "Next page" -msgstr "Следущая страница" - -#: init.lua -msgid "No item to show" -msgstr "Нет элемента для показа" - -#: init.lua -msgid "Crafting Guide" -msgstr "книга рецептов крафта" - -#: init.lua -msgid "Crafting Guide Sign" -msgstr "табличка рецептов крафта" - -#: init.lua -msgid "Shows a list of available crafting recipes, cooking recipes and fuels" -msgstr "Показывает список рецептов крафта, преготовления и топливо" +Craft Guide=книга рецептов крафта +Crafting Guide=книга рецептов крафта +Crafting Guide Sign= +Search=Поиск +Reset=Сброс +Previous page=Предыдущая страница +Next page=Следущая страница +Usage @1 of @2=использование @1 из @2 +Recipe @1 of @2=Рецепт @1 из @2 +Burning time: @1=Время горения: @1 +Cooking time: @1=Время преготовления: @1 +Any item belonging to the group(s): @1=Любой элемент из группы: @1 +Recipe is too big to be displayed (@1x@2)=Рецепт слишком большой для показа (@1x@2) +Shapeless= +Cooking= +Increase window size=Увеличить окно +Decrease window size=Уменьшить окно +No item to show=Нет элемента для показа +Collect items to reveal more recipes= +Show recipe(s) of the pointed node= +No node pointed= +You don't know a recipe for this node= +No recipe for this node= diff --git a/locale/template b/locale/template new file mode 100644 index 0000000..d051c27 --- /dev/null +++ b/locale/template @@ -0,0 +1,25 @@ +# textdomain: craftguide + +Craft Guide= +Crafting Guide= +Crafting Guide Sign= +Search= +Reset= +Previous page= +Next page= +Usage @1 of @2= +Recipe @1 of @2= +Burning time: @1= +Cooking time: @1= +Any item belonging to the group(s): @1= +Recipe is too big to be displayed (@1x@2)= +Shapeless= +Cooking= +Increase window size= +Decrease window size= +No item to show= +Collect items to reveal more recipes= +Show recipe(s) of the pointed node= +No node pointed= +You don't know a recipe for this node= +No recipe for this node= diff --git a/locale/template.pot b/locale/template.pot deleted file mode 100644 index 8f8470d..0000000 --- a/locale/template.pot +++ /dev/null @@ -1,88 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-03-23 18:35+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: init.lua -msgid "Unknown Item (@1)" -msgstr "" - -#: init.lua -msgid "Any item belonging to the group(s)" -msgstr "" - -#: init.lua -msgid "Cooking time" -msgstr "" - -#: init.lua -msgid "Burning time" -msgstr "" - -#: init.lua -msgid "Alternate" -msgstr "" - -#: init.lua -msgid "Recipe @1 of @2" -msgstr "" - -#: init.lua -msgid "" -"Recipe is too big to\n" -"be displayed (@1x@2)" -msgstr "" - -#: init.lua -msgid "Search" -msgstr "" - -#: init.lua -msgid "Reset" -msgstr "" - -#: init.lua -msgid "Increase window size" -msgstr "" - -#: init.lua -msgid "Decrease window size" -msgstr "" - -#: init.lua -msgid "Previous page" -msgstr "" - -#: init.lua -msgid "Next page" -msgstr "" - -#: init.lua -msgid "No item to show" -msgstr "" - -#: init.lua -msgid "Crafting Guide" -msgstr "" - -#: init.lua -msgid "Crafting Guide Sign" -msgstr "" - -#: init.lua -msgid "Shows a list of available crafting recipes, cooking recipes and fuels" -msgstr "" From 183a9ff7a12f7ce2f64176498c8fc5e20537afa3 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Feb 2019 17:28:41 +0100 Subject: [PATCH 064/188] Fix get_filtered_items again --- init.lua | 4 ++-- locale/craftguide.fr.tr | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index d921808..09248a9 100644 --- a/init.lua +++ b/init.lua @@ -259,8 +259,8 @@ local function get_filtered_items(player) local usages = usages_cache[item] if recipes and #apply_recipe_filters(recipes, player) > 0 or - (usages and (progressive_mode and item_in_inv(item, data.inv_items)) and - #apply_recipe_filters(usages_cache[item], player) > 0) then + (usages and (not progressive_mode or item_in_inv(item, data.inv_items)) and + #apply_recipe_filters(usages_cache[item], player) > 0) then c = c + 1 items[c] = item end diff --git a/locale/craftguide.fr.tr b/locale/craftguide.fr.tr index 2bdbf9d..b09a1b0 100644 --- a/locale/craftguide.fr.tr +++ b/locale/craftguide.fr.tr @@ -2,7 +2,6 @@ Craft Guide=Guide de recettes Crafting Guide=Guide de recettes -Crafting Guide Sign=Guide de recettes (panneau) Search=Rechercher Reset=Réinitialiser Previous page=Page précédente From 8b79f321504071112d0888fab397f2e9afae041c Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 21 Feb 2019 18:23:13 +0100 Subject: [PATCH 065/188] Update German translation --- locale/craftguide.de.tr | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/locale/craftguide.de.tr b/locale/craftguide.de.tr index b630835..57e154f 100644 --- a/locale/craftguide.de.tr +++ b/locale/craftguide.de.tr @@ -11,15 +11,15 @@ Usage @1 of @2=Verwendung @1 von @2 Recipe @1 of @2=Rezept @1 von @2 Burning time: @1=Brennzeit: @1 Cooking time: @1=Kochzeit: @1 -Any item belonging to the group(s): @1=Beliebiger Gegenstand aus der Gruppe: @1 -Recipe is too big to be displayed (@1x@2)=Rezept ist zu groß für die Anzeige (@1x@2) -Shapeless= +Any item belonging to the group(s): @1=Beliebiger Gegenstand aus Gruppe(n): @1 +Recipe is too big to be displayed (@1x@2)=Rezept ist zu groß für die Anzeige (@1×@2) +Shapeless=Formlos Cooking=Kochen Increase window size=Fenster vergrößern Decrease window size=Fenster verkleinern No item to show=Nichts anzuzeigen -Collect items to reveal more recipes= -Show recipe(s) of the pointed node= -No node pointed= -You don't know a recipe for this node= -No recipe for this node= +Collect items to reveal more recipes=Gegenstände aufsammeln, um mehr Rezepte aufzudecken +Show recipe(s) of the pointed node=Rezept(e) des gezeigten Blocks anzeigen +No node pointed=Auf keinen Block gezeigt +You don't know a recipe for this node=Sie kennen kein Rezept für diesen Block +No recipe for this node=Kein Rezept für diesen Block From 799c0c70385c4b90771776f7e807a2f39b8cd03c Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Feb 2019 18:47:05 +0100 Subject: [PATCH 066/188] Update settingtypes.txt --- settingtypes.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/settingtypes.txt b/settingtypes.txt index 48fab09..14198ae 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -1,4 +1,5 @@ -#For enabling some options of craftguide. - +# The progressive mode shows recipes you can craft from items you ever had in your inventory. craftguide_progressive_mode (Progressive Mode) bool false + +# Integration in the default Minetest Game inventory. craftguide_sfinv_only (Sfinv only) bool false \ No newline at end of file From 92daae3e95d286758480d56b7ab276d18b84ebc6 Mon Sep 17 00:00:00 2001 From: pauloue Date: Fri, 1 Mar 2019 13:34:45 +0100 Subject: [PATCH 067/188] Replace group with item in item's usages --- .luacheckrc | 1 + init.lua | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 0e8162f..5a495c7 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -8,4 +8,5 @@ read_globals = { "sfinv_buttons", "vector", "string", + "table", } diff --git a/init.lua b/init.lua index 09248a9..9f11aa2 100644 --- a/init.lua +++ b/init.lua @@ -23,10 +23,12 @@ local serialize, deserialize = M.serialize, M.deserialize local ESC = M.formspec_escape local S = M.get_translator("craftguide") -local maxn, sort, concat, insert = table.maxn, table.sort, table.concat, table.insert -local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil +local maxn, sort, concat, insert, copy = + table.maxn, table.sort, table.concat, table.insert, table.copy local fmt, find, match, sub, split = string.format, string.find, string.match, string.sub, string.split + +local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local pairs, next, unpack = pairs, next, unpack local vec_add, vec_mul = vector.add, vector.multiply @@ -76,6 +78,14 @@ local function table_merge(t, t2) return t end +local function table_replace(t, val, new) + for k, v in pairs(t) do + if v == val then + t[k] = new + end + end +end + local function table_diff(t, t2) local hash = {} @@ -192,14 +202,22 @@ local function extract_groups(str) end local function item_in_recipe(item, recipe) - local item_groups = reg_items[item].groups for _, recipe_item in pairs(recipe.items) do if recipe_item == item then return true - elseif sub(recipe_item, 1, 6) == "group:" then + end + end +end + +local function groups_item_in_recipe(item, recipe) + local item_groups = reg_items[item].groups + for _, recipe_item in pairs(recipe.items) do + if sub(recipe_item, 1, 6) == "group:" then local groups = extract_groups(recipe_item) if item_has_groups(item_groups, groups) then - return true + local usage = copy(recipe) + table_replace(usage.items, recipe_item, item) + return usage end end end @@ -214,6 +232,12 @@ local function get_item_usages(item) if item_in_recipe(item, recipe) then c = c + 1 usages[c] = recipe + else + recipe = groups_item_in_recipe(item, recipe) + if recipe then + c = c + 1 + usages[c] = recipe + end end end end @@ -249,8 +273,6 @@ local function item_in_inv(item, inv_items) end local function get_filtered_items(player) - local name = player:get_player_name() - local data = player_data[name] local items, c = {}, 0 for i = 1, #init_items do @@ -259,8 +281,7 @@ local function get_filtered_items(player) local usages = usages_cache[item] if recipes and #apply_recipe_filters(recipes, player) > 0 or - (usages and (not progressive_mode or item_in_inv(item, data.inv_items)) and - #apply_recipe_filters(usages_cache[item], player) > 0) then + usages and #apply_recipe_filters(usages, player) > 0 then c = c + 1 items[c] = item end From eb2a81b8b5d5479d68480d1017274cda20eae935 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 1 Mar 2019 19:02:22 +0100 Subject: [PATCH 068/188] Allow special search filters by groups Using :groups= --- init.lua | 86 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 29 deletions(-) diff --git a/init.lua b/init.lua index 9f11aa2..d2613a8 100644 --- a/init.lua +++ b/init.lua @@ -24,9 +24,12 @@ local ESC = M.formspec_escape local S = M.get_translator("craftguide") local maxn, sort, concat, insert, copy = - table.maxn, table.sort, table.concat, table.insert, table.copy -local fmt, find, match, sub, split = - string.format, string.find, string.match, string.sub, string.split + table.maxn, table.sort, table.concat, table.insert, + table.copy + +local fmt, find, match, sub, split, lower = + string.format, string.find, string.match, string.sub, + string.split, string.lower local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local pairs, next, unpack = pairs, next, unpack @@ -249,29 +252,6 @@ local function get_item_usages(item) return usages end -local function item_in_inv(item, inv_items) - local inv_items_size = #inv_items - - if sub(item, 1, 6) == "group:" then - local groups = extract_groups(item) - for i = 1, inv_items_size do - local inv_item = reg_items[inv_items[i]] - if inv_item then - local item_groups = inv_item.groups - if item_has_groups(item_groups, groups) then - return true - end - end - end - else - for i = 1, inv_items_size do - if inv_items[i] == item then - return true - end - end - end -end - local function get_filtered_items(player) local items, c = {}, 0 @@ -681,9 +661,34 @@ local function search(data) for i = 1, #data.items_raw do local item = data.items_raw[i] - local desc = reg_items[item].description:lower() + local def = reg_items[item] + local desc = lower(def.description) - if find(item .. desc, filter, 1, true) then + local to_add + local search_in = item .. desc + local subfilter, search_groups, group_filters = + match(filter, "(.*)(:groups=)([%w_,]+)$") + + if search_groups then + local groups = split(group_filters, ",") + local has_groups = true + + for j = 1, #groups do + local group = groups[j] + if not def.groups[group] then + has_groups = nil + break + end + end + + if has_groups then + to_add = not subfilter or find(search_in, subfilter, 1, true) + end + else + to_add = find(search_in, filter, 1, true) + end + + if to_add then c = c + 1 filtered_list[c] = item end @@ -795,7 +800,7 @@ local function on_receive_fields(player, fields) elseif (fields.key_enter_field == "filter" or fields.search) and fields.filter ~= "" then - local fltr = fields.filter:lower() + local fltr = lower(fields.filter) if data.filter == fltr then return end @@ -993,6 +998,29 @@ else end if progressive_mode then + local function item_in_inv(item, inv_items) + local inv_items_size = #inv_items + + if sub(item, 1, 6) == "group:" then + local groups = extract_groups(item) + for i = 1, inv_items_size do + local inv_item = reg_items[inv_items[i]] + if inv_item then + local item_groups = inv_item.groups + if item_has_groups(item_groups, groups) then + return true + end + end + end + else + for i = 1, inv_items_size do + if inv_items[i] == item then + return true + end + end + end + end + local function recipe_in_inv(recipe, inv_items) for _, item in pairs(recipe.items) do if not item_in_inv(item, inv_items) then From 3f7ad71e0051544148e139cbe369ee31dc5ef873 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 3 Mar 2019 16:20:19 +0100 Subject: [PATCH 069/188] Add an API for search filters --- API.md | 55 +++++++++++++++++++++++++++++++++++ init.lua | 88 +++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 116 insertions(+), 27 deletions(-) diff --git a/API.md b/API.md index 76fe70b..9a0f74b 100644 --- a/API.md +++ b/API.md @@ -22,6 +22,8 @@ craftguide.register_craft({ }) ``` +--- + ### Recipe filters Recipe filters can be used to filter the recipes shown to players. Progressive @@ -61,6 +63,57 @@ Removes all recipe filters and adds a new one. Returns a map of recipe filters, indexed by name. +--- + +### Search filters + +Search filters are used to perform specific searches inside the search field. +They can be used like so: `+=,,<...>` + +Notes: +- If `optional name` is omitted, the search filter will apply to all items, without pre-filtering. +- Filters can be combined. +- The `+groups=` filter is currently implemented by default. + +#### `craftguide.add_search_filter(name, function(item, values))` + +Adds a search filter with the given name. +The search function should return a boolean value (whether the given item should be listed or not). + +Example function to show items which contain at least a recipe of given width(s): + +```lua +craftguide.add_search_filter("widths", function(item, widths) + local has_width + local recipes = recipes_cache[item] + + if recipes then + for i = 1, #recipes do + local recipe_width = recipes[i].width + for j = 1, #widths do + local width = tonumber(widths[j]) + if width == recipe_width then + has_width = true + break + end + end + end + end + + return has_width +end) +``` + +#### `craftguide.remove_search_filter(name)` + +Removes the search filter with the given name. + +#### `craftguide.get_search_filters()` + +Returns a map of search filters, indexed by name. + +--- + ### Custom formspec elements #### `craftguide.add_formspec_element(name, def)` @@ -102,6 +155,8 @@ Removes the formspec element with the given name. Returns a map of formspec elements, indexed by name. +--- + ### Miscellaneous #### `craftguide.show(player_name, item, show_usages)` diff --git a/init.lua b/init.lua index d2613a8..e3a1466 100644 --- a/init.lua +++ b/init.lua @@ -27,9 +27,9 @@ local maxn, sort, concat, insert, copy = table.maxn, table.sort, table.concat, table.insert, table.copy -local fmt, find, match, sub, split, lower = - string.format, string.find, string.match, string.sub, - string.split, string.lower +local fmt, find, gmatch, match, sub, split, lower = + string.format, string.find, string.gmatch, string.match, + string.sub, string.split, string.lower local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local pairs, next, unpack = pairs, next, unpack @@ -102,17 +102,17 @@ local function table_diff(t, t2) hash[v] = nil end - local ret, c = {}, 0 + local diff, c = {}, 0 for i = 1, #t do local v = t[i] if hash[v] then c = c + 1 - ret[c] = v + diff[c] = v end end - return ret + return diff end local function __func() @@ -142,16 +142,24 @@ end local recipe_filters = {} -function craftguide.add_recipe_filter(name, func) - recipe_filters[name] = func +function craftguide.add_recipe_filter(name, f) + local func = "craftguide." .. __func() .. "(): " + assert(name, func .. "filter name missing") + assert(f and type(f) == "function", func .. "filter function missing") + + recipe_filters[name] = f end function craftguide.remove_recipe_filter(name) recipe_filters[name] = nil end -function craftguide.set_recipe_filter(name, func) - recipe_filters = {[name] = func} +function craftguide.set_recipe_filter(name, f) + local func = "craftguide." .. __func() .. "(): " + assert(name, func .. "filter name missing") + assert(f and type(f) == "function", func .. "filter function missing") + + recipe_filters = {[name] = f} end function craftguide.get_recipe_filters() @@ -166,6 +174,24 @@ local function apply_recipe_filters(recipes, player) return recipes end +local search_filters = {} + +function craftguide.add_search_filter(name, f) + local func = "craftguide." .. __func() .. "(): " + assert(name, func .. "filter name missing") + assert(f and type(f) == "function", func .. "filter function missing") + + search_filters[name] = f +end + +function craftguide.remove_search_filter(name) + search_filters[name] = nil +end + +function craftguide.get_search_filters() + return search_filters +end + local formspec_elements = {} function craftguide.add_formspec_element(name, def) @@ -649,6 +675,21 @@ local show_fs = function(player, name) end end +craftguide.add_search_filter("groups", function(item, groups) + local itemdef = reg_items[item] + local has_groups = true + + for i = 1, #groups do + local group = groups[i] + if not itemdef.groups[group] then + has_groups = nil + break + end + end + + return has_groups +end) + local function search(data) local filter = data.filter @@ -663,27 +704,20 @@ local function search(data) local item = data.items_raw[i] local def = reg_items[item] local desc = lower(def.description) - - local to_add local search_in = item .. desc - local subfilter, search_groups, group_filters = - match(filter, "(.*)(:groups=)([%w_,]+)$") + local pattern = "%+([%w_]+)=([%w_,]+)" + local to_add - if search_groups then - local groups = split(group_filters, ",") - local has_groups = true - - for j = 1, #groups do - local group = groups[j] - if not def.groups[group] then - has_groups = nil - break + if find(filter, pattern) then + local prepend = match(filter, "^(.-)%+") + for filter_name, values in gmatch(filter, pattern) do + local func = search_filters[filter_name] + if func then + values = split(values, ",") + to_add = func(item, values) and (not prepend or + find(search_in, prepend, 1, true)) end end - - if has_groups then - to_add = not subfilter or find(search_in, subfilter, 1, true) - end else to_add = find(search_in, filter, 1, true) end From e0e57b45eaf4a7a4ed749112604624f65537623f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 4 Mar 2019 00:45:30 +0100 Subject: [PATCH 070/188] Quick fix --- init.lua | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/init.lua b/init.lua index e3a1466..031dba6 100644 --- a/init.lua +++ b/init.lua @@ -699,24 +699,31 @@ local function search(data) end local filtered_list, c = {}, 0 + local pattern = "^(.-)%+([%w_]+)=([%w_,]+)" + local search_filter = next(search_filters) and match(filter, pattern) + local filters = {} + + if search_filter then + for filter_name, values in gmatch(filter, sub(pattern, 6, -1)) do + if search_filters[filter_name] then + values = split(values, ",") + filters[filter_name] = values + end + end + end for i = 1, #data.items_raw do local item = data.items_raw[i] local def = reg_items[item] local desc = lower(def.description) local search_in = item .. desc - local pattern = "%+([%w_]+)=([%w_,]+)" local to_add - if find(filter, pattern) then - local prepend = match(filter, "^(.-)%+") - for filter_name, values in gmatch(filter, pattern) do + if search_filter then + for filter_name, values in pairs(filters) do local func = search_filters[filter_name] - if func then - values = split(values, ",") - to_add = func(item, values) and (not prepend or - find(search_in, prepend, 1, true)) - end + to_add = func(item, values) and (not search_filter or + find(search_in, search_filter, 1, true)) end else to_add = find(search_in, filter, 1, true) From b1a67eb63239724280bee7686513cd785f325d66 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 7 Mar 2019 13:43:47 +0100 Subject: [PATCH 071/188] Add examples in doc --- API.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/API.md b/API.md index 9a0f74b..e03a0e2 100644 --- a/API.md +++ b/API.md @@ -70,10 +70,15 @@ Returns a map of recipe filters, indexed by name. Search filters are used to perform specific searches inside the search field. They can be used like so: `+=,,<...>` +Examples: + +- `+groups=cracky,crumbly`: search for groups `cracky` and `crumbly` in all items. +- `sand+groups=falling_node`: search for group `falling_node` for items which contain `sand` in their names. + Notes: - If `optional name` is omitted, the search filter will apply to all items, without pre-filtering. - Filters can be combined. -- The `+groups=` filter is currently implemented by default. +- The `groups` filter is currently implemented by default. #### `craftguide.add_search_filter(name, function(item, values))` From 054a7ab3af0b03b56cdaf591d745336b17e7bbdd Mon Sep 17 00:00:00 2001 From: Ramir1 <> Date: Thu, 7 Mar 2019 13:47:15 +0100 Subject: [PATCH 072/188] Update russian translations --- locale/craftguide.ru.tr | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/locale/craftguide.ru.tr b/locale/craftguide.ru.tr index cd92378..2d4dfa2 100644 --- a/locale/craftguide.ru.tr +++ b/locale/craftguide.ru.tr @@ -2,7 +2,7 @@ Craft Guide=книга рецептов крафта Crafting Guide=книга рецептов крафта -Crafting Guide Sign= +Crafting Guide Sign=Знак с книгой рецептов Search=Поиск Reset=Сброс Previous page=Предыдущая страница @@ -13,13 +13,13 @@ Burning time: @1=Время горения: @1 Cooking time: @1=Время преготовления: @1 Any item belonging to the group(s): @1=Любой элемент из группы: @1 Recipe is too big to be displayed (@1x@2)=Рецепт слишком большой для показа (@1x@2) -Shapeless= -Cooking= +Shapeless=Бесформенный +Cooking=Приготовление Increase window size=Увеличить окно Decrease window size=Уменьшить окно No item to show=Нет элемента для показа -Collect items to reveal more recipes= -Show recipe(s) of the pointed node= -No node pointed= -You don't know a recipe for this node= -No recipe for this node= +Collect items to reveal more recipes=Собирайте предметы, чтобы раскрыть больше рецептов +Show recipe(s) of the pointed node=Показать рецепт(ы) выбранной ноды +No node pointed=Не указана нода +You don't know a recipe for this node=Вы не знаете рецепт для этой ноды +No recipe for this node=Нет рецептов для этой ноды From c9ebd5c0697a7aa2438a3d77fddf415ebd0fc664 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 10 Mar 2019 15:57:54 +0100 Subject: [PATCH 073/188] Cleanup --- init.lua | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/init.lua b/init.lua index 031dba6..863a6af 100644 --- a/init.lua +++ b/init.lua @@ -399,7 +399,7 @@ local function get_tooltip(item, groups, cooktime, burntime) S("Burning time: @1", colorize("yellow", burntime)) end - return fmt(FMT.tooltip, item, ESC(tooltip)) + return fmt("tooltip[:%s;%s]", item, ESC(tooltip)) end local function get_recipe_fs(data, iY) @@ -464,7 +464,7 @@ local function get_recipe_fs(data, iY) local label = groups and "\nG" or "" - fs[#fs + 1] = fmt(FMT.item_image_button, + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;:%s;]", X, Y + (sfinv_only and 0.7 or 0.2), btn_size, @@ -529,7 +529,7 @@ local function get_recipe_fs(data, iY) local output_name = match(recipe.output, "%S+") local burntime = fuel_cache[output_name] - fs[#fs + 1] = fmt(FMT.item_image_button, + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;:%s;]", output_X, sfinv_only and 6.7 or iY + 2.2, 1.1, @@ -640,7 +640,7 @@ local function make_formspec(name) local X = i % data.iX local Y = (i % ipp - X) / data.iX + 1 - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s_inv;]", + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;:%s;]", X - (sfinv_only and 0 or (X * 0.05)), Y, 1.1, @@ -699,12 +699,12 @@ local function search(data) end local filtered_list, c = {}, 0 - local pattern = "^(.-)%+([%w_]+)=([%w_,]+)" - local search_filter = next(search_filters) and match(filter, pattern) + local extras = "^(.-)%+([%w_]+)=([%w_,]+)" + local search_filter = next(search_filters) and match(filter, extras) local filters = {} if search_filter then - for filter_name, values in gmatch(filter, sub(pattern, 6, -1)) do + for filter_name, values in gmatch(filter, sub(extras, 6, -1)) do if search_filters[filter_name] then values = split(values, ",") filters[filter_name] = values @@ -722,7 +722,7 @@ local function search(data) if search_filter then for filter_name, values in pairs(filters) do local func = search_filters[filter_name] - to_add = func(item, values) and (not search_filter or + to_add = func(item, values) and (search_filter == "" or find(search_in, search_filter, 1, true)) end else @@ -752,8 +752,8 @@ local function get_inv_items(player) local stacks = {} for i = 1, #item_lists do - local l = inv:get_list(item_lists[i]) - stacks = table_merge(stacks, l) + local list = inv:get_list(item_lists[i]) + table_merge(stacks, list) end local inv_items, c = {}, 0 @@ -871,20 +871,17 @@ local function on_receive_fields(player, fields) data.pagenum = 1 data.iX = data.iX + (fields.size_inc and 1 or -1) show_fs(player, name) - else local item for field in pairs(fields) do - if find(field, ":") then - item = field + if sub(field, 1, 1) == ":" then + item = sub(field, 2, -1) break end end if not item then return - elseif sub(item, -4) == "_inv" then - item = sub(item, 1, -5) end if item ~= data.query_item then From a242f6c61c2be7a7def80e01f2aa716041d3f14e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 11 Mar 2019 02:49:27 +0100 Subject: [PATCH 074/188] Revert some changes --- init.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index 863a6af..0407cbc 100644 --- a/init.lua +++ b/init.lua @@ -399,7 +399,7 @@ local function get_tooltip(item, groups, cooktime, burntime) S("Burning time: @1", colorize("yellow", burntime)) end - return fmt("tooltip[:%s;%s]", item, ESC(tooltip)) + return fmt(FMT.tooltip, item, ESC(tooltip)) end local function get_recipe_fs(data, iY) @@ -464,7 +464,7 @@ local function get_recipe_fs(data, iY) local label = groups and "\nG" or "" - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;:%s;]", + fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0.2), btn_size, @@ -529,7 +529,7 @@ local function get_recipe_fs(data, iY) local output_name = match(recipe.output, "%S+") local burntime = fuel_cache[output_name] - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;:%s;]", + fs[#fs + 1] = fmt(FMT.item_image_button, output_X, sfinv_only and 6.7 or iY + 2.2, 1.1, @@ -640,7 +640,7 @@ local function make_formspec(name) local X = i % data.iX local Y = (i % ipp - X) / data.iX + 1 - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;:%s;]", + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s_inv;]", X - (sfinv_only and 0 or (X * 0.05)), Y, 1.1, @@ -874,14 +874,16 @@ local function on_receive_fields(player, fields) else local item for field in pairs(fields) do - if sub(field, 1, 1) == ":" then - item = sub(field, 2, -1) + if find(field, ":") then + item = field break end end if not item then return + elseif sub(item, -4) == "_inv" then + item = sub(item, 1, -5) end if item ~= data.query_item then From 9df355b8994dcb9f23f9cded120c0cbfbbb5407f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 12 Mar 2019 14:19:54 +0100 Subject: [PATCH 075/188] Add more assert checks --- init.lua | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/init.lua b/init.lua index 0407cbc..8519340 100644 --- a/init.lua +++ b/init.lua @@ -13,6 +13,7 @@ local fuel_cache = {} local progressive_mode = M.settings:get_bool("craftguide_progressive_mode") local sfinv_only = M.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") +local after = M.after local colorize = M.colorize local reg_items = M.registered_items local get_result = M.get_craft_result @@ -119,23 +120,31 @@ local function __func() return debug.getinfo(2, "n").name end +local function is_str(x) + return type(x) == "string" +end + +local function is_func(x) + return type(x) == "function" +end + local custom_crafts, craft_types = {}, {} function craftguide.register_craft_type(name, def) local func = "craftguide." .. __func() .. "(): " - assert(name, func .. "'name' field missing") - assert(def.description, func .. "'description' field missing") - assert(def.icon, func .. "'icon' field missing") + assert(is_str(name), func .. "'name' field missing") + assert(is_str(def.description), func .. "'description' field missing") + assert(is_str(def.icon), func .. "'icon' field missing") craft_types[name] = def end function craftguide.register_craft(def) local func = "craftguide." .. __func() .. "(): " - assert(def.type, func .. "'type' field missing") - assert(def.width, func .. "'width' field missing") - assert(def.output, func .. "'output' field missing") - assert(def.items, func .. "'items' field missing") + assert(is_str(def.type), func .. "'type' field missing") + assert(is_str(def.width), func .. "'width' field missing") + assert(is_str(def.output), func .. "'output' field missing") + assert(is_str(def.items), func .. "'items' field missing") custom_crafts[#custom_crafts + 1] = def end @@ -144,8 +153,8 @@ local recipe_filters = {} function craftguide.add_recipe_filter(name, f) local func = "craftguide." .. __func() .. "(): " - assert(name, func .. "filter name missing") - assert(f and type(f) == "function", func .. "filter function missing") + assert(is_str(name), func .. "filter name missing") + assert(is_func(f), func .. "filter function missing") recipe_filters[name] = f end @@ -156,8 +165,8 @@ end function craftguide.set_recipe_filter(name, f) local func = "craftguide." .. __func() .. "(): " - assert(name, func .. "filter name missing") - assert(f and type(f) == "function", func .. "filter function missing") + assert(is_str(name), func .. "filter name missing") + assert(is_func(f), func .. "filter function missing") recipe_filters = {[name] = f} end @@ -178,8 +187,8 @@ local search_filters = {} function craftguide.add_search_filter(name, f) local func = "craftguide." .. __func() .. "(): " - assert(name, func .. "filter name missing") - assert(f and type(f) == "function", func .. "filter function missing") + assert(is_str(name), func .. "filter name missing") + assert(is_func(f), func .. "filter function missing") search_filters[name] = f end @@ -196,8 +205,9 @@ local formspec_elements = {} function craftguide.add_formspec_element(name, def) local func = "craftguide." .. __func() .. "(): " - assert(def.element, func .. "'element' field not defined") - assert(def.type, func .. "'type' field not defined") + assert(is_str(name), func .. "formspec element name missing") + assert(is_str(def.element), func .. "'element' field not defined") + assert(is_str(def.type), func .. "'type' field not defined") assert(FMT[def.type], func .. "'" .. def.type .. "' type not supported by the API") formspec_elements[name] = { @@ -1107,7 +1117,7 @@ if progressive_mode then end end - M.after(POLL_FREQ, poll_new_items) + after(POLL_FREQ, poll_new_items) end poll_new_items() From eb7292da7a9fed822f6411f59165497770ad1869 Mon Sep 17 00:00:00 2001 From: Wuzzy2 Date: Wed, 13 Mar 2019 15:13:37 +0100 Subject: [PATCH 076/188] =?UTF-8?q?2=C3=972=20for=20shapeless=20recipe=20w?= =?UTF-8?q?/=20<=3D=204=20items?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 8519340..666f408 100644 --- a/init.lua +++ b/init.lua @@ -423,7 +423,8 @@ local function get_recipe_fs(data, iY) cooktime, width = width, 1 elseif width == 0 then shapeless = true - width = min(3, #recipe.items) + local n = #recipe.items + width = n <= 4 and 2 or min(3, n) end local rows = ceil(maxn(recipe.items) / width) From b6181ebd7a1d752e6afab11d8e47ec787b8adfa6 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 13 Mar 2019 16:56:35 +0100 Subject: [PATCH 077/188] Minor cleanup --- init.lua | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/init.lua b/init.lua index 666f408..ad30e7a 100644 --- a/init.lua +++ b/init.lua @@ -758,31 +758,6 @@ local function search(data) data.items = filtered_list end -local function get_inv_items(player) - local inv = player:get_inventory() - local stacks = {} - - for i = 1, #item_lists do - local list = inv:get_list(item_lists[i]) - table_merge(stacks, list) - end - - local inv_items, c = {}, 0 - - for i = 1, #stacks do - local stack = stacks[i] - if not stack:is_empty() then - local name = stack:get_name() - if reg_items[name] then - c = c + 1 - inv_items[c] = name - end - end - end - - return inv_items -end - local function init_data(name) player_data[name] = { filter = "", @@ -1102,6 +1077,31 @@ if progressive_mode then return filtered end + local function get_inv_items(player) + local inv = player:get_inventory() + local stacks = {} + + for i = 1, #item_lists do + local list = inv:get_list(item_lists[i]) + table_merge(stacks, list) + end + + local inv_items, c = {}, 0 + + for i = 1, #stacks do + local stack = stacks[i] + if not stack:is_empty() then + local name = stack:get_name() + if reg_items[name] then + c = c + 1 + inv_items[c] = name + end + end + end + + return inv_items + end + -- Workaround. Need an engine call to detect when the contents -- of the player inventory changed, instead. local function poll_new_items() @@ -1212,7 +1212,7 @@ M.register_chatcommand("craft", { function craftguide.show(name, item, show_usages) local func = "craftguide." .. __func() .. "(): " - assert(name, func .. "player name missing") + assert(is_str(name), func .. "player name missing") local data = player_data[name] local player = get_player_by_name(name) From 4c0371c5cc01a5fd3103ab4109b7d4788e094ddb Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 14 Mar 2019 14:11:44 +0100 Subject: [PATCH 078/188] Progressive mode: Fix crash on player leaving --- init.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/init.lua b/init.lua index ad30e7a..263c043 100644 --- a/init.lua +++ b/init.lua @@ -898,11 +898,6 @@ M.register_on_joinplayer(function(player) init_data(name) end) -M.register_on_leaveplayer(function(player) - local name = player:get_player_name() - player_data[name] = nil -end) - if sfinv_only then sfinv.register_page("craftguide:craftguide", { title = S("Craft Guide"), @@ -1152,6 +1147,11 @@ if progressive_mode then end) end +M.register_on_leaveplayer(function(player) + local name = player:get_player_name() + player_data[name] = nil +end) + M.register_chatcommand("craft", { description = S("Show recipe(s) of the pointed node"), func = function(name) From 9dc656d5a22f7cd7739fc3d36b804aa1577b5d5a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Mar 2019 00:21:11 +0100 Subject: [PATCH 079/188] Fix broken assert() --- init.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index 263c043..cd85f77 100644 --- a/init.lua +++ b/init.lua @@ -124,6 +124,14 @@ local function is_str(x) return type(x) == "string" end +local function is_num(x) + return type(x) == "number" +end + +local function is_table(x) + return type(x) == "table" +end + local function is_func(x) return type(x) == "function" end @@ -142,9 +150,9 @@ end function craftguide.register_craft(def) local func = "craftguide." .. __func() .. "(): " assert(is_str(def.type), func .. "'type' field missing") - assert(is_str(def.width), func .. "'width' field missing") + assert(is_num(def.width), func .. "'width' field missing") assert(is_str(def.output), func .. "'output' field missing") - assert(is_str(def.items), func .. "'items' field missing") + assert(is_table(def.items), func .. "'items' field missing") custom_crafts[#custom_crafts + 1] = def end From 84756af3a11a8e9e8635b5ab0300443a095852dd Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Mar 2019 17:30:46 +0100 Subject: [PATCH 080/188] Opens the stereotypes to the API --- API.md | 9 +++++++++ init.lua | 8 +++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/API.md b/API.md index e03a0e2..d9cf161 100644 --- a/API.md +++ b/API.md @@ -171,3 +171,12 @@ Opens the Crafting Guide with the current filter applied. * `player_name`: string param. * `item`: optional, string param. If set, this item is pre-selected. If the item does not exist or has no recipe, use the player's previous selection. By default, player's previous selection is used * `show_usages`: optional, boolean param. If true, show item usages. + +#### `craftguide.group_stereotypes` + +This is the table indexing the item groups by stereotypes. +You can add a stereotype like so: + +```Lua +craftguide.group_stereotypes.radioactive = "mod:item" +``` diff --git a/init.lua b/init.lua index cd85f77..7236fe9 100644 --- a/init.lua +++ b/init.lua @@ -54,7 +54,7 @@ local FMT = { item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]", } -local group_stereotypes = { +craftguide.group_stereotypes = { wool = "wool:white", dye = "dye:white", water_bucket = "bucket:bucket_water", @@ -373,9 +373,11 @@ local function groups_to_item(groups) if #groups == 1 then local group = groups[1] local def_gr = "default:" .. group + local stereotypes = craftguide.group_stereotypes + local stereotype = stereotypes and stereotypes[group] - if group_stereotypes[group] then - return group_stereotypes[group] + if stereotype then + return stereotype elseif reg_items[def_gr] then return def_gr end From 0271f61fc2068617741e80a5b82be21b6391e73b Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 21 Mar 2019 17:36:00 +0100 Subject: [PATCH 081/188] Change tooltip format --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index 7236fe9..363a61d 100644 --- a/init.lua +++ b/init.lua @@ -48,7 +48,7 @@ local FMT = { label = "label[%f,%f;%s]", image = "image[%f,%f;%f,%f;%s]", button = "button[%f,%f;%f,%f;%s;%s]", - tooltip = "tooltip[%s;%s]", + tooltip = "tooltip[%f,%f;%f,%f;%s]", item_image = "item_image[%f,%f;%f,%f;%s]", image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]", @@ -419,7 +419,7 @@ local function get_tooltip(item, groups, cooktime, burntime) S("Burning time: @1", colorize("yellow", burntime)) end - return fmt(FMT.tooltip, item, ESC(tooltip)) + return fmt("tooltip[%s;%s]", item, ESC(tooltip)) end local function get_recipe_fs(data, iY) From 22a85f50c1bb979c23325cb30ec0f49604105269 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 8 May 2019 20:57:45 +0200 Subject: [PATCH 082/188] Sugar --- init.lua | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index 363a61d..965fc01 100644 --- a/init.lua +++ b/init.lua @@ -258,6 +258,7 @@ end local function groups_item_in_recipe(item, recipe) local item_groups = reg_items[item].groups + for _, recipe_item in pairs(recipe.items) do if sub(recipe_item, 1, 6) == "group:" then local groups = extract_groups(recipe_item) @@ -478,6 +479,7 @@ local function get_recipe_fs(data, iY) end local groups + if sub(item, 1, 6) == "group:" then groups = extract_groups(item) item = groups_to_item(groups) @@ -770,10 +772,10 @@ end local function init_data(name) player_data[name] = { - filter = "", - pagenum = 1, - iX = sfinv_only and 8 or DEFAULT_SIZE, - items = init_items, + filter = "", + pagenum = 1, + iX = sfinv_only and 8 or DEFAULT_SIZE, + items = init_items, items_raw = init_items, } end @@ -1168,11 +1170,12 @@ M.register_chatcommand("craft", { local player = get_player_by_name(name) local ppos = player:get_pos() local dir = player:get_look_dir() - local eye_h = {x = ppos.x, y = ppos.y + 1.625, z = ppos.z} + + ppos.y = ppos.y + 1.625 local node_name for i = 1, 10 do - local look_at = vec_add(eye_h, vec_mul(dir, i)) + local look_at = vec_add(ppos, vec_mul(dir, i)) local node = M.get_node(look_at) if node.name ~= "air" then From a2e4f2079131af0d67829a9f70ac6c346b6908f5 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 23 Jun 2019 01:24:26 +0200 Subject: [PATCH 083/188] Items with no recipes but with usages are shown --- init.lua | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/init.lua b/init.lua index 965fc01..8483219 100644 --- a/init.lua +++ b/init.lua @@ -271,7 +271,7 @@ local function groups_item_in_recipe(item, recipe) end end -local function get_item_usages(item) +local function get_usages(item) local usages, c = {}, 0 for _, recipes in pairs(recipes_cache) do @@ -329,7 +329,13 @@ local function cache_recipes(output) if #recipes > 0 then recipes_cache[output] = recipes - return true + end +end + +local function cache_usages(item) + local usages = get_usages(item) + if #usages > 0 then + usages_cache[item] = usages end end @@ -350,7 +356,7 @@ local function get_recipes(item, data, player) if data.show_usages then recipes = apply_recipe_filters(usages_cache[item], player) - if #recipes == 0 then + if recipes and #recipes == 0 then return end end @@ -790,28 +796,38 @@ local function reset_data(data) data.items = data.items_raw end -local function cache_usages() - for i = 1, #init_items do - local item = init_items[i] - usages_cache[item] = get_item_usages(item) - end +local function check_item(def) + return not (def.groups.not_in_craft_guide == 1 or + def.groups.not_in_creative_inventory == 1) and + def.description and def.description ~= "" end local function get_init_items() - local c = 0 + local items, c = {}, 0 + for name, def in pairs(reg_items) do - local is_fuel = cache_fuel(name) - if not (def.groups.not_in_craft_guide == 1 or - def.groups.not_in_creative_inventory == 1) and - def.description and def.description ~= "" and - (cache_recipes(name) or is_fuel) then + if check_item(def) then + cache_fuel(name) + cache_recipes(name) + + c = c + 1 + items[c] = name + end + end + + c = 0 + + for i = 1, #items do + local name = items[i] + cache_usages(name) + + if recipes_cache[name] or usages_cache[name] then c = c + 1 init_items[c] = name end end sort(init_items) - cache_usages() end local function on_receive_fields(player, fields) From e710fcd48395f230f3a732086de59a6a358aeb15 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 23 Jun 2019 01:42:12 +0200 Subject: [PATCH 084/188] Small optimization --- init.lua | 60 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/init.lua b/init.lua index 8483219..03afd38 100644 --- a/init.lua +++ b/init.lua @@ -1,7 +1,7 @@ craftguide = {} local M = minetest -local player_data = {} +local pdata = {} -- Caches local init_items = {} @@ -18,6 +18,8 @@ local colorize = M.colorize local reg_items = M.registered_items local get_result = M.get_craft_result local show_formspec = M.show_formspec +local get_players = M.get_connected_players +local get_all_recipes = M.get_all_craft_recipes local get_player_by_name = M.get_player_by_name local serialize, deserialize = M.serialize, M.deserialize @@ -41,7 +43,6 @@ local MIN_LIMIT, MAX_LIMIT = 10, 12 DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) local GRID_LIMIT = 5 -local POLL_FREQ = 0.25 local FMT = { box = "box[%f,%f;%f,%f;%s]", @@ -316,7 +317,7 @@ local function get_filtered_items(player) end local function cache_recipes(output) - local recipes = M.get_all_craft_recipes(output) or {} + local recipes = get_all_recipes(output) or {} local c = 0 for i = 1, #custom_crafts do @@ -590,7 +591,7 @@ local function get_recipe_fs(data, iY) end local function make_formspec(name) - local data = player_data[name] + local data = pdata[name] local iY = sfinv_only and 4 or data.iX - 5 local ipp = data.iX * iY @@ -777,7 +778,7 @@ local function search(data) end local function init_data(name) - player_data[name] = { + pdata[name] = { filter = "", pagenum = 1, iX = sfinv_only and 8 or DEFAULT_SIZE, @@ -832,7 +833,7 @@ end local function on_receive_fields(player, fields) local name = player:get_player_name() - local data = player_data[name] + local data = pdata[name] for elem_name, def in pairs(formspec_elements) do if fields[elem_name] and def.action then @@ -940,7 +941,7 @@ if sfinv_only then on_enter = function(self, player, context) if next(recipe_filters) then local name = player:get_player_name() - local data = player_data[name] + local data = pdata[name] data.items_raw = get_filtered_items(player) search(data) @@ -962,7 +963,7 @@ else local name = user:get_player_name() if next(recipe_filters) then - local data = player_data[name] + local data = pdata[name] data.items_raw = get_filtered_items(user) search(data) end @@ -1047,6 +1048,9 @@ else end if progressive_mode then + local PLAYERS = {} + local POLL_FREQ = 0.25 + local function item_in_inv(item, inv_items) local inv_items_size = #inv_items @@ -1082,7 +1086,7 @@ if progressive_mode then local function progressive_filter(recipes, player) local name = player:get_player_name() - local data = player_data[name] + local data = pdata[name] if #data.inv_items == 0 then return {} @@ -1128,13 +1132,13 @@ if progressive_mode then -- Workaround. Need an engine call to detect when the contents -- of the player inventory changed, instead. local function poll_new_items() - local players = M.get_connected_players() - for i = 1, #players do - local player = players[i] + for i = 1, #PLAYERS do + local player = PLAYERS[i] local name = player:get_player_name() - local data = player_data[name] + local data = pdata[name] + local inv_items = get_inv_items(player) - local diff = table_diff(inv_items, data.inv_items) + local diff = table_diff(inv_items, data.inv_items) if #diff > 0 then data.inv_items = table_merge(diff, data.inv_items) @@ -1149,9 +1153,11 @@ if progressive_mode then craftguide.add_recipe_filter("Default progressive filter", progressive_filter) M.register_on_joinplayer(function(player) + PLAYERS = get_players() + local meta = player:get_meta() local name = player:get_player_name() - local data = player_data[name] + local data = pdata[name] data.inv_items = deserialize(meta:get_string("inv_items")) or {} end) @@ -1159,17 +1165,19 @@ if progressive_mode then local function save_meta(player) local meta = player:get_meta() local name = player:get_player_name() - local data = player_data[name] + local data = pdata[name] meta:set_string("inv_items", serialize(data.inv_items)) end - M.register_on_leaveplayer(save_meta) + M.register_on_leaveplayer(function(player) + PLAYERS = get_players() + save_meta(player) + end) M.register_on_shutdown(function() - local players = M.get_connected_players() - for i = 1, #players do - local player = players[i] + for i = 1, #PLAYERS do + local player = PLAYERS[i] save_meta(player) end end) @@ -1177,17 +1185,17 @@ end M.register_on_leaveplayer(function(player) local name = player:get_player_name() - player_data[name] = nil + pdata[name] = nil end) M.register_chatcommand("craft", { description = S("Show recipe(s) of the pointed node"), func = function(name) local player = get_player_by_name(name) - local ppos = player:get_pos() local dir = player:get_look_dir() + local ppos = player:get_pos() + ppos.y = ppos.y + 1.625 - ppos.y = ppos.y + 1.625 local node_name for i = 1, 10 do @@ -1206,7 +1214,7 @@ M.register_chatcommand("craft", { return false, red .. S("No node pointed") end - local data = player_data[name] + local data = pdata[name] reset_data(data) local recipes = recipes_cache[node_name] @@ -1233,7 +1241,7 @@ M.register_chatcommand("craft", { end data.query_item = node_name - data.recipes = recipes + data.recipes = recipes return true, show_fs(player, name) end, @@ -1243,7 +1251,7 @@ function craftguide.show(name, item, show_usages) local func = "craftguide." .. __func() .. "(): " assert(is_str(name), func .. "player name missing") - local data = player_data[name] + local data = pdata[name] local player = get_player_by_name(name) local query_item = data.query_item From ca18ae0e3a1a2f71792b0433e372915b0c833dc1 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 30 Jun 2019 16:24:18 +0200 Subject: [PATCH 085/188] Fix nil item crash in get_tooltip() - Fixes #84, regression caused by d950c71db (@pauloue) --- init.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/init.lua b/init.lua index 03afd38..0029a66 100644 --- a/init.lua +++ b/init.lua @@ -30,9 +30,9 @@ local maxn, sort, concat, insert, copy = table.maxn, table.sort, table.concat, table.insert, table.copy -local fmt, find, gmatch, match, sub, split, lower = +local fmt, find, gmatch, match, sub, split, upper, lower = string.format, string.find, string.gmatch, string.match, - string.sub, string.split, string.lower + string.sub, string.split, string.upper, string.lower local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local pairs, next, unpack = pairs, next, unpack @@ -414,7 +414,11 @@ local function get_tooltip(item, groups, cooktime, burntime) groupstr = concat(groupstr, ", ") tooltip = S("Any item belonging to the group(s): @1", groupstr) else - tooltip = reg_items[item].description + local def = reg_items[item] + + tooltip = def and def.description or + (def and match(item, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or + S("Unknown Item (@1)", item)) end if cooktime then @@ -734,7 +738,7 @@ local function search(data) local filters = {} if search_filter then - for filter_name, values in gmatch(filter, sub(extras, 6, -1)) do + for filter_name, values in gmatch(filter, sub(extras, 6)) do if search_filters[filter_name] then values = split(values, ",") filters[filter_name] = values From 97676d094ecbc44559d924ea2e65b6e01b368997 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 30 Jun 2019 19:42:32 +0200 Subject: [PATCH 086/188] Fix possible crash --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 0029a66..80b129f 100644 --- a/init.lua +++ b/init.lua @@ -749,7 +749,7 @@ local function search(data) for i = 1, #data.items_raw do local item = data.items_raw[i] local def = reg_items[item] - local desc = lower(def.description) + local desc = (def and def.description) and lower(def.description) or "" local search_in = item .. desc local to_add From 22c5c9444e75144437bd8a09eec652f1008d03ed Mon Sep 17 00:00:00 2001 From: Beha Date: Sun, 4 Aug 2019 13:09:47 -0400 Subject: [PATCH 087/188] Interpret group value 0 as "not in group". This fixes instances where items are counted as part of a group by craftguide but not by the engine. --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 80b129f..bb75208 100644 --- a/init.lua +++ b/init.lua @@ -237,7 +237,7 @@ end local function item_has_groups(item_groups, groups) for i = 1, #groups do local group = groups[i] - if not item_groups[group] then + if (item_groups[group] or 0) == 0 then return end end From 80a0d67f15e5df9c3fb8469497d9ce182e0d3edc Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 29 Aug 2019 13:48:06 +0200 Subject: [PATCH 088/188] Ability to register recipes in MC-like way --- API.md | 22 ++++++++++++++-- init.lua | 78 ++++++++++++++++++++++++++++++++------------------------ 2 files changed, 64 insertions(+), 36 deletions(-) diff --git a/API.md b/API.md index d9cf161..68793ac 100644 --- a/API.md +++ b/API.md @@ -11,17 +11,35 @@ craftguide.register_craft_type("digging", { }) ``` -#### Registering a custom crafting recipe (example) +#### Registering a custom crafting recipe (examples) ```Lua craftguide.register_craft({ type = "digging", width = 1, - output = "default:cobble 2", + result = "default:cobble 2", items = {"default:stone"}, }) ``` +Recipes can also be registered in a Minecraft-like way: + +```Lua +craftguide.register_craft({ + grid = { + "X #", + " ## ", + "X#X#", + "X X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +}) +``` + --- ### Recipe filters diff --git a/init.lua b/init.lua index bb75208..1928b65 100644 --- a/init.lua +++ b/init.lua @@ -149,11 +149,46 @@ function craftguide.register_craft_type(name, def) end function craftguide.register_craft(def) - local func = "craftguide." .. __func() .. "(): " - assert(is_str(def.type), func .. "'type' field missing") - assert(is_num(def.width), func .. "'width' field missing") - assert(is_str(def.output), func .. "'output' field missing") - assert(is_table(def.items), func .. "'items' field missing") + if def.result then + def.output = def.result -- Backward compatibility + end + + if not is_str(def.output) then + def.output = "" + end + + if not is_table(def.items) then + def.items = {} + end + + if not is_num(def.width) then + def.width = 0 + end + + if def.grid then + if not is_table(def.grid) then + def.grid = {} + end + + local cp = copy(def.grid) + sort(cp, function(a, b) + return #a > #b + end) + + def.width = #cp[1] + + for i = 1, #def.grid do + while #def.grid[i] < def.width do + def.grid[i] = def.grid[i] .. " " + end + end + + local c = 1 + for symbol in gmatch(concat(def.grid), ".") do + def.items[c] = def.key[symbol] + c = c + 1 + end + end custom_crafts[#custom_crafts + 1] = def end @@ -318,13 +353,11 @@ end local function cache_recipes(output) local recipes = get_all_recipes(output) or {} - local c = 0 for i = 1, #custom_crafts do local custom_craft = custom_crafts[i] if match(custom_craft.output, "%S*") == output then - c = c + 1 - recipes[c] = custom_craft + recipes[#recipes + 1] = custom_craft end end @@ -481,7 +514,7 @@ local function get_recipe_fs(data, iY) if width > 3 or rows > 3 then btn_size = width > 3 and 3 / width or 3 / rows s_btn_size = btn_size - X = btn_size * (i % width) + xoffset - 2.65 + X = btn_size * ((i - 1) % width) + xoffset - 2.65 Y = btn_size * floor((i - 1) / width) + (iY + 3) - min(2, rows) end @@ -491,7 +524,7 @@ local function get_recipe_fs(data, iY) local groups - if sub(item, 1, 6) == "group:" then + if sub(item, 1,6) == "group:" then groups = extract_groups(item) item = groups_to_item(groups) end @@ -525,7 +558,7 @@ local function get_recipe_fs(data, iY) end fs[#fs + 1] = fmt(FMT.image, - rightest + 1.2, + min(3.9, rightest) + 1.2, sfinv_only and 6.2 or iY + 1.7, 0.5, 0.5, @@ -1269,26 +1302,3 @@ function craftguide.show(name, item, show_usages) show_fs(player, name) end - ---[[ Custom recipes (>3x3) test code - -M.register_craftitem(":secretstuff:custom_recipe_test", { - description = "Custom Recipe Test", -}) - -local cr = {} -for x = 1, 6 do - cr[x] = {} - for i = 1, 10 - x do - cr[x][i] = {} - for j = 1, 10 - x do - cr[x][i][j] = "group:wood" - end - end - - M.register_craft({ - output = "secretstuff:custom_recipe_test", - recipe = cr[x] - }) -end -]] From dfa45789e20142beeca6d8b28c0c15d09e4de1ad Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 29 Aug 2019 15:20:19 +0200 Subject: [PATCH 089/188] Style cleaning --- .luacheckrc | 1 + init.lua | 94 +++++++++++++++++++++++------------------------------ 2 files changed, 42 insertions(+), 53 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 5a495c7..3b6cf93 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -2,6 +2,7 @@ unused_args = false allow_defined_top = true read_globals = { + "core", "minetest", "default", "sfinv", diff --git a/init.lua b/init.lua index 1928b65..e23d4b5 100644 --- a/init.lua +++ b/init.lua @@ -1,6 +1,5 @@ craftguide = {} -local M = minetest local pdata = {} -- Caches @@ -10,21 +9,21 @@ local recipes_cache = {} local usages_cache = {} local fuel_cache = {} -local progressive_mode = M.settings:get_bool("craftguide_progressive_mode") -local sfinv_only = M.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") +local progressive_mode = core.settings:get_bool("craftguide_progressive_mode") +local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") -local after = M.after -local colorize = M.colorize -local reg_items = M.registered_items -local get_result = M.get_craft_result -local show_formspec = M.show_formspec -local get_players = M.get_connected_players -local get_all_recipes = M.get_all_craft_recipes -local get_player_by_name = M.get_player_by_name -local serialize, deserialize = M.serialize, M.deserialize +local after = core.after +local colorize = core.colorize +local reg_items = core.registered_items +local get_result = core.get_craft_result +local show_formspec = core.show_formspec +local get_players = core.get_connected_players +local get_all_recipes = core.get_all_craft_recipes +local get_player_by_name = core.get_player_by_name +local serialize, deserialize = core.serialize, core.deserialize -local ESC = M.formspec_escape -local S = M.get_translator("craftguide") +local ESC = core.formspec_escape +local S = core.get_translator("craftguide") local maxn, sort, concat, insert, copy = table.maxn, table.sort, table.concat, table.insert, @@ -644,33 +643,22 @@ local function make_formspec(name) background[1,1;1,1;craftguide_bg.png;true] ]] - fs[#fs + 1] = fmt([[ tooltip[size_inc;%s] - tooltip[size_dec;%s] ]], - ESC(S("Increase window size")), - ESC(S("Decrease window size"))) - fs[#fs + 1] = fmt([[ image_button[%f,0.12;0.8,0.8;craftguide_zoomin_icon.png;size_inc;] - image_button[%f,0.12;0.8,0.8;craftguide_zoomout_icon.png;size_dec;] ]], + image_button[%f,0.12;0.8,0.8;craftguide_zoomout_icon.png;size_dec;] + ]], data.iX * 0.47, data.iX * 0.47 + 0.6) end + fs[#fs + 1] = fmt("field[0.3,0.33;2.5,1;filter;;%s]", ESC(data.filter)) + fs[#fs + 1] = [[ image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] field_close_on_enter[filter;false] ]] - fs[#fs + 1] = fmt([[ tooltip[search;%s] - tooltip[clear;%s] - tooltip[prev;%s] - tooltip[next;%s] ]], - ESC(S("Search")), - ESC(S("Reset")), - ESC(S("Previous page")), - ESC(S("Next page"))) - fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", sfinv_only and 6.3 or data.iX - 2.2, 0.22, @@ -679,12 +667,11 @@ local function make_formspec(name) fs[#fs + 1] = fmt([[ image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;] - image_button[%f,0.12;0.8,0.8;craftguide_next_icon.png;next;] ]], + image_button[%f,0.12;0.8,0.8;craftguide_next_icon.png;next;] + ]], sfinv_only and 5.5 or data.iX - 3.1, sfinv_only and 7.3 or (data.iX - 1.2) - (data.iX >= 11 and 0.08 or 0)) - fs[#fs + 1] = fmt("field[0.3,0.32;2.5,1;filter;;%s]", ESC(data.filter)) - if #data.items == 0 then local no_item = S("No item to show") local pos = (data.iX / 2) - 1 @@ -765,13 +752,12 @@ local function search(data) return end - local filtered_list, c = {}, 0 - local extras = "^(.-)%+([%w_]+)=([%w_,]+)" - local search_filter = next(search_filters) and match(filter, extras) + local opt = "^(.-)%+([%w_]+)=([%w_,]+)" + local search_filter = next(search_filters) and match(filter, opt) local filters = {} if search_filter then - for filter_name, values in gmatch(filter, sub(extras, 6)) do + for filter_name, values in gmatch(filter, sub(opt, 6)) do if search_filters[filter_name] then values = split(values, ",") filters[filter_name] = values @@ -779,11 +765,13 @@ local function search(data) end end + local filtered_list, c = {}, 0 + for i = 1, #data.items_raw do local item = data.items_raw[i] local def = reg_items[item] local desc = (def and def.description) and lower(def.description) or "" - local search_in = item .. desc + local search_in = item .. " " .. desc local to_add if search_filter then @@ -957,9 +945,9 @@ local function on_receive_fields(player, fields) end end -M.register_on_mods_loaded(get_init_items) +core.register_on_mods_loaded(get_init_items) -M.register_on_joinplayer(function(player) +core.register_on_joinplayer(function(player) local name = player:get_player_name() init_data(name) end) @@ -990,7 +978,7 @@ if sfinv_only then end, }) else - M.register_on_player_receive_fields(function(player, formname, fields) + core.register_on_player_receive_fields(function(player, formname, fields) if formname == "craftguide" then on_receive_fields(player, fields) end @@ -1008,7 +996,7 @@ else show_formspec(name, "craftguide", make_formspec(name)) end - M.register_craftitem("craftguide:book", { + core.register_craftitem("craftguide:book", { description = S("Crafting Guide"), inventory_image = "craftguide_book.png", wield_image = "craftguide_book.png", @@ -1019,7 +1007,7 @@ else end }) - M.register_node("craftguide:sign", { + core.register_node("craftguide:sign", { description = S("Crafting Guide Sign"), drawtype = "nodebox", tiles = {"craftguide_sign.png"}, @@ -1037,7 +1025,7 @@ else }, on_construct = function(pos) - local meta = M.get_meta(pos) + local meta = core.get_meta(pos) meta:set_string("infotext", "Crafting Guide Sign") end, @@ -1046,27 +1034,27 @@ else end }) - M.register_craft({ + core.register_craft({ output = "craftguide:book", recipe = { {"default:book"} } }) - M.register_craft({ + core.register_craft({ type = "fuel", recipe = "craftguide:book", burntime = 3 }) - M.register_craft({ + core.register_craft({ output = "craftguide:sign", recipe = { {"default:sign_wall_wood"} } }) - M.register_craft({ + core.register_craft({ type = "fuel", recipe = "craftguide:sign", burntime = 10 @@ -1189,7 +1177,7 @@ if progressive_mode then craftguide.add_recipe_filter("Default progressive filter", progressive_filter) - M.register_on_joinplayer(function(player) + core.register_on_joinplayer(function(player) PLAYERS = get_players() local meta = player:get_meta() @@ -1207,12 +1195,12 @@ if progressive_mode then meta:set_string("inv_items", serialize(data.inv_items)) end - M.register_on_leaveplayer(function(player) + core.register_on_leaveplayer(function(player) PLAYERS = get_players() save_meta(player) end) - M.register_on_shutdown(function() + core.register_on_shutdown(function() for i = 1, #PLAYERS do local player = PLAYERS[i] save_meta(player) @@ -1220,12 +1208,12 @@ if progressive_mode then end) end -M.register_on_leaveplayer(function(player) +core.register_on_leaveplayer(function(player) local name = player:get_player_name() pdata[name] = nil end) -M.register_chatcommand("craft", { +core.register_chatcommand("craft", { description = S("Show recipe(s) of the pointed node"), func = function(name) local player = get_player_by_name(name) @@ -1237,7 +1225,7 @@ M.register_chatcommand("craft", { for i = 1, 10 do local look_at = vec_add(ppos, vec_mul(dir, i)) - local node = M.get_node(look_at) + local node = core.get_node(look_at) if node.name ~= "air" then node_name = node.name From d324c5f1e5c4d5cd1d3abf883532ac13584feeb9 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 30 Aug 2019 17:05:03 +0200 Subject: [PATCH 090/188] Progressive mode: Add a Steam-like HUD success + remove useless API functions --- API.md | 43 -------------- init.lua | 175 +++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 118 insertions(+), 100 deletions(-) diff --git a/API.md b/API.md index 68793ac..5df2d98 100644 --- a/API.md +++ b/API.md @@ -137,49 +137,6 @@ Returns a map of search filters, indexed by name. --- -### Custom formspec elements - -#### `craftguide.add_formspec_element(name, def)` - -Adds a formspec element to the current formspec. -Supported types: `box`, `label`, `image`, `button`, `tooltip`, `item_image`, `image_button`, `item_image_button` - -Example: - -```lua -craftguide.add_formspec_element("export", { - type = "button", - element = function(data) - -- Should return a table of parameters according to the formspec element type. - -- Note: for all buttons, the 'name' parameter *must not* be specified! - if data.recipes then - return { - data.iX - 3.7, -- X - sfinv_only and 7.9 or 8, -- Y - 1.6, -- W - 1, -- H - ESC(S("Export")) -- label - } - end - end, - -- Optional. - action = function(player, data) - -- When the button is pressed. - print("Exported!") - end -}) -``` - -#### `craftguide.remove_formspec_element(name)` - -Removes the formspec element with the given name. - -#### `craftguide.get_formspec_elements()` - -Returns a map of formspec elements, indexed by name. - ---- - ### Miscellaneous #### `craftguide.show(player_name, item, show_usages)` diff --git a/init.lua b/init.lua index e23d4b5..bb8d6b3 100644 --- a/init.lua +++ b/init.lua @@ -16,8 +16,8 @@ local after = core.after local colorize = core.colorize local reg_items = core.registered_items local get_result = core.get_craft_result -local show_formspec = core.show_formspec local get_players = core.get_connected_players +local show_formspec = core.show_formspec local get_all_recipes = core.get_all_craft_recipes local get_player_by_name = core.get_player_by_name local serialize, deserialize = core.serialize, core.deserialize @@ -25,16 +25,15 @@ local serialize, deserialize = core.serialize, core.deserialize local ESC = core.formspec_escape local S = core.get_translator("craftguide") -local maxn, sort, concat, insert, copy = - table.maxn, table.sort, table.concat, table.insert, - table.copy +local maxn, sort, concat, copy = + table.maxn, table.sort, table.concat, table.copy local fmt, find, gmatch, match, sub, split, upper, lower = string.format, string.find, string.gmatch, string.match, string.sub, string.split, string.upper, string.lower local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil -local pairs, next, unpack = pairs, next, unpack +local pairs, next = pairs, next local vec_add, vec_mul = vector.add, vector.multiply local DEFAULT_SIZE = 10 @@ -44,10 +43,10 @@ DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) local GRID_LIMIT = 5 local FMT = { - box = "box[%f,%f;%f,%f;%s]", - label = "label[%f,%f;%s]", - image = "image[%f,%f;%f,%f;%s]", - button = "button[%f,%f;%f,%f;%s;%s]", + box = "box[%f,%f;%f,%f;%s]", + label = "label[%f,%f;%s]", + image = "image[%f,%f;%f,%f;%s]", + button = "button[%f,%f;%f,%f;%s;%s]", tooltip = "tooltip[%f,%f;%f,%f;%s]", item_image = "item_image[%f,%f;%f,%f;%s]", image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", @@ -244,30 +243,6 @@ function craftguide.get_search_filters() return search_filters end -local formspec_elements = {} - -function craftguide.add_formspec_element(name, def) - local func = "craftguide." .. __func() .. "(): " - assert(is_str(name), func .. "formspec element name missing") - assert(is_str(def.element), func .. "'element' field not defined") - assert(is_str(def.type), func .. "'type' field not defined") - assert(FMT[def.type], func .. "'" .. def.type .. "' type not supported by the API") - - formspec_elements[name] = { - type = def.type, - element = def.element, - action = def.action, - } -end - -function craftguide.remove_formspec_element(name) - formspec_elements[name] = nil -end - -function craftguide.get_formspec_elements() - return formspec_elements -end - local function item_has_groups(item_groups, groups) for i = 1, #groups do local group = groups[i] @@ -332,22 +307,33 @@ local function get_usages(item) return usages end -local function get_filtered_items(player) +local function get_filtered_items(player, data) local items, c = {}, 0 + local known = 0 for i = 1, #init_items do local item = init_items[i] local recipes = recipes_cache[item] local usages = usages_cache[item] - if recipes and #apply_recipe_filters(recipes, player) > 0 or - usages and #apply_recipe_filters(usages, player) > 0 then - c = c + 1 - items[c] = item + recipes = #apply_recipe_filters(recipes or {}, player) + usages = #apply_recipe_filters(usages or {}, player) + + if recipes > 0 or usages > 0 then + if not data then + c = c + 1 + items[c] = item + else + known = known + recipes + usages + end end end - return items + if data then + data.known_recipes = known + else + return items + end end local function cache_recipes(output) @@ -707,17 +693,6 @@ local function make_formspec(name) fs[#fs + 1] = get_recipe_fs(data, iY) end - for elem_name, def in pairs(formspec_elements) do - local element = def.element(data) - if element then - if find(def.type, "button") then - insert(element, #element, elem_name) - end - - fs[#fs + 1] = fmt(FMT[def.type], unpack(element)) - end - end - return concat(fs) end @@ -860,12 +835,6 @@ local function on_receive_fields(player, fields) local name = player:get_player_name() local data = pdata[name] - for elem_name, def in pairs(formspec_elements) do - if fields[elem_name] and def.action then - return def.action(player, data) - end - end - if fields.clear then reset_data(data) show_fs(player, name) @@ -1110,6 +1079,10 @@ if progressive_mode then end local function progressive_filter(recipes, player) + if not recipes then + return {} + end + local name = player:get_player_name() local data = pdata[name] @@ -1154,8 +1127,48 @@ if progressive_mode then return inv_items end + local function show_hud_success(player, data, dtime) + local hud_info_bg = player:hud_get(data.hud.bg) + + if hud_info_bg.position.y <= 0.9 then + data.show_hud = false + data.hud_timer = (data.hud_timer or 0) + dtime + end + + if data.show_hud then + for _, def in pairs(data.hud) do + local hud_info = player:hud_get(def) + + player:hud_change(def, "position", { + x = hud_info.position.x, + y = hud_info.position.y - (dtime / 5) + }) + end + + player:hud_change(data.hud.text, "text", + S("@1 new recipe(s) discovered!", data.discovered)) + + elseif data.show_hud == false then + if data.hud_timer > 3 then + for _, def in pairs(data.hud) do + local hud_info = player:hud_get(def) + + player:hud_change(def, "position", { + x = hud_info.position.x, + y = hud_info.position.y + (dtime / 5) + }) + end + + if hud_info_bg.position.y >= 1 then + data.show_hud = nil + data.hud_timer = nil + end + end + end + end + -- Workaround. Need an engine call to detect when the contents - -- of the player inventory changed, instead. + -- of the player inventory changed, instead local function poll_new_items() for i = 1, #PLAYERS do local player = PLAYERS[i] @@ -1167,6 +1180,14 @@ if progressive_mode then if #diff > 0 then data.inv_items = table_merge(diff, data.inv_items) + + local oldknown = data.known_recipes or 0 + get_filtered_items(player, data) + data.discovered = data.known_recipes - oldknown + + if data.show_hud == nil and data.discovered > 0 then + data.show_hud = true + end end end @@ -1175,6 +1196,18 @@ if progressive_mode then poll_new_items() + minetest.register_globalstep(function(dtime) + for i = 1, #PLAYERS do + local player = PLAYERS[i] + local name = player:get_player_name() + local data = pdata[name] + + if data.show_hud ~= nil then + show_hud_success(player, data, dtime) + end + end + end) + craftguide.add_recipe_filter("Default progressive filter", progressive_filter) core.register_on_joinplayer(function(player) @@ -1185,6 +1218,33 @@ if progressive_mode then local data = pdata[name] data.inv_items = deserialize(meta:get_string("inv_items")) or {} + data.known_recipes = deserialize(meta:get_string("known_recipes")) or 0 + + data.hud = { + bg = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.8, y = 1}, + alignment = {x = 1, y = 1}, + scale = {x = 320, y = 112}, + text = "craftguide_bg.png", + }), + + book = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.81, y = 1.02}, + alignment = {x = 1, y = 1}, + scale = {x = 4, y = 4}, + text = "craftguide_book.png", + }), + + text = player:hud_add({ + hud_elem_type = "text", + position = {x = 0.85, y = 1.04}, + alignment = {x = 1, y = 1}, + number = 0xFFFFFF, + text = "", + }), + } end) local function save_meta(player) @@ -1193,6 +1253,7 @@ if progressive_mode then local data = pdata[name] meta:set_string("inv_items", serialize(data.inv_items)) + meta:set_string("known_recipes", serialize(data.known_recipes)) end core.register_on_leaveplayer(function(player) From c468ab22fd722200e37e594556a965d80781ce3a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 30 Aug 2019 17:20:39 +0200 Subject: [PATCH 091/188] Update mod.conf --- mod.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mod.conf b/mod.conf index c32f714..cb6dbd9 100644 --- a/mod.conf +++ b/mod.conf @@ -1 +1,3 @@ name = craftguide +optional_depends = sfinv, sfinv_buttons +description = The most comprehensive Crafting Guide on Minetest From 8b86dfc8570b72ca2a640b37afc11686fcf0cb29 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 30 Aug 2019 17:39:03 +0200 Subject: [PATCH 092/188] Fine-tune HUD --- init.lua | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index bb8d6b3..f6a748e 100644 --- a/init.lua +++ b/init.lua @@ -1223,15 +1223,15 @@ if progressive_mode then data.hud = { bg = player:hud_add({ hud_elem_type = "image", - position = {x = 0.8, y = 1}, + position = {x = 0.78, y = 1}, alignment = {x = 1, y = 1}, - scale = {x = 320, y = 112}, + scale = {x = 370, y = 112}, text = "craftguide_bg.png", }), book = player:hud_add({ hud_elem_type = "image", - position = {x = 0.81, y = 1.02}, + position = {x = 0.79, y = 1.02}, alignment = {x = 1, y = 1}, scale = {x = 4, y = 4}, text = "craftguide_book.png", @@ -1239,7 +1239,7 @@ if progressive_mode then text = player:hud_add({ hud_elem_type = "text", - position = {x = 0.85, y = 1.04}, + position = {x = 0.84, y = 1.04}, alignment = {x = 1, y = 1}, number = 0xFFFFFF, text = "", @@ -1247,13 +1247,20 @@ if progressive_mode then } end) + local to_save = { + "inv_items", + "known_recipes", + } + local function save_meta(player) local meta = player:get_meta() local name = player:get_player_name() local data = pdata[name] - meta:set_string("inv_items", serialize(data.inv_items)) - meta:set_string("known_recipes", serialize(data.known_recipes)) + for i = 1, #to_save do + local meta_name = to_save[i] + meta:set_string(meta_name, serialize(data[meta_name])) + end end core.register_on_leaveplayer(function(player) From 2fa14ae1466892d1ce81590301c95dafc45a3d7d Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 30 Aug 2019 18:50:55 +0200 Subject: [PATCH 093/188] Code cleaning --- init.lua | 130 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 61 deletions(-) diff --git a/init.lua b/init.lua index f6a748e..e46e2af 100644 --- a/init.lua +++ b/init.lua @@ -1,6 +1,7 @@ craftguide = {} local pdata = {} +local core = core -- Caches local init_items = {} @@ -15,12 +16,19 @@ local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G local after = core.after local colorize = core.colorize local reg_items = core.registered_items -local get_result = core.get_craft_result -local get_players = core.get_connected_players local show_formspec = core.show_formspec +local globalstep = core.register_globalstep +local on_shutdown = core.register_on_shutdown +local get_craft_result = core.get_craft_result +local get_players = core.get_connected_players +local on_joinplayer = core.register_on_joinplayer +local register_command = core.register_chatcommand local get_all_recipes = core.get_all_craft_recipes local get_player_by_name = core.get_player_by_name +local on_mods_loaded = core.register_on_mods_loaded +local on_leaveplayer = core.register_on_leaveplayer local serialize, deserialize = core.serialize, core.deserialize +local on_receive_fields = core.register_on_player_receive_fields local ESC = core.formspec_escape local S = core.get_translator("craftguide") @@ -63,24 +71,6 @@ craftguide.group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } -local item_lists = { - "main", - "craft", - "craftpreview", -} - -local function table_merge(t, t2) - t, t2 = t or {}, t2 or {} - local c = #t - - for i = 1, #t2 do - c = c + 1 - t[c] = t2[i] - end - - return t -end - local function table_replace(t, val, new) for k, v in pairs(t) do if v == val then @@ -89,32 +79,6 @@ local function table_replace(t, val, new) end end -local function table_diff(t, t2) - local hash = {} - - for i = 1, #t do - local v = t[i] - hash[v] = true - end - - for i = 1, #t2 do - local v = t2[i] - hash[v] = nil - end - - local diff, c = {}, 0 - - for i = 1, #t do - local v = t[i] - if hash[v] then - c = c + 1 - diff[c] = v - end - end - - return diff -end - local function __func() return debug.getinfo(2, "n").name end @@ -270,7 +234,7 @@ local function groups_item_in_recipe(item, recipe) local item_groups = reg_items[item].groups for _, recipe_item in pairs(recipe.items) do - if sub(recipe_item, 1, 6) == "group:" then + if sub(recipe_item, 1,6) == "group:" then local groups = extract_groups(recipe_item) if item_has_groups(item_groups, groups) then local usage = copy(recipe) @@ -384,7 +348,7 @@ local function get_recipes(item, data, player) end local function get_burntime(item) - return get_result({method = "fuel", width = 1, items = {item}}).time + return get_craft_result({method = "fuel", width = 1, items = {item}}).time end local function cache_fuel(item) @@ -831,7 +795,7 @@ local function get_init_items() sort(init_items) end -local function on_receive_fields(player, fields) +local function _fields(player, fields) local name = player:get_player_name() local data = pdata[name] @@ -914,9 +878,9 @@ local function on_receive_fields(player, fields) end end -core.register_on_mods_loaded(get_init_items) +on_mods_loaded(get_init_items) -core.register_on_joinplayer(function(player) +on_joinplayer(function(player) local name = player:get_player_name() init_data(name) end) @@ -943,13 +907,13 @@ if sfinv_only then end, on_player_receive_fields = function(self, player, context, fields) - on_receive_fields(player, fields) + _fields(player, fields) end, }) else - core.register_on_player_receive_fields(function(player, formname, fields) + on_receive_fields(function(player, formname, fields) if formname == "craftguide" then - on_receive_fields(player, fields) + _fields(player, fields) end end) @@ -1048,7 +1012,7 @@ if progressive_mode then local function item_in_inv(item, inv_items) local inv_items_size = #inv_items - if sub(item, 1, 6) == "group:" then + if sub(item, 1,6) == "group:" then local groups = extract_groups(item) for i = 1, inv_items_size do local inv_item = reg_items[inv_items[i]] @@ -1102,6 +1066,50 @@ if progressive_mode then return filtered end + local item_lists = { + "main", + "craft", + "craftpreview", + } + + local function table_merge(t, t2) + t, t2 = t or {}, t2 or {} + local c = #t + + for i = 1, #t2 do + c = c + 1 + t[c] = t2[i] + end + + return t + end + + local function table_diff(t, t2) + local hash = {} + + for i = 1, #t do + local v = t[i] + hash[v] = true + end + + for i = 1, #t2 do + local v = t2[i] + hash[v] = nil + end + + local diff, c = {}, 0 + + for i = 1, #t do + local v = t[i] + if hash[v] then + c = c + 1 + diff[c] = v + end + end + + return diff + end + local function get_inv_items(player) local inv = player:get_inventory() local stacks = {} @@ -1196,7 +1204,7 @@ if progressive_mode then poll_new_items() - minetest.register_globalstep(function(dtime) + globalstep(function(dtime) for i = 1, #PLAYERS do local player = PLAYERS[i] local name = player:get_player_name() @@ -1210,7 +1218,7 @@ if progressive_mode then craftguide.add_recipe_filter("Default progressive filter", progressive_filter) - core.register_on_joinplayer(function(player) + on_joinplayer(function(player) PLAYERS = get_players() local meta = player:get_meta() @@ -1263,12 +1271,12 @@ if progressive_mode then end end - core.register_on_leaveplayer(function(player) + on_leaveplayer(function(player) PLAYERS = get_players() save_meta(player) end) - core.register_on_shutdown(function() + on_shutdown(function() for i = 1, #PLAYERS do local player = PLAYERS[i] save_meta(player) @@ -1276,12 +1284,12 @@ if progressive_mode then end) end -core.register_on_leaveplayer(function(player) +on_leaveplayer(function(player) local name = player:get_player_name() pdata[name] = nil end) -core.register_chatcommand("craft", { +register_command("craft", { description = S("Show recipe(s) of the pointed node"), func = function(name) local player = get_player_by_name(name) From ae4b15a748c2aaa013be617f8915cbef294063d9 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 5 Sep 2019 14:24:11 +0200 Subject: [PATCH 094/188] Improve grid display --- init.lua | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/init.lua b/init.lua index e46e2af..40ff84a 100644 --- a/init.lua +++ b/init.lua @@ -48,7 +48,7 @@ local DEFAULT_SIZE = 10 local MIN_LIMIT, MAX_LIMIT = 10, 12 DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) -local GRID_LIMIT = 5 +local GRID_LIMIT = 6 local FMT = { box = "box[%f,%f;%f,%f;%s]", @@ -455,16 +455,24 @@ local function get_recipe_fs(data, iY) return concat(fs) end - for i, item in pairs(recipe.items) do + for i = 1, width * rows do + local item = recipe.items[i] or "" local X = ceil((i - 1) % width + xoffset - width) - (sfinv_only and 0 or 0.2) local Y = ceil(i / width + (iY + 2) - min(2, rows)) if width > 3 or rows > 3 then - btn_size = width > 3 and 3 / width or 3 / rows + local xof = 1 - 4 / width + local yof = 1 - 4 / rows + local x_y = width > rows and xof or yof + + btn_size = width > rows and + (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows s_btn_size = btn_size - X = btn_size * ((i - 1) % width) + xoffset - 2.65 - Y = btn_size * floor((i - 1) / width) + (iY + 3) - min(2, rows) + + X = (btn_size * ((i - 1) % width) + xoffset - 2.49) * (0.83 - (x_y / 5)) + Y = (btn_size * floor((i - 1) / width) + (iY + (1.98 + (x_y * 1.2)))) * + (0.86 - (x_y / 5)) end if X > rightest then @@ -802,6 +810,7 @@ local function _fields(player, fields) if fields.clear then reset_data(data) show_fs(player, name) + return true elseif fields.alternate then if #data.recipes == 1 then @@ -811,6 +820,7 @@ local function _fields(player, fields) local num_next = data.rnum + 1 data.rnum = data.recipes[num_next] and num_next or 1 show_fs(player, name) + return true elseif (fields.key_enter_field == "filter" or fields.search) and fields.filter ~= "" then @@ -823,6 +833,7 @@ local function _fields(player, fields) data.pagenum = 1 search(data) show_fs(player, name) + return true elseif fields.prev or fields.next then if data.pagemax == 1 then @@ -838,12 +849,14 @@ local function _fields(player, fields) end show_fs(player, name) + return true elseif (fields.size_inc and data.iX < MAX_LIMIT) or (fields.size_dec and data.iX > MIN_LIMIT) then data.pagenum = 1 data.iX = data.iX + (fields.size_inc and 1 or -1) show_fs(player, name) + return true else local item for field in pairs(fields) do @@ -875,6 +888,7 @@ local function _fields(player, fields) data.rnum = 1 show_fs(player, name) + return true end end From cb0200a222ed52c8a9e0235d2f14814db16f4358 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 5 Sep 2019 14:57:58 +0200 Subject: [PATCH 095/188] Small cleanup --- init.lua | 60 +++++++++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/init.lua b/init.lua index 40ff84a..4ee331f 100644 --- a/init.lua +++ b/init.lua @@ -210,9 +210,7 @@ end local function item_has_groups(item_groups, groups) for i = 1, #groups do local group = groups[i] - if (item_groups[group] or 0) == 0 then - return - end + if (item_groups[group] or 0) == 0 then return end end return true @@ -339,9 +337,7 @@ local function get_recipes(item, data, player) if data.show_usages then recipes = apply_recipe_filters(usages_cache[item], player) - if recipes and #recipes == 0 then - return - end + if recipes and #recipes == 0 then return end end return recipes @@ -645,9 +641,7 @@ local function make_formspec(name) local first_item = (data.pagenum - 1) * ipp for i = first_item, first_item + ipp - 1 do local item = data.items[i + 1] - if not item then - break - end + if not item then break end local X = i % data.iX local Y = (i % ipp - X) / data.iX + 1 @@ -806,41 +800,35 @@ end local function _fields(player, fields) local name = player:get_player_name() local data = pdata[name] + local _f = fields - if fields.clear then + if _f.clear then reset_data(data) show_fs(player, name) return true - elseif fields.alternate then - if #data.recipes == 1 then - return - end - + elseif _f.alternate then + if #data.recipes == 1 then return end local num_next = data.rnum + 1 data.rnum = data.recipes[num_next] and num_next or 1 + show_fs(player, name) return true - elseif (fields.key_enter_field == "filter" or fields.search) and - fields.filter ~= "" then - local fltr = lower(fields.filter) - if data.filter == fltr then - return - end + elseif (_f.key_enter_field == "filter" or _f.search) and _f.filter ~= "" then + local fltr = lower(_f.filter) + if data.filter == fltr then return end data.filter = fltr data.pagenum = 1 search(data) + show_fs(player, name) return true - elseif fields.prev or fields.next then - if data.pagemax == 1 then - return - end - - data.pagenum = data.pagenum - (fields.prev and 1 or -1) + elseif _f.prev or _f.next then + if data.pagemax == 1 then return end + data.pagenum = data.pagenum - (_f.prev and 1 or -1) if data.pagenum > data.pagemax then data.pagenum = 1 @@ -851,15 +839,15 @@ local function _fields(player, fields) show_fs(player, name) return true - elseif (fields.size_inc and data.iX < MAX_LIMIT) or - (fields.size_dec and data.iX > MIN_LIMIT) then + elseif (_f.size_inc and data.iX < MAX_LIMIT) or + (_f.size_dec and data.iX > MIN_LIMIT) then data.pagenum = 1 - data.iX = data.iX + (fields.size_inc and 1 or -1) + data.iX = data.iX + (_f.size_inc and 1 or -1) show_fs(player, name) return true else local item - for field in pairs(fields) do + for field in pairs(_f) do if find(field, ":") then item = field break @@ -869,7 +857,7 @@ local function _fields(player, fields) if not item then return elseif sub(item, -4) == "_inv" then - item = sub(item, 1, -5) + item = sub(item, 1,-5) end if item ~= data.query_item then @@ -879,9 +867,7 @@ local function _fields(player, fields) end local recipes = get_recipes(item, data, player) - if not recipes then - return - end + if not recipes then return end data.query_item = item data.recipes = recipes @@ -1048,9 +1034,7 @@ if progressive_mode then local function recipe_in_inv(recipe, inv_items) for _, item in pairs(recipe.items) do - if not item_in_inv(item, inv_items) then - return - end + if not item_in_inv(item, inv_items) then return end end return true From 337ac898cd3215ca5cd6323a40c2abba942e53f0 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 5 Sep 2019 20:31:50 +0200 Subject: [PATCH 096/188] Fine-tune items positioning + Remove zoom in/out features --- init.lua | 110 ++++++++++++++++++++++++------------------------------- 1 file changed, 48 insertions(+), 62 deletions(-) diff --git a/init.lua b/init.lua index 4ee331f..f7e23ba 100644 --- a/init.lua +++ b/init.lua @@ -44,11 +44,10 @@ local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local pairs, next = pairs, next local vec_add, vec_mul = vector.add, vector.multiply -local DEFAULT_SIZE = 10 -local MIN_LIMIT, MAX_LIMIT = 10, 12 -DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE)) - -local GRID_LIMIT = 6 +local ROWS = sfinv_only and 9 or 11 +local LINES = 5 +local IPP = ROWS * LINES +local GRID_LIMIT = 8 local FMT = { box = "box[%f,%f;%f,%f;%s]", @@ -412,11 +411,11 @@ local function get_tooltip(item, groups, cooktime, burntime) return fmt("tooltip[%s;%s]", item, ESC(tooltip)) end -local function get_recipe_fs(data, iY) +local function get_recipe_fs(data) local fs = {} local recipe = data.recipes[data.rnum] local width = recipe.width - local xoffset = data.iX / 2.15 + local xoffset = sfinv_only and 4 or 4.92 local cooktime, shapeless if recipe.type == "cooking" then @@ -435,8 +434,8 @@ local function get_recipe_fs(data, iY) ESC(S("Recipe @1 of @2", data.rnum, #data.recipes)) fs[#fs + 1] = fmt(FMT.button, - sfinv_only and 5.8 or data.iX - 2.6, - sfinv_only and 7.9 or iY + 3.3, + sfinv_only and 5.8 or 7.4, + sfinv_only and 8 or 8.4, 2.2, 1, "alternate", @@ -444,8 +443,8 @@ local function get_recipe_fs(data, iY) if width > GRID_LIMIT or rows > GRID_LIMIT then fs[#fs + 1] = fmt(FMT.label, - (data.iX / 2) - 2, - iY + 2.2, + sfinv_only and 2 or 3, + 7, ESC(S("Recipe is too big to be displayed (@1x@2)", width, rows))) return concat(fs) @@ -453,9 +452,9 @@ local function get_recipe_fs(data, iY) for i = 1, width * rows do local item = recipe.items[i] or "" - local X = ceil((i - 1) % width + xoffset - width) - + local X = ceil((i - 1) % width - width) + xoffset - (sfinv_only and 0 or 0.2) - local Y = ceil(i / width + (iY + 2) - min(2, rows)) + local Y = ceil(i / width + (sfinv_only and 6 or 7) - min(2, rows)) if width > 3 or rows > 3 then local xof = 1 - 4 / width @@ -466,9 +465,10 @@ local function get_recipe_fs(data, iY) (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows s_btn_size = btn_size - X = (btn_size * ((i - 1) % width) + xoffset - 2.49) * (0.83 - (x_y / 5)) - Y = (btn_size * floor((i - 1) / width) + (iY + (1.98 + (x_y * 1.2)))) * - (0.86 - (x_y / 5)) + X = (btn_size * ((i - 1) % width) + xoffset - + (sfinv_only and 2.8 or 2.84)) * (0.83 - (x_y / 5)) + Y = (btn_size * floor((i - 1) / width) + + (5 + ((sfinv_only and 0.81 or 1.97) + x_y))) * (0.86 - (x_y / 5)) end if X > rightest then @@ -486,7 +486,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.item_image_button, X, - Y + (sfinv_only and 0.7 or 0.2), + Y + (sfinv_only and 0.7 or 0), btn_size, btn_size, item, @@ -512,7 +512,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.image, min(3.9, rightest) + 1.2, - sfinv_only and 6.2 or iY + 1.7, + sfinv_only and 6.2 or 6.55, 0.5, 0.5, icon) @@ -522,7 +522,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", rightest + 1.2, - sfinv_only and 6.2 or iY + 1.7, + sfinv_only and 6.2 or 6.55, 0.5, 0.5, ESC(tooltip)) @@ -533,7 +533,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.image, arrow_X, - sfinv_only and 6.85 or iY + 2.35, + sfinv_only and 6.85 or 7.2, 0.9, 0.7, "craftguide_arrow.png") @@ -541,7 +541,7 @@ local function get_recipe_fs(data, iY) if recipe.type == "fuel" then fs[#fs + 1] = fmt(FMT.image, output_X, - sfinv_only and 6.68 or iY + 2.18, + sfinv_only and 6.68 or 7, 1.1, 1.1, "craftguide_fire.png") @@ -551,7 +551,7 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.item_image_button, output_X, - sfinv_only and 6.7 or iY + 2.2, + sfinv_only and 6.7 or 7, 1.1, 1.1, recipe.output, @@ -563,14 +563,14 @@ local function get_recipe_fs(data, iY) fs[#fs + 1] = fmt(FMT.image, output_X + 1, - sfinv_only and 6.83 or iY + 2.33, + sfinv_only and 6.83 or 7.1, 0.6, 0.4, "craftguide_arrow.png") fs[#fs + 1] = fmt(FMT.image, output_X + 1.6, - sfinv_only and 6.68 or iY + 2.18, + sfinv_only and 6.68 or 6.95, 0.6, 0.6, "craftguide_fire.png") @@ -582,39 +582,33 @@ end local function make_formspec(name) local data = pdata[name] - local iY = sfinv_only and 4 or data.iX - 5 - local ipp = data.iX * iY - - data.pagemax = max(1, ceil(#data.items / ipp)) + data.pagemax = max(1, ceil(#data.items / IPP)) local fs = {} if not sfinv_only then - fs[#fs + 1] = fmt("size[%f,%f;]", data.iX - 0.35, iY + 4) + fs[#fs + 1] = fmt("size[%f,%f;]", 9.62, 9) fs[#fs + 1] = [[ no_prepend[] background[1,1;1,1;craftguide_bg.png;true] ]] - - fs[#fs + 1] = fmt([[ - image_button[%f,0.12;0.8,0.8;craftguide_zoomin_icon.png;size_inc;] - image_button[%f,0.12;0.8,0.8;craftguide_zoomout_icon.png;size_dec;] - ]], - data.iX * 0.47, - data.iX * 0.47 + 0.6) end - fs[#fs + 1] = fmt("field[0.3,0.33;2.5,1;filter;;%s]", ESC(data.filter)) + fs[#fs + 1] = fmt("field[0.3,0.33;%f,1;filter;;%s]", + sfinv_only and 2.75 or 2.72, + ESC(data.filter)) - fs[#fs + 1] = [[ - image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] - image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] + fs[#fs + 1] = fmt([[ + image_button[%f,0.09;0.85,0.85;craftguide_search_icon.png;search;] + image_button[%f,0.09;0.85,0.85;craftguide_clear_icon.png;clear;] field_close_on_enter[filter;false] - ]] + ]], + sfinv_only and 2.65 or 2.6, + sfinv_only and 3.35 or 3.3) fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", - sfinv_only and 6.3 or data.iX - 2.2, + sfinv_only and 6.3 or 7.8, 0.22, colorize("yellow", data.pagenum), data.pagemax) @@ -623,12 +617,12 @@ local function make_formspec(name) image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;] image_button[%f,0.12;0.8,0.8;craftguide_next_icon.png;next;] ]], - sfinv_only and 5.5 or data.iX - 3.1, - sfinv_only and 7.3 or (data.iX - 1.2) - (data.iX >= 11 and 0.08 or 0)) + sfinv_only and 5.5 or 6.88, + sfinv_only and 7.25 or 8.8) if #data.items == 0 then local no_item = S("No item to show") - local pos = (data.iX / 2) - 1 + local pos = sfinv_only and 3 or 3.8 if next(recipe_filters) and #init_items > 0 and data.filter == "" then no_item = S("Collect items to reveal more recipes") @@ -638,25 +632,25 @@ local function make_formspec(name) fs[#fs + 1] = fmt(FMT.label, pos, 2, ESC(no_item)) end - local first_item = (data.pagenum - 1) * ipp - for i = first_item, first_item + ipp - 1 do + local first_item = (data.pagenum - 1) * IPP + for i = first_item, first_item + IPP - 1 do local item = data.items[i + 1] if not item then break end - local X = i % data.iX - local Y = (i % ipp - X) / data.iX + 1 + local X = i % ROWS + local Y = (i % IPP - X) / ROWS + 1 fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s_inv;]", - X - (sfinv_only and 0 or (X * 0.05)), - Y, - 1.1, - 1.1, + X - (X * (sfinv_only and 0.12 or 0.14)), + Y - (Y * 0.1) + 0.1, + 1, + 1, item, item) end if data.recipes and #data.recipes > 0 then - fs[#fs + 1] = get_recipe_fs(data, iY) + fs[#fs + 1] = get_recipe_fs(data) end return concat(fs) @@ -747,7 +741,6 @@ local function init_data(name) pdata[name] = { filter = "", pagenum = 1, - iX = sfinv_only and 8 or DEFAULT_SIZE, items = init_items, items_raw = init_items, } @@ -838,13 +831,6 @@ local function _fields(player, fields) show_fs(player, name) return true - - elseif (_f.size_inc and data.iX < MAX_LIMIT) or - (_f.size_dec and data.iX > MIN_LIMIT) then - data.pagenum = 1 - data.iX = data.iX + (_f.size_inc and 1 or -1) - show_fs(player, name) - return true else local item for field in pairs(_f) do From 83151cb394ff9246c5f469d03b2db44d3bc9ea4a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 6 Sep 2019 13:29:51 +0200 Subject: [PATCH 097/188] More interface fine-tuning --- init.lua | 62 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/init.lua b/init.lua index f7e23ba..d48662b 100644 --- a/init.lua +++ b/init.lua @@ -415,7 +415,8 @@ local function get_recipe_fs(data) local fs = {} local recipe = data.recipes[data.rnum] local width = recipe.width - local xoffset = sfinv_only and 4 or 4.92 + local xoffset = sfinv_only and 3.83 or 4.66 + local yoffset = sfinv_only and 6 or 6.6 local cooktime, shapeless if recipe.type == "cooking" then @@ -434,8 +435,8 @@ local function get_recipe_fs(data) ESC(S("Recipe @1 of @2", data.rnum, #data.recipes)) fs[#fs + 1] = fmt(FMT.button, - sfinv_only and 5.8 or 7.4, - sfinv_only and 8 or 8.4, + xoffset + (sfinv_only and 1.98 or 2.7), + yoffset + (sfinv_only and 1.9 or 1.2), 2.2, 1, "alternate", @@ -452,9 +453,8 @@ local function get_recipe_fs(data) for i = 1, width * rows do local item = recipe.items[i] or "" - local X = ceil((i - 1) % width - width) + xoffset - - (sfinv_only and 0 or 0.2) - local Y = ceil(i / width + (sfinv_only and 6 or 7) - min(2, rows)) + local X = ceil((i - 1) % width - width) + xoffset + local Y = ceil(i / width) + yoffset - min(2, rows) if width > 3 or rows > 3 then local xof = 1 - 4 / width @@ -466,9 +466,9 @@ local function get_recipe_fs(data) s_btn_size = btn_size X = (btn_size * ((i - 1) % width) + xoffset - - (sfinv_only and 2.8 or 2.84)) * (0.83 - (x_y / 5)) + (sfinv_only and 2.83 or (xoffset - 2))) * (0.83 - (x_y / 5)) Y = (btn_size * floor((i - 1) / width) + - (5 + ((sfinv_only and 0.81 or 1.97) + x_y))) * (0.86 - (x_y / 5)) + (5 + ((sfinv_only and 0.81 or 1.5) + x_y))) * (0.86 - (x_y / 5)) end if X > rightest then @@ -510,9 +510,11 @@ local function get_recipe_fs(data) icon = fmt("craftguide_%s.png^[resize:16x16", icon) end + local pos_y = yoffset + (sfinv_only and 0.25 or -0.45) + fs[#fs + 1] = fmt(FMT.image, min(3.9, rightest) + 1.2, - sfinv_only and 6.2 or 6.55, + pos_y, 0.5, 0.5, icon) @@ -522,7 +524,7 @@ local function get_recipe_fs(data) fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", rightest + 1.2, - sfinv_only and 6.2 or 6.55, + pos_y, 0.5, 0.5, ESC(tooltip)) @@ -533,7 +535,7 @@ local function get_recipe_fs(data) fs[#fs + 1] = fmt(FMT.image, arrow_X, - sfinv_only and 6.85 or 7.2, + yoffset + (sfinv_only and 0.9 or 0.2), 0.9, 0.7, "craftguide_arrow.png") @@ -541,7 +543,7 @@ local function get_recipe_fs(data) if recipe.type == "fuel" then fs[#fs + 1] = fmt(FMT.image, output_X, - sfinv_only and 6.68 or 7, + yoffset + (sfinv_only and 0.7 or 0), 1.1, 1.1, "craftguide_fire.png") @@ -551,7 +553,7 @@ local function get_recipe_fs(data) fs[#fs + 1] = fmt(FMT.item_image_button, output_X, - sfinv_only and 6.7 or 7, + yoffset + (sfinv_only and 0.7 or 0), 1.1, 1.1, recipe.output, @@ -563,14 +565,14 @@ local function get_recipe_fs(data) fs[#fs + 1] = fmt(FMT.image, output_X + 1, - sfinv_only and 6.83 or 7.1, + yoffset + (sfinv_only and 0.7 or 0.1), 0.6, 0.4, "craftguide_arrow.png") fs[#fs + 1] = fmt(FMT.image, output_X + 1.6, - sfinv_only and 6.68 or 6.95, + yoffset + (sfinv_only and 0.55 or 0), 0.6, 0.6, "craftguide_fire.png") @@ -587,7 +589,7 @@ local function make_formspec(name) local fs = {} if not sfinv_only then - fs[#fs + 1] = fmt("size[%f,%f;]", 9.62, 9) + fs[#fs + 1] = fmt("size[%f,%f;]", 9.5, 8.4) fs[#fs + 1] = [[ no_prepend[] @@ -595,30 +597,30 @@ local function make_formspec(name) ]] end - fs[#fs + 1] = fmt("field[0.3,0.33;%f,1;filter;;%s]", - sfinv_only and 2.75 or 2.72, + fs[#fs + 1] = fmt("field[0.25,0.2;%f,1;filter;;%s]", + sfinv_only and 2.76 or 2.72, ESC(data.filter)) fs[#fs + 1] = fmt([[ - image_button[%f,0.09;0.85,0.85;craftguide_search_icon.png;search;] - image_button[%f,0.09;0.85,0.85;craftguide_clear_icon.png;clear;] + image_button[%f,-0.05;0.85,0.85;craftguide_search_icon.png;search;] + image_button[%f,-0.05;0.85,0.85;craftguide_clear_icon.png;clear;] field_close_on_enter[filter;false] ]], - sfinv_only and 2.65 or 2.6, - sfinv_only and 3.35 or 3.3) + sfinv_only and 2.6 or 2.54, + sfinv_only and 3.3 or 3.25) fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", - sfinv_only and 6.3 or 7.8, - 0.22, + sfinv_only and 6.35 or 7.85, + 0.06, colorize("yellow", data.pagenum), data.pagemax) fs[#fs + 1] = fmt([[ - image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;] - image_button[%f,0.12;0.8,0.8;craftguide_next_icon.png;next;] + image_button[%f,-0.05;0.8,0.8;craftguide_prev_icon.png;prev;] + image_button[%f,-0.05;0.8,0.8;craftguide_next_icon.png;next;] ]], - sfinv_only and 5.5 or 6.88, - sfinv_only and 7.25 or 8.8) + sfinv_only and 5.45 or 6.83, + sfinv_only and 7.2 or 8.75) if #data.items == 0 then local no_item = S("No item to show") @@ -641,8 +643,8 @@ local function make_formspec(name) local Y = (i % IPP - X) / ROWS + 1 fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s_inv;]", - X - (X * (sfinv_only and 0.12 or 0.14)), - Y - (Y * 0.1) + 0.1, + X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, + Y - (Y * 0.1) - 0.1, 1, 1, item, From 3d77ec58b432aaa71c68f48f166eaac5ba102f5f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 6 Sep 2019 14:48:44 +0200 Subject: [PATCH 098/188] Ability to register custom crafts dynamically --- API.md | 4 --- init.lua | 83 ++++++++++++++++++++++++++++++-------------------------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/API.md b/API.md index 5df2d98..93dc6ed 100644 --- a/API.md +++ b/API.md @@ -73,10 +73,6 @@ end) Removes the recipe filter with the given name. -#### `craftguide.set_recipe_filter(name, function(recipe, player))` - -Removes all recipe filters and adds a new one. - #### `craftguide.get_recipe_filters()` Returns a map of recipe filters, indexed by name. diff --git a/init.lua b/init.lua index d48662b..c4f017c 100644 --- a/init.lua +++ b/init.lua @@ -13,6 +13,7 @@ local fuel_cache = {} local progressive_mode = core.settings:get_bool("craftguide_progressive_mode") local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") +local log = core.log local after = core.after local colorize = core.colorize local reg_items = core.registered_items @@ -33,8 +34,8 @@ local on_receive_fields = core.register_on_player_receive_fields local ESC = core.formspec_escape local S = core.get_translator("craftguide") -local maxn, sort, concat, copy = - table.maxn, table.sort, table.concat, table.copy +local maxn, sort, concat, copy, insert = + table.maxn, table.sort, table.concat, table.copy, table.insert local fmt, find, gmatch, match, sub, split, upper, lower = string.format, string.find, string.gmatch, string.match, @@ -78,10 +79,6 @@ local function table_replace(t, val, new) end end -local function __func() - return debug.getinfo(2, "n").name -end - local function is_str(x) return type(x) == "string" end @@ -98,24 +95,35 @@ local function is_func(x) return type(x) == "function" end -local custom_crafts, craft_types = {}, {} +local craft_types = {} function craftguide.register_craft_type(name, def) - local func = "craftguide." .. __func() .. "(): " - assert(is_str(name), func .. "'name' field missing") - assert(is_str(def.description), func .. "'description' field missing") - assert(is_str(def.icon), func .. "'icon' field missing") + if not is_str(name) or name == "" then + return log("error", "craftguide.register_craft_type(): name missing") + end + + if not is_str(def.description) then + def.description = "" + end + + if not is_str(def.icon) then + def.icon = "" + end craft_types[name] = def end function craftguide.register_craft(def) + if not is_table(def) or not next(def) then + return log("error", "craftguide.register_craft(): craft definition missing") + end + if def.result then def.output = def.result -- Backward compatibility end - if not is_str(def.output) then - def.output = "" + if not is_str(def.output) or def.output == "" then + return log("error", "craftguide.register_craft(): output missing") end if not is_table(def.items) then @@ -151,15 +159,19 @@ function craftguide.register_craft(def) end end - custom_crafts[#custom_crafts + 1] = def + local output = match(def.output, "%S*") + recipes_cache[output] = recipes_cache[output] or {} + insert(recipes_cache[output], def) end local recipe_filters = {} function craftguide.add_recipe_filter(name, f) - local func = "craftguide." .. __func() .. "(): " - assert(is_str(name), func .. "filter name missing") - assert(is_func(f), func .. "filter function missing") + if not is_str(name) or name == "" then + return log("error", "craftguide.add_recipe_filter(): name missing") + elseif not is_func(f) then + return log("error", "craftguide.add_recipe_filter(): function missing") + end recipe_filters[name] = f end @@ -168,14 +180,6 @@ function craftguide.remove_recipe_filter(name) recipe_filters[name] = nil end -function craftguide.set_recipe_filter(name, f) - local func = "craftguide." .. __func() .. "(): " - assert(is_str(name), func .. "filter name missing") - assert(is_func(f), func .. "filter function missing") - - recipe_filters = {[name] = f} -end - function craftguide.get_recipe_filters() return recipe_filters end @@ -191,9 +195,11 @@ end local search_filters = {} function craftguide.add_search_filter(name, f) - local func = "craftguide." .. __func() .. "(): " - assert(is_str(name), func .. "filter name missing") - assert(is_func(f), func .. "filter function missing") + if not is_str(name) or name == "" then + return log("error", "craftguide.add_search_filter(): name missing") + elseif not is_func(f) then + return log("error", "craftguide.add_search_filter(): function missing") + end search_filters[name] = f end @@ -299,17 +305,17 @@ end local function cache_recipes(output) local recipes = get_all_recipes(output) or {} + local num = #recipes - for i = 1, #custom_crafts do - local custom_craft = custom_crafts[i] - if match(custom_craft.output, "%S*") == output then - recipes[#recipes + 1] = custom_craft + if num > 0 then + if recipes_cache[output] then + for i = 1, num do + insert(recipes_cache[output], 1, recipes[i]) + end + else + recipes_cache[output] = recipes end end - - if #recipes > 0 then - recipes_cache[output] = recipes - end end local function cache_usages(item) @@ -1335,8 +1341,9 @@ register_command("craft", { }) function craftguide.show(name, item, show_usages) - local func = "craftguide." .. __func() .. "(): " - assert(is_str(name), func .. "player name missing") + if not is_str(name) or name == "" then + return log("error", "craftguide.show(): player name missing") + end local data = pdata[name] local player = get_player_by_name(name) From ea12d5ca147a67fae523f2a5f71ea69e948fda3d Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 6 Sep 2019 16:16:23 +0200 Subject: [PATCH 099/188] Optimize textures with oxipng --- README.md | 3 +-- depends.txt | 2 -- textures/craftguide_arrow.png | Bin 230 -> 127 bytes textures/craftguide_bg.png | Bin 169 -> 68 bytes textures/craftguide_book.png | Bin 3128 -> 233 bytes textures/craftguide_clear_icon.png | Bin 708 -> 523 bytes textures/craftguide_fire.png | Bin 3131 -> 256 bytes textures/craftguide_furnace.png | Bin 3365 -> 438 bytes textures/craftguide_next_icon.png | Bin 727 -> 518 bytes textures/craftguide_prev_icon.png | Bin 728 -> 523 bytes textures/craftguide_search_icon.png | Bin 1908 -> 1051 bytes textures/craftguide_shapeless.png | Bin 305 -> 155 bytes textures/craftguide_sign.png | Bin 685 -> 417 bytes textures/craftguide_sign_inv.png | Bin 685 -> 528 bytes textures/craftguide_zoomin_icon.png | Bin 3544 -> 0 bytes textures/craftguide_zoomout_icon.png | Bin 2948 -> 0 bytes 16 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 depends.txt delete mode 100644 textures/craftguide_zoomin_icon.png delete mode 100644 textures/craftguide_zoomout_icon.png diff --git a/README.md b/README.md index 00f7e8e..15e7113 100644 --- a/README.md +++ b/README.md @@ -17,5 +17,4 @@ Use the command `/craft` to show the recipe(s) of the pointed node. For developers, `craftguide` also has a [modding API](https://github.com/minetest-mods/craftguide/blob/master/API.md). -![Preview2](https://i.imgur.com/bToFH38.png) - +![Preview2](https://i.imgur.com/ZxGNxrK.png) diff --git a/depends.txt b/depends.txt deleted file mode 100644 index ad29828..0000000 --- a/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -sfinv? -sfinv_buttons? \ No newline at end of file diff --git a/textures/craftguide_arrow.png b/textures/craftguide_arrow.png index 7171e82e9a5f2aea7c0c1f45ed3288a82c088663..cef827e73073b8888ae053fcefb5b09724b1e038 100644 GIT binary patch delta 108 zcmV-y0F(db0e_GgW&{8L0CTvM2mk;8MoC0LRCwC8(t!m)K@0@Zt9439|IEh+jxcap zfQMLn_QTT;=^RJwxO1G&ac+)#=H@sl*zwQlwEx`O@I}w~U>lJxd;S2Wmd?}15n!VL O0000OnH#p}QHd`*1-eMCd;3+cs%RddJb|LR+ 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 ai~S7RcYg7^AD8w4@jYGrT-G@yGywpRQ$kY! diff --git a/textures/craftguide_fire.png b/textures/craftguide_fire.png index 6e3a83282875d71c2dd33cb42964a58ca8b3a044..bd7b4fc3029c9152009839c763d3a018c25028c5 100644 GIT binary patch delta 240 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 literal 3365 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 diff --git a/textures/craftguide_next_icon.png b/textures/craftguide_next_icon.png index 82cf3d3616bfeb8cef3bbd14e5811c349cce3226..7718abaee4d887d17e02fb87b88965ae97580e53 100644 GIT binary patch literal 518 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H0wgodS2{2-FrM{vaSW-r_4dxunE{RrEQv9~ z2j+4VcsB~aD>(Ye!RSF-wAqeqo)^Els<+!cijI{$^Z)FZUw&C@w_c0NUc2?1H;i>H zDp_mu%(FaO7(Pdy77H^7_BvqYS1^xxP1>qS4R2!}2wt~5mi1IOLET)U;$$vgW}YL% zfdkR&iaS!zxNtHs`|msw7iK7|%CP4-=k-sD9t>_x(_>DxFJP3AKUDhdsqO}bC%OfU zC!QHFwiM4`_$koCVA*cfu!j|a|14O+aDu;Uy2T6@u?Ce3j8B%kSvAaYmUTF{kWXQ| z1N#IP1owFW`-JEP%pOc2Sr&!o9~iu6Gzu}Wy({eVJ+qZ*&vU)>n`ulZ6z`npdMfkq@OJTV`SmlYA!HiG7tYj$q6@nt&znOe{duq2>ncc?l=5L13m-em%-E3 K&t;ucLK6V5RNpuN literal 727 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrV4COY;uunK>+PMrdBTn&4iAk_ zCzVg(Na=19?+|cZ@IbL5e8K}(p%j$~LCzBsW`=l_98+=LxOqcU#KxZ4bF1w%xt0{a z`}n5x5A!4yPfR4$8*;e!gynrkwWs^THJ8fwm6_+NZhvfNz`X2$*7H3+nrmg>zn$fk zcU;DTEsp7Yqx;j4fC<766bo4PXc+pOTKe$LWCb^d;0JOacKq4RS~rcuZuyjTGNpGJ zdGs?sCo&vRd%owBN{66>{6Xdinj19ZyXSmv6+FVRpg$o@?6BAl?l~2f9l{R##m}7n zuvdnKCqd%iW=9Tg|0WBd0qnUq*`xfMA{hVF3Oz`Y&}R^LW-c%^fl>ZU%pX(?803|t z4oqwB*k7+NsASMk@89(JA%AxN0fuev7cTA1*!Id^O!B}t4yQjGPcSs;x3LM-7@9OZ z=w8Uk63@e{@FOXM;ULghj(rkR4j+zQ04pijarA>!#Pd1(`(A$LlzLtR)BDcFwBi3|wtWop4gCi;u{`7xI8ZA2L-PYy1jFf#wRRI3-_)Pq&*Imx z{ps&h?Ts7z{(f(M7~k`?l9BmF{*UDcW^d%bulm8@@b{Ao7I4RluIDspxZ8IB{^$7q z%7?}cf4Be5TKAJ}!~JbQq4U|*l{*+&ZhqrE(0ZO>k$w%({XjJjxaR}i|AR;2$Dwqf z`|W`4{~+n`0jQ)&zs5XMrtS@Ycb-gLPVZrJhW300zWWR^`xq^1m zyWUxR_7M!z4@iFKeHXjyz0AM7AYOB&=QfLf7qn^Ky}aAIU0%C^v)*oIvhlX<8Qz#F e2P9I`9q-0Hd(Hm59fiOI%i!ti=d#Wzp$P!RnKjM; diff --git a/textures/craftguide_prev_icon.png b/textures/craftguide_prev_icon.png index b26cd157f95aec853fce734574e5d319686b8399..1c15373af78cd4d21e16e619c9a89b46efb1bab0 100644 GIT binary patch literal 523 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H0wgodS2{2-FkbR>aSW-r_4W>9TWF$8+sDKm z$#+Cmf)?L&oSL#tKw#EPJthI&lq`0}ypqLFeLNm6vW>Br*YK}`G3mpe^L+d6m%pp# zJ0r98T2%I06k_-0h{98v$36P%4@v4*9G$^! z{0-l}u^%w4HEWo$k70t{ALfMF`xq|V`^VssU(YaQyFJ4q@%ao1egCJu-SZ=ap|VEQ zq3+uXhN52~43@Q84S(LQX880&t6`3vsDs~pE`{a(tP}RviaN-}vrf3YoGIZb^Sbn3 zH4NEtA12D{B(Uyy&=$=X)*zZ5bC%&1!zXSB_6heJtQu-Wft+Ly_6aOj4Rf5u51e_Z z8h>N+4Tdy6`HhLk=QRr{+~)wv$U2-`$fxi;fPF&o3g#1*R~VnjykaQgD`l{3N0nyb ze4r}9pm~tNgOkm{%YY%MiE)AuPs5Z1hAAxDkJ-FVdQ&MBb@05~k+S^xk5 literal 728 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 diff --git a/textures/craftguide_shapeless.png b/textures/craftguide_shapeless.png index 8d6886350ef3dbad53143496eefb62bb394ac5f3..58b2a963d9c3bc3e60d1357250e8c3de20729f81 100644 GIT binary patch delta 138 zcmV;50CoSd0-FJl8Gi%-002sU^>Y9K0Afi*K~#9!Vi>XjP&*l501(4K@UQ!X{+~UL zGcIabqycKCktCH>3sxr_l!OuIQ{)l9S7*rc`c=Sl1{CmI0}6QT5(;>n14;mz3;_={ sT)X7ZrG5_Wr0ZSkw{`13fN!4%Z%zqKnX)(z00000NkvXXt^-0~f*Tez`v3p{ delta 289 zcmV++0p9+b0kHy*8Gi-<007{3J@^0s00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z000SaNLh0L01m?d01m?e$8V@)0002SNklLo=WvUMXQR$^}z9IGH$ nnQUwL?^*^A#~M4&UnHd$63?p8Z=#~h00000NkvXXu0mjfs_}P+ diff --git a/textures/craftguide_sign.png b/textures/craftguide_sign.png index f64b5ab5a67db1501315eefd08a6dc32e685074a..065aa3d2c764915de580b647fea7b554d139ef54 100644 GIT binary patch delta 402 zcmV;D0d4-R1)&3w8Gi!+001a04^sdD0Hsh&R7H|}QJ8^Km3&l9nt@lCeN&NoSDb`e|NsA#fLM=pOPGIJjdxI$e^#A@Sr=+t94BoOj*Qq}0fy+Rm%j%ckAauz%;>y4K33+s>ij*0R{l zsp8kP(8!$A!Q-~!}a@E ztwgggEPy{ zzn$mxFB37_)D_*>xO_dkzxug&-Cip*Z1^J&e6FvM468R2vno5k&I`k$m91hoZ;2w3 wg`|zN7-#k(9m#F%WT~kZ8OSgz^@D5xeb!fwRxW`r01E&B07*qoM6N<$g5JT`z5oCK delta 672 zcmV;R0$=^11FZ#+8Gi-<001BJ|6u?C00v@9M??Vs0RI60puMM)00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-&l9s~_3Y=0$Y0006yNklLLw`_<1XM&ttZf7>jD;wo zB*x9{?auA|vPflVUisiXUh%%<_T>{XO9kF07#~q0kR%FlWT}9t7#K&PGls@cbTWc- z486idhbnZ3bC+flwxBy#Pe;)&OSUQ%1uBS?yH`%e|DGQlI+rM|Gju9BFm;eLm9!#~ zI!Tn^TluU}&tgODitwV}IhJ1d`7=ygX(GL5$ml_|X63|r-qGU3a| z&&X7vqCfuUm~QoOfhx}Ycus`3Yu2c|G}gU2!2>mjsG z>6aygauq+Uc(FLg>i4faTbM<6I=oqWN;9ZhYJENlg$E& z;{5gbEwOO(!jULk61L33Xs<_d$XXzVVAVLa zK5TAFyX zd7$Bk=Uh3l`1;W~PjBzIdujdss~ayLnFDlorO{rXcNrW?g8V@KMh8F@2*7|~qO(9! z3?E!CX95kF?djqeQgJJ^w>i(nQNr!{np}7DHMb?6{%+rzd%HV-@?JaR{jH1(yypno zKQVM%V8WrgD1_sZZ-U_>c9(|eQ?d>9nF^`@jF!7RbCQ+TDL7lc?qs6!|EwU%h>Pkm zK5u%$5>H6bi!W#Z`&64|f-b$&iu8Q~H+cWLo^8M>pZc$Qu6ce~cd(HVZO#$y_ mD+qRRsk)e~6^uRVUdEvo7#e?NG5<`EKRsRjT-G@yGywp9R132J delta 672 zcmV;R0$=@*1g!;-8Gi-<001BJ|6u?C00v@9M??Vs0RI60puMM)00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-&l9s~|4M^bjB0006yNkla65Q5k#DnU>S8~+0fLDWJJJ3$4-!cIbrA%Cbv0xF^+);59`#zGWP z665CfcHiy$Sc_DaX3BvXrudDxefb1wA_-1lLyMLXAvEAg6A7(mU_H4>8Cpx;Nr~Pw z3>x2hbZ$DFyEMyIbm!`6WWOlbs&p&SQ6}8IaPx;LFF) zs6?Y%iHr^%LPIz2(8iX%lanBF#<%CJuSv8{2*Ht>oIKAdiyurLn8H>y0ncc!hcqUk zUla_ARl>03#o`>R-@o!~VHVTr@Mh^L^`PY8y;~qhaDPohl4V%iP*ydvUs<9|80k%* zvMz^bPV?&d64Ns$Se}2t)S+o!EY5NG_%U8SS)i=esQ#=XqhmBTi2K*hFm%2>dg?42 z#X2es8QZawYEY782Im~6(_!P+H-gF->un>%z{|(;3~eK1zbH^>*4DqX^5Fx4$nT%u z2tE+oNPqMjNGVCjCQwT8{@q*Z!GN-=Q7YZ!z>7#XA7|hGaip}=71ZTAZn#185nF!6 z=|CCnl&gagH1{R0000@ooW diff --git a/textures/craftguide_zoomin_icon.png b/textures/craftguide_zoomin_icon.png deleted file mode 100644 index 5b8ecc2cbdfbee1ae0398c6562221d711d47e6f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3544 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 Date: Fri, 6 Sep 2019 17:06:23 +0200 Subject: [PATCH 100/188] Improve the interface --- init.lua | 23 +++++++++++++---------- textures/craftguide_bg_full.png | Bin 0 -> 979 bytes 2 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 textures/craftguide_bg_full.png diff --git a/init.lua b/init.lua index c4f017c..12ae257 100644 --- a/init.lua +++ b/init.lua @@ -599,7 +599,8 @@ local function make_formspec(name) fs[#fs + 1] = [[ no_prepend[] - background[1,1;1,1;craftguide_bg.png;true] + bgcolor[#00000000;false] + background[1,1;1,1;craftguide_bg_full.png;true;10] ]] end @@ -607,11 +608,12 @@ local function make_formspec(name) sfinv_only and 2.76 or 2.72, ESC(data.filter)) - fs[#fs + 1] = fmt([[ - image_button[%f,-0.05;0.85,0.85;craftguide_search_icon.png;search;] - image_button[%f,-0.05;0.85,0.85;craftguide_clear_icon.png;clear;] - field_close_on_enter[filter;false] - ]], + fs[#fs + 1] = fmt( + "field_close_on_enter[filter;false]\ + image_button[%f,-0.05;0.85,0.85;craftguide_search_icon.png;search;;;false;" .. + "craftguide_search_icon.png^\\[colorize:yellow:255]" .. + "image_button[%f,-0.05;0.85,0.85;craftguide_clear_icon.png;clear;;;false;" .. + "craftguide_clear_icon.png^\\[colorize:red:255]", sfinv_only and 2.6 or 2.54, sfinv_only and 3.3 or 3.25) @@ -621,10 +623,11 @@ local function make_formspec(name) colorize("yellow", data.pagenum), data.pagemax) - fs[#fs + 1] = fmt([[ - image_button[%f,-0.05;0.8,0.8;craftguide_prev_icon.png;prev;] - image_button[%f,-0.05;0.8,0.8;craftguide_next_icon.png;next;] - ]], + fs[#fs + 1] = fmt( + "image_button[%f,-0.05;0.8,0.8;craftguide_prev_icon.png;prev;;;false;" .. + "craftguide_prev_icon.png^\\[colorize:yellow:255]" .. + "image_button[%f,-0.05;0.8,0.8;craftguide_next_icon.png;next;;;false;" .. + "craftguide_next_icon.png^\\[colorize:yellow:255]", sfinv_only and 5.45 or 6.83, sfinv_only and 7.2 or 8.75) diff --git a/textures/craftguide_bg_full.png b/textures/craftguide_bg_full.png new file mode 100644 index 0000000000000000000000000000000000000000..9a97df69ba777320ef87b4f17acebaa5b81f02d9 GIT binary patch literal 979 zcmeAS@N?(olHy`uVBq!ia0y~yV4M%cNgOOdk>=;JHy9Y0XL-6fhE&{ody`#sj)O$& z#rsFO9F9(IU}9O2#=C%-c`-Bl#)0c z>gSE}pZTWTRJf4(Z;HP$dr9W}x=B*ZRl0UkA8czJPNZ;17=?xzADFOp(@e&;oPE0v zt_ZU{!{FR!#MGlD+)(3SryxIpAB0b^KVkmF2*N)bY8ZeRRSF`FBn6QM2}7km{3h2Z zgaZiM!T@$3$a0tiU{3!DlY%+@1UpO$>MI93m=rl49(5&h3Lz;hL->>rOjvvgnC_xd zjhT6FYOR(`I1x1y$X~YVR9;8khU>E@9~HTqu(DkJtVHaBtL>9-%ETtD^H&dVK9G6+ z*PA*28yMbv{d)4Kw7{GTMJsm+UYKkxu%TY|`~ho$isw5EjqX=;Fh@PJD&AD{O@jSR seeem{}P-UHx3vIVCg!0B0YPAOHXW literal 0 HcmV?d00001 From 6b76c8c10f56a4a3c9e642fec6b6800bf962216f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 6 Sep 2019 17:23:27 +0200 Subject: [PATCH 101/188] API to set a custom background --- API.md | 9 ++ README.md | 2 +- init.lua | 130 +++++++++++----------------- textures/craftguide_arrow.png | Bin 127 -> 230 bytes textures/craftguide_bg_full.png | Bin 979 -> 1150 bytes textures/craftguide_book.png | Bin 233 -> 3128 bytes textures/craftguide_clear_icon.png | Bin 523 -> 708 bytes textures/craftguide_fire.png | Bin 256 -> 3131 bytes textures/craftguide_furnace.png | Bin 438 -> 3365 bytes textures/craftguide_next_icon.png | Bin 518 -> 727 bytes textures/craftguide_prev_icon.png | Bin 523 -> 0 bytes textures/craftguide_search_icon.png | Bin 1051 -> 1908 bytes textures/craftguide_shapeless.png | Bin 155 -> 305 bytes textures/craftguide_sign.png | Bin 417 -> 685 bytes textures/craftguide_sign_inv.png | Bin 528 -> 685 bytes 15 files changed, 59 insertions(+), 82 deletions(-) delete mode 100644 textures/craftguide_prev_icon.png diff --git a/API.md b/API.md index 93dc6ed..b6e5073 100644 --- a/API.md +++ b/API.md @@ -151,3 +151,12 @@ You can add a stereotype like so: ```Lua craftguide.group_stereotypes.radioactive = "mod:item" ``` + +#### `craftguide.background` + +You can set a custom background theme by overriding this variable: + +```Lua +craftguide.background = "my_custom_bg.png" + +``` diff --git a/README.md b/README.md index 15e7113..53c869e 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,4 @@ Use the command `/craft` to show the recipe(s) of the pointed node. For developers, `craftguide` also has a [modding API](https://github.com/minetest-mods/craftguide/blob/master/API.md). -![Preview2](https://i.imgur.com/ZxGNxrK.png) +![Preview2](https://i.imgur.com/oGSvbTW.png) diff --git a/init.lua b/init.lua index 12ae257..0d223f4 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,7 @@ craftguide = {} +craftguide.background = "craftguide_bg_full.png" + local pdata = {} local core = core @@ -443,15 +445,11 @@ local function get_recipe_fs(data) fs[#fs + 1] = fmt(FMT.button, xoffset + (sfinv_only and 1.98 or 2.7), yoffset + (sfinv_only and 1.9 or 1.2), - 2.2, - 1, - "alternate", - btn_lab) + 2.2, 1, "alternate", btn_lab) if width > GRID_LIMIT or rows > GRID_LIMIT then fs[#fs + 1] = fmt(FMT.label, - sfinv_only and 2 or 3, - 7, + sfinv_only and 2 or 3, 7, ESC(S("Recipe is too big to be displayed (@1x@2)", width, rows))) return concat(fs) @@ -491,13 +489,8 @@ local function get_recipe_fs(data) local label = groups and "\nG" or "" fs[#fs + 1] = fmt(FMT.item_image_button, - X, - Y + (sfinv_only and 0.7 or 0), - btn_size, - btn_size, - item, - match(item, "%S*"), - ESC(label)) + X, Y + (sfinv_only and 0.7 or 0), + btn_size, btn_size, item, match(item, "%S*"), ESC(label)) local burntime = fuel_cache[item] @@ -519,69 +512,44 @@ local function get_recipe_fs(data) local pos_y = yoffset + (sfinv_only and 0.25 or -0.45) fs[#fs + 1] = fmt(FMT.image, - min(3.9, rightest) + 1.2, - pos_y, - 0.5, - 0.5, - icon) + min(3.9, rightest) + 1.2, pos_y, 0.5, 0.5, icon) local tooltip = custom_recipe and custom_recipe.description or shapeless and S("Shapeless") or S("Cooking") fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", - rightest + 1.2, - pos_y, - 0.5, - 0.5, - ESC(tooltip)) + rightest + 1.2, pos_y, 0.5, 0.5, ESC(tooltip)) end local arrow_X = rightest + (s_btn_size or 1.1) local output_X = arrow_X + 0.9 fs[#fs + 1] = fmt(FMT.image, - arrow_X, - yoffset + (sfinv_only and 0.9 or 0.2), - 0.9, - 0.7, - "craftguide_arrow.png") + arrow_X, yoffset + (sfinv_only and 0.9 or 0.2), + 0.9, 0.7, "craftguide_arrow.png") if recipe.type == "fuel" then fs[#fs + 1] = fmt(FMT.image, - output_X, - yoffset + (sfinv_only and 0.7 or 0), - 1.1, - 1.1, - "craftguide_fire.png") + output_X, yoffset + (sfinv_only and 0.7 or 0), + 1.1, 1.1, "craftguide_fire.png") else local output_name = match(recipe.output, "%S+") local burntime = fuel_cache[output_name] fs[#fs + 1] = fmt(FMT.item_image_button, - output_X, - yoffset + (sfinv_only and 0.7 or 0), - 1.1, - 1.1, - recipe.output, - ESC(output_name), - "") + output_X, yoffset + (sfinv_only and 0.7 or 0), + 1.1, 1.1, recipe.output, ESC(output_name), "") if burntime then fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime) fs[#fs + 1] = fmt(FMT.image, - output_X + 1, - yoffset + (sfinv_only and 0.7 or 0.1), - 0.6, - 0.4, - "craftguide_arrow.png") + output_X + 1, yoffset + (sfinv_only and 0.7 or 0.1), + 0.6, 0.4, "craftguide_arrow.png") fs[#fs + 1] = fmt(FMT.image, - output_X + 1.6, - yoffset + (sfinv_only and 0.55 or 0), - 0.6, - 0.6, - "craftguide_fire.png") + output_X + 1.6, yoffset + (sfinv_only and 0.55 or 0), + 0.6, 0.6, "craftguide_fire.png") end end @@ -595,41 +563,44 @@ local function make_formspec(name) local fs = {} if not sfinv_only then - fs[#fs + 1] = fmt("size[%f,%f;]", 9.5, 8.4) - - fs[#fs + 1] = [[ + fs[#fs + 1] = fmt([[ + size[%f,%f;] no_prepend[] bgcolor[#00000000;false] - background[1,1;1,1;craftguide_bg_full.png;true;10] - ]] + background[1,1;1,1;%s;true;10] + ]], + 9.5, 8.4, craftguide.background) end - fs[#fs + 1] = fmt("field[0.25,0.2;%f,1;filter;;%s]", - sfinv_only and 2.76 or 2.72, - ESC(data.filter)) + fs[#fs + 1] = fmt([[ + field[0.25,0.2;%f,1;filter;;%s] + field_close_on_enter[filter;false] + ]], + sfinv_only and 2.76 or 2.72, ESC(data.filter)) - fs[#fs + 1] = fmt( - "field_close_on_enter[filter;false]\ - image_button[%f,-0.05;0.85,0.85;craftguide_search_icon.png;search;;;false;" .. - "craftguide_search_icon.png^\\[colorize:yellow:255]" .. - "image_button[%f,-0.05;0.85,0.85;craftguide_clear_icon.png;clear;;;false;" .. - "craftguide_clear_icon.png^\\[colorize:red:255]", - sfinv_only and 2.6 or 2.54, - sfinv_only and 3.3 or 3.25) + local search_icon = "craftguide_search_icon.png" + local clear_icon = "craftguide_clear_icon.png" + + fs[#fs + 1] = fmt([[ + image_button[%f,-0.05;0.85,0.85;%s;search;;;false;%s^\[colorize:yellow:255] + image_button[%f,-0.05;0.85,0.85;%s;clear;;;false;%s^\[colorize:red:255] + ]], + sfinv_only and 2.6 or 2.54, search_icon, search_icon, + sfinv_only and 3.3 or 3.25, clear_icon, clear_icon) fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", - sfinv_only and 6.35 or 7.85, - 0.06, - colorize("yellow", data.pagenum), - data.pagemax) + sfinv_only and 6.35 or 7.85, 0.06, + colorize("yellow", data.pagenum), data.pagemax) - fs[#fs + 1] = fmt( - "image_button[%f,-0.05;0.8,0.8;craftguide_prev_icon.png;prev;;;false;" .. - "craftguide_prev_icon.png^\\[colorize:yellow:255]" .. - "image_button[%f,-0.05;0.8,0.8;craftguide_next_icon.png;next;;;false;" .. - "craftguide_next_icon.png^\\[colorize:yellow:255]", - sfinv_only and 5.45 or 6.83, - sfinv_only and 7.2 or 8.75) + local prev_icon = "craftguide_next_icon.png^\\[transformFX" + local next_icon = "craftguide_next_icon.png" + + fs[#fs + 1] = fmt([[ + image_button[%f,-0.05;0.8,0.8;%s;prev;;;false;%s^\[colorize:yellow:255] + image_button[%f,-0.05;0.8,0.8;%s;next;;;false;%s^\[colorize:yellow:255] + ]], + sfinv_only and 5.45 or 6.83, prev_icon, prev_icon, + sfinv_only and 7.2 or 8.75, next_icon, next_icon) if #data.items == 0 then local no_item = S("No item to show") @@ -654,10 +625,7 @@ local function make_formspec(name) fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s_inv;]", X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, Y - (Y * 0.1) - 0.1, - 1, - 1, - item, - item) + 1, 1, item, item) end if data.recipes and #data.recipes > 0 then diff --git a/textures/craftguide_arrow.png b/textures/craftguide_arrow.png index cef827e73073b8888ae053fcefb5b09724b1e038..7171e82e9a5f2aea7c0c1f45ed3288a82c088663 100644 GIT binary patch delta 212 zcmb<_#yCN;o{fQl;pWDeW+25_9OUlAuOnH#p}QHd`*1-eMCd;3+cs%RddJb|LR+ zGk(5}-nxAK^|=McbBgahN|Sh7Al_qghgX@?-*3751*UCb*-L}G4(&U5Nj009U-IZ3 z32zIVeLwa~Zl8R5N%_n`5u+|q*SrX)iQLx$QrgN_?EF06lJxd;S2Wmd?}15n!VL O0000W}~c010qNS#tmYE+YT{E+YYWr9XB6000Mc zNliru;|T^2H5Mtx&ieoW1P@6>K~#9!?bxwuT44Z&;m<#tIJyQT5DFOrlA%Z!mrlh? zkkC1kL&uN{2%%G_(z=%}A)AvIP!PO;;E+)|IhPJ1wbizsGk+EOJd>W|^uf#TIgMWS z7^I(WI%x;~cgrj?%QO$Ww;I3X)5<8XWdnOM8s}|R+n0`xx4#YZDKFEs6zpi`MK1F- z^ZohU`;ek~L%`9;m3D(fagxln>N6e@;pU;(=P{&!D7l2dJfA(zOEA(k8IEL>XHwWe*uA$4*?OAECM5wjsbF$4*?OAECM5wjsbF$4*?OAECM5wjsb3e z;9t#WX#}WcS+cMK)Uqgo2-(f<0P4(0n`VJNgM|E$XoUi}@002ovPDHLkV1j(n_Uixu delta 385 zcmeyzahZLBay|1bPZ!6Kid%1QvWw1fkZ8Sl|0tKk(a8-=EDO?j7ces~W@g_w@!sav znO~lqEB$cp=ZezzDW_)X>bl1rsDJ5kdYWnQ*Eu>jd)ejRMxI-0ynH72zKcfo-Osbs zcD$~#pWE$jR*`i6X_?Jgiw_~Y1t(aa_uNqZyixu$-;|pQ7gGOCG4wZPFUg!=H%W@Q zO4m;6gKdq&i4+bAqtGzp0~5Axn#tIfvv1eI6=9ZV7@Yfzn0mB?Cp$9vGJW_xc_OpP zbmv#>_l7wN^_eoQRqU&=}14GeF-em!|qT42tFqLsS@ zFHE);*ibKf{(!YW#q*toM)xZ^n4_Lq6>qBfCc*wDa@BKi__Tlg;V+wcbCYD+uJDuE XAHN0_n*7xZVE_V8S3j3^P6uJ@VVD_U zC<6{NG_fI~0ue<-1QkJoA_k0xBC#Thg@9ne9*`iQ#9$OrQF$}6R&?d%y_c8YA7_1Q zpS|}zXYYO1x&V;8{kgn!SPFnNo`4_X z6{c}T{8k*B#$jdxfFg<9uYy1K45IaYvHg`_dOZM)Sy63ve6hvv1)yUy0P^?0*fb9UASvow z`@mQCp^4`uNg&9uGcn1|&Nk+9SjOUl{-OWr@Hh0;_l(8q{wNRKos+;6rV8ldy0Owz z(}jF`W(JeRp&R{qi2rfmU!TJ;gp(Kmm5I1s5m_f-n#TRsj}B0%?E` zvOzxB2#P=n*a3EfYETOrKoe*ICqM@{4K9Go;5xVgZi5G41dM~{UdP z6d+Yd3o?MrAqM0Kc|iV92owdyL5UC#5<>aVCa44|hpM4Es0sQWIt5*Tu0n&*J!lk~ zf_{hI!w5`*sjxDv4V%CW*ah~3!{C*0BD@;TgA3v9a1~q+AA{TB3-ERLHar49hi4Ih z5D^-ph8Q6X#0?2VqLBoIkE}zAkxHZUgRb+f=natP#6>iMMoK->`~sRLq)(kHo*Vn{;LcG6+e zdD1=7D>9j^O?D{Qg|tCDK{ym)H7&wDr6*;uGTJg8GHjVb znL{!cWyUB7MT6o-VNo_w8Yq`2<5Ub)hw4L3rj}5@qxMs0WMyP6Wy582WNT#4$d1qu znl{acmP#w5ouJ*Jy_Zv#bCKi7ZIf$}8dZdVy&)LYdbX%I9R8VMQ|8r>Q*nyQ)sn)#Z|n)kKvS`4iutvy=3T65Yu+7a4Yv^%sX zb>ww?bn(=Yu(!=O6^iuTp>)p_Y^{w=i^lS773}6Fm1Fpe-gF!>I zp{*g$u-szvGhed; zvo5pW&GpS$<~8QGEXWp~7V9lKEnZq0SaK{6Sl+dwSOr*ZvFf(^Xl-N7w{EeXveC4O zv)N}e%%C!Y7^RFWwrE>d+x51mZQt2h+X?JW*!^a2WS?Sx)P8cQ&Qi|OhNWW;>JChY zI)@QQx?`Nj^#uJBl~d&PK+RZLOLos~K(b5>qmrMN0})tOkySZ3_WICNY@+|jrX%s^&6b2i>5 zeqa0y%Z;^%^_=a@u3%4b9605ii3Ep)@`TAmhs0fpQ%O!ql}XcFH*PieWwLj2ZSq`7 zV9Mc?h17`D)-+sNT-qs~3@?S(ldh7UlRlVXkWrK|vf6I-?$tAVKYn8-l({mqQ$Q8{ zO!WzMg`0(=S&msXS#Pt$vrpzo=kRj+a`kh!z=6$;cwT88(J6|n-WB%w`m$h~4 zpmp)YIh_3ETV2tjiAU!0h1dxU-n=E9e!)6|Z;4?!H=SSy{V>ut&IOq{_dlbFb#!9eY1iCsp6Bajj|H zr?hX|zPbJE{X++w546-O*Ot`2Kgd0Jx6Z4syTu9enWavU5N9)I?I-1m1* z_?_rJ$vD~agVqoG+9++s?NEDe`%Fht$4F;X=in*dQ{7$mU2Q)a|9JSc+Uc4zvS-T9 z63!N$T{xF_ZuWe}`RNOZ7sk3{yB}PPym+f8xTpV;-=!;;JuhGEb?H5K#o@~7t9DmU zU1MD9xNd#Dz0azz?I)|B+WM{g+Xrk0I&awC=o(x)cy`EX=)z6+o0o6-+`4{y+3mqQ z%kSJBju{@g%f35#FZJHb`&swrA8dGtepviS>QUumrN{L@>;2q1Vm)$Z)P1z?N$8UY zW2~{~zhwUMVZ87u`Dx{Z>O|9|`Q+&->FRy-Sjp7DHsy69KwU-!MxeeuI@&cF4| zM9z%ARI+y?e7jKeZ#YO-C0ewkCK~#90V*LOAKLaHIAb^-C(hURv z0YtF@00G1TB35l!j3HrSXz@QfdlHF$RH5-`TY}^esuFVSaW^HMuv-rmVv_pAb`Lwz@{0d5vCbt zb7{?d22=NRct8RK5ZHjpb>3jpL5i>ekX&_@ zAP^fQSKYJ}#by`)2q17e0L5)<-%McCY-iZHell1hFt(oI+n0B6XQSH;0{{U8Pe?G+ z-2-#~bMXi<%$uCYaQFUgyqZA(Ab>DZB1~~o?xg=97vR$j0ssNTNNIKk2rvN3eW$rT S1fr$@0000RRZ?%)EI-S@z?xoOy}jxV z0|Q$*5S(4Yz`(Soyu2y~sEavhP5IF!KnBYhrBkF!Z|@rB2|J3gJ=k70z3Wah^M%`UZ;N<5 zVRL-MW9h$x(R=}~_=YL>Vi@Gkx-q3px^d>rxwQT3{hnO>_kU01=}qQLKm(D0*Xc7` zw@%$Y%kzi0;72>-a@lpc=Ih=bGFvNBmsWS`Onv*AJ?GD??z>iIy6$CS%wnMsp8tX3 zsy}r9xO-ht_@n1lpi-lnA@OgCYK0P*p`u#h_`@sUfztgaFSqet+iIB{>lKjs+qwg8f2AE*&oSe{d$8>EUj}dXarX9QO+qY9>4UP;2}!)!|1U z^TXLJhs-%!>=%1($QStc&$MlSkm9pFzs>s?%p3EV-qxsY_zYC%mGDNpaqfDSvVA~H zy%L^-Ifwp#XSc3ajd*rrzr6P|>4V&Ne%7-rV&UeC=WJQeawxn>^YHzzWe26FEtsu7 ze~lVfeZ8z;zS5&jk513|^Y_ok{QTqp*FH5;(kni8UQ#QvrQf#iR@dYM{I35>7kdBm zE4Wx}_BZ5>j(Vef_q?AfFW&L(cHnHe|G?tIfsXKymSFD-PxgM5R28Ue_I$7~kXx_u z_%Yo-cMql=Dz*K(_KEb#t8-c8WOqLhs;KzVJDGa%*$ ai~S7RcYg7^AD8w4@jYGrT-G@yGywpRQ$kY! delta 508 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 Vez(c=Kl1&Mn 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 delta 423 zcmV;Y0a*T}8ny$F8Gi!+001a04^sdD0K-sBR7GcDVV<6&m6V&Co1l}EmsL?!V_{^e zsjrENk%NPbrKPG|S6q2_etKn7d0$X|XjOc9gLZa*i;0df001=r0DO9ZaA|3roS`%T z05<>tJOcno1^`0_051aoJO%(&4FFFK0GyeFW?*8cr>CKzp?|8Xs-B*nudJ+xhlhcD ze|~#@jEsyY001ih0Dpabn|~7jY5*(%0Gl-c|FjZq8UQZ<0RR6ad3kvw005UY08vj; zN<~T^001@s0FX5RA^-p`002qG7u^5=0Io?yK~#9!HH!msC}0@GHXj~p+r9sxYLDvv zsxw>!0s4ZW?tk#-rx?)D=#do%2@Un&Eu{Z7e~gk37Lz<@qAyFYe@i^pzcRiW>Ugy% zXcE45Cd%Jp8O;sA3}1YjX6hY|%o;nd@SF6(_sRv_Ev`w{drO=Q)~8 zO}To#?(5pT4oRjz+P>QC&idJ^)MT@7^7ZQSzVY9s*&y)6^GIHr{`>yNf diff --git a/textures/craftguide_next_icon.png b/textures/craftguide_next_icon.png index 7718abaee4d887d17e02fb87b88965ae97580e53..82cf3d3616bfeb8cef3bbd14e5811c349cce3226 100644 GIT binary patch literal 727 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrV4COY;uunK>+PMrdBTn&4iAk_ zCzVg(Na=19?+|cZ@IbL5e8K}(p%j$~LCzBsW`=l_98+=LxOqcU#KxZ4bF1w%xt0{a z`}n5x5A!4yPfR4$8*;e!gynrkwWs^THJ8fwm6_+NZhvfNz`X2$*7H3+nrmg>zn$fk zcU;DTEsp7Yqx;j4fC<766bo4PXc+pOTKe$LWCb^d;0JOacKq4RS~rcuZuyjTGNpGJ zdGs?sCo&vRd%owBN{66>{6Xdinj19ZyXSmv6+FVRpg$o@?6BAl?l~2f9l{R##m}7n zuvdnKCqd%iW=9Tg|0WBd0qnUq*`xfMA{hVF3Oz`Y&}R^LW-c%^fl>ZU%pX(?803|t z4oqwB*k7+NsASMk@89(JA%AxN0fuev7cTA1*!Id^O!B}t4yQjGPcSs;x3LM-7@9OZ z=w8Uk63@e{@FOXM;ULghj(rkR4j+zQ04pijarA>!#Pd1(`(A$LlzLtR)BDcFwBi3|wtWop4gCi;u{`7xI8ZA2L-PYy1jFf#wRRI3-_)Pq&*Imx z{ps&h?Ts7z{(f(M7~k`?l9BmF{*UDcW^d%bulm8@@b{Ao7I4RluIDspxZ8IB{^$7q z%7?}cf4Be5TKAJ}!~JbQq4U|*l{*+&ZhqrE(0ZO>k$w%({XjJjxaR}i|AR;2$Dwqf z`|W`4{~+n`0jQ)&zs5XMrtS@Ycb-gLPVZrJhW300zWWR^`xq^1m zyWUxR_7M!z4@iFKeHXjyz0AM7AYOB&=QfLf7qn^Ky}aAIU0%C^v)*oIvhlX<8Qz#F e2P9I`9q-0Hd(Hm59fiOI%i!ti=d#Wzp$P!RnKjM; literal 518 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H0wgodS2{2-FrM{vaSW-r_4dxunE{RrEQv9~ z2j+4VcsB~aD>(Ye!RSF-wAqeqo)^Els<+!cijI{$^Z)FZUw&C@w_c0NUc2?1H;i>H zDp_mu%(FaO7(Pdy77H^7_BvqYS1^xxP1>qS4R2!}2wt~5mi1IOLET)U;$$vgW}YL% zfdkR&iaS!zxNtHs`|msw7iK7|%CP4-=k-sD9t>_x(_>DxFJP3AKUDhdsqO}bC%OfU zC!QHFwiM4`_$koCVA*cfu!j|a|14O+aDu;Uy2T6@u?Ce3j8B%kSvAaYmUTF{kWXQ| z1N#IP1owFW`-JEP%pOc2Sr&!o9~iu6Gzu}Wy({eVJ+qZ*&vU)>n`ulZ6z`npdMfkq@OJTV`SmlYA!HiG7tYj$q6@nt&znOe{duq2>ncc?l=5L13m-em%-E3 K&t;ucLK6V5RNpuN diff --git a/textures/craftguide_prev_icon.png b/textures/craftguide_prev_icon.png deleted file mode 100644 index 1c15373af78cd4d21e16e619c9a89b46efb1bab0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 523 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H0wgodS2{2-FkbR>aSW-r_4W>9TWF$8+sDKm z$#+Cmf)?L&oSL#tKw#EPJthI&lq`0}ypqLFeLNm6vW>Br*YK}`G3mpe^L+d6m%pp# zJ0r98T2%I06k_-0h{98v$36P%4@v4*9G$^! z{0-l}u^%w4HEWo$k70t{ALfMF`xq|V`^VssU(YaQyFJ4q@%ao1egCJu-SZ=ap|VEQ zq3+uXhN52~43@Q84S(LQX880&t6`3vsDs~pE`{a(tP}RviaN-}vrf3YoGIZb^Sbn3 zH4NEtA12D{B(Uyy&=$=X)*zZ5bC%&1!zXSB_6heJtQu-Wft+Ly_6aOj4Rf5u51e_Z z8h>N+4Tdy6`HhLk=QRr{+~)wv$U2-`$fxi;fPF&o3g#1*R~VnjykaQgD`l{3N0nyb ze4r}9pm~tNgOkm{%YY%MiE)AuPs5Z1hAAxDkJ-FVdQ&MBb@05~k+S^xk5 diff --git a/textures/craftguide_search_icon.png b/textures/craftguide_search_icon.png index 3fb8a824ec5c5e72cccdb637cb6e6c5c3bb6b20f..aace8044ac235bcf5935ed8a72c4cb136746a916 100644 GIT binary patch literal 1908 zcmZ`)do;r*hEgWpDPBKS7mN|uQ4@RU{bU;RZBGG9cM4QZ&YGw2;badcT z8^0=@n`5_k4cg)jkHrR_ZUs6C)#;ru{p*MnFzSSy14BnK9k99qvx%(Q|Ku6*tVeE= z;j}fOm}70k#m=-1{B|WKep=e`sqE6mH$a&vhfe)BT5{~=GqH7W4FDtAPF6XfUJMg0 zG)SRiFgWX|#Hdo<6h%bjftQL_(g^a6TBkuGS!%-M3?v2!!-LD$RV3F+$;z#Y3Lq&# z_lXLz)euUtSfqnLL7jl2b-JcIw!dO0JQC!^>f882mU~^SkXzr`0xD$%3+f2q+OnxW z1#r9If&|iNnfe3`b*4|E043HiVCS~J?2$Nf98bhA$TsSxMtQ>bU0iB`d;--0U8=Ry zJ$(nF6is0}714=%paq!4^8&7*G-=qVnCc)Uq1GXZTEy1xasEqQke2{%ythu6(G*D6 zDF?-+D!Ue41yd=tX`8nuzFuMdv3v8p=sx4(#)k(VUp+7uXc=E9WXOjk_@2pQs9(A3 z%Fe+(gW#yEwq~Ezh<5oM;;RAsmL}jVtqyDg;3RO6+(ZS+wa!eGy%Xv)cY8sdSn&;K z=Ps^SBI2ddjn|*vyW-*bv2?_ZIuz7pOr~qbsWd5m^(%dw z+V538xQ3H(-4_xppDzC3sA8pkh`&sY6Nru)^Z(SD+qXv7TA(SYSIuP68ayyP+H0?< zaowVMuFU-jk-0cLhl6vgDyMeXaRacK-*^{WOw9U|9&j|Vd<#9+JeGf*Iy5>ye)R3f z!qwGPGPOQQ{6H;&(Wc;AI2huTl){mQQt=*;F&g!IJS<08ZLf>0u+ENg7s343c&1m7mb$YSA$oW=Ou(;WVMAGQ+9 zU{v(RH~IzT(6ZnE)c?h#57hs2bs8di1zc28QeyD_;W>7ZU(8N^yT}Ash708loHCa&7K!Wixy30l1~_H zt%s71ttI{vsu(~*IL^WdO-8p|;mo$+Ut=}jyoU52j>@^LpIy;y;Aknl_Rb!tje;t0 z4`ZQ&Pd~ODxH|QAh4G_8Ov>8b6FKrNMcniQ{aQW-sL+^9m+j?+iW)Y8u-@$4+ZyKqr5_OPwunRDLxq8ZX8<(~$=F88q9F&sb0`#Qm~!Ma?^gL*o;c9xJrXIg(l#>Bs<*5P z_Oorurv`1CY#wa(+`Gd3dpUO9?{|2zxdX|~OX;BN^lt;g?q=M*AyZzwcOF=an-aR$ zWvqD9Pja5@lpfUFh3giFZ@YlBpa8ns&|&HPv69cekehvTx1-3K!uJ{pthx&pQMU_X zz_OYBuTku;iCT@2eL`2sndtrXyaIV!7w1Pc;qV4`&`*DVI@)O3>nZp58l2 zh86Z3I>$`!bGRg_`o{BU|3AaXW{t-BrPl3lJI0##E>?4JbBElN!tO>W;jyUC9TP&C zcdY$f=J{hbR^H#JQa?PKHouPy0s)EE-W+MDc;Xz%zs`T$`R%Yt?QXQVAN^tty#4`5(6Lbv2~siR@4 z@`h)pegmd;G66wTd;1v6$`5#mabMDZA>){oRw~(J+i2oaY0;7FQaR<-xTRoy>!JU5 oz)Hy+PJ7*y{67!tO!d0_mw-1lpr~N2?{5lnuywWJ5y{E_0lF-AYXATM delta 1041 zcmV+s1n&Fv4x0#&8Gi%-003z>sXzb#1L8?UK~#9!?7@Km0001hp#7;AsR9510001( zJv)GGYm37GE>H$gHU$8ET53#zJ}?YGfEBvZvBZ_6)U#wJ9g&6rEAwNT{v@W-?kMMv!1wj&Cgh{>Oe>8|B&i9uxi1Kd(-@L ziyGQ~_+9+a*0AWgp>KX%S)$|0ZE>X|Q8sRf+kdUDE%m2Jwbi{gl+8a@ap;S?;)_ES zj}2M-Q>vO${eM8JscOnlY5sQabv)yU;gMKip|E`J^im2!Q zVW|8*+cnoHG;Ud|Q7~uM=Wrr8jMf(zR}bgDPj(djX~m))pF&@t9;rK2)((GtJ6^a; z%@=mUe}T5LC|90D8r=O|MR%=Rv>RwaDv5ASvZxa%|B*TUs66K=mBQjHDA-MltnuxG!zwY|cLJs*S(7cb5=n^e zne9LTmxGP34`>xE2ST{*SsVnsvM-C4l0lqP(tnc0zE^P&@Yb;`_7n#~K+&Eoj=hb8 zfW(1bhvgdfmuC2pCZhwvDfG5OC#M z7HbLvA)sJQ7T2zF0`e=6i(ozmb0d^n;d~j&*Wo-6$s@5m6wPDthx9P=)4%@qfS<;` z`+vs+ejMeyZGU;N&*S{Wf9;#G4FW+B19Kv3AfXf*AtE5477`lx0w{+RB$_~4LZ|3f zC*k)@2cF-*$X=u%s~{nyAgChKS72R|>MJm>$q8})D*-c#l4e&hp(<;spjnpoSJ1A@ z`zz33VhRS&p(Zo2SI`_yz3Nf#`j{(d%zx%?b*#ns3dHzuvi7S{Fgl%;0^{dU42-Ak zub>YKP=JE|bI28-00k)EIphlX5m11FYi+X?TogY~!L!b_k$^M>iXW*!@go%|eyDo_>l?}KT?6>M=DVKLLo=WvUMXQR$^}z9IGH$ nnQUwL?^*^A#~M4&UnHd$63?p8Z=#~h00000NkvXXu0mjfs_}P+ delta 138 zcmV;50CoSd0-FJl8Gi%-002sU^>Y9K0Afi*K~#9!Vi>XjP&*l501(4K@UQ!X{+~UL zGcIabqycKCktCH>3sxr_l!OuIQ{)l9S7*rc`c=Sl1{CmI0}6QT5(;>n14;mz3;_={ sT)X7ZrG5_Wr0ZSkw{`13fN!4%Z%zqKnX)(z00000NkvXXt^-0~f*Tez`v3p{ diff --git a/textures/craftguide_sign.png b/textures/craftguide_sign.png index 065aa3d2c764915de580b647fea7b554d139ef54..f64b5ab5a67db1501315eefd08a6dc32e685074a 100644 GIT binary patch delta 672 zcmV;R0$=^11FZ#+8Gi-<001BJ|6u?C00v@9M??Vs0RI60puMM)00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-&l9s~_3Y=0$Y0006yNklLLw`_<1XM&ttZf7>jD;wo zB*x9{?auA|vPflVUisiXUh%%<_T>{XO9kF07#~q0kR%FlWT}9t7#K&PGls@cbTWc- z486idhbnZ3bC+flwxBy#Pe;)&OSUQ%1uBS?yH`%e|DGQlI+rM|Gju9BFm;eLm9!#~ zI!Tn^TluU}&tgODitwV}IhJ1d`7=ygX(GL5$ml_|X63|r-qGU3a| z&&X7vqCfuUm~QoOfhx}Ycus`3Yu2c|G}gU2!2>mjsG z>6aygauq+Uc(FLg>i4faTbM<6I=oqWN;9ZhYJENlg$E& z;{5gbEwOO(!jULk61L33Xs<_d9nt@lCeN&NoSDb`e|NsA#fLM=pOPGIJjdxI$e^#A@Sr=+t94BoOj*Qq}0fy+Rm%j%ckAauz%;>y4K33+s>ij*0R{l zsp8kP(8!$A!Q-~!}a@E ztwgggEPy{ zzn$mxFB37_)D_*>xO_dkzxug&-Cip*Z1^J&e6FvM468R2vno5k&I`k$m91hoZ;2w3 wg`|zN7-#k(9m#F%WT~kZ8OSgz^@D5xeb!fwRxW`r01E&B07*qoM6N<$g5JT`z5oCK diff --git a/textures/craftguide_sign_inv.png b/textures/craftguide_sign_inv.png index 54fc85b6846f11fe605d4f03705b15ec487571a6..61372344bbb71a1af0164333415bb90d750bb609 100644 GIT binary patch delta 672 zcmV;R0$=@*1g!;-8Gi-<001BJ|6u?C00v@9M??Vs0RI60puMM)00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-&l9s~|4M^bjB0006yNkla65Q5k#DnU>S8~+0fLDWJJJ3$4-!cIbrA%Cbv0xF^+);59`#zGWP z665CfcHiy$Sc_DaX3BvXrudDxefb1wA_-1lLyMLXAvEAg6A7(mU_H4>8Cpx;Nr~Pw z3>x2hbZ$DFyEMyIbm!`6WWOlbs&p&SQ6}8IaPx;LFF) zs6?Y%iHr^%LPIz2(8iX%lanBF#<%CJuSv8{2*Ht>oIKAdiyurLn8H>y0ncc!hcqUk zUla_ARl>03#o`>R-@o!~VHVTr@Mh^L^`PY8y;~qhaDPohl4V%iP*ydvUs<9|80k%* zvMz^bPV?&d64Ns$Se}2t)S+o!EY5NG_%U8SS)i=esQ#=XqhmBTi2K*hFm%2>dg?42 z#X2es8QZawYEY782Im~6(_!P+H-gF->un>%z{|(;3~eK1zbH^>*4DqX^5Fx4$nT%u z2tE+oNPqMjNGVCjCQwT8{@q*Z!GN-=Q7YZ!z>7#XA7|hGaip}=71ZTAZn#185nF!6 z=|CCnl&gagH1{R0000@ooW literal 528 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMflK`I(*GV;jGa7@Z)`av{22ZRG zoKzD!qanPvB6xa3$XXzVVAVLa zK5TAFyX zd7$Bk=Uh3l`1;W~PjBzIdujdss~ayLnFDlorO{rXcNrW?g8V@KMh8F@2*7|~qO(9! z3?E!CX95kF?djqeQgJJ^w>i(nQNr!{np}7DHMb?6{%+rzd%HV-@?JaR{jH1(yypno zKQVM%V8WrgD1_sZZ-U_>c9(|eQ?d>9nF^`@jF!7RbCQ+TDL7lc?qs6!|EwU%h>Pkm zK5u%$5>H6bi!W#Z`&64|f-b$&iu8Q~H+cWLo^8M>pZc$Qu6ce~cd(HVZO#$y_ mD+qRRsk)e~6^uRVUdEvo7#e?NG5<`EKRsRjT-G@yGywp9R132J From 22787e41e36642b431bac40c95b61a87f1dd689e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 6 Sep 2019 18:09:54 +0200 Subject: [PATCH 102/188] Change sign texture --- init.lua | 14 +++++++------- textures/craftguide_sign.png | Bin 685 -> 894 bytes textures/craftguide_sign_inv.png | Bin 685 -> 0 bytes 3 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 textures/craftguide_sign_inv.png diff --git a/init.lua b/init.lua index 0d223f4..69b27a6 100644 --- a/init.lua +++ b/init.lua @@ -1,7 +1,5 @@ craftguide = {} -craftguide.background = "craftguide_bg_full.png" - local pdata = {} local core = core @@ -73,6 +71,8 @@ craftguide.group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } +craftguide.background = "craftguide_bg_full.png" + local function table_replace(t, val, new) for k, v in pairs(t) do if v == val then @@ -909,17 +909,17 @@ else description = S("Crafting Guide Sign"), drawtype = "nodebox", tiles = {"craftguide_sign.png"}, - inventory_image = "craftguide_sign_inv.png", - wield_image = "craftguide_sign_inv.png", + inventory_image = "craftguide_sign.png", + wield_image = "craftguide_sign.png", paramtype = "light", paramtype2 = "wallmounted", sunlight_propagates = true, groups = {oddly_breakable_by_hand = 1, flammable = 3}, node_box = { type = "wallmounted", - wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}, - wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, - wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375} + wall_top = {-0.5, 0.4375, -0.5, 0.5, 0.5, 0.5}, + wall_bottom = {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.5}, + wall_side = {-0.5, -0.5, -0.5, -0.4375, 0.5, 0.5} }, on_construct = function(pos) diff --git a/textures/craftguide_sign.png b/textures/craftguide_sign.png index f64b5ab5a67db1501315eefd08a6dc32e685074a..f691f661c55882c3492ed1560e13ac2bccacdbf3 100644 GIT binary patch delta 865 zcmV-n1D^b?1^xz*Dt`a~RRFWWT(uGa000SaNLh0L04^f{04^f|c%?sf00007bV*G` z2jd9_5D__Kh4x7R00Rq2L_t(I%RQ3KZW~nqM$f%>#xr-uaugY{bWrz3a=?EfsfeeCx2plz&3SB~2r47JXiH9;0;;K}GCKI6py7m*8Y2Cvw-v&VLGk2sE(3_g7I z6NXZ()_-bbR~gZKPHUw>vYYb#V2g(S6{GnH!|o$oU4+q7tg7G}>%r1O$#rPg>pbgp z$rc%wX>xqtMM;UFa)jJM#QT&yiB*o6ggN8a03fq0qw1Bo99;A6dJDT?vB-0zkepun zwC{jg>5=OmhL)hAUUiwpDM^wn8HBSLx05La(|_c0Frem@Y1V42R%=YhpEB$!2p+PC z?s5Hc4wVSI@HJ5sVT57GR&$MLzU*8n$x5Zl$e)mA8QOk=GA+;Mg z(RE$?{%cw*4T9Me+bnQ;aZbCwN~2OmSl^PRF~f^>pwA>Ua2gK?E`LEOh3xnHD5bcW zj9R(dT1P2`5P}o`jAxw=BtK$mO&t4htMQx!@^y;qHjd*U4i67=DJ8Sn3;@Sj_8vtM rwr!K=IfX)jBuNlLkf!PXtCZqDl?_~4)lZ3>00000NkvXXu0mjf7M_=s delta 655 zcmV;A0&xBQ2CW5y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2jKx81Pv){eQ{s$ITdqL`AG^1TBn(D550B&42Cf&h7lNNM&hW`QSZX z@xJ8tPnYA5kKZBnoh3seq^$7)PNqhQ?5IGJbSgP8b&xcbv?7u^NtEDQ`;Ql*M<{`_o_DWb zV;X~yDEhUbyMJvvE1y>Abw@}tjkgY!DZJkdTjh~5;mgO*$W)=CKm?2OzNK4qh#|6f zauSk)@$CicYXYTGytib!pePEe@&}U#rZ9Db$1&RLA+%2EmnDO86+f(au{g)-_pdx# zm_>IwyjglmGpKlY?-qy=Y}=CNImWb9b%W^Fh9FW#dVdqhyvyO4)4Y1V#PrMwmggTZ zb!eIwi*p=4evFq-7O3hq>OZT9U>Pkm$^C0*;?O#do;u4$xsLQh#&+za9#rJH##)Q+ zblCXy4KH)XdfV{9^YZaLL(?MqWr;+ww*H-!4s$y{Pp=Qv2gRkktkdew#>q4 puSas@;!ISD`tSKNjkGrK7ux1IBV3;%oB#j-00>D%PDHLkV1g2$D(wIO diff --git a/textures/craftguide_sign_inv.png b/textures/craftguide_sign_inv.png deleted file mode 100644 index 61372344bbb71a1af0164333415bb90d750bb609..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 685 zcmV;e0#f~nP)=-)$~AB+*Jl5G-ucSQ!w4*eNPOPzxLX0}DaaLJ&Ja1;xTn zLX07(MFJ|KBGxv77REvpQ4-_k_IBUx`&f%qmS)O<8K(G+xPAEqX(9hbs@A=VV zG9|PzDJD@Im^w(3C>q(4ctxuqH0~cSwgIUn-UZ&hevPdyQlaTrmhQIgtbAIb*BwEm zhTuFp)r7Dab~>Px;LFF)s6?Y%iHr^%LPIz2(8iX%lanBF#<%CJuSv8{2*Ht>oIKAd ziyurLn8H>y0ncc!hcqUkUla_ARl>03#o`>R-@o!~VHVTr@Mh^L^`PY8y;~qha7{y! zWmwx#RyDF;S)xoB=}n-rE{A7M^XmB$(=#Vno`1m9p=n+$&T;toFCC2``6AebiO@$>MR?@Iw}kq+p&{sP?BW^=NzWfVdK{~g31`{Z6n0M%g6H!Z6jpA zC{SqD*1xmz;RAul@1NfYJ`meT^czSiNyjEoO7Z^PTk64pvZ_%k-Q>WFNH-s6-~Mr= zwA2;U+@nODBrwr1nEWG@)t&XJ;aTRGiagzd%j9q8W;Hsgqk%d TEQ3u-00000NkvXXu0mjfIe;*O From bf616f5d21234022577411a6c49b69461f56e0a6 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sat, 7 Sep 2019 12:07:25 +0200 Subject: [PATCH 103/188] Add fallback background is not -dev version --- init.lua | 105 ++++++++++++++++++++++------------------ locale/craftguide.de.tr | 8 +-- locale/craftguide.fr.tr | 8 +-- locale/craftguide.ru.tr | 8 +-- locale/template | 8 +-- 5 files changed, 62 insertions(+), 75 deletions(-) diff --git a/init.lua b/init.lua index 69b27a6..20c29ff 100644 --- a/init.lua +++ b/init.lua @@ -48,7 +48,27 @@ local vec_add, vec_mul = vector.add, vector.multiply local ROWS = sfinv_only and 9 or 11 local LINES = 5 local IPP = ROWS * LINES -local GRID_LIMIT = 8 +local WH_LIMIT = 8 + +local XOFFSET = sfinv_only and 3.83 or 4.66 +local YOFFSET = sfinv_only and 6 or 6.6 + +local DEV_CORE = sub(core.get_version().string, -3) == "dev" + +craftguide.background = "craftguide_bg_full.png" + +local PNG = { + bg = "craftguide_bg.png", + bg_full = craftguide.background, + search = "craftguide_search_icon.png", + clear = "craftguide_clear_icon.png", + prev = "craftguide_next_icon.png^\\[transformFX", + next = "craftguide_next_icon.png", + arrow = "craftguide_arrow.png", + fire = "craftguide_fire.png", + book = "craftguide_book.png", + sign = "craftguide_sign.png", +} local FMT = { box = "box[%f,%f;%f,%f;%s]", @@ -71,8 +91,6 @@ craftguide.group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } -craftguide.background = "craftguide_bg_full.png" - local function table_replace(t, val, new) for k, v in pairs(t) do if v == val then @@ -385,7 +403,7 @@ local function groups_to_item(groups) return "" end -local function get_tooltip(item, groups, cooktime, burntime) +local function get_tooltip(item, burntime, groups, cooktime) local tooltip if groups then @@ -423,8 +441,6 @@ local function get_recipe_fs(data) local fs = {} local recipe = data.recipes[data.rnum] local width = recipe.width - local xoffset = sfinv_only and 3.83 or 4.66 - local yoffset = sfinv_only and 6 or 6.6 local cooktime, shapeless if recipe.type == "cooking" then @@ -443,22 +459,22 @@ local function get_recipe_fs(data) ESC(S("Recipe @1 of @2", data.rnum, #data.recipes)) fs[#fs + 1] = fmt(FMT.button, - xoffset + (sfinv_only and 1.98 or 2.7), - yoffset + (sfinv_only and 1.9 or 1.2), + XOFFSET + (sfinv_only and 1.98 or 2.7), + YOFFSET + (sfinv_only and 1.9 or 1.2), 2.2, 1, "alternate", btn_lab) - if width > GRID_LIMIT or rows > GRID_LIMIT then + if width > WH_LIMIT or rows > WH_LIMIT then fs[#fs + 1] = fmt(FMT.label, sfinv_only and 2 or 3, 7, - ESC(S("Recipe is too big to be displayed (@1x@2)", width, rows))) + ESC(S("Recipe's too big to be displayed (@1x@2)", width, rows))) return concat(fs) end for i = 1, width * rows do local item = recipe.items[i] or "" - local X = ceil((i - 1) % width - width) + xoffset - local Y = ceil(i / width) + yoffset - min(2, rows) + local X = ceil((i - 1) % width - width) + XOFFSET + local Y = ceil(i / width) + YOFFSET - min(2, rows) if width > 3 or rows > 3 then local xof = 1 - 4 / width @@ -469,10 +485,10 @@ local function get_recipe_fs(data) (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows s_btn_size = btn_size - X = (btn_size * ((i - 1) % width) + xoffset - - (sfinv_only and 2.83 or (xoffset - 2))) * (0.83 - (x_y / 5)) + X = (btn_size * ((i - 1) % width) + XOFFSET - + (sfinv_only and 2.83 or (XOFFSET - 2))) * (0.83 - (x_y / 5)) Y = (btn_size * floor((i - 1) / width) + - (5 + ((sfinv_only and 0.81 or 1.5) + x_y))) * (0.86 - (x_y / 5)) + (sfinv_only and 5.81 or 6.5) + x_y) * (0.86 - (x_y / 5)) end if X > rightest then @@ -495,7 +511,7 @@ local function get_recipe_fs(data) local burntime = fuel_cache[item] if groups or cooktime or burntime then - fs[#fs + 1] = get_tooltip(item, groups, cooktime, burntime) + fs[#fs + 1] = get_tooltip(item, burntime, groups, cooktime) end end @@ -509,7 +525,7 @@ local function get_recipe_fs(data) icon = fmt("craftguide_%s.png^[resize:16x16", icon) end - local pos_y = yoffset + (sfinv_only and 0.25 or -0.45) + local pos_y = YOFFSET + (sfinv_only and 0.25 or -0.45) fs[#fs + 1] = fmt(FMT.image, min(3.9, rightest) + 1.2, pos_y, 0.5, 0.5, icon) @@ -525,31 +541,31 @@ local function get_recipe_fs(data) local output_X = arrow_X + 0.9 fs[#fs + 1] = fmt(FMT.image, - arrow_X, yoffset + (sfinv_only and 0.9 or 0.2), - 0.9, 0.7, "craftguide_arrow.png") + arrow_X, YOFFSET + (sfinv_only and 0.9 or 0.2), + 0.9, 0.7, PNG.arrow) if recipe.type == "fuel" then fs[#fs + 1] = fmt(FMT.image, - output_X, yoffset + (sfinv_only and 0.7 or 0), - 1.1, 1.1, "craftguide_fire.png") + output_X, YOFFSET + (sfinv_only and 0.7 or 0), + 1.1, 1.1, PNG.fire) else local output_name = match(recipe.output, "%S+") local burntime = fuel_cache[output_name] fs[#fs + 1] = fmt(FMT.item_image_button, - output_X, yoffset + (sfinv_only and 0.7 or 0), + output_X, YOFFSET + (sfinv_only and 0.7 or 0), 1.1, 1.1, recipe.output, ESC(output_name), "") if burntime then - fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime) + fs[#fs + 1] = get_tooltip(output_name, burntime) fs[#fs + 1] = fmt(FMT.image, - output_X + 1, yoffset + (sfinv_only and 0.7 or 0.1), - 0.6, 0.4, "craftguide_arrow.png") + output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1), + 0.6, 0.4, PNG.arrow) fs[#fs + 1] = fmt(FMT.image, - output_X + 1.6, yoffset + (sfinv_only and 0.55 or 0), - 0.6, 0.6, "craftguide_fire.png") + output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0), + 0.6, 0.6, PNG.fire) end end @@ -567,9 +583,9 @@ local function make_formspec(name) size[%f,%f;] no_prepend[] bgcolor[#00000000;false] - background[1,1;1,1;%s;true;10] + background[1,1;1,1;%s;true%s] ]], - 9.5, 8.4, craftguide.background) + 9.5, 8.4, PNG.bg_full, DEV_CORE and ";10" or "") end fs[#fs + 1] = fmt([[ @@ -578,29 +594,23 @@ local function make_formspec(name) ]], sfinv_only and 2.76 or 2.72, ESC(data.filter)) - local search_icon = "craftguide_search_icon.png" - local clear_icon = "craftguide_clear_icon.png" - fs[#fs + 1] = fmt([[ image_button[%f,-0.05;0.85,0.85;%s;search;;;false;%s^\[colorize:yellow:255] image_button[%f,-0.05;0.85,0.85;%s;clear;;;false;%s^\[colorize:red:255] ]], - sfinv_only and 2.6 or 2.54, search_icon, search_icon, - sfinv_only and 3.3 or 3.25, clear_icon, clear_icon) + sfinv_only and 2.6 or 2.54, PNG.search, PNG.search, + sfinv_only and 3.3 or 3.25, PNG.clear, PNG.clear) fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", sfinv_only and 6.35 or 7.85, 0.06, colorize("yellow", data.pagenum), data.pagemax) - local prev_icon = "craftguide_next_icon.png^\\[transformFX" - local next_icon = "craftguide_next_icon.png" - fs[#fs + 1] = fmt([[ image_button[%f,-0.05;0.8,0.8;%s;prev;;;false;%s^\[colorize:yellow:255] image_button[%f,-0.05;0.8,0.8;%s;next;;;false;%s^\[colorize:yellow:255] ]], - sfinv_only and 5.45 or 6.83, prev_icon, prev_icon, - sfinv_only and 7.2 or 8.75, next_icon, next_icon) + sfinv_only and 5.45 or 6.83, PNG.prev, PNG.prev, + sfinv_only and 7.2 or 8.75, PNG.next, PNG.next) if #data.items == 0 then local no_item = S("No item to show") @@ -615,6 +625,7 @@ local function make_formspec(name) end local first_item = (data.pagenum - 1) * IPP + for i = first_item, first_item + IPP - 1 do local item = data.items[i + 1] if not item then break end @@ -896,8 +907,8 @@ else core.register_craftitem("craftguide:book", { description = S("Crafting Guide"), - inventory_image = "craftguide_book.png", - wield_image = "craftguide_book.png", + inventory_image = PNG.book, + wield_image = PNG.book, stack_max = 1, groups = {book = 1}, on_use = function(itemstack, user) @@ -908,9 +919,9 @@ else core.register_node("craftguide:sign", { description = S("Crafting Guide Sign"), drawtype = "nodebox", - tiles = {"craftguide_sign.png"}, - inventory_image = "craftguide_sign.png", - wield_image = "craftguide_sign.png", + tiles = {PNG.sign}, + inventory_image = PNG.sign, + wield_image = PNG.sign, paramtype = "light", paramtype2 = "wallmounted", sunlight_propagates = true, @@ -962,7 +973,7 @@ else sfinv_buttons.register_button("craftguide", { title = S("Crafting Guide"), tooltip = S("Shows a list of available crafting recipes, cooking recipes and fuels"), - image = "craftguide_book.png", + image = PNG.book, action = function(player) on_use(player) end, @@ -1197,7 +1208,7 @@ if progressive_mode then position = {x = 0.78, y = 1}, alignment = {x = 1, y = 1}, scale = {x = 370, y = 112}, - text = "craftguide_bg.png", + text = PNG.bg, }), book = player:hud_add({ @@ -1205,7 +1216,7 @@ if progressive_mode then position = {x = 0.79, y = 1.02}, alignment = {x = 1, y = 1}, scale = {x = 4, y = 4}, - text = "craftguide_book.png", + text = PNG.book, }), text = player:hud_add({ diff --git a/locale/craftguide.de.tr b/locale/craftguide.de.tr index 57e154f..807012e 100644 --- a/locale/craftguide.de.tr +++ b/locale/craftguide.de.tr @@ -3,20 +3,14 @@ Craft Guide=Rezeptbuch Crafting Guide=Rezeptbuch Crafting Guide Sign=Rezepttafel -Search=Suche -Reset=Zurücksetzen -Previous page=Vorherige Seite -Next page=Nächste Seite Usage @1 of @2=Verwendung @1 von @2 Recipe @1 of @2=Rezept @1 von @2 Burning time: @1=Brennzeit: @1 Cooking time: @1=Kochzeit: @1 Any item belonging to the group(s): @1=Beliebiger Gegenstand aus Gruppe(n): @1 -Recipe is too big to be displayed (@1x@2)=Rezept ist zu groß für die Anzeige (@1×@2) +Recipe's too big to be displayed (@1x@2)=Rezept ist zu groß für die Anzeige (@1×@2) Shapeless=Formlos Cooking=Kochen -Increase window size=Fenster vergrößern -Decrease window size=Fenster verkleinern No item to show=Nichts anzuzeigen Collect items to reveal more recipes=Gegenstände aufsammeln, um mehr Rezepte aufzudecken Show recipe(s) of the pointed node=Rezept(e) des gezeigten Blocks anzeigen diff --git a/locale/craftguide.fr.tr b/locale/craftguide.fr.tr index b09a1b0..76d1304 100644 --- a/locale/craftguide.fr.tr +++ b/locale/craftguide.fr.tr @@ -2,20 +2,14 @@ Craft Guide=Guide de recettes Crafting Guide=Guide de recettes -Search=Rechercher -Reset=Réinitialiser -Previous page=Page précédente -Next page=Page suivante Usage @1 of @2=Usage @1 de @2 Recipe @1 of @2=Recette @1 de @2 Burning time: @1=Temps de combustion : @1 Cooking time: @1=Temps de cuisson : @1 Any item belonging to the group(s): @1=Tout item appartenant au(x) groupe(s) : @1 -Recipe is too big to be displayed (@1x@2)=La recette est trop grande pour être affichée (@1x@2) +Recipe's too big to be displayed (@1x@2)=La recette est trop grande pour être affichée (@1x@2) Shapeless=Sans forme Cooking=Cuisson -Increase window size=Agrandir la fenêtre -Decrease window size=Réduire la fenêtre No item to show=Aucun item à afficher Collect items to reveal more recipes=Collecte des items pour révéler plus de recettes Show recipe(s) of the pointed node=Affiche les recettes du bloc visé diff --git a/locale/craftguide.ru.tr b/locale/craftguide.ru.tr index 2d4dfa2..fb023e1 100644 --- a/locale/craftguide.ru.tr +++ b/locale/craftguide.ru.tr @@ -3,20 +3,14 @@ Craft Guide=книга рецептов крафта Crafting Guide=книга рецептов крафта Crafting Guide Sign=Знак с книгой рецептов -Search=Поиск -Reset=Сброс -Previous page=Предыдущая страница -Next page=Следущая страница Usage @1 of @2=использование @1 из @2 Recipe @1 of @2=Рецепт @1 из @2 Burning time: @1=Время горения: @1 Cooking time: @1=Время преготовления: @1 Any item belonging to the group(s): @1=Любой элемент из группы: @1 -Recipe is too big to be displayed (@1x@2)=Рецепт слишком большой для показа (@1x@2) +Recipe's too big to be displayed (@1x@2)=Рецепт слишком большой для показа (@1x@2) Shapeless=Бесформенный Cooking=Приготовление -Increase window size=Увеличить окно -Decrease window size=Уменьшить окно No item to show=Нет элемента для показа Collect items to reveal more recipes=Собирайте предметы, чтобы раскрыть больше рецептов Show recipe(s) of the pointed node=Показать рецепт(ы) выбранной ноды diff --git a/locale/template b/locale/template index d051c27..b6a6f29 100644 --- a/locale/template +++ b/locale/template @@ -3,20 +3,14 @@ Craft Guide= Crafting Guide= Crafting Guide Sign= -Search= -Reset= -Previous page= -Next page= Usage @1 of @2= Recipe @1 of @2= Burning time: @1= Cooking time: @1= Any item belonging to the group(s): @1= -Recipe is too big to be displayed (@1x@2)= +Recipe's too big to be displayed (@1x@2)= Shapeless= Cooking= -Increase window size= -Decrease window size= No item to show= Collect items to reveal more recipes= Show recipe(s) of the pointed node= From 742627aa8c8a22ffa4bd8b562e7ab5bcb8f978d8 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 8 Sep 2019 12:22:24 +0200 Subject: [PATCH 104/188] Add more doc to custom recipes --- API.md | 3 +++ init.lua | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/API.md b/API.md index b6e5073..e7fe6ea 100644 --- a/API.md +++ b/API.md @@ -2,6 +2,9 @@ ### Custom recipes +Custom recipes are nonconventional crafts outside the main crafting grid. +They can be registered in-game dynamically and have a size beyond 3x3 items. + #### Registering a custom crafting type (example) ```Lua diff --git a/init.lua b/init.lua index 20c29ff..8b296b8 100644 --- a/init.lua +++ b/init.lua @@ -59,7 +59,6 @@ craftguide.background = "craftguide_bg_full.png" local PNG = { bg = "craftguide_bg.png", - bg_full = craftguide.background, search = "craftguide_search_icon.png", clear = "craftguide_clear_icon.png", prev = "craftguide_next_icon.png^\\[transformFX", @@ -580,12 +579,12 @@ local function make_formspec(name) if not sfinv_only then fs[#fs + 1] = fmt([[ - size[%f,%f;] + size[9.5,8.4] no_prepend[] bgcolor[#00000000;false] background[1,1;1,1;%s;true%s] ]], - 9.5, 8.4, PNG.bg_full, DEV_CORE and ";10" or "") + craftguide.background, DEV_CORE and ";10" or "") end fs[#fs + 1] = fmt([[ From b8c79d17651f0cab919de550ec7d1d2b5a270d43 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 8 Sep 2019 12:31:45 +0200 Subject: [PATCH 105/188] Change sign texture again --- textures/craftguide_sign.png | Bin 894 -> 2380 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/textures/craftguide_sign.png b/textures/craftguide_sign.png index f691f661c55882c3492ed1560e13ac2bccacdbf3..2d1c4aaeea1e4b260d5f5e99c6185796463ca1b7 100644 GIT binary patch literal 2380 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 From b026e94d6e50edcfc4f062f00dfc2ba1dbe5bc4c Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 8 Sep 2019 12:47:27 +0200 Subject: [PATCH 106/188] Fix custom recipe icon position --- init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index 8b296b8..70a2170 100644 --- a/init.lua +++ b/init.lua @@ -524,16 +524,16 @@ local function get_recipe_fs(data) icon = fmt("craftguide_%s.png^[resize:16x16", icon) end + local pos_x = rightest + btn_size + 0.1 local pos_y = YOFFSET + (sfinv_only and 0.25 or -0.45) - fs[#fs + 1] = fmt(FMT.image, - min(3.9, rightest) + 1.2, pos_y, 0.5, 0.5, icon) + fs[#fs + 1] = fmt(FMT.image, pos_x, pos_y, 0.5, 0.5, icon) local tooltip = custom_recipe and custom_recipe.description or shapeless and S("Shapeless") or S("Cooking") fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", - rightest + 1.2, pos_y, 0.5, 0.5, ESC(tooltip)) + pos_x, pos_y, 0.5, 0.5, ESC(tooltip)) end local arrow_X = rightest + (s_btn_size or 1.1) From 727758b816317c6bff9402e8f3e313b41488c3bf Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 9 Sep 2019 18:27:02 +0200 Subject: [PATCH 107/188] craftguide can read replacements! --- .luacheckrc | 6 +- init.lua | 352 ++++++++++++++++++++++++---------------- locale/craftguide.fr.tr | 1 + locale/template | 1 + 4 files changed, 220 insertions(+), 140 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 3b6cf93..8ecfd80 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -2,7 +2,6 @@ unused_args = false allow_defined_top = true read_globals = { - "core", "minetest", "default", "sfinv", @@ -11,3 +10,8 @@ read_globals = { "string", "table", } + +globals = { + "craftguide", + "core", +} diff --git a/init.lua b/init.lua index 70a2170..8a8e8e9 100644 --- a/init.lua +++ b/init.lua @@ -1,9 +1,7 @@ craftguide = {} -local pdata = {} -local core = core - -- Caches +local pdata = {} local init_items = {} local searches = {} local recipes_cache = {} @@ -20,11 +18,9 @@ local reg_items = core.registered_items local show_formspec = core.show_formspec local globalstep = core.register_globalstep local on_shutdown = core.register_on_shutdown -local get_craft_result = core.get_craft_result local get_players = core.get_connected_players local on_joinplayer = core.register_on_joinplayer local register_command = core.register_chatcommand -local get_all_recipes = core.get_all_craft_recipes local get_player_by_name = core.get_player_by_name local on_mods_loaded = core.register_on_mods_loaded local on_leaveplayer = core.register_on_leaveplayer @@ -90,6 +86,26 @@ craftguide.group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } +local function table_merge(t1, t2, hash) + t1 = t1 or {} + t2 = t2 or {} + + if hash then + for k, v in pairs(t2) do + t1[k] = v + end + else + local c = #t1 + + for i = 1, #t2 do + c = c + 1 + t1[c] = t2[i] + end + end + + return t1 +end + local function table_replace(t, val, new) for k, v in pairs(t) do if v == val then @@ -132,6 +148,18 @@ function craftguide.register_craft_type(name, def) craft_types[name] = def end +local function get_width(recipe) + if is_table(recipe) then + sort(recipe, function(a, b) + return #a > #b + end) + + return #recipe[1] + end + + return 0 +end + function craftguide.register_craft(def) if not is_table(def) or not next(def) then return log("error", "craftguide.register_craft(): craft definition missing") @@ -159,11 +187,7 @@ function craftguide.register_craft(def) end local cp = copy(def.grid) - sort(cp, function(a, b) - return #a > #b - end) - - def.width = #cp[1] + def.width = get_width(cp) for i = 1, #def.grid do while #def.grid[i] < def.width do @@ -253,7 +277,8 @@ local function item_in_recipe(item, recipe) end local function groups_item_in_recipe(item, recipe) - local item_groups = reg_items[item].groups + local def = reg_items[item] + local item_groups = def.groups for _, recipe_item in pairs(recipe.items) do if sub(recipe_item, 1,6) == "group:" then @@ -267,32 +292,6 @@ local function groups_item_in_recipe(item, recipe) end end -local function get_usages(item) - local usages, c = {}, 0 - - for _, recipes in pairs(recipes_cache) do - for i = 1, #recipes do - local recipe = recipes[i] - if item_in_recipe(item, recipe) then - c = c + 1 - usages[c] = recipe - else - recipe = groups_item_in_recipe(item, recipe) - if recipe then - c = c + 1 - usages[c] = recipe - end - end - end - end - - if fuel_cache[item] then - usages[#usages + 1] = {type = "fuel", width = 1, items = {item}} - end - - return usages -end - local function get_filtered_items(player, data) local items, c = {}, 0 local known = 0 @@ -322,25 +321,41 @@ local function get_filtered_items(player, data) end end -local function cache_recipes(output) - local recipes = get_all_recipes(output) or {} - local num = #recipes +local function get_usages(item) + local usages, c = {}, 0 - if num > 0 then - if recipes_cache[output] then - for i = 1, num do - insert(recipes_cache[output], 1, recipes[i]) - end + for _, recipes in pairs(recipes_cache) do + for i = 1, #recipes do + local recipe = recipes[i] + if item_in_recipe(item, recipe) then + c = c + 1 + usages[c] = recipe else - recipes_cache[output] = recipes + recipe = groups_item_in_recipe(item, recipe) + if recipe then + c = c + 1 + usages[c] = recipe + end end end + end + + if fuel_cache[item] then + usages[#usages + 1] = { + type = "fuel", + width = 1, + items = {item}, + replacements = fuel_cache[item].replacements, + } + end + + return usages end local function cache_usages(item) local usages = get_usages(item) if #usages > 0 then - usages_cache[item] = usages + usages_cache[item] = table_merge(usages, usages_cache[item] or {}) end end @@ -367,20 +382,8 @@ local function get_recipes(item, data, player) return recipes end -local function get_burntime(item) - return get_craft_result({method = "fuel", width = 1, items = {item}}).time -end - -local function cache_fuel(item) - local burntime = get_burntime(item) - if burntime > 0 then - fuel_cache[item] = burntime - return true - end -end - -local function groups_to_item(groups) - if #groups == 1 then +local function groups_to_items(groups, get_all) + if not get_all and #groups == 1 then local group = groups[1] local def_gr = "default:" .. group local stereotypes = craftguide.group_stereotypes @@ -393,16 +396,17 @@ local function groups_to_item(groups) end end + local names = {} for name, def in pairs(reg_items) do if item_has_groups(def.groups, groups) then - return name + names[#names + 1] = name end end - return "" + return #names > 0 and concat(names, ",") or "" end -local function get_tooltip(item, burntime, groups, cooktime) +local function get_tooltip(item, burntime, groups, cooktime, replace) local tooltip if groups then @@ -433,6 +437,12 @@ local function get_tooltip(item, burntime, groups, cooktime) S("Burning time: @1", colorize("yellow", burntime)) end + if replace then + local def = reg_items[replace] + tooltip = tooltip .. "\n" .. + S("Replaced by: @1", colorize("yellow", def.description)) + end + return fmt("tooltip[%s;%s]", item, ESC(tooltip)) end @@ -440,6 +450,7 @@ local function get_recipe_fs(data) local fs = {} local recipe = data.recipes[data.rnum] local width = recipe.width + local replacements = recipe.replacements local cooktime, shapeless if recipe.type == "cooking" then @@ -498,19 +509,30 @@ local function get_recipe_fs(data) if sub(item, 1,6) == "group:" then groups = extract_groups(item) - item = groups_to_item(groups) + item = groups_to_items(groups) end local label = groups and "\nG" or "" + local replace + + if replacements then + for j = 1, #replacements do + local replacement = replacements[j] + if replacement[1] == item then + label = (label ~= "" and "\n" or "") .. label .. "\nR" + replace = replacement[2] + end + end + end fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), btn_size, btn_size, item, match(item, "%S*"), ESC(label)) - local burntime = fuel_cache[item] + local burntime = fuel_cache[item] and fuel_cache[item].burntime if groups or cooktime or burntime then - fs[#fs + 1] = get_tooltip(item, burntime, groups, cooktime) + fs[#fs + 1] = get_tooltip(item, burntime, groups, cooktime, replace) end end @@ -549,7 +571,7 @@ local function get_recipe_fs(data) 1.1, 1.1, PNG.fire) else local output_name = match(recipe.output, "%S+") - local burntime = fuel_cache[output_name] + local burntime = fuel_cache[output_name] and fuel_cache[output_name].burntime fs[#fs + 1] = fmt(FMT.item_image_button, output_X, YOFFSET + (sfinv_only and 0.7 or 0), @@ -745,40 +767,113 @@ local function reset_data(data) data.items = data.items_raw end -local function check_item(def) +-- Because `core.get_craft_recipe` and `core.get_all_craft_recipes` do not return the replacements, +-- we have to override `core.register_craft` and `core.register_alias` and do some reverse engineering. +-- See engine's issue #4901. + +local old_register_alias = core.register_alias +local current_alias = {} + +core.register_alias = function(old, new) + current_alias = {old, new} + old_register_alias(old, new) +end + +local old_register_craft = core.register_craft + +core.register_craft = function(recipe) + old_register_craft(recipe) + + local output = recipe.output or (is_str(recipe.recipe) and recipe.recipe or "") + if output == "" then return end + output = output:match(match(output, "%S*")) + local groups + + if sub(output, 1,6) == "group:" then + groups = extract_groups(output) + output = groups_to_items(groups, true) + end + + output = split(output, ",") + + for i = 1, #output do + local item = output[i] + if item == current_alias[1] then + item = current_alias[2] + end + + local rcp = copy(recipe) + rcp.items = {} + + if rcp.type == "fuel" then + fuel_cache[item] = rcp + + elseif rcp.type == "cooking" then + rcp.width = rcp.cooktime + rcp.cooktime = nil + rcp.items[1] = rcp.recipe + + elseif rcp.type == "shapeless" then + rcp.width = 0 + for j = 1, #rcp.recipe do + rcp.items[#rcp.items + 1] = rcp.recipe[j] + end + else + rcp.width = get_width(rcp.recipe) + local c = 1 + + for j = 1, #rcp.recipe do + if rcp.recipe[j] then + for h = 1, rcp.width do + local it = rcp.recipe[j][h] + + if it and it ~= "" then + rcp.items[c] = it + end + + c = c + 1 + end + end + end + end + + if rcp.type ~= "fuel" then + rcp.recipe = nil + recipes_cache[item] = recipes_cache[item] or {} + insert(recipes_cache[item], 1, rcp) + end + end +end + +local function show_item(def) return not (def.groups.not_in_craft_guide == 1 or def.groups.not_in_creative_inventory == 1) and def.description and def.description ~= "" end local function get_init_items() - local items, c = {}, 0 - + local c = 1 for name, def in pairs(reg_items) do - if check_item(def) then - cache_fuel(name) - cache_recipes(name) + if show_item(def) then + cache_usages(name) - c = c + 1 - items[c] = name - end - end - - c = 0 - - for i = 1, #items do - local name = items[i] - cache_usages(name) - - if recipes_cache[name] or usages_cache[name] then - c = c + 1 - init_items[c] = name + if recipes_cache[name] or usages_cache[name] then + init_items[c] = name + c = c + 1 + end end end sort(init_items) end +on_mods_loaded(get_init_items) + +on_joinplayer(function(player) + local name = player:get_player_name() + init_data(name) +end) + local function _fields(player, fields) local name = player:get_player_name() local data = pdata[name] @@ -853,13 +948,6 @@ local function _fields(player, fields) end end -on_mods_loaded(get_init_items) - -on_joinplayer(function(player) - local name = player:get_player_name() - init_data(name) -end) - if sfinv_only then sfinv.register_page("craftguide:craftguide", { title = S("Craft Guide"), @@ -944,9 +1032,8 @@ else core.register_craft({ output = "craftguide:book", - recipe = { - {"default:book"} - } + type = "shapeless", + recipe = {"default:book"} }) core.register_craft({ @@ -957,9 +1044,8 @@ else core.register_craft({ output = "craftguide:sign", - recipe = { - {"default:sign_wall_wood"} - } + type = "shapeless", + recipe = {"default:sign_wall_wood"} }) core.register_craft({ @@ -984,6 +1070,32 @@ if progressive_mode then local PLAYERS = {} local POLL_FREQ = 0.25 + local function table_diff(t1, t2) + local hash = {} + + for i = 1, #t1 do + local v = t1[i] + hash[v] = true + end + + for i = 1, #t2 do + local v = t2[i] + hash[v] = nil + end + + local diff, c = {}, 0 + + for i = 1, #t1 do + local v = t1[i] + if hash[v] then + c = c + 1 + diff[c] = v + end + end + + return diff + end + local function item_in_inv(item, inv_items) local inv_items_size = #inv_items @@ -1045,44 +1157,6 @@ if progressive_mode then "craftpreview", } - local function table_merge(t, t2) - t, t2 = t or {}, t2 or {} - local c = #t - - for i = 1, #t2 do - c = c + 1 - t[c] = t2[i] - end - - return t - end - - local function table_diff(t, t2) - local hash = {} - - for i = 1, #t do - local v = t[i] - hash[v] = true - end - - for i = 1, #t2 do - local v = t2[i] - hash[v] = nil - end - - local diff, c = {}, 0 - - for i = 1, #t do - local v = t[i] - if hash[v] then - c = c + 1 - diff[c] = v - end - end - - return diff - end - local function get_inv_items(player) local inv = player:get_inventory() local stacks = {} diff --git a/locale/craftguide.fr.tr b/locale/craftguide.fr.tr index 76d1304..00d502b 100644 --- a/locale/craftguide.fr.tr +++ b/locale/craftguide.fr.tr @@ -6,6 +6,7 @@ Usage @1 of @2=Usage @1 de @2 Recipe @1 of @2=Recette @1 de @2 Burning time: @1=Temps de combustion : @1 Cooking time: @1=Temps de cuisson : @1 +Replaced by: @1=Remplacé par : @1 Any item belonging to the group(s): @1=Tout item appartenant au(x) groupe(s) : @1 Recipe's too big to be displayed (@1x@2)=La recette est trop grande pour être affichée (@1x@2) Shapeless=Sans forme diff --git a/locale/template b/locale/template index b6a6f29..23b690e 100644 --- a/locale/template +++ b/locale/template @@ -7,6 +7,7 @@ Usage @1 of @2= Recipe @1 of @2= Burning time: @1= Cooking time: @1= +Replaced by: @1= Any item belonging to the group(s): @1= Recipe's too big to be displayed (@1x@2)= Shapeless= From 08e758aca5616e0ed951c5c7900595adf23fa44b Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 9 Sep 2019 19:02:09 +0200 Subject: [PATCH 108/188] Fix shapeless width bounds --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 8a8e8e9..7e7105e 100644 --- a/init.lua +++ b/init.lua @@ -458,7 +458,7 @@ local function get_recipe_fs(data) elseif width == 0 then shapeless = true local n = #recipe.items - width = n <= 4 and 2 or min(3, n) + width = (n < 5 and n > 1) and 2 or min(3, max(1, n)) end local rows = ceil(maxn(recipe.items) / width) From 11da33ca76675355d785b356f6d3a0b679fbfa0e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 9 Sep 2019 19:06:35 +0200 Subject: [PATCH 109/188] Add comment --- init.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index 7e7105e..9487b2a 100644 --- a/init.lua +++ b/init.lua @@ -767,7 +767,7 @@ local function reset_data(data) data.items = data.items_raw end --- Because `core.get_craft_recipe` and `core.get_all_craft_recipes` do not return the replacements, +-- As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not return the replacements, -- we have to override `core.register_craft` and `core.register_alias` and do some reverse engineering. -- See engine's issue #4901. @@ -1183,6 +1183,9 @@ if progressive_mode then end local function show_hud_success(player, data, dtime) + -- It'd better to have an engine function `hud_move` to do not + -- depend on the server dtime, and use the client dtime internally instead. + local hud_info_bg = player:hud_get(data.hud.bg) if hud_info_bg.position.y <= 0.9 then @@ -1222,8 +1225,8 @@ if progressive_mode then end end - -- Workaround. Need an engine call to detect when the contents - -- of the player inventory changed, instead + -- Workaround. Need an engine call to detect when the contents of + -- the player inventory changed, instead. local function poll_new_items() for i = 1, #PLAYERS do local player = PLAYERS[i] From 12e35f80f0e3db17505d62af64ea1f895cedb23c Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 9 Sep 2019 19:29:36 +0200 Subject: [PATCH 110/188] Fix replace tooltip --- init.lua | 16 ++++++++++------ locale/craftguide.fr.tr | 2 +- locale/template | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/init.lua b/init.lua index 9487b2a..9d28a31 100644 --- a/init.lua +++ b/init.lua @@ -406,6 +406,12 @@ local function groups_to_items(groups, get_all) return #names > 0 and concat(names, ",") or "" end +local function get_description(item, def) + return def and def.description or + (def and match(item, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or + S("Unknown Item (@1)", item)) +end + local function get_tooltip(item, burntime, groups, cooktime, replace) local tooltip @@ -421,10 +427,7 @@ local function get_tooltip(item, burntime, groups, cooktime, replace) tooltip = S("Any item belonging to the group(s): @1", groupstr) else local def = reg_items[item] - - tooltip = def and def.description or - (def and match(item, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or - S("Unknown Item (@1)", item)) + tooltip = get_description(item, def) end if cooktime then @@ -440,7 +443,8 @@ local function get_tooltip(item, burntime, groups, cooktime, replace) if replace then local def = reg_items[replace] tooltip = tooltip .. "\n" .. - S("Replaced by: @1", colorize("yellow", def.description)) + S("Replaced by @1 on crafting", + colorize("yellow", get_description(replace, def))) end return fmt("tooltip[%s;%s]", item, ESC(tooltip)) @@ -531,7 +535,7 @@ local function get_recipe_fs(data) local burntime = fuel_cache[item] and fuel_cache[item].burntime - if groups or cooktime or burntime then + if groups or cooktime or burntime or replace then fs[#fs + 1] = get_tooltip(item, burntime, groups, cooktime, replace) end end diff --git a/locale/craftguide.fr.tr b/locale/craftguide.fr.tr index 00d502b..9aedeaf 100644 --- a/locale/craftguide.fr.tr +++ b/locale/craftguide.fr.tr @@ -6,7 +6,7 @@ Usage @1 of @2=Usage @1 de @2 Recipe @1 of @2=Recette @1 de @2 Burning time: @1=Temps de combustion : @1 Cooking time: @1=Temps de cuisson : @1 -Replaced by: @1=Remplacé par : @1 +Replaced by @1 on crafting=Remplacé par @1 lors de la fabrication Any item belonging to the group(s): @1=Tout item appartenant au(x) groupe(s) : @1 Recipe's too big to be displayed (@1x@2)=La recette est trop grande pour être affichée (@1x@2) Shapeless=Sans forme diff --git a/locale/template b/locale/template index 23b690e..514d129 100644 --- a/locale/template +++ b/locale/template @@ -7,7 +7,7 @@ Usage @1 of @2= Recipe @1 of @2= Burning time: @1= Cooking time: @1= -Replaced by: @1= +Replaced by @1 on crafting= Any item belonging to the group(s): @1= Recipe's too big to be displayed (@1x@2)= Shapeless= From 19b8e28afbf3a32bcbd50b29f943de94f02a0e59 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 9 Sep 2019 21:55:51 +0200 Subject: [PATCH 111/188] Code cleaning --- init.lua | 67 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/init.lua b/init.lua index 9d28a31..8a4590a 100644 --- a/init.lua +++ b/init.lua @@ -130,6 +130,10 @@ local function is_func(x) return type(x) == "function" end +local function is_group(item) + return sub(item, 1, 6) == "group:" +end + local craft_types = {} function craftguide.register_craft_type(name, def) @@ -281,7 +285,7 @@ local function groups_item_in_recipe(item, recipe) local item_groups = def.groups for _, recipe_item in pairs(recipe.items) do - if sub(recipe_item, 1,6) == "group:" then + if is_group(recipe_item) then local groups = extract_groups(recipe_item) if item_has_groups(item_groups, groups) then local usage = copy(recipe) @@ -368,6 +372,7 @@ local function get_recipes(item, data, player) end local no_recipes = not recipes or #recipes == 0 + if no_recipes and not usages then return elseif usages and no_recipes then @@ -511,7 +516,7 @@ local function get_recipe_fs(data) local groups - if sub(item, 1,6) == "group:" then + if is_group(item) then groups = extract_groups(item) item = groups_to_items(groups) end @@ -788,12 +793,14 @@ local old_register_craft = core.register_craft core.register_craft = function(recipe) old_register_craft(recipe) - local output = recipe.output or (is_str(recipe.recipe) and recipe.recipe or "") + local output = recipe.output or + (is_str(recipe.recipe) and recipe.recipe or "") + if output == "" then return end output = output:match(match(output, "%S*")) local groups - if sub(output, 1,6) == "group:" then + if is_group(output) then groups = extract_groups(output) output = groups_to_items(groups, true) end @@ -806,33 +813,32 @@ core.register_craft = function(recipe) item = current_alias[2] end - local rcp = copy(recipe) - rcp.items = {} + recipe.items = {} - if rcp.type == "fuel" then - fuel_cache[item] = rcp + if recipe.type == "fuel" then + fuel_cache[item] = recipe - elseif rcp.type == "cooking" then - rcp.width = rcp.cooktime - rcp.cooktime = nil - rcp.items[1] = rcp.recipe + elseif recipe.type == "cooking" then + recipe.width = recipe.cooktime + recipe.cooktime = nil + recipe.items[1] = recipe.recipe - elseif rcp.type == "shapeless" then - rcp.width = 0 - for j = 1, #rcp.recipe do - rcp.items[#rcp.items + 1] = rcp.recipe[j] + elseif recipe.type == "shapeless" then + recipe.width = 0 + for j = 1, #recipe.recipe do + recipe.items[#recipe.items + 1] = recipe.recipe[j] end else - rcp.width = get_width(rcp.recipe) + recipe.width = get_width(recipe.recipe) local c = 1 - for j = 1, #rcp.recipe do - if rcp.recipe[j] then - for h = 1, rcp.width do - local it = rcp.recipe[j][h] + for j = 1, #recipe.recipe do + if recipe.recipe[j] then + for h = 1, recipe.width do + local it = recipe.recipe[j][h] if it and it ~= "" then - rcp.items[c] = it + recipe.items[c] = it end c = c + 1 @@ -841,10 +847,10 @@ core.register_craft = function(recipe) end end - if rcp.type ~= "fuel" then - rcp.recipe = nil + if recipe.type ~= "fuel" then + recipe.recipe = nil recipes_cache[item] = recipes_cache[item] or {} - insert(recipes_cache[item], 1, rcp) + insert(recipes_cache[item], 1, recipe) end end end @@ -931,7 +937,7 @@ local function _fields(player, fields) if not item then return elseif sub(item, -4) == "_inv" then - item = sub(item, 1,-5) + item = sub(item, 1, -5) end if item ~= data.query_item then @@ -1103,12 +1109,13 @@ if progressive_mode then local function item_in_inv(item, inv_items) local inv_items_size = #inv_items - if sub(item, 1,6) == "group:" then + if is_group(item) then local groups = extract_groups(item) for i = 1, inv_items_size do - local inv_item = reg_items[inv_items[i]] - if inv_item then - local item_groups = inv_item.groups + local def = reg_items[inv_items[i]] + + if def then + local item_groups = def.groups if item_has_groups(item_groups, groups) then return true end From 00a88a320a1b3ded4d5516c953fe30a78a906e03 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 9 Sep 2019 23:57:37 +0200 Subject: [PATCH 112/188] craftguide can show repairable tools --- init.lua | 41 +++++++++++++++++++++++++++++++---------- locale/craftguide.fr.tr | 1 + locale/template | 1 + 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/init.lua b/init.lua index 8a4590a..bf67b47 100644 --- a/init.lua +++ b/init.lua @@ -8,12 +8,15 @@ local recipes_cache = {} local usages_cache = {} local fuel_cache = {} +local toolrepair + local progressive_mode = core.settings:get_bool("craftguide_progressive_mode") local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") local log = core.log local after = core.after local colorize = core.colorize +local reg_tools = core.registered_tools local reg_items = core.registered_items local show_formspec = core.show_formspec local globalstep = core.register_globalstep @@ -411,13 +414,18 @@ local function groups_to_items(groups, get_all) return #names > 0 and concat(names, ",") or "" end +local function not_repairable(tool) + local def = reg_tools[tool] + return toolrepair and def and def.groups and def.groups.disable_repair == 1 +end + local function get_description(item, def) return def and def.description or (def and match(item, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or S("Unknown Item (@1)", item)) end -local function get_tooltip(item, burntime, groups, cooktime, replace) +local function get_tooltip(item, burntime, norepair, groups, cooktime, replace) local tooltip if groups then @@ -433,6 +441,10 @@ local function get_tooltip(item, burntime, groups, cooktime, replace) else local def = reg_items[item] tooltip = get_description(item, def) + + if norepair then + tooltip = tooltip .. "\n" .. S("This tool cannot be repaired") + end end if cooktime then @@ -541,7 +553,8 @@ local function get_recipe_fs(data) local burntime = fuel_cache[item] and fuel_cache[item].burntime if groups or cooktime or burntime or replace then - fs[#fs + 1] = get_tooltip(item, burntime, groups, cooktime, replace) + fs[#fs + 1] = get_tooltip( + item, burntime, nil, groups, cooktime, replace) end end @@ -586,16 +599,20 @@ local function get_recipe_fs(data) output_X, YOFFSET + (sfinv_only and 0.7 or 0), 1.1, 1.1, recipe.output, ESC(output_name), "") - if burntime then - fs[#fs + 1] = get_tooltip(output_name, burntime) + local norepair = not_repairable(recipe.output) - fs[#fs + 1] = fmt(FMT.image, - output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1), - 0.6, 0.4, PNG.arrow) + if burntime or norepair then + fs[#fs + 1] = get_tooltip(output_name, burntime, norepair) - fs[#fs + 1] = fmt(FMT.image, - output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0), - 0.6, 0.6, PNG.fire) + if burntime then + fs[#fs + 1] = fmt(FMT.image, + output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1), + 0.6, 0.4, PNG.arrow) + + fs[#fs + 1] = fmt(FMT.image, + output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0), + 0.6, 0.6, PNG.fire) + end end end @@ -793,6 +810,10 @@ local old_register_craft = core.register_craft core.register_craft = function(recipe) old_register_craft(recipe) + if recipe.type == "toolrepair" then + toolrepair = recipe.additional_wear ~= 0 + end + local output = recipe.output or (is_str(recipe.recipe) and recipe.recipe or "") diff --git a/locale/craftguide.fr.tr b/locale/craftguide.fr.tr index 9aedeaf..97357cc 100644 --- a/locale/craftguide.fr.tr +++ b/locale/craftguide.fr.tr @@ -7,6 +7,7 @@ Recipe @1 of @2=Recette @1 de @2 Burning time: @1=Temps de combustion : @1 Cooking time: @1=Temps de cuisson : @1 Replaced by @1 on crafting=Remplacé par @1 lors de la fabrication +This tool cannot be repaired=Cet outil ne peut être réparé Any item belonging to the group(s): @1=Tout item appartenant au(x) groupe(s) : @1 Recipe's too big to be displayed (@1x@2)=La recette est trop grande pour être affichée (@1x@2) Shapeless=Sans forme diff --git a/locale/template b/locale/template index 514d129..71f41be 100644 --- a/locale/template +++ b/locale/template @@ -8,6 +8,7 @@ Recipe @1 of @2= Burning time: @1= Cooking time: @1= Replaced by @1 on crafting= +This tool cannot be repaired= Any item belonging to the group(s): @1= Recipe's too big to be displayed (@1x@2)= Shapeless= From fc3f1fece231444c5fcc86d97fffb28d0504718e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 10 Sep 2019 11:28:13 +0200 Subject: [PATCH 113/188] Code cleaning --- API.md | 4 +- init.lua | 237 +++++++++++++++++++++++++++++++------------------------ 2 files changed, 139 insertions(+), 102 deletions(-) diff --git a/API.md b/API.md index e7fe6ea..904cbc2 100644 --- a/API.md +++ b/API.md @@ -160,6 +160,8 @@ craftguide.group_stereotypes.radioactive = "mod:item" You can set a custom background theme by overriding this variable: ```Lua -craftguide.background = "my_custom_bg.png" +craftguide.background = ":" ``` + +`middle` (number) refers to a 9-sliced background. Read the engine's Lua API documentation for more info. diff --git a/init.lua b/init.lua index bf67b47..5816b63 100644 --- a/init.lua +++ b/init.lua @@ -15,7 +15,7 @@ local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G local log = core.log local after = core.after -local colorize = core.colorize +local clrz = core.colorize local reg_tools = core.registered_tools local reg_items = core.registered_items local show_formspec = core.show_formspec @@ -54,7 +54,7 @@ local YOFFSET = sfinv_only and 6 or 6.6 local DEV_CORE = sub(core.get_version().string, -3) == "dev" -craftguide.background = "craftguide_bg_full.png" +craftguide.background = "craftguide_bg_full.png:10" local PNG = { bg = "craftguide_bg.png", @@ -167,6 +167,10 @@ local function get_width(recipe) return 0 end +local function clean_name(item) + return match(item, "%S+") +end + function craftguide.register_craft(def) if not is_table(def) or not next(def) then return log("error", "craftguide.register_craft(): craft definition missing") @@ -411,7 +415,7 @@ local function groups_to_items(groups, get_all) end end - return #names > 0 and concat(names, ",") or "" + return names end local function not_repairable(tool) @@ -419,56 +423,121 @@ local function not_repairable(tool) return toolrepair and def and def.groups and def.groups.disable_repair == 1 end -local function get_description(item, def) - return def and def.description or - (def and match(item, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or - S("Unknown Item (@1)", item)) -end - -local function get_tooltip(item, burntime, norepair, groups, cooktime, replace) +local function get_tooltip(item, info) local tooltip - if groups then + local function add(str) + return tooltip .. "\n" .. str + end + + local function get_desc(def, name) + name = name or item + return def and def.description or + (def and match(name, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or + S("Unknown Item (@1)", name)) + end + + if info.groups then local groupstr, c = {}, 0 - for i = 1, #groups do + for i = 1, #info.groups do c = c + 1 - groupstr[c] = colorize("yellow", groups[i]) + groupstr[c] = clrz("yellow", info.groups[i]) end groupstr = concat(groupstr, ", ") tooltip = S("Any item belonging to the group(s): @1", groupstr) else local def = reg_items[item] - tooltip = get_description(item, def) + tooltip = get_desc(def) - if norepair then - tooltip = tooltip .. "\n" .. S("This tool cannot be repaired") + if info.norepair then + tooltip = add(S("This tool cannot be repaired")) end end - if cooktime then - tooltip = tooltip .. "\n" .. - S("Cooking time: @1", colorize("yellow", cooktime)) + if info.cooktime then + tooltip = add(S("Cooking time: @1", clrz("yellow", info.cooktime))) end - if burntime then - tooltip = tooltip .. "\n" .. - S("Burning time: @1", colorize("yellow", burntime)) + if info.burntime then + tooltip = add(S("Burning time: @1", clrz("yellow", info.burntime))) end - if replace then - local def = reg_items[replace] - tooltip = tooltip .. "\n" .. - S("Replaced by @1 on crafting", - colorize("yellow", get_description(replace, def))) + if info.replace then + local def = reg_items[info.replace] + tooltip = add(S("Replaced by @1 on crafting", + clrz("yellow", get_desc(def, info.replace)))) end return fmt("tooltip[%s;%s]", item, ESC(tooltip)) end -local function get_recipe_fs(data) - local fs = {} +local function get_output_fs(fs, L) + local custom_recipe = craft_types[L.recipe.type] + + if custom_recipe or L.shapeless or L.recipe.type == "cooking" then + local icon = custom_recipe and custom_recipe.icon or + L.shapeless and "shapeless" or "furnace" + + if not custom_recipe then + icon = fmt("craftguide_%s.png^[resize:16x16", icon) + end + + local pos_x = L.rightest + L.btn_size + 0.1 + local pos_y = YOFFSET + (sfinv_only and 0.25 or -0.45) + + fs[#fs + 1] = fmt(FMT.image, pos_x, pos_y, 0.5, 0.5, icon) + + local tooltip = custom_recipe and custom_recipe.description or + L.shapeless and S("Shapeless") or S("Cooking") + + fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", + pos_x, pos_y, 0.5, 0.5, ESC(tooltip)) + end + + local arrow_X = L.rightest + (L.s_btn_size or 1.1) + local output_X = arrow_X + 0.9 + + fs[#fs + 1] = fmt(FMT.image, + arrow_X, YOFFSET + (sfinv_only and 0.9 or 0.2), + 0.9, 0.7, PNG.arrow) + + if L.recipe.type == "fuel" then + fs[#fs + 1] = fmt(FMT.image, + output_X, YOFFSET + (sfinv_only and 0.7 or 0), + 1.1, 1.1, PNG.fire) + else + local item = L.recipe.output + local name = clean_name(item) + local burntime = fuel_cache[name] and fuel_cache[name].burntime + + fs[#fs + 1] = fmt(FMT.item_image_button, + output_X, YOFFSET + (sfinv_only and 0.7 or 0), + 1.1, 1.1, item, ESC(name), "") + + local norepair = not_repairable(item) + + if burntime or norepair then + fs[#fs + 1] = get_tooltip(name, { + burntime = burntime, + norepair = norepair, + }) + + if burntime then + fs[#fs + 1] = fmt(FMT.image, + output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1), + 0.6, 0.4, PNG.arrow) + + fs[#fs + 1] = fmt(FMT.image, + output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0), + 0.6, 0.6, PNG.fire) + end + end + end +end + +local function get_recipe_fs(data, fs) local recipe = data.recipes[data.rnum] local width = recipe.width local replacements = recipe.replacements @@ -530,7 +599,8 @@ local function get_recipe_fs(data) if is_group(item) then groups = extract_groups(item) - item = groups_to_items(groups) + local items = groups_to_items(groups) + item = items[1] or items end local label = groups and "\nG" or "" @@ -548,75 +618,38 @@ local function get_recipe_fs(data) fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, match(item, "%S*"), ESC(label)) + btn_size, btn_size, item, clean_name(item), ESC(label)) local burntime = fuel_cache[item] and fuel_cache[item].burntime - if groups or cooktime or burntime or replace then - fs[#fs + 1] = get_tooltip( - item, burntime, nil, groups, cooktime, replace) - end - end + local more_info + local infos = { + groups = groups, + burntime = burntime, + cooktime = cooktime, + replace = replace, + norepair = nil, + } - local custom_recipe = craft_types[recipe.type] - - if custom_recipe or shapeless or recipe.type == "cooking" then - local icon = custom_recipe and custom_recipe.icon or - shapeless and "shapeless" or "furnace" - - if not custom_recipe then - icon = fmt("craftguide_%s.png^[resize:16x16", icon) - end - - local pos_x = rightest + btn_size + 0.1 - local pos_y = YOFFSET + (sfinv_only and 0.25 or -0.45) - - fs[#fs + 1] = fmt(FMT.image, pos_x, pos_y, 0.5, 0.5, icon) - - local tooltip = custom_recipe and custom_recipe.description or - shapeless and S("Shapeless") or S("Cooking") - - fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", - pos_x, pos_y, 0.5, 0.5, ESC(tooltip)) - end - - local arrow_X = rightest + (s_btn_size or 1.1) - local output_X = arrow_X + 0.9 - - fs[#fs + 1] = fmt(FMT.image, - arrow_X, YOFFSET + (sfinv_only and 0.9 or 0.2), - 0.9, 0.7, PNG.arrow) - - if recipe.type == "fuel" then - fs[#fs + 1] = fmt(FMT.image, - output_X, YOFFSET + (sfinv_only and 0.7 or 0), - 1.1, 1.1, PNG.fire) - else - local output_name = match(recipe.output, "%S+") - local burntime = fuel_cache[output_name] and fuel_cache[output_name].burntime - - fs[#fs + 1] = fmt(FMT.item_image_button, - output_X, YOFFSET + (sfinv_only and 0.7 or 0), - 1.1, 1.1, recipe.output, ESC(output_name), "") - - local norepair = not_repairable(recipe.output) - - if burntime or norepair then - fs[#fs + 1] = get_tooltip(output_name, burntime, norepair) - - if burntime then - fs[#fs + 1] = fmt(FMT.image, - output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1), - 0.6, 0.4, PNG.arrow) - - fs[#fs + 1] = fmt(FMT.image, - output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0), - 0.6, 0.6, PNG.fire) + for _, v in pairs(infos) do + if v then + more_info = true + break end end + + if more_info then + fs[#fs + 1] = get_tooltip(item, infos) + end end - return concat(fs) + get_output_fs(fs, { + recipe = recipe, + shapeless = shapeless, + rightest = rightest, + btn_size = btn_size, + s_btn_size = s_btn_size, + }) end local function make_formspec(name) @@ -626,13 +659,17 @@ local function make_formspec(name) local fs = {} if not sfinv_only then + local bg, middle = match(craftguide.background, "(.-):(%d+)") + bg = bg or "" + middle = middle or "10" + fs[#fs + 1] = fmt([[ size[9.5,8.4] no_prepend[] bgcolor[#00000000;false] background[1,1;1,1;%s;true%s] ]], - craftguide.background, DEV_CORE and ";10" or "") + bg, DEV_CORE and ";" .. middle or "") end fs[#fs + 1] = fmt([[ @@ -650,7 +687,7 @@ local function make_formspec(name) fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", sfinv_only and 6.35 or 7.85, 0.06, - colorize("yellow", data.pagenum), data.pagemax) + clrz("yellow", data.pagenum), data.pagemax) fs[#fs + 1] = fmt([[ image_button[%f,-0.05;0.8,0.8;%s;prev;;;false;%s^\[colorize:yellow:255] @@ -687,7 +724,7 @@ local function make_formspec(name) end if data.recipes and #data.recipes > 0 then - fs[#fs + 1] = get_recipe_fs(data) + get_recipe_fs(data, fs) end return concat(fs) @@ -818,16 +855,14 @@ core.register_craft = function(recipe) (is_str(recipe.recipe) and recipe.recipe or "") if output == "" then return end - output = output:match(match(output, "%S*")) + output = {clean_name(output)} local groups - if is_group(output) then - groups = extract_groups(output) + if is_group(output[1]) then + groups = extract_groups(output[1]) output = groups_to_items(groups, true) end - output = split(output, ",") - for i = 1, #output do local item = output[i] if item == current_alias[1] then @@ -1391,7 +1426,7 @@ register_command("craft", { end end - local red = colorize("red", "[craftguide] ") + local red = clrz("red", "[craftguide] ") if not node_name then return false, red .. S("No node pointed") @@ -1408,7 +1443,7 @@ register_command("craft", { end if not recipes or #recipes == 0 then - local ylw = colorize("yellow", node_name) + local ylw = clrz("yellow", node_name) local msg = red .. "%s: " .. ylw if usages then From 84795a65238345ccbe4a5d56c4ddf338c922051a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 10 Sep 2019 12:37:39 +0200 Subject: [PATCH 114/188] Fix tooltip for replacements --- init.lua | 11 +++++++++-- locale/craftguide.fr.tr | 2 ++ locale/template | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index 5816b63..6e52a3c 100644 --- a/init.lua +++ b/init.lua @@ -466,8 +466,15 @@ local function get_tooltip(item, info) if info.replace then local def = reg_items[info.replace] - tooltip = add(S("Replaced by @1 on crafting", - clrz("yellow", get_desc(def, info.replace)))) + local desc = clrz("yellow", get_desc(def, info.replace)) + + if info.cooktime then + tooltip = add(S("Replaced by @1 on smelting", desc)) + elseif info.burntime then + tooltip = add(S("Replaced by @1 on burning", desc)) + else + tooltip = add(S("Replaced by @1 on crafting", desc)) + end end return fmt("tooltip[%s;%s]", item, ESC(tooltip)) diff --git a/locale/craftguide.fr.tr b/locale/craftguide.fr.tr index 97357cc..e12308f 100644 --- a/locale/craftguide.fr.tr +++ b/locale/craftguide.fr.tr @@ -6,6 +6,8 @@ Usage @1 of @2=Usage @1 de @2 Recipe @1 of @2=Recette @1 de @2 Burning time: @1=Temps de combustion : @1 Cooking time: @1=Temps de cuisson : @1 +Replaced by @1 on smelting=Remplacé par @1 lors de la cuisson +Replaced by @1 on burning=Remplacé par @1 lors de la combustion Replaced by @1 on crafting=Remplacé par @1 lors de la fabrication This tool cannot be repaired=Cet outil ne peut être réparé Any item belonging to the group(s): @1=Tout item appartenant au(x) groupe(s) : @1 diff --git a/locale/template b/locale/template index 71f41be..bab996a 100644 --- a/locale/template +++ b/locale/template @@ -7,6 +7,8 @@ Usage @1 of @2= Recipe @1 of @2= Burning time: @1= Cooking time: @1= +Replaced by @1 on smelting= +Replaced by @1 on burning= Replaced by @1 on crafting= This tool cannot be repaired= Any item belonging to the group(s): @1= From 3b3da66a0df8e8989a4f80d755a34a4e8a2eb59c Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 10 Sep 2019 13:41:17 +0200 Subject: [PATCH 115/188] Improve tooltip for toolrepair --- init.lua | 69 ++++++++++++++++++++--------------------- locale/craftguide.fr.tr | 2 +- locale/template | 2 +- 3 files changed, 35 insertions(+), 38 deletions(-) diff --git a/init.lua b/init.lua index 6e52a3c..238b0c4 100644 --- a/init.lua +++ b/init.lua @@ -15,7 +15,7 @@ local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G local log = core.log local after = core.after -local clrz = core.colorize +local clr = core.colorize local reg_tools = core.registered_tools local reg_items = core.registered_items local show_formspec = core.show_formspec @@ -418,18 +418,12 @@ local function groups_to_items(groups, get_all) return names end -local function not_repairable(tool) +local function repairable(tool) local def = reg_tools[tool] - return toolrepair and def and def.groups and def.groups.disable_repair == 1 + return toolrepair and def and def.groups and def.groups.disable_repair ~= 1 end local function get_tooltip(item, info) - local tooltip - - local function add(str) - return tooltip .. "\n" .. str - end - local function get_desc(def, name) name = name or item return def and def.description or @@ -437,36 +431,35 @@ local function get_tooltip(item, info) S("Unknown Item (@1)", name)) end + local tooltip = get_desc(reg_items[item]) + + local function add(str) + return tooltip .. "\n" .. str + end + if info.groups then local groupstr, c = {}, 0 for i = 1, #info.groups do c = c + 1 - groupstr[c] = clrz("yellow", info.groups[i]) + groupstr[c] = clr("yellow", info.groups[i]) end groupstr = concat(groupstr, ", ") tooltip = S("Any item belonging to the group(s): @1", groupstr) - else - local def = reg_items[item] - tooltip = get_desc(def) - - if info.norepair then - tooltip = add(S("This tool cannot be repaired")) - end end if info.cooktime then - tooltip = add(S("Cooking time: @1", clrz("yellow", info.cooktime))) + tooltip = add(S("Cooking time: @1", clr("yellow", info.cooktime))) end if info.burntime then - tooltip = add(S("Burning time: @1", clrz("yellow", info.burntime))) + tooltip = add(S("Burning time: @1", clr("yellow", info.burntime))) end if info.replace then local def = reg_items[info.replace] - local desc = clrz("yellow", get_desc(def, info.replace)) + local desc = clr("yellow", get_desc(def, info.replace)) if info.cooktime then tooltip = add(S("Replaced by @1 on smelting", desc)) @@ -477,6 +470,10 @@ local function get_tooltip(item, info) end end + if info.repair then + tooltip = add(S("Repairable by step of @1", clr("yellow", toolrepair .. "%"))) + end + return fmt("tooltip[%s;%s]", item, ESC(tooltip)) end @@ -523,23 +520,23 @@ local function get_output_fs(fs, L) output_X, YOFFSET + (sfinv_only and 0.7 or 0), 1.1, 1.1, item, ESC(name), "") - local norepair = not_repairable(item) + local repair = repairable(item) - if burntime or norepair then + if burntime or repair then fs[#fs + 1] = get_tooltip(name, { burntime = burntime, - norepair = norepair, + repair = repair, }) + end - if burntime then - fs[#fs + 1] = fmt(FMT.image, - output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1), - 0.6, 0.4, PNG.arrow) + if burntime then + fs[#fs + 1] = fmt(FMT.image, + output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1), + 0.6, 0.4, PNG.arrow) - fs[#fs + 1] = fmt(FMT.image, - output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0), - 0.6, 0.6, PNG.fire) - end + fs[#fs + 1] = fmt(FMT.image, + output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0), + 0.6, 0.6, PNG.fire) end end end @@ -635,7 +632,7 @@ local function get_recipe_fs(data, fs) burntime = burntime, cooktime = cooktime, replace = replace, - norepair = nil, + repair = nil, } for _, v in pairs(infos) do @@ -694,7 +691,7 @@ local function make_formspec(name) fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", sfinv_only and 6.35 or 7.85, 0.06, - clrz("yellow", data.pagenum), data.pagemax) + clr("yellow", data.pagenum), data.pagemax) fs[#fs + 1] = fmt([[ image_button[%f,-0.05;0.8,0.8;%s;prev;;;false;%s^\[colorize:yellow:255] @@ -855,7 +852,7 @@ core.register_craft = function(recipe) old_register_craft(recipe) if recipe.type == "toolrepair" then - toolrepair = recipe.additional_wear ~= 0 + toolrepair = recipe.additional_wear * -100 end local output = recipe.output or @@ -1433,7 +1430,7 @@ register_command("craft", { end end - local red = clrz("red", "[craftguide] ") + local red = clr("red", "[craftguide] ") if not node_name then return false, red .. S("No node pointed") @@ -1450,7 +1447,7 @@ register_command("craft", { end if not recipes or #recipes == 0 then - local ylw = clrz("yellow", node_name) + local ylw = clr("yellow", node_name) local msg = red .. "%s: " .. ylw if usages then diff --git a/locale/craftguide.fr.tr b/locale/craftguide.fr.tr index e12308f..f624eaa 100644 --- a/locale/craftguide.fr.tr +++ b/locale/craftguide.fr.tr @@ -9,7 +9,7 @@ Cooking time: @1=Temps de cuisson : @1 Replaced by @1 on smelting=Remplacé par @1 lors de la cuisson Replaced by @1 on burning=Remplacé par @1 lors de la combustion Replaced by @1 on crafting=Remplacé par @1 lors de la fabrication -This tool cannot be repaired=Cet outil ne peut être réparé +Repairable by step of @1=Réparable par étape de @1 Any item belonging to the group(s): @1=Tout item appartenant au(x) groupe(s) : @1 Recipe's too big to be displayed (@1x@2)=La recette est trop grande pour être affichée (@1x@2) Shapeless=Sans forme diff --git a/locale/template b/locale/template index bab996a..dbacf30 100644 --- a/locale/template +++ b/locale/template @@ -10,7 +10,7 @@ Cooking time: @1= Replaced by @1 on smelting= Replaced by @1 on burning= Replaced by @1 on crafting= -This tool cannot be repaired= +Repairable by step of @1= Any item belonging to the group(s): @1= Recipe's too big to be displayed (@1x@2)= Shapeless= From db626eaece54c58b2c56453da9d3101a752e61e7 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 10 Sep 2019 16:18:27 +0200 Subject: [PATCH 116/188] Small cleaning --- init.lua | 84 +++++++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/init.lua b/init.lua index 238b0c4..f9ea300 100644 --- a/init.lua +++ b/init.lua @@ -155,18 +155,6 @@ function craftguide.register_craft_type(name, def) craft_types[name] = def end -local function get_width(recipe) - if is_table(recipe) then - sort(recipe, function(a, b) - return #a > #b - end) - - return #recipe[1] - end - - return 0 -end - local function clean_name(item) return match(item, "%S+") end @@ -198,7 +186,11 @@ function craftguide.register_craft(def) end local cp = copy(def.grid) - def.width = get_width(cp) + sort(cp, function(a, b) + return #a > #b + end) + + def.width = #cp[1] for i = 1, #def.grid do while #def.grid[i] < def.width do @@ -294,6 +286,7 @@ local function groups_item_in_recipe(item, recipe) for _, recipe_item in pairs(recipe.items) do if is_group(recipe_item) then local groups = extract_groups(recipe_item) + if item_has_groups(item_groups, groups) then local usage = copy(recipe) table_replace(usage.items, recipe_item, item) @@ -338,6 +331,7 @@ local function get_usages(item) for _, recipes in pairs(recipes_cache) do for i = 1, #recipes do local recipe = recipes[i] + if item_in_recipe(item, recipe) then c = c + 1 usages[c] = recipe @@ -424,18 +418,7 @@ local function repairable(tool) end local function get_tooltip(item, info) - local function get_desc(def, name) - name = name or item - return def and def.description or - (def and match(name, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or - S("Unknown Item (@1)", name)) - end - - local tooltip = get_desc(reg_items[item]) - - local function add(str) - return tooltip .. "\n" .. str - end + local tooltip if info.groups then local groupstr, c = {}, 0 @@ -447,6 +430,21 @@ local function get_tooltip(item, info) groupstr = concat(groupstr, ", ") tooltip = S("Any item belonging to the group(s): @1", groupstr) + + return fmt("tooltip[%s;%s]", item, ESC(tooltip)) + end + + local function get_desc(def, name) + name = name or item + return def and def.description or + (def and match(name, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or + S("Unknown Item (@1)", name)) + end + + tooltip = get_desc(reg_items[item]) + + local function add(str) + return tooltip .. "\n" .. str end if info.cooktime then @@ -614,7 +612,7 @@ local function get_recipe_fs(data, fs) for j = 1, #replacements do local replacement = replacements[j] if replacement[1] == item then - label = (label ~= "" and "\n" or "") .. label .. "\nR" + label = label .. "\nR" replace = replacement[2] end end @@ -626,8 +624,7 @@ local function get_recipe_fs(data, fs) local burntime = fuel_cache[item] and fuel_cache[item].burntime - local more_info - local infos = { + local info = { groups = groups, burntime = burntime, cooktime = cooktime, @@ -635,16 +632,12 @@ local function get_recipe_fs(data, fs) repair = nil, } - for _, v in pairs(infos) do + for _, v in pairs(info) do if v then - more_info = true + fs[#fs + 1] = get_tooltip(item, info) break end end - - if more_info then - fs[#fs + 1] = get_tooltip(item, infos) - end end get_output_fs(fs, { @@ -836,14 +829,14 @@ end -- As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not return the replacements, -- we have to override `core.register_craft` and `core.register_alias` and do some reverse engineering. --- See engine's issue #4901. +-- See engine's issues #4901 and #8920. local old_register_alias = core.register_alias local current_alias = {} core.register_alias = function(old, new) - current_alias = {old, new} old_register_alias(old, new) + current_alias = {old, new} end local old_register_craft = core.register_craft @@ -889,7 +882,7 @@ core.register_craft = function(recipe) recipe.items[#recipe.items + 1] = recipe.recipe[j] end else - recipe.width = get_width(recipe.recipe) + recipe.width = #recipe.recipe[1] local c = 1 for j = 1, #recipe.recipe do @@ -944,10 +937,9 @@ on_joinplayer(function(player) init_data(name) end) -local function _fields(player, fields) +local function fields(player, _f) local name = player:get_player_name() local data = pdata[name] - local _f = fields if _f.clear then reset_data(data) @@ -963,10 +955,10 @@ local function _fields(player, fields) return true elseif (_f.key_enter_field == "filter" or _f.search) and _f.filter ~= "" then - local fltr = lower(_f.filter) - if data.filter == fltr then return end + local str = lower(_f.filter) + if data.filter == str then return end - data.filter = fltr + data.filter = str data.pagenum = 1 search(data) @@ -1039,14 +1031,14 @@ if sfinv_only then end end, - on_player_receive_fields = function(self, player, context, fields) - _fields(player, fields) + on_player_receive_fields = function(self, player, context, _f) + fields(player, _f) end, }) else - on_receive_fields(function(player, formname, fields) + on_receive_fields(function(player, formname, _f) if formname == "craftguide" then - _fields(player, fields) + fields(player, _f) end end) From 59b806c9c494b98f0f67015afa4978f75d17b309 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 11 Sep 2019 12:25:28 +0200 Subject: [PATCH 117/188] Progressive: Update items in sfinv without page change --- init.lua | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index f9ea300..3f56830 100644 --- a/init.lua +++ b/init.lua @@ -309,10 +309,10 @@ local function get_filtered_items(player, data) usages = #apply_recipe_filters(usages or {}, player) if recipes > 0 or usages > 0 then - if not data then - c = c + 1 - items[c] = item - else + c = c + 1 + items[c] = item + + if data then known = known + recipes + usages end end @@ -320,9 +320,9 @@ local function get_filtered_items(player, data) if data then data.known_recipes = known - else - return items end + + return items end local function get_usages(item) @@ -1303,12 +1303,19 @@ if progressive_mode then data.inv_items = table_merge(diff, data.inv_items) local oldknown = data.known_recipes or 0 - get_filtered_items(player, data) + local items = get_filtered_items(player, data) + data.discovered = data.known_recipes - oldknown if data.show_hud == nil and data.discovered > 0 then data.show_hud = true end + + if sfinv_only then + data.items_raw = items + search(data) + sfinv.set_player_inventory_formspec(player) + end end end From fb1b0cf869ad056e954005d065c580be6eac06c9 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 11 Sep 2019 12:44:08 +0200 Subject: [PATCH 118/188] Notification success: do not depend on dtime --- README.md | 6 ++++-- init.lua | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 53c869e..f28905a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This crafting guide is a blue book named *"Crafting Guide"* or a wooden sign. This crafting guide features a **progressive mode**. -The progressive mode is a Terraria-like system that shows recipes you can craft +This mode is a Terraria-like system that shows recipes you can craft from items you ever had in your inventory. To enable it: `craftguide_progressive_mode = true` in `minetest.conf`. `craftguide` is also integrated in `sfinv` (Minetest Game inventory). To enable it: @@ -16,5 +16,7 @@ Use the command `/craft` to show the recipe(s) of the pointed node. For developers, `craftguide` also has a [modding API](https://github.com/minetest-mods/craftguide/blob/master/API.md). +Love this mod? Donations are appreciated: https://www.paypal.me/jpg84240 -![Preview2](https://i.imgur.com/oGSvbTW.png) + +![Preview2](https://i.imgur.com/IbexMwQ.png) diff --git a/init.lua b/init.lua index 3f56830..971c7ff 100644 --- a/init.lua +++ b/init.lua @@ -1131,6 +1131,7 @@ end if progressive_mode then local PLAYERS = {} local POLL_FREQ = 0.25 + local HUD_TIMER_MAX = 1.5 local function table_diff(t1, t2) local hash = {} @@ -1245,15 +1246,16 @@ if progressive_mode then return inv_items end - local function show_hud_success(player, data, dtime) - -- It'd better to have an engine function `hud_move` to do not - -- depend on the server dtime, and use the client dtime internally instead. + local function show_hud_success(player, data) + -- It'd better to have an engine function `hud_move` to only need + -- 2 calls for the notification's back and forth. local hud_info_bg = player:hud_get(data.hud.bg) + local dt = 0.016 if hud_info_bg.position.y <= 0.9 then data.show_hud = false - data.hud_timer = (data.hud_timer or 0) + dtime + data.hud_timer = (data.hud_timer or 0) + dt end if data.show_hud then @@ -1262,7 +1264,7 @@ if progressive_mode then player:hud_change(def, "position", { x = hud_info.position.x, - y = hud_info.position.y - (dtime / 5) + y = hud_info.position.y - (dt / 5) }) end @@ -1270,13 +1272,13 @@ if progressive_mode then S("@1 new recipe(s) discovered!", data.discovered)) elseif data.show_hud == false then - if data.hud_timer > 3 then + if data.hud_timer >= HUD_TIMER_MAX then for _, def in pairs(data.hud) do local hud_info = player:hud_get(def) player:hud_change(def, "position", { x = hud_info.position.x, - y = hud_info.position.y + (dtime / 5) + y = hud_info.position.y + (dt / 5) }) end @@ -1324,14 +1326,14 @@ if progressive_mode then poll_new_items() - globalstep(function(dtime) + globalstep(function() for i = 1, #PLAYERS do local player = PLAYERS[i] local name = player:get_player_name() local data = pdata[name] if data.show_hud ~= nil then - show_hud_success(player, data, dtime) + show_hud_success(player, data) end end end) From 2ffef6794ab17770cfe8cb4286c15d067c808c4e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 11 Sep 2019 16:28:37 +0200 Subject: [PATCH 119/188] Do not require to specify width in custom recipes --- API.md | 12 +++++++++++- init.lua | 47 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/API.md b/API.md index 904cbc2..0000814 100644 --- a/API.md +++ b/API.md @@ -19,12 +19,22 @@ craftguide.register_craft_type("digging", { ```Lua craftguide.register_craft({ type = "digging", - width = 1, result = "default:cobble 2", items = {"default:stone"}, }) ``` +```Lua +craftguide.register_craft({ + result = "default:cobble 16", + items = { + "default:stone, default:stone, default:stone", + "default:stone, , default:stone", + "default:stone, default:stone, default:stone", + } +}) +``` + Recipes can also be registered in a Minecraft-like way: ```Lua diff --git a/init.lua b/init.lua index 971c7ff..494345a 100644 --- a/init.lua +++ b/init.lua @@ -121,10 +121,6 @@ local function is_str(x) return type(x) == "string" end -local function is_num(x) - return type(x) == "number" -end - local function is_table(x) return type(x) == "table" end @@ -160,6 +156,10 @@ local function clean_name(item) end function craftguide.register_craft(def) + def.custom = true + def.width = 0 + local c = 1 + if not is_table(def) or not next(def) then return log("error", "craftguide.register_craft(): craft definition missing") end @@ -172,14 +172,6 @@ function craftguide.register_craft(def) return log("error", "craftguide.register_craft(): output missing") end - if not is_table(def.items) then - def.items = {} - end - - if not is_num(def.width) then - def.width = 0 - end - if def.grid then if not is_table(def.grid) then def.grid = {} @@ -198,11 +190,38 @@ function craftguide.register_craft(def) end end - local c = 1 for symbol in gmatch(concat(def.grid), ".") do def.items[c] = def.key[symbol] c = c + 1 end + else + if not is_table(def.items) then + def.items = {} + end + + local len = #def.items + + for i = 1, len do + def.items[i] = def.items[i]:gsub(",,", ", ,") + + local row = split(def.items[i], ",") + local l = #row + + if l > def.width then + def.width = l + end + end + + for i = 1, len do + while #split(def.items[i], ",") < def.width do + def.items[i] = def.items[i] .. ", " + end + end + + for name in gmatch(concat(def.items, ","), "[%s%w_:]+") do + def.items[c] = clean_name(name) + c = c + 1 + end end local output = match(def.output, "%S*") @@ -547,7 +566,7 @@ local function get_recipe_fs(data, fs) if recipe.type == "cooking" then cooktime, width = width, 1 - elseif width == 0 then + elseif width == 0 and not recipe.custom then shapeless = true local n = #recipe.items width = (n < 5 and n > 1) and 2 or min(3, max(1, n)) From 738c2140a7800471ae1bbd3a10e15e73ccdd3090 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 11 Sep 2019 16:35:56 +0200 Subject: [PATCH 120/188] Show itemstring for unknown item --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 494345a..eeab743 100644 --- a/init.lua +++ b/init.lua @@ -644,11 +644,11 @@ local function get_recipe_fs(data, fs) local burntime = fuel_cache[item] and fuel_cache[item].burntime local info = { + unknown = not reg_items[item], groups = groups, burntime = burntime, cooktime = cooktime, replace = replace, - repair = nil, } for _, v in pairs(info) do From 06bef9777a813223a2060f244429613121a2044a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 11 Sep 2019 17:10:46 +0200 Subject: [PATCH 121/188] Minor cleaning --- API.md | 2 +- init.lua | 79 +++++++++++++++++++++++++++----------------------------- 2 files changed, 39 insertions(+), 42 deletions(-) diff --git a/API.md b/API.md index 0000814..a6e3df8 100644 --- a/API.md +++ b/API.md @@ -27,7 +27,7 @@ craftguide.register_craft({ ```Lua craftguide.register_craft({ result = "default:cobble 16", - items = { + items = { "default:stone, default:stone, default:stone", "default:stone, , default:stone", "default:stone, default:stone, default:stone", diff --git a/init.lua b/init.lua index eeab743..427719c 100644 --- a/init.lua +++ b/init.lua @@ -172,6 +172,10 @@ function craftguide.register_craft(def) return log("error", "craftguide.register_craft(): output missing") end + if not is_table(def.items) then + def.items = {} + end + if def.grid then if not is_table(def.grid) then def.grid = {} @@ -195,20 +199,14 @@ function craftguide.register_craft(def) c = c + 1 end else - if not is_table(def.items) then - def.items = {} - end - local len = #def.items for i = 1, len do def.items[i] = def.items[i]:gsub(",,", ", ,") + local rlen = #split(def.items[i], ",") - local row = split(def.items[i], ",") - local l = #row - - if l > def.width then - def.width = l + if rlen > def.width then + def.width = rlen end end @@ -224,7 +222,7 @@ function craftguide.register_craft(def) end end - local output = match(def.output, "%S*") + local output = clean_name(def.output) recipes_cache[output] = recipes_cache[output] or {} insert(recipes_cache[output], def) end @@ -860,18 +858,17 @@ end local old_register_craft = core.register_craft -core.register_craft = function(recipe) - old_register_craft(recipe) +core.register_craft = function(def) + old_register_craft(def) - if recipe.type == "toolrepair" then - toolrepair = recipe.additional_wear * -100 + if def.type == "toolrepair" then + toolrepair = def.additional_wear * -100 end - local output = recipe.output or - (is_str(recipe.recipe) and recipe.recipe or "") - + local output = def.output or (is_str(def.recipe) and def.recipe or "") if output == "" then return end output = {clean_name(output)} + local groups if is_group(output[1]) then @@ -880,37 +877,37 @@ core.register_craft = function(recipe) end for i = 1, #output do - local item = output[i] - if item == current_alias[1] then - item = current_alias[2] + local name = output[i] + if name == current_alias[1] then + name = current_alias[2] end - recipe.items = {} + def.items = {} - if recipe.type == "fuel" then - fuel_cache[item] = recipe + if def.type == "fuel" then + fuel_cache[name] = def - elseif recipe.type == "cooking" then - recipe.width = recipe.cooktime - recipe.cooktime = nil - recipe.items[1] = recipe.recipe + elseif def.type == "cooking" then + def.width = def.cooktime + def.cooktime = nil + def.items[1] = def.recipe - elseif recipe.type == "shapeless" then - recipe.width = 0 - for j = 1, #recipe.recipe do - recipe.items[#recipe.items + 1] = recipe.recipe[j] + elseif def.type == "shapeless" then + def.width = 0 + for j = 1, #def.recipe do + def.items[#def.items + 1] = def.recipe[j] end else - recipe.width = #recipe.recipe[1] + def.width = #def.recipe[1] local c = 1 - for j = 1, #recipe.recipe do - if recipe.recipe[j] then - for h = 1, recipe.width do - local it = recipe.recipe[j][h] + for j = 1, #def.recipe do + if def.recipe[j] then + for h = 1, def.width do + local it = def.recipe[j][h] if it and it ~= "" then - recipe.items[c] = it + def.items[c] = it end c = c + 1 @@ -919,10 +916,10 @@ core.register_craft = function(recipe) end end - if recipe.type ~= "fuel" then - recipe.recipe = nil - recipes_cache[item] = recipes_cache[item] or {} - insert(recipes_cache[item], 1, recipe) + if def.type ~= "fuel" then + def.recipe = nil + recipes_cache[name] = recipes_cache[name] or {} + insert(recipes_cache[name], 1, def) end end end From 7c891ff2b6956842e6debe7f69360e60f4f62114 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 11 Sep 2019 17:47:44 +0200 Subject: [PATCH 122/188] Small fix for custom recipe --- init.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index 427719c..02e1aae 100644 --- a/init.lua +++ b/init.lua @@ -202,9 +202,17 @@ function craftguide.register_craft(def) local len = #def.items for i = 1, len do - def.items[i] = def.items[i]:gsub(",,", ", ,") - local rlen = #split(def.items[i], ",") + local cc = 1 + for char in gmatch(def.items[i], ".") do + if char == "," and sub(def.items[i], cc, cc) == "," then + def.items[i] = sub(def.items[i], 1, cc) .. " " .. + sub(def.items[i], cc + 1) + end + cc = cc + 1 + end + + local rlen = #split(def.items[i], ",") if rlen > def.width then def.width = rlen end From 9dcccadfc2a38d85c47fc2f0b46803c74b1d11b2 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 12 Sep 2019 12:34:03 +0200 Subject: [PATCH 123/188] Minor fix --- init.lua | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/init.lua b/init.lua index 02e1aae..e6bd97c 100644 --- a/init.lua +++ b/init.lua @@ -199,32 +199,25 @@ function craftguide.register_craft(def) c = c + 1 end else - local len = #def.items + local items, len = def.items, #def.items + def.items = {} for i = 1, len do - local cc = 1 - for char in gmatch(def.items[i], ".") do - if char == "," and sub(def.items[i], cc, cc) == "," then - def.items[i] = sub(def.items[i], 1, cc) .. " " .. - sub(def.items[i], cc + 1) - end + items[i] = items[i]:gsub(",", ", ") + local rlen = #split(items[i], ",") - cc = cc + 1 - end - - local rlen = #split(def.items[i], ",") if rlen > def.width then def.width = rlen end end for i = 1, len do - while #split(def.items[i], ",") < def.width do - def.items[i] = def.items[i] .. ", " + while #split(items[i], ",") < def.width do + items[i] = items[i] .. ", " end end - for name in gmatch(concat(def.items, ","), "[%s%w_:]+") do + for name in gmatch(concat(items, ","), "[%s%w_:]+") do def.items[c] = clean_name(name) c = c + 1 end From 7a8b8d19df7c7e38434b18560734b5d2bc1ea84b Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 15 Sep 2019 22:39:08 +0200 Subject: [PATCH 124/188] Fix possible nil crash --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index e6bd97c..6900c80 100644 --- a/init.lua +++ b/init.lua @@ -630,7 +630,7 @@ local function get_recipe_fs(data, fs) for j = 1, #replacements do local replacement = replacements[j] if replacement[1] == item then - label = label .. "\nR" + label = "\nR" replace = replacement[2] end end @@ -638,7 +638,7 @@ local function get_recipe_fs(data, fs) fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, clean_name(item), ESC(label)) + btn_size, btn_size, item, clean_name(item), ESC(label) or "") local burntime = fuel_cache[item] and fuel_cache[item].burntime From 732535c9da279b9bd115f0f6cb6892bcf3406cbd Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 16 Sep 2019 12:33:28 +0200 Subject: [PATCH 125/188] Another attempt to fix nil crash --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index 6900c80..3d1e79c 100644 --- a/init.lua +++ b/init.lua @@ -152,7 +152,7 @@ function craftguide.register_craft_type(name, def) end local function clean_name(item) - return match(item, "%S+") + return match(item, "%S*") end function craftguide.register_craft(def) @@ -638,7 +638,7 @@ local function get_recipe_fs(data, fs) fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, clean_name(item), ESC(label) or "") + btn_size, btn_size, item, clean_name(item), ESC(label)) local burntime = fuel_cache[item] and fuel_cache[item].burntime From 768e06e2d03ce114251231107943aa1d1bdebef4 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 16 Sep 2019 12:56:04 +0200 Subject: [PATCH 126/188] why the hell the page number not colorized anymore? --- init.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/init.lua b/init.lua index 3d1e79c..3fddf1d 100644 --- a/init.lua +++ b/init.lua @@ -700,16 +700,14 @@ local function make_formspec(name) sfinv_only and 2.6 or 2.54, PNG.search, PNG.search, sfinv_only and 3.3 or 3.25, PNG.clear, PNG.clear) - fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", - sfinv_only and 6.35 or 7.85, 0.06, - clr("yellow", data.pagenum), data.pagemax) - fs[#fs + 1] = fmt([[ image_button[%f,-0.05;0.8,0.8;%s;prev;;;false;%s^\[colorize:yellow:255] + label[%f,%f;%s / %u] image_button[%f,-0.05;0.8,0.8;%s;next;;;false;%s^\[colorize:yellow:255] ]], sfinv_only and 5.45 or 6.83, PNG.prev, PNG.prev, - sfinv_only and 7.2 or 8.75, PNG.next, PNG.next) + sfinv_only and 6.35 or 7.85, 0.06, clr("yellow", data.pagenum), data.pagemax, + sfinv_only and 7.2 or 8.75, PNG.next, PNG.next) if #data.items == 0 then local no_item = S("No item to show") From a936452e2108719eb7ed9dbe32f1706ab2262089 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 18 Sep 2019 20:09:03 +0200 Subject: [PATCH 127/188] Fix non-shown recipes --- init.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/init.lua b/init.lua index 3fddf1d..5c32121 100644 --- a/init.lua +++ b/init.lua @@ -23,6 +23,7 @@ local globalstep = core.register_globalstep local on_shutdown = core.register_on_shutdown local get_players = core.get_connected_players local on_joinplayer = core.register_on_joinplayer +local get_all_recipes = core.get_all_craft_recipes local register_command = core.register_chatcommand local get_player_by_name = core.get_player_by_name local on_mods_loaded = core.register_on_mods_loaded @@ -382,6 +383,21 @@ local function cache_usages(item) end end +local function cache_recipes(output) + local recipes = get_all_recipes(output) or {} + local num = #recipes + + if num > 0 then + if recipes_cache[output] then + for i = 1, num do + insert(recipes_cache[output], 1, recipes[i]) + end + else + recipes_cache[output] = recipes + end + end +end + local function get_recipes(item, data, player) local recipes = recipes_cache[item] local usages = usages_cache[item] @@ -935,6 +951,10 @@ local function get_init_items() if show_item(def) then cache_usages(name) + if not recipes_cache[name] then + cache_recipes(name) + end + if recipes_cache[name] or usages_cache[name] then init_items[c] = name c = c + 1 From 60b09a27f7bfee70ab611de23294d98d15c6fa5a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 19 Sep 2019 11:54:38 +0200 Subject: [PATCH 128/188] Ensure that no fuel usages are not shown --- init.lua | 109 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/init.lua b/init.lua index 5c32121..196b066 100644 --- a/init.lua +++ b/init.lua @@ -22,6 +22,7 @@ local show_formspec = core.show_formspec local globalstep = core.register_globalstep local on_shutdown = core.register_on_shutdown local get_players = core.get_connected_players +local get_craft_result = core.get_craft_result local on_joinplayer = core.register_on_joinplayer local get_all_recipes = core.get_all_craft_recipes local register_command = core.register_chatcommand @@ -58,15 +59,15 @@ local DEV_CORE = sub(core.get_version().string, -3) == "dev" craftguide.background = "craftguide_bg_full.png:10" local PNG = { - bg = "craftguide_bg.png", - search = "craftguide_search_icon.png", - clear = "craftguide_clear_icon.png", - prev = "craftguide_next_icon.png^\\[transformFX", - next = "craftguide_next_icon.png", - arrow = "craftguide_arrow.png", - fire = "craftguide_fire.png", - book = "craftguide_book.png", - sign = "craftguide_sign.png", + bg = "craftguide_bg.png", + search = "craftguide_search_icon.png", + clear = "craftguide_clear_icon.png", + prev = "craftguide_next_icon.png^\\[transformFX", + next = "craftguide_next_icon.png", + arrow = "craftguide_arrow.png", + fire = "craftguide_fire.png", + book = "craftguide_book.png", + sign = "craftguide_sign.png", } local FMT = { @@ -81,12 +82,12 @@ local FMT = { } craftguide.group_stereotypes = { - wool = "wool:white", - dye = "dye:white", + dye = "dye:white", + wool = "wool:white", + coal = "default:coal_lump", + vessel = "vessels:glass_bottle", + flower = "flowers:dandelion_yellow", water_bucket = "bucket:bucket_water", - vessel = "vessels:glass_bottle", - coal = "default:coal_lump", - flower = "flowers:dandelion_yellow", mesecon_conductor_craftable = "mesecons:wire_00000000_off", } @@ -159,7 +160,7 @@ end function craftguide.register_craft(def) def.custom = true def.width = 0 - local c = 1 + local c = 0 if not is_table(def) or not next(def) then return log("error", "craftguide.register_craft(): craft definition missing") @@ -196,8 +197,8 @@ function craftguide.register_craft(def) end for symbol in gmatch(concat(def.grid), ".") do - def.items[c] = def.key[symbol] c = c + 1 + def.items[c] = def.key[symbol] end else local items, len = def.items, #def.items @@ -219,8 +220,8 @@ function craftguide.register_craft(def) end for name in gmatch(concat(items, ","), "[%s%w_:]+") do - def.items[c] = clean_name(name) c = c + 1 + def.items[c] = clean_name(name) end end @@ -316,8 +317,7 @@ local function groups_item_in_recipe(item, recipe) end local function get_filtered_items(player, data) - local items, c = {}, 0 - local known = 0 + local items, known, c = {}, 0, 0 for i = 1, #init_items do local item = init_items[i] @@ -350,7 +350,6 @@ local function get_usages(item) for _, recipes in pairs(recipes_cache) do for i = 1, #recipes do local recipe = recipes[i] - if item_in_recipe(item, recipe) then c = c + 1 usages[c] = recipe @@ -367,15 +366,25 @@ local function get_usages(item) if fuel_cache[item] then usages[#usages + 1] = { type = "fuel", - width = 1, items = {item}, - replacements = fuel_cache[item].replacements, + replacements = fuel_cache.replacements[item], } end return usages end +local function get_burntime(item) + return get_craft_result({method = "fuel", items = {item}}).time +end + +local function cache_fuel(item) + local burntime = get_burntime(item) + if burntime > 0 then + fuel_cache[item] = burntime + end +end + local function cache_usages(item) local usages = get_usages(item) if #usages > 0 then @@ -385,16 +394,8 @@ end local function cache_recipes(output) local recipes = get_all_recipes(output) or {} - local num = #recipes - - if num > 0 then - if recipes_cache[output] then - for i = 1, num do - insert(recipes_cache[output], 1, recipes[i]) - end - else - recipes_cache[output] = recipes - end + if #recipes > 0 then + recipes_cache[output] = recipes end end @@ -478,7 +479,7 @@ local function get_tooltip(item, info) tooltip = get_desc(reg_items[item]) local function add(str) - return tooltip .. "\n" .. str + return fmt("%s\n%s", tooltip, str) end if info.cooktime then @@ -532,7 +533,7 @@ local function get_output_fs(fs, L) pos_x, pos_y, 0.5, 0.5, ESC(tooltip)) end - local arrow_X = L.rightest + (L.s_btn_size or 1.1) + local arrow_X = L.rightest + (L.s_btn_size or 1.1) local output_X = arrow_X + 0.9 fs[#fs + 1] = fmt(FMT.image, @@ -546,13 +547,13 @@ local function get_output_fs(fs, L) else local item = L.recipe.output local name = clean_name(item) - local burntime = fuel_cache[name] and fuel_cache[name].burntime fs[#fs + 1] = fmt(FMT.item_image_button, output_X, YOFFSET + (sfinv_only and 0.7 or 0), 1.1, 1.1, item, ESC(name), "") - local repair = repairable(item) + local burntime = fuel_cache[name] + local repair = repairable(name) if burntime or repair then fs[#fs + 1] = get_tooltip(name, { @@ -575,7 +576,7 @@ end local function get_recipe_fs(data, fs) local recipe = data.recipes[data.rnum] - local width = recipe.width + local width = recipe.width or 1 local replacements = recipe.replacements local cooktime, shapeless @@ -656,12 +657,10 @@ local function get_recipe_fs(data, fs) X, Y + (sfinv_only and 0.7 or 0), btn_size, btn_size, item, clean_name(item), ESC(label)) - local burntime = fuel_cache[item] and fuel_cache[item].burntime - local info = { unknown = not reg_items[item], groups = groups, - burntime = burntime, + burntime = fuel_cache[item], cooktime = cooktime, replace = replace, } @@ -718,11 +717,11 @@ local function make_formspec(name) fs[#fs + 1] = fmt([[ image_button[%f,-0.05;0.8,0.8;%s;prev;;;false;%s^\[colorize:yellow:255] - label[%f,%f;%s / %u] + label[%f,%f;%u / %u] image_button[%f,-0.05;0.8,0.8;%s;next;;;false;%s^\[colorize:yellow:255] ]], sfinv_only and 5.45 or 6.83, PNG.prev, PNG.prev, - sfinv_only and 6.35 or 7.85, 0.06, clr("yellow", data.pagenum), data.pagemax, + sfinv_only and 6.35 or 7.85, 0.06, data.pagenum, data.pagemax, sfinv_only and 7.2 or 8.75, PNG.next, PNG.next) if #data.items == 0 then @@ -809,7 +808,7 @@ local function search(data) local item = data.items_raw[i] local def = reg_items[item] local desc = (def and def.description) and lower(def.description) or "" - local search_in = item .. " " .. desc + local search_in = fmt("%s %s", item, desc) local to_add if search_filter then @@ -863,6 +862,8 @@ end -- we have to override `core.register_craft` and `core.register_alias` and do some reverse engineering. -- See engine's issues #4901 and #8920. +fuel_cache.replacements = {} + local old_register_alias = core.register_alias local current_alias = {} @@ -897,10 +898,13 @@ core.register_craft = function(def) name = current_alias[2] end - def.items = {} + if def.type ~= "fuel" then + def.items = {} + end if def.type == "fuel" then - fuel_cache[name] = def + fuel_cache[name] = def.burntime + fuel_cache.replacements[name] = def.replacements elseif def.type == "cooking" then def.width = def.cooktime @@ -914,18 +918,17 @@ core.register_craft = function(def) end else def.width = #def.recipe[1] - local c = 1 + local c = 0 for j = 1, #def.recipe do if def.recipe[j] then for h = 1, def.width do + c = c + 1 local it = def.recipe[j][h] if it and it ~= "" then def.items[c] = it end - - c = c + 1 end end end @@ -946,18 +949,22 @@ local function show_item(def) end local function get_init_items() - local c = 1 + local c = 0 for name, def in pairs(reg_items) do if show_item(def) then - cache_usages(name) + if not fuel_cache[name] then + cache_fuel(name) + end if not recipes_cache[name] then cache_recipes(name) end + cache_usages(name) + if recipes_cache[name] or usages_cache[name] then - init_items[c] = name c = c + 1 + init_items[c] = name end end end From 3f9d7bc12d406b686744b0a356429a6cdb043cad Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 25 Sep 2019 12:44:49 +0200 Subject: [PATCH 129/188] Table check --- init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/init.lua b/init.lua index 196b066..81ca41b 100644 --- a/init.lua +++ b/init.lua @@ -183,6 +183,10 @@ function craftguide.register_craft(def) def.grid = {} end + if not is_table(def.key) then + def.key = {} + end + local cp = copy(def.grid) sort(cp, function(a, b) return #a > #b From f1843416636c6ec41a7e44f522099eba6bb1c953 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 25 Sep 2019 16:12:33 +0200 Subject: [PATCH 130/188] String checking --- init.lua | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/init.lua b/init.lua index 81ca41b..cb5d4fa 100644 --- a/init.lua +++ b/init.lua @@ -119,8 +119,16 @@ local function table_replace(t, val, new) end end +local function err(str) + return log("error", str) +end + +local function clean_str(str) + return match(str, "%S*") +end + local function is_str(x) - return type(x) == "string" + return type(x) == "string" and clean_str(x) end local function is_table(x) @@ -138,8 +146,8 @@ end local craft_types = {} function craftguide.register_craft_type(name, def) - if not is_str(name) or name == "" then - return log("error", "craftguide.register_craft_type(): name missing") + if not is_str(name) then + return err("craftguide.register_craft_type(): name missing") end if not is_str(def.description) then @@ -153,25 +161,21 @@ function craftguide.register_craft_type(name, def) craft_types[name] = def end -local function clean_name(item) - return match(item, "%S*") -end - function craftguide.register_craft(def) def.custom = true def.width = 0 local c = 0 if not is_table(def) or not next(def) then - return log("error", "craftguide.register_craft(): craft definition missing") + return err("craftguide.register_craft(): craft definition missing") end if def.result then def.output = def.result -- Backward compatibility end - if not is_str(def.output) or def.output == "" then - return log("error", "craftguide.register_craft(): output missing") + if not is_str(def.output) then + return err("craftguide.register_craft(): output missing") end if not is_table(def.items) then @@ -225,11 +229,11 @@ function craftguide.register_craft(def) for name in gmatch(concat(items, ","), "[%s%w_:]+") do c = c + 1 - def.items[c] = clean_name(name) + def.items[c] = clean_str(name) end end - local output = clean_name(def.output) + local output = clean_str(def.output) recipes_cache[output] = recipes_cache[output] or {} insert(recipes_cache[output], def) end @@ -237,10 +241,10 @@ end local recipe_filters = {} function craftguide.add_recipe_filter(name, f) - if not is_str(name) or name == "" then - return log("error", "craftguide.add_recipe_filter(): name missing") + if not is_str(name) then + return err("craftguide.add_recipe_filter(): name missing") elseif not is_func(f) then - return log("error", "craftguide.add_recipe_filter(): function missing") + return err("craftguide.add_recipe_filter(): function missing") end recipe_filters[name] = f @@ -265,10 +269,10 @@ end local search_filters = {} function craftguide.add_search_filter(name, f) - if not is_str(name) or name == "" then - return log("error", "craftguide.add_search_filter(): name missing") + if not is_str(name) then + return err("craftguide.add_search_filter(): name missing") elseif not is_func(f) then - return log("error", "craftguide.add_search_filter(): function missing") + return err("craftguide.add_search_filter(): function missing") end search_filters[name] = f @@ -550,7 +554,7 @@ local function get_output_fs(fs, L) 1.1, 1.1, PNG.fire) else local item = L.recipe.output - local name = clean_name(item) + local name = clean_str(item) fs[#fs + 1] = fmt(FMT.item_image_button, output_X, YOFFSET + (sfinv_only and 0.7 or 0), @@ -659,7 +663,7 @@ local function get_recipe_fs(data, fs) fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, clean_name(item), ESC(label)) + btn_size, btn_size, item, clean_str(item), ESC(label)) local info = { unknown = not reg_items[item], @@ -885,9 +889,9 @@ core.register_craft = function(def) toolrepair = def.additional_wear * -100 end - local output = def.output or (is_str(def.recipe) and def.recipe or "") - if output == "" then return end - output = {clean_name(output)} + local output = def.output or is_str(def.recipe) + if not output then return end + output = {clean_str(output)} local groups @@ -1517,8 +1521,8 @@ register_command("craft", { }) function craftguide.show(name, item, show_usages) - if not is_str(name) or name == "" then - return log("error", "craftguide.show(): player name missing") + if not is_str(name) then + return err("craftguide.show(): player name missing") end local data = pdata[name] From dd98cb2cb3cde20cc10b0ac3e15395c684f5d2ca Mon Sep 17 00:00:00 2001 From: h4ml3t <54187342+h4ml3t@users.noreply.github.com> Date: Sun, 29 Sep 2019 13:30:22 +0200 Subject: [PATCH 131/188] Italian locale --- locale/craftguide.it.tr | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 locale/craftguide.it.tr diff --git a/locale/craftguide.it.tr b/locale/craftguide.it.tr new file mode 100644 index 0000000..189f675 --- /dev/null +++ b/locale/craftguide.it.tr @@ -0,0 +1,23 @@ +# textdomain: craftguide + +Craft Guide=Guida di assemblaggio +Crafting Guide=Guida d'assemblaggio +Crafting Guide Sign=Cartello della guida d'assemblaggio +Usage @1 of @2=Utilizzo @1 di @2 +Recipe @1 of @2=Ricetta @1 di @2 +Burning time: @1=Tempo di bruciatura: @1 +Cooking time: @1=Tempo di cottura: @1 +Replaced by @1 on smelting=Sostituito da @1 alla fusione +Replaced by @1 on burning=Sostituito da @1 alla bruciatura +Replaced by @1 on crafting=Sostituito da @1 all'assemblaggio +Repairable by step of @1=Riparabile per passo di @1 +Any item belonging to the group(s): @1=Qualunque oggetto appartenente al gruppo: @1 +Recipe's too big to be displayed (@1x@2)=La ricetta è troppo grande per essere mostrata (@1x@2) +Shapeless=Senza forma +Cooking=Cottura +No item to show=Nessun oggetto da mostrare +Collect items to reveal more recipes=Raccogli oggetti per svelare più ricette +Show recipe(s) of the pointed node=Mostra la ricetta del nodo puntato +No node pointed=Nessun nodo puntato +You don't know a recipe for this node=Non conosci una ricetta per questo nodo +No recipe for this node=Nessuna ricetta per questo nodo From aef1fe0dc6863cff47312068a7519c9b03b8012f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 29 Sep 2019 15:16:41 +0200 Subject: [PATCH 132/188] Fix non-shown aliased recipes --- init.lua | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index cb5d4fa..eb507a3 100644 --- a/init.lua +++ b/init.lua @@ -7,6 +7,7 @@ local searches = {} local recipes_cache = {} local usages_cache = {} local fuel_cache = {} +local alias_cache = {} local toolrepair @@ -873,15 +874,13 @@ end fuel_cache.replacements = {} local old_register_alias = core.register_alias -local current_alias = {} +local old_register_craft = core.register_craft core.register_alias = function(old, new) old_register_alias(old, new) - current_alias = {old, new} + alias_cache[new] = old end -local old_register_craft = core.register_craft - core.register_craft = function(def) old_register_craft(def) @@ -902,9 +901,6 @@ core.register_craft = function(def) for i = 1, #output do local name = output[i] - if name == current_alias[1] then - name = current_alias[2] - end if def.type ~= "fuel" then def.items = {} @@ -960,6 +956,20 @@ local function get_init_items() local c = 0 for name, def in pairs(reg_items) do if show_item(def) then + local old_name = alias_cache[name] + if old_name then + local old_recipes = recipes_cache[old_name] + local old_usages = usages_cache[old_name] + + if old_recipes then + recipes_cache[name] = old_recipes + end + + if old_usages then + usages_cache[name] = old_usages + end + end + if not fuel_cache[name] then cache_fuel(name) end From 29f87f2607b33c9cbe7d03c5785b319179904026 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 29 Sep 2019 15:20:21 +0200 Subject: [PATCH 133/188] Put the page number color back --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index eb507a3..95dfae3 100644 --- a/init.lua +++ b/init.lua @@ -726,11 +726,11 @@ local function make_formspec(name) fs[#fs + 1] = fmt([[ image_button[%f,-0.05;0.8,0.8;%s;prev;;;false;%s^\[colorize:yellow:255] - label[%f,%f;%u / %u] + label[%f,%f;%s / %u] image_button[%f,-0.05;0.8,0.8;%s;next;;;false;%s^\[colorize:yellow:255] ]], sfinv_only and 5.45 or 6.83, PNG.prev, PNG.prev, - sfinv_only and 6.35 or 7.85, 0.06, data.pagenum, data.pagemax, + sfinv_only and 6.35 or 7.85, 0.06, clr("yellow", data.pagenum), data.pagemax, sfinv_only and 7.2 or 8.75, PNG.next, PNG.next) if #data.items == 0 then From 07820fa37c93e8c158b419cc68595ee817468595 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 29 Sep 2019 15:24:04 +0200 Subject: [PATCH 134/188] Re-add accidentally removed --- API.md | 4 ++++ init.lua | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/API.md b/API.md index a6e3df8..f19f475 100644 --- a/API.md +++ b/API.md @@ -82,6 +82,10 @@ craftguide.add_recipe_filter("Hide secretstuff", function(recipes) end) ``` +#### `craftguide.set_recipe_filter(name, function(recipe, player))` + +Removes all recipe filters and adds a new one. + #### `craftguide.remove_recipe_filter(name)` Removes the recipe filter with the given name. diff --git a/init.lua b/init.lua index 95dfae3..46aff49 100644 --- a/init.lua +++ b/init.lua @@ -251,6 +251,16 @@ function craftguide.add_recipe_filter(name, f) recipe_filters[name] = f end +function craftguide.set_recipe_filter(name, f) + if not is_str(name) then + return err("craftguide.set_recipe_filter(): name missing") + elseif not is_func(f) then + return err("craftguide.set_recipe_filter(): function missing") + end + + recipe_filters = {[name] = f} +end + function craftguide.remove_recipe_filter(name) recipe_filters[name] = nil end From 9dd63cd83a7cdb77775fe54f19b77607cad26af1 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 29 Sep 2019 15:28:53 +0200 Subject: [PATCH 135/188] Fixed comment --- init.lua | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index 46aff49..43b31a8 100644 --- a/init.lua +++ b/init.lua @@ -877,20 +877,22 @@ local function reset_data(data) data.items = data.items_raw end --- As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not return the replacements, --- we have to override `core.register_craft` and `core.register_alias` and do some reverse engineering. --- See engine's issues #4901 and #8920. - -fuel_cache.replacements = {} - local old_register_alias = core.register_alias -local old_register_craft = core.register_craft core.register_alias = function(old, new) old_register_alias(old, new) alias_cache[new] = old end +--[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not + return the replacements and toolrepair, we have to override + `core.register_craft` and do some reverse engineering. + See engine's issues #4901 and #8920. ]] + +fuel_cache.replacements = {} + +local old_register_craft = core.register_craft + core.register_craft = function(def) old_register_craft(def) From 19fb5e2691f6f1c54c2a850fe0682109fa88bbe2 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 29 Sep 2019 16:58:33 +0200 Subject: [PATCH 136/188] Check compat for background[] --- API.md | 2 +- init.lua | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/API.md b/API.md index f19f475..519cc03 100644 --- a/API.md +++ b/API.md @@ -174,7 +174,7 @@ craftguide.group_stereotypes.radioactive = "mod:item" You can set a custom background theme by overriding this variable: ```Lua -craftguide.background = ":" +craftguide.background = "#" ``` diff --git a/init.lua b/init.lua index 43b31a8..5ff5f30 100644 --- a/init.lua +++ b/init.lua @@ -55,9 +55,11 @@ local WH_LIMIT = 8 local XOFFSET = sfinv_only and 3.83 or 4.66 local YOFFSET = sfinv_only and 6 or 6.6 -local DEV_CORE = sub(core.get_version().string, -3) == "dev" +local CORE_VERSION = core.get_version().string + CORE_VERSION = match(CORE_VERSION, "[^%-]*"):gsub("%.", "") + CORE_VERSION = tonumber(CORE_VERSION) -craftguide.background = "craftguide_bg_full.png:10" +craftguide.background = "craftguide_bg_full.png#10" local PNG = { bg = "craftguide_bg.png", @@ -708,17 +710,19 @@ local function make_formspec(name) local fs = {} if not sfinv_only then - local bg, middle = match(craftguide.background, "(.-):(%d+)") + local bg, middle = match(craftguide.background, "([%w_%.]*)([#%d]*)") bg = bg or "" - middle = middle or "10" + middle = tonumber(sub(middle, 2)) or 10 - fs[#fs + 1] = fmt([[ + fs[#fs + 1] = [[ size[9.5,8.4] no_prepend[] - bgcolor[#00000000;false] - background[1,1;1,1;%s;true%s] - ]], - bg, DEV_CORE and ";" .. middle or "") + bgcolor[#0000] + ]] + + fs[#fs + 1] = CORE_VERSION >= 510 and + fmt("background9[1,1;1,1;%s;true;%d]", bg, middle) or + fmt("background[1,1;1,1;%s;true]", bg) end fs[#fs + 1] = fmt([[ From 3320fbdd6b725ba27fdc6ce78810528e254749ee Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 29 Sep 2019 18:34:17 +0200 Subject: [PATCH 137/188] Full backward compat with MT 0.4.17 --- init.lua | 95 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/init.lua b/init.lua index 5ff5f30..a0afc1d 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,9 @@ craftguide = {} +local CORE_VERSION = core.get_version().string + CORE_VERSION = CORE_VERSION:match("[^%-]*"):gsub("%.", "") + CORE_VERSION = tonumber(CORE_VERSION) + -- Caches local pdata = {} local init_items = {} @@ -28,13 +32,22 @@ local on_joinplayer = core.register_on_joinplayer local get_all_recipes = core.get_all_craft_recipes local register_command = core.register_chatcommand local get_player_by_name = core.get_player_by_name +local slz, dslz = core.serialize, core.deserialize local on_mods_loaded = core.register_on_mods_loaded local on_leaveplayer = core.register_on_leaveplayer -local serialize, deserialize = core.serialize, core.deserialize local on_receive_fields = core.register_on_player_receive_fields local ESC = core.formspec_escape -local S = core.get_translator("craftguide") +local S = CORE_VERSION >= 500 and core.get_translator("craftguide") or + function(...) + local args = {...} + local i = 1 + + return args[1]:gsub("@%d+", function() + i = i + 1 + return args[i] + end) + end local maxn, sort, concat, copy, insert = table.maxn, table.sort, table.concat, table.copy, table.insert @@ -55,10 +68,6 @@ local WH_LIMIT = 8 local XOFFSET = sfinv_only and 3.83 or 4.66 local YOFFSET = sfinv_only and 6 or 6.6 -local CORE_VERSION = core.get_version().string - CORE_VERSION = match(CORE_VERSION, "[^%-]*"):gsub("%.", "") - CORE_VERSION = tonumber(CORE_VERSION) - craftguide.background = "craftguide_bg_full.png#10" local PNG = { @@ -550,8 +559,9 @@ local function get_output_fs(fs, L) local tooltip = custom_recipe and custom_recipe.description or L.shapeless and S("Shapeless") or S("Cooking") - fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]", - pos_x, pos_y, 0.5, 0.5, ESC(tooltip)) + if CORE_VERSION >= 500 then + fs[#fs + 1] = fmt(FMT.tooltip, pos_x, pos_y, 0.5, 0.5, ESC(tooltip)) + end end local arrow_X = L.rightest + (L.s_btn_size or 1.1) @@ -862,25 +872,6 @@ local function search(data) data.items = filtered_list end -local function init_data(name) - pdata[name] = { - filter = "", - pagenum = 1, - items = init_items, - items_raw = init_items, - } -end - -local function reset_data(data) - data.filter = "" - data.pagenum = 1 - data.rnum = 1 - data.query_item = nil - data.show_usages = nil - data.recipes = nil - data.items = data.items_raw -end - local old_register_alias = core.register_alias core.register_alias = function(old, new) @@ -1006,7 +997,31 @@ local function get_init_items() sort(init_items) end -on_mods_loaded(get_init_items) +local function init_data(name) + local items = CORE_VERSION >= 500 and init_items or + (#init_items == 0 and get_init_items() or init_items) + + pdata[name] = { + filter = "", + pagenum = 1, + items = items, + items_raw = items, + } +end + +local function reset_data(data) + data.filter = "" + data.pagenum = 1 + data.rnum = 1 + data.query_item = nil + data.show_usages = nil + data.recipes = nil + data.items = data.items_raw +end + +if CORE_VERSION >= 500 then + on_mods_loaded(get_init_items) +end on_joinplayer(function(player) local name = player:get_player_name() @@ -1419,12 +1434,17 @@ if progressive_mode then on_joinplayer(function(player) PLAYERS = get_players() - local meta = player:get_meta() local name = player:get_player_name() local data = pdata[name] - data.inv_items = deserialize(meta:get_string("inv_items")) or {} - data.known_recipes = deserialize(meta:get_string("known_recipes")) or 0 + if CORE_VERSION >= 500 then + local meta = player:get_meta() + data.inv_items = dslz(meta:get_string("inv_items")) or {} + data.known_recipes = dslz(meta:get_string("known_recipes")) or 0 + else + data.inv_items = dslz(player:get_attribute("inv_items")) or {} + data.known_recipes = dslz(player:get_attribute("known_recipes")) or 0 + end data.hud = { bg = player:hud_add({ @@ -1459,13 +1479,22 @@ if progressive_mode then } local function save_meta(player) - local meta = player:get_meta() + local meta local name = player:get_player_name() local data = pdata[name] + if CORE_VERSION >= 500 then + meta = player:get_meta() + end + for i = 1, #to_save do local meta_name = to_save[i] - meta:set_string(meta_name, serialize(data[meta_name])) + + if CORE_VERSION >= 500 then + meta:set_string(meta_name, slz(data[meta_name])) + else + player:set_attribute(meta_name, slz(data[meta_name])) + end end end From e2134e479e80e8efc6d16cbd3edf2d02c421f4ed Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 29 Sep 2019 20:39:31 +0200 Subject: [PATCH 138/188] Delete description file --- description.txt | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 description.txt diff --git a/description.txt b/description.txt deleted file mode 100644 index b5c0540..0000000 --- a/description.txt +++ /dev/null @@ -1,2 +0,0 @@ -The most comprehensive Crafting Guide -on Minetest. From a50a99836a5114ad35f4677d491a4ec6ec9910f9 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 29 Sep 2019 21:03:15 +0200 Subject: [PATCH 139/188] Fix version number check --- init.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/init.lua b/init.lua index a0afc1d..e0d71a5 100644 --- a/init.lua +++ b/init.lua @@ -1,8 +1,11 @@ craftguide = {} -local CORE_VERSION = core.get_version().string - CORE_VERSION = CORE_VERSION:match("[^%-]*"):gsub("%.", "") - CORE_VERSION = tonumber(CORE_VERSION) +local p = 0 +local CORE_VERSION = core.get_version().string:match("[^%-]*"):gsub("%.", function(a) + p = p + 1 + return p == 3 and a or "" +end) +CORE_VERSION = tonumber(CORE_VERSION) -- Caches local pdata = {} @@ -40,8 +43,7 @@ local on_receive_fields = core.register_on_player_receive_fields local ESC = core.formspec_escape local S = CORE_VERSION >= 500 and core.get_translator("craftguide") or function(...) - local args = {...} - local i = 1 + local args, i = {...}, 1 return args[1]:gsub("@%d+", function() i = i + 1 From bb6b3a4ee58cfc1383847e7d74e460e0dfd3ef93 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 30 Sep 2019 11:17:01 +0200 Subject: [PATCH 140/188] Show recipes for force-alised items --- init.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/init.lua b/init.lua index e0d71a5..4bfe149 100644 --- a/init.lua +++ b/init.lua @@ -881,6 +881,13 @@ core.register_alias = function(old, new) alias_cache[new] = old end +local old_register_alias_force = core.register_alias_force + +core.register_alias_force = function(old, new) + old_register_alias_force(old, new) + alias_cache[new] = old +end + --[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not return the replacements and toolrepair, we have to override `core.register_craft` and do some reverse engineering. From 94637c624ef0d4a0ecd8a285b8c16aa43842b551 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 30 Sep 2019 16:33:15 +0200 Subject: [PATCH 141/188] Do not override alias func --- init.lua | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/init.lua b/init.lua index 4bfe149..c6ab853 100644 --- a/init.lua +++ b/init.lua @@ -14,7 +14,6 @@ local searches = {} local recipes_cache = {} local usages_cache = {} local fuel_cache = {} -local alias_cache = {} local toolrepair @@ -26,6 +25,7 @@ local after = core.after local clr = core.colorize local reg_tools = core.registered_tools local reg_items = core.registered_items +local reg_alias = core.registered_aliases local show_formspec = core.show_formspec local globalstep = core.register_globalstep local on_shutdown = core.register_on_shutdown @@ -874,20 +874,6 @@ local function search(data) data.items = filtered_list end -local old_register_alias = core.register_alias - -core.register_alias = function(old, new) - old_register_alias(old, new) - alias_cache[new] = old -end - -local old_register_alias_force = core.register_alias_force - -core.register_alias_force = function(old, new) - old_register_alias_force(old, new) - alias_cache[new] = old -end - --[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not return the replacements and toolrepair, we have to override `core.register_craft` and do some reverse engineering. @@ -972,7 +958,7 @@ local function get_init_items() local c = 0 for name, def in pairs(reg_items) do if show_item(def) then - local old_name = alias_cache[name] + local old_name = reg_alias[name] if old_name then local old_recipes = recipes_cache[old_name] local old_usages = usages_cache[old_name] From 9e48e9ea3e79ecd9c2d520f3a239999f811aa661 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 30 Sep 2019 18:04:50 +0200 Subject: [PATCH 142/188] Fix missing recipes (again) --- init.lua | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/init.lua b/init.lua index c6ab853..d1410a8 100644 --- a/init.lua +++ b/init.lua @@ -25,8 +25,8 @@ local after = core.after local clr = core.colorize local reg_tools = core.registered_tools local reg_items = core.registered_items -local reg_alias = core.registered_aliases local show_formspec = core.show_formspec +local reg_aliases = core.registered_aliases local globalstep = core.register_globalstep local on_shutdown = core.register_on_shutdown local get_players = core.get_connected_players @@ -958,20 +958,6 @@ local function get_init_items() local c = 0 for name, def in pairs(reg_items) do if show_item(def) then - local old_name = reg_alias[name] - if old_name then - local old_recipes = recipes_cache[old_name] - local old_usages = usages_cache[old_name] - - if old_recipes then - recipes_cache[name] = old_recipes - end - - if old_usages then - usages_cache[name] = old_usages - end - end - if not fuel_cache[name] then cache_fuel(name) end @@ -989,6 +975,20 @@ local function get_init_items() end end + for name in pairs(reg_aliases) do + local def = reg_items[name] + if def and show_item(def) then + if not recipes_cache[name] then + cache_recipes(name) + end + + if recipes_cache[name] then + c = c + 1 + init_items[c] = name + end + end + end + sort(init_items) end From b09870a5b295f1b87036c0bdb85769600688feb1 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 1 Oct 2019 13:05:53 +0200 Subject: [PATCH 143/188] Fix aliased items --- init.lua | 92 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 35 deletions(-) diff --git a/init.lua b/init.lua index d1410a8..69c516c 100644 --- a/init.lua +++ b/init.lua @@ -105,6 +105,32 @@ craftguide.group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } +local function table_diff(t1, t2) + local hash = {} + + for i = 1, #t1 do + local v = t1[i] + hash[v] = true + end + + for i = 1, #t2 do + local v = t2[i] + hash[v] = nil + end + + local diff, c = {}, 0 + + for i = 1, #t1 do + local v = t1[i] + if hash[v] then + c = c + 1 + diff[c] = v + end + end + + return diff +end + local function table_merge(t1, t2, hash) t1 = t1 or {} t2 = t2 or {} @@ -333,6 +359,7 @@ end local function groups_item_in_recipe(item, recipe) local def = reg_items[item] + if not def then return end local item_groups = def.groups for _, recipe_item in pairs(recipe.items) do @@ -955,7 +982,7 @@ local function show_item(def) end local function get_init_items() - local c = 0 + local hash, c = {}, 0 for name, def in pairs(reg_items) do if show_item(def) then if not fuel_cache[name] then @@ -971,22 +998,43 @@ local function get_init_items() if recipes_cache[name] or usages_cache[name] then c = c + 1 init_items[c] = name + hash[name] = true end end end - for name in pairs(reg_aliases) do - local def = reg_items[name] - if def and show_item(def) then - if not recipes_cache[name] then - cache_recipes(name) + for oldname, newname in pairs(reg_aliases) do + local recipes = recipes_cache[oldname] + if recipes then + if not recipes_cache[newname] then + recipes_cache[newname] = {} end - if recipes_cache[name] then - c = c + 1 - init_items[c] = name + local is_similar + + for i = 1, #recipes_cache[oldname] do + local rcp_old = recipes_cache[oldname][i] + + for j = 1, #recipes_cache[newname] do + local rcp_new = recipes_cache[newname][j] + local diff = table_diff(rcp_old, rcp_new) + + if #diff == 0 then + is_similar = true + break + end + end + + if not is_similar then + insert(recipes_cache[newname], rcp_old) + end end end + + if recipes_cache[oldname] and not hash[newname] then + c = c + 1 + init_items[c] = newname + end end sort(init_items) @@ -1219,32 +1267,6 @@ if progressive_mode then local POLL_FREQ = 0.25 local HUD_TIMER_MAX = 1.5 - local function table_diff(t1, t2) - local hash = {} - - for i = 1, #t1 do - local v = t1[i] - hash[v] = true - end - - for i = 1, #t2 do - local v = t2[i] - hash[v] = nil - end - - local diff, c = {}, 0 - - for i = 1, #t1 do - local v = t1[i] - if hash[v] then - c = c + 1 - diff[c] = v - end - end - - return diff - end - local function item_in_inv(item, inv_items) local inv_items_size = #inv_items From 937f5f0918fc4c0f3c74274b076828535ceedfa6 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 3 Oct 2019 17:02:19 +0200 Subject: [PATCH 144/188] Fix aliased items once and for all(?) --- init.lua | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index 69c516c..eeb7e42 100644 --- a/init.lua +++ b/init.lua @@ -51,15 +51,16 @@ local S = CORE_VERSION >= 500 and core.get_translator("craftguide") or end) end -local maxn, sort, concat, copy, insert = - table.maxn, table.sort, table.concat, table.copy, table.insert +local maxn, sort, concat, copy, insert, remove = + table.maxn, table.sort, table.concat, table.copy, + table.insert, table.remove local fmt, find, gmatch, match, sub, split, upper, lower = string.format, string.find, string.gmatch, string.match, string.sub, string.split, string.upper, string.lower local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil -local pairs, next = pairs, next +local pairs, next, type = pairs, next, type local vec_add, vec_mul = vector.add, vector.multiply local ROWS = sfinv_only and 9 or 11 @@ -105,7 +106,7 @@ craftguide.group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } -local function table_diff(t1, t2) +local function array_diff(t1, t2) local hash = {} for i = 1, #t1 do @@ -131,6 +132,60 @@ local function table_diff(t1, t2) return diff end +local function table_eq(T1, T2) + local avoid_loops = {} + + local function recurse(t1, t2) + if type(t1) ~= type(t2) then return end + if type(t1) ~= "table" then + return t1 == t2 + end + + if avoid_loops[t1] then return + avoid_loops[t1] == t2 + end + + avoid_loops[t1] = t2 + local t2keys = {} + local t2tablekeys = {} + + for k in pairs(t2) do + if type(k) == "table" then + insert(t2tablekeys, k) + end + + t2keys[k] = true + end + + for k1, v1 in pairs(t1) do + local v2 = t2[k1] + if type(k1) == "table" then + local ok + for i = 1, #t2tablekeys do + local tk = t2tablekeys[i] + if table_eq(k1, tk) and recurse(v1, t2[tk]) then + remove(t2tablekeys, i) + t2keys[tk] = nil + ok = true + break + end + end + + if not ok then return end + else + if v2 == nil then return end + t2keys[k1] = nil + if not recurse(v1, v2) then return end + end + end + + if next(t2keys) then return end + return true + end + + return recurse(T1, T2) +end + local function table_merge(t1, t2, hash) t1 = t1 or {} t2 = t2 or {} @@ -1017,9 +1072,10 @@ local function get_init_items() for j = 1, #recipes_cache[newname] do local rcp_new = recipes_cache[newname][j] - local diff = table_diff(rcp_old, rcp_new) + rcp_new.type = nil + rcp_new.method = nil - if #diff == 0 then + if table_eq(rcp_old, rcp_new) then is_similar = true break end @@ -1407,7 +1463,7 @@ if progressive_mode then local data = pdata[name] local inv_items = get_inv_items(player) - local diff = table_diff(inv_items, data.inv_items) + local diff = array_diff(inv_items, data.inv_items) if #diff > 0 then data.inv_items = table_merge(diff, data.inv_items) From 502318fb66a71d7d28554a95ff02bfe1fb7ba634 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 3 Oct 2019 22:08:51 +0200 Subject: [PATCH 145/188] Major Interface Overhaul --- init.lua | 508 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 311 insertions(+), 197 deletions(-) diff --git a/init.lua b/init.lua index eeb7e42..f98dba8 100644 --- a/init.lua +++ b/init.lua @@ -20,13 +20,17 @@ local toolrepair local progressive_mode = core.settings:get_bool("craftguide_progressive_mode") local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") +local reg_items = core.registered_items +local reg_nodes = core.registered_nodes +local reg_tools = core.registered_tools +local reg_entities = core.registered_nodes +local reg_aliases = core.registered_aliases +local reg_craftitems = core.registered_craftitems + local log = core.log local after = core.after local clr = core.colorize -local reg_tools = core.registered_tools -local reg_items = core.registered_items local show_formspec = core.show_formspec -local reg_aliases = core.registered_aliases local globalstep = core.register_globalstep local on_shutdown = core.register_on_shutdown local get_players = core.get_connected_players @@ -63,26 +67,25 @@ local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local pairs, next, type = pairs, next, type local vec_add, vec_mul = vector.add, vector.multiply -local ROWS = sfinv_only and 9 or 11 -local LINES = 5 +local ROWS = 9 +local LINES = sfinv_only and 5 or 9 local IPP = ROWS * LINES local WH_LIMIT = 8 -local XOFFSET = sfinv_only and 3.83 or 4.66 -local YOFFSET = sfinv_only and 6 or 6.6 - -craftguide.background = "craftguide_bg_full.png#10" +local XOFFSET = sfinv_only and 3.83 or 11.2 +local YOFFSET = sfinv_only and 6 or 1 local PNG = { - bg = "craftguide_bg.png", - search = "craftguide_search_icon.png", - clear = "craftguide_clear_icon.png", - prev = "craftguide_next_icon.png^\\[transformFX", - next = "craftguide_next_icon.png", - arrow = "craftguide_arrow.png", - fire = "craftguide_fire.png", - book = "craftguide_book.png", - sign = "craftguide_sign.png", + bg = "craftguide_bg.png", + bg_full = "craftguide_bg_full.png", + search = "craftguide_search_icon.png", + clear = "craftguide_clear_icon.png", + prev = "craftguide_next_icon.png^\\[transformFX", + next = "craftguide_next_icon.png", + arrow = "craftguide_arrow.png", + fire = "craftguide_fire.png", + book = "craftguide_book.png", + sign = "craftguide_sign.png", } local FMT = { @@ -522,19 +525,18 @@ local function get_recipes(item, data, player) end local no_recipes = not recipes or #recipes == 0 - if no_recipes and not usages then return - elseif usages and no_recipes then + elseif sfinv_only and usages and no_recipes then data.show_usages = true end - if data.show_usages then - recipes = apply_recipe_filters(usages_cache[item], player) - if recipes and #recipes == 0 then return end + if not sfinv_only or (sfinv_only and data.show_usages) then + usages = apply_recipe_filters(usages, player) + if usages and #usages == 0 then return end end - return recipes + return recipes, usages end local function groups_to_items(groups, get_all) @@ -566,6 +568,14 @@ local function repairable(tool) return toolrepair and def and def.groups and def.groups.disable_repair ~= 1 end +local function get_desc(name) + local def = reg_items[name] + + return def and (match(def.description, "%)([%w%s]*)") or def.description) or + (def and match(name, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or + S("Unknown Item (@1)", name)) +end + local function get_tooltip(item, info) local tooltip @@ -583,14 +593,7 @@ local function get_tooltip(item, info) return fmt("tooltip[%s;%s]", item, ESC(tooltip)) end - local function get_desc(def, name) - name = name or item - return def and def.description or - (def and match(name, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") or - S("Unknown Item (@1)", name)) - end - - tooltip = get_desc(reg_items[item]) + tooltip = get_desc(item) local function add(str) return fmt("%s\n%s", tooltip, str) @@ -605,8 +608,7 @@ local function get_tooltip(item, info) end if info.replace then - local def = reg_items[info.replace] - local desc = clr("yellow", get_desc(def, info.replace)) + local desc = clr("yellow", get_desc(info.replace)) if info.cooktime then tooltip = add(S("Replaced by @1 on smelting", desc)) @@ -638,13 +640,13 @@ local function get_output_fs(fs, L) local pos_x = L.rightest + L.btn_size + 0.1 local pos_y = YOFFSET + (sfinv_only and 0.25 or -0.45) - fs[#fs + 1] = fmt(FMT.image, pos_x, pos_y, 0.5, 0.5, icon) + fs[#fs + 1] = fmt(FMT.image, pos_x, pos_y + L.spacing, 0.5, 0.5, icon) local tooltip = custom_recipe and custom_recipe.description or L.shapeless and S("Shapeless") or S("Cooking") if CORE_VERSION >= 500 then - fs[#fs + 1] = fmt(FMT.tooltip, pos_x, pos_y, 0.5, 0.5, ESC(tooltip)) + fs[#fs + 1] = fmt(FMT.tooltip, pos_x, pos_y + L.spacing, 0.5, 0.5, ESC(tooltip)) end end @@ -652,21 +654,25 @@ local function get_output_fs(fs, L) local output_X = arrow_X + 0.9 fs[#fs + 1] = fmt(FMT.image, - arrow_X, YOFFSET + (sfinv_only and 0.9 or 0.2), + arrow_X, YOFFSET + (sfinv_only and 0.9 or 0.2) + L.spacing, 0.9, 0.7, PNG.arrow) if L.recipe.type == "fuel" then fs[#fs + 1] = fmt(FMT.image, - output_X, YOFFSET + (sfinv_only and 0.7 or 0), + output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, 1.1, 1.1, PNG.fire) else local item = L.recipe.output local name = clean_str(item) fs[#fs + 1] = fmt(FMT.item_image_button, - output_X, YOFFSET + (sfinv_only and 0.7 or 0), + output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, 1.1, 1.1, item, ESC(name), "") + fs[#fs + 1] = fmt(FMT.image, + output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, + 1.1, 1.1, "craftguide_selected.png") + local burntime = fuel_cache[name] local repair = repairable(name) @@ -679,122 +685,236 @@ local function get_output_fs(fs, L) if burntime then fs[#fs + 1] = fmt(FMT.image, - output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1), + output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1) + L.spacing, 0.6, 0.4, PNG.arrow) fs[#fs + 1] = fmt(FMT.image, - output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0), + output_X + 1.6, YOFFSET + (sfinv_only and 0.55 or 0) + L.spacing, 0.6, 0.6, PNG.fire) end end end -local function get_recipe_fs(data, fs) - local recipe = data.recipes[data.rnum] - local width = recipe.width or 1 - local replacements = recipe.replacements - local cooktime, shapeless +local function pretty_wrap(str, limit) + return #str > limit + 3 and sub(str, 1, limit) .. "..." or str +end - if recipe.type == "cooking" then - cooktime, width = width, 1 - elseif width == 0 and not recipe.custom then - shapeless = true - local n = #recipe.items - width = (n < 5 and n > 1) and 2 or min(3, max(1, n)) +local function get_itemdef_fs(fs, L) + fs[#fs + 1] = CORE_VERSION >= 510 and + fmt("background9[8.1,%f;6.6,2.19;%s;false;%d]", + L.y, PNG.bg_full, 10) or + fmt("background[8.1,%f;6.6,2.19;%s;false]", L.y, PNG.bg_full) + + local def = reg_items[L.item] + local namestr = fmt("%s (%s)", pretty_wrap(get_desc(L.item), 25), L.item) + + local typestr = "" + if reg_nodes[L.item] then + typestr = fmt("%s (%s)", ESC(S("Node")), def.drawtype) + elseif reg_entities[L.item] then + typestr = ESC(S("Entity")) + elseif reg_craftitems[L.item] then + typestr = ESC(S("Craftitem")) + elseif reg_tools[L.item] then + typestr = ESC(S("Tool")) end - local rows = ceil(maxn(recipe.items) / width) - local rightest, btn_size, s_btn_size = 0, 1.1 + local groupstr = "" + for k, v in pairs(def.groups or {}) do + groupstr = groupstr .. fmt("%s(%d), ", pretty_wrap(k, 13), v) + end + groupstr = sub(groupstr, 1, -3) - local btn_lab = data.show_usages and - ESC(S("Usage @1 of @2", data.rnum, #data.recipes)) or - ESC(S("Recipe @1 of @2", data.rnum, #data.recipes)) + local specs = { + ESC(S("Name")), + ESC(S("Type")), + ESC(S("Groups")), + } - fs[#fs + 1] = fmt(FMT.button, - XOFFSET + (sfinv_only and 1.98 or 2.7), - YOFFSET + (sfinv_only and 1.9 or 1.2), - 2.2, 1, "alternate", btn_lab) + local tstr = "" + for i = 1, #specs do + tstr = tstr .. "#6389FF," .. specs[i] .. ",#FFFFFF,%s," + end + tstr = sub(tstr, 1, -2) - if width > WH_LIMIT or rows > WH_LIMIT then - fs[#fs + 1] = fmt(FMT.label, - sfinv_only and 2 or 3, 7, - ESC(S("Recipe's too big to be displayed (@1x@2)", width, rows))) + fs[#fs + 1] = [[ + tableoptions[background=#00000000;highlight=#00000000;border=false] + tablecolumns[color;text] + ]] - return concat(fs) + fs[#fs + 1] = fmt("table[8.1,%f;6.3,1.8;itemdef;" .. tstr .. ";0]", + L.y + 0.08, + namestr, + ESC(typestr), + ESC(groupstr)) +end + +local function get_info_fs(data, fs) + local t = {recipes = data.recipes, usages = data.usages} + local infonum = 0 + local last_y + + if sfinv_only then + t = data.show_usages and {usages = data.usages} or {recipes = data.recipes} end - for i = 1, width * rows do - local item = recipe.items[i] or "" - local X = ceil((i - 1) % width - width) + XOFFSET - local Y = ceil(i / width) + YOFFSET - min(2, rows) + for k, v in pairs(t) do + infonum = infonum + 1 + local spacing = (infonum - 1) * 3.6 + last_y = -0.2 + infonum * 3.6 - if width > 3 or rows > 3 then - local xof = 1 - 4 / width - local yof = 1 - 4 / rows - local x_y = width > rows and xof or yof + local rcp = k == "recipes" and v[data.rnum] or v[data.unum] + local width = rcp.width or 1 + local replacements = rcp.replacements + local cooktime, shapeless - btn_size = width > rows and - (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows - s_btn_size = btn_size - - X = (btn_size * ((i - 1) % width) + XOFFSET - - (sfinv_only and 2.83 or (XOFFSET - 2))) * (0.83 - (x_y / 5)) - Y = (btn_size * floor((i - 1) / width) + - (sfinv_only and 5.81 or 6.5) + x_y) * (0.86 - (x_y / 5)) + if rcp.type == "cooking" then + cooktime, width = width, 1 + elseif width == 0 and not rcp.custom then + shapeless = true + local n = #rcp.items + width = (n < 5 and n > 1) and 2 or min(3, max(1, n)) end - if X > rightest then - rightest = X + local rows = ceil(maxn(rcp.items) / width) + local rightest, btn_size, s_btn_size = 0, 1.1 + + if not sfinv_only then + fs[#fs + 1] = CORE_VERSION >= 510 and + fmt("background9[8.1,%f;6.6,3.5;%s;false;%d]", + -0.2 + spacing, PNG.bg_full, 10) or + fmt("background[8.1,%f;6.6,3.5;%s;false]", + -0.2 + spacing, PNG.bg_full) end - local groups + local btn_lab - if is_group(item) then - groups = extract_groups(item) - local items = groups_to_items(groups) - item = items[1] or items + if (not sfinv_only and k == "recipes") or + (sfinv_only and not data.show_usages) then + btn_lab = ESC(S("Recipe @1 of @2", data.rnum, #v)) + elseif not sfinv_only or (sfinv_only and data.show_usages) then + btn_lab = ESC(S("Usage @1 of @2", data.unum, #v)) end - local label = groups and "\nG" or "" - local replace + if sfinv_only then + btn_lab = data.show_usages and + ESC(S("Usage @1 of @2", data.rnum, #v)) or + ESC(S("Recipe @1 of @2", data.rnum, #v)) + end - if replacements then - for j = 1, #replacements do - local replacement = replacements[j] - if replacement[1] == item then - label = "\nR" - replace = replacement[2] + fs[#fs + 1] = fmt(FMT.button, + XOFFSET + (sfinv_only and 1.98 or 1.12), + YOFFSET + (sfinv_only and 1.9 or 1.2 + spacing), + 2.2, 1, "alternate_" .. (k == "recipes" and "recipe" or "usage"), btn_lab) + + if width > WH_LIMIT or rows > WH_LIMIT then + fs[#fs + 1] = fmt(FMT.label, + sfinv_only and 2 or 3, 7, + ESC(S("Recipe's too big to be displayed (@1x@2)", width, rows))) + + return concat(fs) + end + + local large_recipe = width > 3 or rows > 3 + + if large_recipe then + fs[#fs + 1] = "style_type[item_image_button;border=true]" + end + + for i = 1, width * rows do + local item = rcp.items[i] + local X = ceil((i - 1) % width - width) + XOFFSET + local Y = ceil(i / width) + YOFFSET - min(2, rows) + spacing + + if item or large_recipe then + if large_recipe then + item = item or "" + local xof = 1 - 4 / width + local yof = 1 - 4 / rows + local x_y = width > rows and xof or yof + + btn_size = width > rows and + (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows + s_btn_size = btn_size + + X = (btn_size * ((i - 1) % width) + XOFFSET - + (sfinv_only and 2.83 or 0.5)) * (0.83 - (x_y / 5)) + Y = (btn_size * floor((i - 1) / width) + + (sfinv_only and 5.81 or 4) + x_y) * (0.86 - (x_y / 5)) + end + + if X > rightest then + rightest = X + end + + local groups + + if is_group(item) then + groups = extract_groups(item) + local items = groups_to_items(groups) + item = items[1] or items + end + + local label = groups and "\nG" or "" + local replace + + if replacements then + for j = 1, #replacements do + local replacement = replacements[j] + if replacement[1] == item then + label = "\nR" + replace = replacement[2] + end + end + end + + fs[#fs + 1] = fmt(FMT.item_image_button, + X, Y + (sfinv_only and 0.7 or 0), + btn_size, btn_size, item, clean_str(item), ESC(label)) + + local infos = { + unknown = not reg_items[item], + groups = groups, + burntime = fuel_cache[item], + cooktime = cooktime, + replace = replace, + } + + for _, info in pairs(infos) do + if info then + fs[#fs + 1] = get_tooltip(item, infos) + break + end + end + + if not large_recipe then + fs[#fs + 1] = fmt(FMT.image, + X, Y + (sfinv_only and 0.7 or 0), + btn_size, btn_size, "craftguide_selected.png") end end end - fs[#fs + 1] = fmt(FMT.item_image_button, - X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, clean_str(item), ESC(label)) - - local info = { - unknown = not reg_items[item], - groups = groups, - burntime = fuel_cache[item], - cooktime = cooktime, - replace = replace, - } - - for _, v in pairs(info) do - if v then - fs[#fs + 1] = get_tooltip(item, info) - break - end + if large_recipe then + fs[#fs + 1] = "style_type[item_image_button;border=false]" end + + get_output_fs(fs, { + recipe = rcp, + shapeless = shapeless, + rightest = rightest, + btn_size = btn_size, + s_btn_size = s_btn_size, + spacing = spacing, + }) end - get_output_fs(fs, { - recipe = recipe, - shapeless = shapeless, - rightest = rightest, - btn_size = btn_size, - s_btn_size = s_btn_size, - }) + if not sfinv_only then + get_itemdef_fs(fs, { + item = data.query_item, + y = last_y, + }) + end end local function make_formspec(name) @@ -804,22 +924,23 @@ local function make_formspec(name) local fs = {} if not sfinv_only then - local bg, middle = match(craftguide.background, "([%w_%.]*)([#%d]*)") - bg = bg or "" - middle = tonumber(sub(middle, 2)) or 10 - - fs[#fs + 1] = [[ - size[9.5,8.4] + fs[#fs + 1] = fmt([[ + size[%f,%f] no_prepend[] bgcolor[#0000] - ]] + ]], + ROWS + (data.query_item and 6.7 or 0) - 1.2, + LINES - 0.3) fs[#fs + 1] = CORE_VERSION >= 510 and - fmt("background9[1,1;1,1;%s;true;%d]", bg, middle) or - fmt("background[1,1;1,1;%s;true]", bg) + fmt("background9[-0.15,-0.2;%f,%f;%s;false;%d]", + ROWS - 0.9, LINES + 0.4, PNG.bg_full, 10) or + fmt("background[-0.15,-0.2;%f,%f;%s;false]", + ROWS - 0.9, LINES + 0.4, PNG.bg_full) end fs[#fs + 1] = fmt([[ + style_type[item_image_button;border=false] field[0.25,0.2;%f,1;filter;;%s] field_close_on_enter[filter;false] ]], @@ -837,13 +958,13 @@ local function make_formspec(name) label[%f,%f;%s / %u] image_button[%f,-0.05;0.8,0.8;%s;next;;;false;%s^\[colorize:yellow:255] ]], - sfinv_only and 5.45 or 6.83, PNG.prev, PNG.prev, - sfinv_only and 6.35 or 7.85, 0.06, clr("yellow", data.pagenum), data.pagemax, - sfinv_only and 7.2 or 8.75, PNG.next, PNG.next) + sfinv_only and 5.45 or (ROWS * 6.83) / 11, PNG.prev, PNG.prev, + sfinv_only and 6.35 or (ROWS * 7.85) / 11, 0.06, clr("yellow", data.pagenum), data.pagemax, + sfinv_only and 7.2 or (ROWS * 8.75) / 11, PNG.next, PNG.next) if #data.items == 0 then local no_item = S("No item to show") - local pos = sfinv_only and 3 or 3.8 + local pos = ROWS / 3 if next(recipe_filters) and #init_items > 0 and data.filter == "" then no_item = S("Collect items to reveal more recipes") @@ -866,10 +987,17 @@ local function make_formspec(name) X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, Y - (Y * 0.1) - 0.1, 1, 1, item, item) + + if data.query_item == item then + fs[#fs + 1] = fmt(FMT.image, + X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, + Y - (Y * 0.1) - 0.1, + 1, 1, "craftguide_selected.png") + end end - if data.recipes and #data.recipes > 0 then - get_recipe_fs(data, fs) + if (data.recipes and #data.recipes > 0) or (data.usages and #data.usages > 0) then + get_info_fs(data, fs) end return concat(fs) @@ -1112,9 +1240,11 @@ local function reset_data(data) data.filter = "" data.pagenum = 1 data.rnum = 1 + data.unum = 1 data.query_item = nil - data.show_usages = nil data.recipes = nil + data.usages = nil + data.show_usages = nil data.items = data.items_raw end @@ -1136,7 +1266,7 @@ local function fields(player, _f) show_fs(player, name) return true - elseif _f.alternate then + elseif _f.alternate_recipe then if #data.recipes == 1 then return end local num_next = data.rnum + 1 data.rnum = data.recipes[num_next] and num_next or 1 @@ -1144,6 +1274,14 @@ local function fields(player, _f) show_fs(player, name) return true + elseif _f.alternate_usage then + if #data.usages == 1 then return end + local num_next = data.unum + 1 + data.unum = data.usages[num_next] and num_next or 1 + + show_fs(player, name) + return true + elseif (_f.key_enter_field == "filter" or _f.search) and _f.filter ~= "" then local str = lower(_f.filter) if data.filter == str then return end @@ -1182,18 +1320,22 @@ local function fields(player, _f) item = sub(item, 1, -5) end - if item ~= data.query_item then - data.show_usages = nil - else - data.show_usages = not data.show_usages + if sfinv_only then + if item ~= data.query_item then + data.show_usages = nil + else + data.show_usages = not data.show_usages + end end - local recipes = get_recipes(item, data, player) - if not recipes then return end + local recipes, usages = get_recipes(item, data, player) + if not recipes and not usages then return end data.query_item = item data.recipes = recipes + data.usages = usages data.rnum = 1 + data.unum = 1 show_fs(player, name) return true @@ -1589,6 +1731,29 @@ on_leaveplayer(function(player) pdata[name] = nil end) +function craftguide.show(name, item, show_usages) + if not is_str(name) then + return err("craftguide.show(): player name missing") + end + + local data = pdata[name] + local player = get_player_by_name(name) + local query_item = data.query_item + + reset_data(data) + + item = reg_items[item] and item or query_item + + data.query_item = item + data.recipes, data.usages = get_recipes(item, data, player) + + if sfinv_only then + data.show_usages = show_usages + end + + show_fs(player, name) +end + register_command("craft", { description = S("Show recipe(s) of the pointed node"), func = function(name) @@ -1609,61 +1774,10 @@ register_command("craft", { end end - local red = clr("red", "[craftguide] ") - if not node_name then - return false, red .. S("No node pointed") + return false, clr("red", "[craftguide] ") .. S("No node pointed") end - local data = pdata[name] - reset_data(data) - - local recipes = recipes_cache[node_name] - local usages = usages_cache[node_name] - - if recipes then - recipes = apply_recipe_filters(recipes, player) - end - - if not recipes or #recipes == 0 then - local ylw = clr("yellow", node_name) - local msg = red .. "%s: " .. ylw - - if usages then - recipes = usages_cache[node_name] - if #recipes > 0 then - data.show_usages = true - end - elseif recipes_cache[node_name] then - return false, fmt(msg, S("You don't know a recipe for this node")) - else - return false, fmt(msg, S("No recipe for this node")) - end - end - - data.query_item = node_name - data.recipes = recipes - - return true, show_fs(player, name) + return true, craftguide.show(name, node_name) end, }) - -function craftguide.show(name, item, show_usages) - if not is_str(name) then - return err("craftguide.show(): player name missing") - end - - local data = pdata[name] - local player = get_player_by_name(name) - local query_item = data.query_item - - reset_data(data) - - item = reg_items[item] and item or query_item - - data.query_item = item - data.show_usages = show_usages - data.recipes = get_recipes(item, data, player) - - show_fs(player, name) -end From 138ac1ae2ccc4238cfd1edf9e17d6624b665af15 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 3 Oct 2019 23:58:27 +0200 Subject: [PATCH 146/188] Add missing textures --- textures/craftguide_selected.png | Bin 0 -> 912 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 textures/craftguide_selected.png diff --git a/textures/craftguide_selected.png b/textures/craftguide_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..753589ddf99fb060b795bbb708410cf76c4ba40f GIT binary patch literal 912 zcmV;B18@9^P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=KJvg0TWh2L4lEWwfx63fB-RP_#K`E$Tr=O*`d zS4~ep%tK5CV_66|pCC!-fBzWaFI<%62vN;bPU*lEbIe@O@Z-9!I~{S=*MsbL^lT6J z3x;X7_jBsozre1K4i>lle6|OxJC5%_`^85*#8R)>0aWWfw1OTm5CBGZXrpO%FBQsNu!!rgok?{2+lca&|HXDPyw zwnKW+XxmA@*KR5FMC~#1(+iV(h%efW(R_@4t**obrBc|7`dG?p!SRHYvbrS{!$;A! zRWgcWi4~$Z&^%FUpiB$}2SsXBXi#7GN)=O#+}Utvt}M&uVw|}yC~+1VYyi`OIG9vW z6PWp)3$1bU8n2RLu($9aV~l^(ezi?hH_j~I?C-O1Vx0EsZRVlpHka3m6?M29gO z5p;C$DVRA+HmWM*#Jii<~APj2p>y=2aUBTRG37P9A@OTnN8p$mE! zc$9MTDQ7(OOsAcG=Cf3!PmNV;s#d+`S{gTL*#0dw3(Z?@rBg>L_1LwiZrywCWgypv zj5u_pVZ%or<)*f&K2xI?a=)fVo7yB6m!CbT!EE*sg646elNpF{BoMbr013^L+2Ir; zPjZvlkr|sp8PrH8oJNxv2*ysVgKl;Ya=+vjH2y1Y{4;W4qWcr%!bG>pedYEIwN}yaT-hy#u`iy#u`iy#xJ!0uB6lz+cVq59|z( z)!;G0Jpcdz24YJ`L;(K)0000pCw%h&000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2jdAI3I+;V%1R#q001;eL_t(I%k9*$5da_z#4v?X8H`!!py$3L9zdnbZF+A(1)u{~ m2m(W}#u{tv11$ct*l9PNGX#XDYBxOq0000 Date: Fri, 4 Oct 2019 00:12:31 +0200 Subject: [PATCH 147/188] Update locale template + fix craft command --- init.lua | 75 +++++++++++++++++++++++++++++++------------------ locale/template | 12 +++++++- 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/init.lua b/init.lua index f98dba8..d19585a 100644 --- a/init.lua +++ b/init.lua @@ -30,6 +30,7 @@ local reg_craftitems = core.registered_craftitems local log = core.log local after = core.after local clr = core.colorize +local chat_send = core.chat_send_player local show_formspec = core.show_formspec local globalstep = core.register_globalstep local on_shutdown = core.register_on_shutdown @@ -109,6 +110,34 @@ craftguide.group_stereotypes = { mesecon_conductor_craftable = "mesecons:wire_00000000_off", } +local function err(str) + return log("error", str) +end + +local function msg(name, str) + return chat_send(name, fmt("[craftguide] %s", clr("#FFFF00", str))) +end + +local function clean_str(str) + return match(str, "%S*") +end + +local function is_str(x) + return type(x) == "string" and clean_str(x) +end + +local function is_table(x) + return type(x) == "table" +end + +local function is_func(x) + return type(x) == "function" +end + +local function is_group(item) + return sub(item, 1, 6) == "group:" +end + local function array_diff(t1, t2) local hash = {} @@ -140,7 +169,7 @@ local function table_eq(T1, T2) local function recurse(t1, t2) if type(t1) ~= type(t2) then return end - if type(t1) ~= "table" then + if not is_table(t1) then return t1 == t2 end @@ -217,30 +246,6 @@ local function table_replace(t, val, new) end end -local function err(str) - return log("error", str) -end - -local function clean_str(str) - return match(str, "%S*") -end - -local function is_str(x) - return type(x) == "string" and clean_str(x) -end - -local function is_table(x) - return type(x) == "table" -end - -local function is_func(x) - return type(x) == "function" -end - -local function is_group(item) - return sub(item, 1, 6) == "group:" -end - local craft_types = {} function craftguide.register_craft_type(name, def) @@ -708,7 +713,7 @@ local function get_itemdef_fs(fs, L) local def = reg_items[L.item] local namestr = fmt("%s (%s)", pretty_wrap(get_desc(L.item), 25), L.item) - local typestr = "" + local typestr if reg_nodes[L.item] then typestr = fmt("%s (%s)", ESC(S("Node")), def.drawtype) elseif reg_entities[L.item] then @@ -745,8 +750,8 @@ local function get_itemdef_fs(fs, L) fs[#fs + 1] = fmt("table[8.1,%f;6.3,1.8;itemdef;" .. tstr .. ";0]", L.y + 0.08, namestr, - ESC(typestr), - ESC(groupstr)) + ESC(typestr or S("Unknown")), + ESC(groupstr or S("None"))) end local function get_info_fs(data, fs) @@ -1747,6 +1752,20 @@ function craftguide.show(name, item, show_usages) data.query_item = item data.recipes, data.usages = get_recipes(item, data, player) + if not data.recipes and not data.usages then + if recipes_cache[item] then + return false, msg(name, S("You don't know a recipe for this node")) + end + + if usages_cache[item] then + return false, msg(name, S("You don't know an usage for this node")) + end + + if not recipes_cache[item] and not usages_cache[item] then + return false, msg(name, S("No recipe or usage for this node")) + end + end + if sfinv_only then data.show_usages = show_usages end diff --git a/locale/template b/locale/template index dbacf30..71f932c 100644 --- a/locale/template +++ b/locale/template @@ -20,4 +20,14 @@ Collect items to reveal more recipes= Show recipe(s) of the pointed node= No node pointed= You don't know a recipe for this node= -No recipe for this node= +You don't know an usage for this node= +No recipe or usage for this node= +Node= +Entity= +Craftitem= +Tool= +Name= +Type= +Groups= +Unknown= +None= From c570fa23371e2c011037e2da1d942c0601e1f859 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Oct 2019 00:19:48 +0200 Subject: [PATCH 148/188] Tune fs style --- init.lua | 109 +++++++++++++++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/init.lua b/init.lua index d19585a..542eff9 100644 --- a/init.lua +++ b/init.lua @@ -827,76 +827,73 @@ local function get_info_fs(data, fs) end for i = 1, width * rows do - local item = rcp.items[i] + local item = rcp.items[i] or "" local X = ceil((i - 1) % width - width) + XOFFSET local Y = ceil(i / width) + YOFFSET - min(2, rows) + spacing - if item or large_recipe then - if large_recipe then - item = item or "" - local xof = 1 - 4 / width - local yof = 1 - 4 / rows - local x_y = width > rows and xof or yof + if large_recipe then + local xof = 1 - 4 / width + local yof = 1 - 4 / rows + local x_y = width > rows and xof or yof - btn_size = width > rows and - (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows - s_btn_size = btn_size + btn_size = width > rows and + (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows + s_btn_size = btn_size - X = (btn_size * ((i - 1) % width) + XOFFSET - - (sfinv_only and 2.83 or 0.5)) * (0.83 - (x_y / 5)) - Y = (btn_size * floor((i - 1) / width) + - (sfinv_only and 5.81 or 4) + x_y) * (0.86 - (x_y / 5)) - end + X = (btn_size * ((i - 1) % width) + XOFFSET - + (sfinv_only and 2.83 or 0.5)) * (0.83 - (x_y / 5)) + Y = (btn_size * floor((i - 1) / width) + + (sfinv_only and 5.81 or 4) + x_y) * (0.86 - (x_y / 5)) + end - if X > rightest then - rightest = X - end + if X > rightest then + rightest = X + end - local groups + local groups - if is_group(item) then - groups = extract_groups(item) - local items = groups_to_items(groups) - item = items[1] or items - end + if is_group(item) then + groups = extract_groups(item) + local items = groups_to_items(groups) + item = items[1] or items + end - local label = groups and "\nG" or "" - local replace + local label = groups and "\nG" or "" + local replace - if replacements then - for j = 1, #replacements do - local replacement = replacements[j] - if replacement[1] == item then - label = "\nR" - replace = replacement[2] - end + if replacements then + for j = 1, #replacements do + local replacement = replacements[j] + if replacement[1] == item then + label = "\nR" + replace = replacement[2] end end + end - fs[#fs + 1] = fmt(FMT.item_image_button, + fs[#fs + 1] = fmt(FMT.item_image_button, + X, Y + (sfinv_only and 0.7 or 0), + btn_size, btn_size, item, clean_str(item), ESC(label)) + + local infos = { + unknown = not reg_items[item], + groups = groups, + burntime = fuel_cache[item], + cooktime = cooktime, + replace = replace, + } + + for _, info in pairs(infos) do + if info then + fs[#fs + 1] = get_tooltip(item, infos) + break + end + end + + if not large_recipe then + fs[#fs + 1] = fmt(FMT.image, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, clean_str(item), ESC(label)) - - local infos = { - unknown = not reg_items[item], - groups = groups, - burntime = fuel_cache[item], - cooktime = cooktime, - replace = replace, - } - - for _, info in pairs(infos) do - if info then - fs[#fs + 1] = get_tooltip(item, infos) - break - end - end - - if not large_recipe then - fs[#fs + 1] = fmt(FMT.image, - X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, "craftguide_selected.png") - end + btn_size, btn_size, "craftguide_selected.png") end end From 16ceea1aaf7cb443be82d36fddb98c2e72248d33 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Oct 2019 00:25:10 +0200 Subject: [PATCH 149/188] Fix message --- init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index 542eff9..0c430e2 100644 --- a/init.lua +++ b/init.lua @@ -724,11 +724,11 @@ local function get_itemdef_fs(fs, L) typestr = ESC(S("Tool")) end - local groupstr = "" + local groupstr for k, v in pairs(def.groups or {}) do - groupstr = groupstr .. fmt("%s(%d), ", pretty_wrap(k, 13), v) + groupstr = (groupstr or "") .. fmt("%s(%d), ", pretty_wrap(k, 13), v) end - groupstr = sub(groupstr, 1, -3) + groupstr = groupstr and sub(groupstr, 1, -3) local specs = { ESC(S("Name")), From 5446e0dbddafefac7bc3b90506d2415f4faf4b56 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Oct 2019 00:29:42 +0200 Subject: [PATCH 150/188] Update README + API --- API.md | 11 ----------- README.md | 2 +- init.lua | 2 +- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/API.md b/API.md index 519cc03..7e490c9 100644 --- a/API.md +++ b/API.md @@ -168,14 +168,3 @@ You can add a stereotype like so: ```Lua craftguide.group_stereotypes.radioactive = "mod:item" ``` - -#### `craftguide.background` - -You can set a custom background theme by overriding this variable: - -```Lua -craftguide.background = "#" - -``` - -`middle` (number) refers to a 9-sliced background. Read the engine's Lua API documentation for more info. diff --git a/README.md b/README.md index f28905a..135906c 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,4 @@ For developers, `craftguide` also has a [modding API](https://github.com/minetes Love this mod? Donations are appreciated: https://www.paypal.me/jpg84240 -![Preview2](https://i.imgur.com/IbexMwQ.png) +![Preview2](https://i.imgur.com/GVQvufb.png) diff --git a/init.lua b/init.lua index 0c430e2..8e60293 100644 --- a/init.lua +++ b/init.lua @@ -1791,7 +1791,7 @@ register_command("craft", { end if not node_name then - return false, clr("red", "[craftguide] ") .. S("No node pointed") + return false, msg(name, S("No node pointed")) end return true, craftguide.show(name, node_name) From 2d332913c582bac90654c585b97272d30f80c004 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Oct 2019 00:52:06 +0200 Subject: [PATCH 151/188] Fix messages in craft command --- init.lua | 30 +++++++++++++++--------------- locale/template | 5 ++--- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/init.lua b/init.lua index 8e60293..b4075b9 100644 --- a/init.lua +++ b/init.lua @@ -1745,23 +1745,23 @@ function craftguide.show(name, item, show_usages) reset_data(data) item = reg_items[item] and item or query_item + local recipes, usages = get_recipes(item, data, player) + + if not recipes and not usages then + if not recipes_cache[item] and not usages_cache[item] then + return false, msg(name, fmt("%s: %s", + S("No recipe or usage for this item"), + get_desc(item))) + end + + return false, msg(name, fmt("%s: %s", + S("You don't know a recipe or usage for this item"), + get_desc(item))) + end data.query_item = item - data.recipes, data.usages = get_recipes(item, data, player) - - if not data.recipes and not data.usages then - if recipes_cache[item] then - return false, msg(name, S("You don't know a recipe for this node")) - end - - if usages_cache[item] then - return false, msg(name, S("You don't know an usage for this node")) - end - - if not recipes_cache[item] and not usages_cache[item] then - return false, msg(name, S("No recipe or usage for this node")) - end - end + data.recipes = recipes + data.usages = usages if sfinv_only then data.show_usages = show_usages diff --git a/locale/template b/locale/template index 71f932c..842dec9 100644 --- a/locale/template +++ b/locale/template @@ -19,9 +19,8 @@ No item to show= Collect items to reveal more recipes= Show recipe(s) of the pointed node= No node pointed= -You don't know a recipe for this node= -You don't know an usage for this node= -No recipe or usage for this node= +You don't know a recipe or usage for this item= +No recipe or usage for this item= Node= Entity= Craftitem= From fb4805ccf0452924310391eb89db543e1ec19c9a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Oct 2019 21:50:32 +0200 Subject: [PATCH 152/188] Add button background only if engine >= 5.1 --- init.lua | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/init.lua b/init.lua index b4075b9..f0818b7 100644 --- a/init.lua +++ b/init.lua @@ -674,9 +674,11 @@ local function get_output_fs(fs, L) output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, 1.1, 1.1, item, ESC(name), "") - fs[#fs + 1] = fmt(FMT.image, - output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, - 1.1, 1.1, "craftguide_selected.png") + if CORE_VERSION >= 510 then + fs[#fs + 1] = fmt(FMT.image, + output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, + 1.1, 1.1, "craftguide_selected.png") + end local burntime = fuel_cache[name] local repair = repairable(name) @@ -755,15 +757,16 @@ local function get_itemdef_fs(fs, L) end local function get_info_fs(data, fs) - local t = {recipes = data.recipes, usages = data.usages} + local panels = {recipes = data.recipes, usages = data.usages} local infonum = 0 local last_y if sfinv_only then - t = data.show_usages and {usages = data.usages} or {recipes = data.recipes} + panels = data.show_usages and + {usages = data.usages} or {recipes = data.recipes} end - for k, v in pairs(t) do + for k, v in pairs(panels) do infonum = infonum + 1 local spacing = (infonum - 1) * 3.6 last_y = -0.2 + infonum * 3.6 @@ -890,7 +893,7 @@ local function get_info_fs(data, fs) end end - if not large_recipe then + if CORE_VERSION >= 510 and not large_recipe then fs[#fs + 1] = fmt(FMT.image, X, Y + (sfinv_only and 0.7 or 0), btn_size, btn_size, "craftguide_selected.png") @@ -990,7 +993,7 @@ local function make_formspec(name) Y - (Y * 0.1) - 0.1, 1, 1, item, item) - if data.query_item == item then + if CORE_VERSION >= 510 and data.query_item == item then fs[#fs + 1] = fmt(FMT.image, X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, Y - (Y * 0.1) - 0.1, From ce74f49773d74c21cb55baa0da2abea4bb4e0ddd Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Oct 2019 22:40:23 +0200 Subject: [PATCH 153/188] Add prev/next buttons for recipes/usages --- init.lua | 64 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/init.lua b/init.lua index f0818b7..a421c41 100644 --- a/init.lua +++ b/init.lua @@ -800,20 +800,36 @@ local function get_info_fs(data, fs) if (not sfinv_only and k == "recipes") or (sfinv_only and not data.show_usages) then btn_lab = ESC(S("Recipe @1 of @2", data.rnum, #v)) + elseif not sfinv_only or (sfinv_only and data.show_usages) then btn_lab = ESC(S("Usage @1 of @2", data.unum, #v)) - end - if sfinv_only then + elseif sfinv_only then btn_lab = data.show_usages and - ESC(S("Usage @1 of @2", data.rnum, #v)) or + ESC(S("Usage @1 of @2", data.unum, #v)) or ESC(S("Recipe @1 of @2", data.rnum, #v)) end - fs[#fs + 1] = fmt(FMT.button, - XOFFSET + (sfinv_only and 1.98 or 1.12), - YOFFSET + (sfinv_only and 1.9 or 1.2 + spacing), - 2.2, 1, "alternate_" .. (k == "recipes" and "recipe" or "usage"), btn_lab) + if #v > 1 then + local btn_suffix = k == "recipes" and "recipe" or "usage" + + fs[#fs + 1] = fmt([[ + image_button[%f,%f;0.8,0.8;%s;prev_%s;;;false;%s^\[colorize:yellow:255] + label[%f,%f;%s] + image_button[%f,%f;0.8,0.8;%s;next_%s;;;false;%s^\[colorize:yellow:255] + ]], + XOFFSET + (sfinv_only and 1.7 or 1), + YOFFSET + (sfinv_only and 2.1 or 1.4 + spacing), + PNG.prev, btn_suffix, PNG.prev, + + XOFFSET + (sfinv_only and 2.3 or 1.6), + YOFFSET + (sfinv_only and 2.2 or 1.5 + spacing), + btn_lab, + + XOFFSET + (sfinv_only and 3.5 or 2.8), + YOFFSET + (sfinv_only and 2.1 or 1.4 + spacing), + PNG.next, btn_suffix, PNG.next) + end if width > WH_LIMIT or rows > WH_LIMIT then fs[#fs + 1] = fmt(FMT.label, @@ -1268,24 +1284,27 @@ local function fields(player, _f) if _f.clear then reset_data(data) - show_fs(player, name) - return true + return true, show_fs(player, name) - elseif _f.alternate_recipe then - if #data.recipes == 1 then return end + elseif _f.prev_recipe then + local num_prev = data.rnum - 1 + data.rnum = data.recipes[num_prev] and num_prev or #data.recipes + return true, show_fs(player, name) + + elseif _f.next_recipe then local num_next = data.rnum + 1 data.rnum = data.recipes[num_next] and num_next or 1 + return true, show_fs(player, name) - show_fs(player, name) - return true + elseif _f.prev_usage then + local num_prev = data.unum - 1 + data.unum = data.usages[num_prev] and num_prev or #data.usages + return true, show_fs(player, name) - elseif _f.alternate_usage then - if #data.usages == 1 then return end + elseif _f.next_usage then local num_next = data.unum + 1 data.unum = data.usages[num_next] and num_next or 1 - - show_fs(player, name) - return true + return true, show_fs(player, name) elseif (_f.key_enter_field == "filter" or _f.search) and _f.filter ~= "" then local str = lower(_f.filter) @@ -1295,8 +1314,7 @@ local function fields(player, _f) data.pagenum = 1 search(data) - show_fs(player, name) - return true + return true, show_fs(player, name) elseif _f.prev or _f.next then if data.pagemax == 1 then return end @@ -1308,8 +1326,7 @@ local function fields(player, _f) data.pagenum = data.pagemax end - show_fs(player, name) - return true + return true, show_fs(player, name) else local item for field in pairs(_f) do @@ -1342,8 +1359,7 @@ local function fields(player, _f) data.rnum = 1 data.unum = 1 - show_fs(player, name) - return true + return true, show_fs(player, name) end end From 9e3997c689a32bf3d86fec37145e560660c92a6e Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Oct 2019 22:52:17 +0200 Subject: [PATCH 154/188] Remove infos from info panel --- init.lua | 53 ++++++++++++----------------------------------------- 1 file changed, 12 insertions(+), 41 deletions(-) diff --git a/init.lua b/init.lua index a421c41..4f1a26c 100644 --- a/init.lua +++ b/init.lua @@ -21,11 +21,8 @@ local progressive_mode = core.settings:get_bool("craftguide_progressive_mode") local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") local reg_items = core.registered_items -local reg_nodes = core.registered_nodes local reg_tools = core.registered_tools -local reg_entities = core.registered_nodes local reg_aliases = core.registered_aliases -local reg_craftitems = core.registered_craftitems local log = core.log local after = core.after @@ -712,32 +709,12 @@ local function get_itemdef_fs(fs, L) L.y, PNG.bg_full, 10) or fmt("background[8.1,%f;6.6,2.19;%s;false]", L.y, PNG.bg_full) - local def = reg_items[L.item] - local namestr = fmt("%s (%s)", pretty_wrap(get_desc(L.item), 25), L.item) - - local typestr - if reg_nodes[L.item] then - typestr = fmt("%s (%s)", ESC(S("Node")), def.drawtype) - elseif reg_entities[L.item] then - typestr = ESC(S("Entity")) - elseif reg_craftitems[L.item] then - typestr = ESC(S("Craftitem")) - elseif reg_tools[L.item] then - typestr = ESC(S("Tool")) - end - - local groupstr - for k, v in pairs(def.groups or {}) do - groupstr = (groupstr or "") .. fmt("%s(%d), ", pretty_wrap(k, 13), v) - end - groupstr = groupstr and sub(groupstr, 1, -3) - local specs = { ESC(S("Name")), - ESC(S("Type")), - ESC(S("Groups")), } + local namestr = fmt("%s (%s)", pretty_wrap(get_desc(L.item), 25), L.item) + local tstr = "" for i = 1, #specs do tstr = tstr .. "#6389FF," .. specs[i] .. ",#FFFFFF,%s," @@ -750,10 +727,7 @@ local function get_itemdef_fs(fs, L) ]] fs[#fs + 1] = fmt("table[8.1,%f;6.3,1.8;itemdef;" .. tstr .. ";0]", - L.y + 0.08, - namestr, - ESC(typestr or S("Unknown")), - ESC(groupstr or S("None"))) + L.y + 0.08, namestr) end local function get_info_fs(data, fs) @@ -810,25 +784,22 @@ local function get_info_fs(data, fs) ESC(S("Recipe @1 of @2", data.rnum, #v)) end + fs[#fs + 1] = fmt(FMT.label, + XOFFSET + (sfinv_only and 2.3 or 1.6), + YOFFSET + (sfinv_only and 2.2 or 1.5 + spacing), + btn_lab) + if #v > 1 then local btn_suffix = k == "recipes" and "recipe" or "usage" + local x_arrow = XOFFSET + (sfinv_only and 1.7 or 1) + local y_arrow = YOFFSET + (sfinv_only and 2.1 or 1.4 + spacing) fs[#fs + 1] = fmt([[ image_button[%f,%f;0.8,0.8;%s;prev_%s;;;false;%s^\[colorize:yellow:255] - label[%f,%f;%s] image_button[%f,%f;0.8,0.8;%s;next_%s;;;false;%s^\[colorize:yellow:255] ]], - XOFFSET + (sfinv_only and 1.7 or 1), - YOFFSET + (sfinv_only and 2.1 or 1.4 + spacing), - PNG.prev, btn_suffix, PNG.prev, - - XOFFSET + (sfinv_only and 2.3 or 1.6), - YOFFSET + (sfinv_only and 2.2 or 1.5 + spacing), - btn_lab, - - XOFFSET + (sfinv_only and 3.5 or 2.8), - YOFFSET + (sfinv_only and 2.1 or 1.4 + spacing), - PNG.next, btn_suffix, PNG.next) + x_arrow, y_arrow, PNG.prev, btn_suffix, PNG.prev, + x_arrow + 1.8, y_arrow, PNG.next, btn_suffix, PNG.next) end if width > WH_LIMIT or rows > WH_LIMIT then From 8b5de4f7f7a24f1ecbdc3d88cc238686066d197a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 4 Oct 2019 23:04:35 +0200 Subject: [PATCH 155/188] Minor refactoring --- init.lua | 55 +++++++++++++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/init.lua b/init.lua index 4f1a26c..bf4e347 100644 --- a/init.lua +++ b/init.lua @@ -95,6 +95,7 @@ local FMT = { item_image = "item_image[%f,%f;%f,%f;%s]", image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]", + arrow = "image_button[%f,%f;0.8,0.8;%s;%s;;;false;%s^\\[colorize:yellow:255]" } craftguide.group_stereotypes = { @@ -794,12 +795,11 @@ local function get_info_fs(data, fs) local x_arrow = XOFFSET + (sfinv_only and 1.7 or 1) local y_arrow = YOFFSET + (sfinv_only and 2.1 or 1.4 + spacing) - fs[#fs + 1] = fmt([[ - image_button[%f,%f;0.8,0.8;%s;prev_%s;;;false;%s^\[colorize:yellow:255] - image_button[%f,%f;0.8,0.8;%s;next_%s;;;false;%s^\[colorize:yellow:255] - ]], - x_arrow, y_arrow, PNG.prev, btn_suffix, PNG.prev, - x_arrow + 1.8, y_arrow, PNG.next, btn_suffix, PNG.next) + fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, + x_arrow, y_arrow, PNG.prev, + fmt("prev_%s", btn_suffix), PNG.prev, + x_arrow + 1.8, y_arrow, PNG.next, + fmt("next_%s", btn_suffix), PNG.next) end if width > WH_LIMIT or rows > WH_LIMIT then @@ -945,14 +945,15 @@ local function make_formspec(name) sfinv_only and 2.6 or 2.54, PNG.search, PNG.search, sfinv_only and 3.3 or 3.25, PNG.clear, PNG.clear) - fs[#fs + 1] = fmt([[ - image_button[%f,-0.05;0.8,0.8;%s;prev;;;false;%s^\[colorize:yellow:255] - label[%f,%f;%s / %u] - image_button[%f,-0.05;0.8,0.8;%s;next;;;false;%s^\[colorize:yellow:255] - ]], - sfinv_only and 5.45 or (ROWS * 6.83) / 11, PNG.prev, PNG.prev, - sfinv_only and 6.35 or (ROWS * 7.85) / 11, 0.06, clr("yellow", data.pagenum), data.pagemax, - sfinv_only and 7.2 or (ROWS * 8.75) / 11, PNG.next, PNG.next) + fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", + sfinv_only and 6.35 or (ROWS * 7.85) / 11, + 0.06, clr("yellow", data.pagenum), data.pagemax) + + fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, + sfinv_only and 5.45 or (ROWS * 6.83) / 11, + -0.05, PNG.prev, "prev_page", PNG.prev, + sfinv_only and 7.2 or (ROWS * 8.75) / 11, + -0.05, PNG.next, "next_page", PNG.next) if #data.items == 0 then local no_item = S("No item to show") @@ -1257,24 +1258,14 @@ local function fields(player, _f) reset_data(data) return true, show_fs(player, name) - elseif _f.prev_recipe then - local num_prev = data.rnum - 1 - data.rnum = data.recipes[num_prev] and num_prev or #data.recipes + elseif _f.prev_recipe or _f.next_recipe then + local num = data.rnum + (_f.prev_recipe and -1 or 1) + data.rnum = data.recipes[num] and num or (_f.prev_recipe and #data.recipes or 1) return true, show_fs(player, name) - elseif _f.next_recipe then - local num_next = data.rnum + 1 - data.rnum = data.recipes[num_next] and num_next or 1 - return true, show_fs(player, name) - - elseif _f.prev_usage then - local num_prev = data.unum - 1 - data.unum = data.usages[num_prev] and num_prev or #data.usages - return true, show_fs(player, name) - - elseif _f.next_usage then - local num_next = data.unum + 1 - data.unum = data.usages[num_next] and num_next or 1 + elseif _f.prev_usage or _f.next_usage then + local num = data.unum + (_f.prev_usage and -1 or 1) + data.unum = data.usages[num] and num or (_f.prev_usage and #data.usages or 1) return true, show_fs(player, name) elseif (_f.key_enter_field == "filter" or _f.search) and _f.filter ~= "" then @@ -1287,9 +1278,9 @@ local function fields(player, _f) return true, show_fs(player, name) - elseif _f.prev or _f.next then + elseif _f.prev_page or _f.next_page then if data.pagemax == 1 then return end - data.pagenum = data.pagenum - (_f.prev and 1 or -1) + data.pagenum = data.pagenum - (_f.prev_page and 1 or -1) if data.pagenum > data.pagemax then data.pagenum = 1 From 36878ce9a0e638be4d2df7fb6d7264a4a36dc565 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sat, 5 Oct 2019 00:09:29 +0200 Subject: [PATCH 156/188] Show item drops --- init.lua | 129 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 23 deletions(-) diff --git a/init.lua b/init.lua index bf4e347..481f32c 100644 --- a/init.lua +++ b/init.lua @@ -1019,6 +1019,16 @@ craftguide.add_search_filter("groups", function(item, groups) return has_groups end) +craftguide.register_craft_type("digging", { + description = ESC(S("Digging")), + icon = "default_tool_steelpick.png", +}) + +craftguide.register_craft_type("digging_chance", { + description = ESC(S("Digging Chance")), + icon = "default_tool_mesepick.png", +}) + local function search(data) local filter = data.filter @@ -1151,34 +1161,78 @@ core.register_craft = function(def) end end -local function show_item(def) - return not (def.groups.not_in_craft_guide == 1 or - def.groups.not_in_creative_inventory == 1) and - def.description and def.description ~= "" -end +local function register_drops(name, def) + -- Code borrowed and modified from unified_inventory + -- https://github.com/minetest-mods/unified_inventory/blob/master/api.lua + local drop = def.drop -local function get_init_items() - local hash, c = {}, 0 - for name, def in pairs(reg_items) do - if show_item(def) then - if not fuel_cache[name] then - cache_fuel(name) - end + if is_str(drop) and drop ~= name then + craftguide.register_craft({ + type = "digging", + items = {name}, + output = drop, + }) - if not recipes_cache[name] then - cache_recipes(name) - end + elseif is_table(drop) then + local drop_sure, drop_maybe = {}, {} + local drop_items = drop.items or {} + local max_items_left = drop.max_items + local max_start = true - cache_usages(name) + for i = 1, #drop_items do + if max_items_left and max_items_left <= 0 then break end + local di = drop_items[i] - if recipes_cache[name] or usages_cache[name] then - c = c + 1 - init_items[c] = name - hash[name] = true + for j = 1, #di.items do + local dname, dcount = match(di.items[j], "(.*)%s*(%d*)") + dcount = dcount and tonumber(dcount) or 1 + + if dname ~= name then + if #di.items == 1 and di.rarity == 1 and max_start then + if not drop_sure[dname] then + drop_sure[dname] = 0 + end + + drop_sure[dname] = drop_sure[dname] + dcount + + if max_items_left then + max_items_left = max_items_left - 1 + if max_items_left <= 0 then break end + end + else + if max_items_left then + max_start = false + end + + if not drop_maybe[dname] then + drop_maybe[dname] = 0 + end + + drop_maybe[dname] = drop_maybe[dname] + dcount + end + end end end - end + for item, count in pairs(drop_sure) do + craftguide.register_craft({ + type = "digging", + items = {name}, + output = item .. " " .. count, + }) + end + + for item, count in pairs(drop_maybe) do + craftguide.register_craft({ + type = "digging_chance", + items = {name}, + output = item .. " " .. count, + }) + end + end +end + +local function handle_aliases(hash) for oldname, newname in pairs(reg_aliases) do local recipes = recipes_cache[oldname] if recipes then @@ -1209,11 +1263,40 @@ local function get_init_items() end if recipes_cache[oldname] and not hash[newname] then - c = c + 1 - init_items[c] = newname + init_items[#init_items + 1] = newname + end + end +end + +local function show_item(def) + return not (def.groups.not_in_craft_guide == 1 or + def.groups.not_in_creative_inventory == 1) and + def.description and def.description ~= "" +end + +local function get_init_items() + local hash = {} + for name, def in pairs(reg_items) do + if show_item(def) then + if not fuel_cache[name] then + cache_fuel(name) + end + + if not recipes_cache[name] then + cache_recipes(name) + end + + cache_usages(name) + register_drops(name, def) + + if recipes_cache[name] or usages_cache[name] then + init_items[#init_items + 1] = name + hash[name] = true + end end end + handle_aliases(hash) sort(init_items) end From c32feb44fc9778d857f2e8829fd7fad195aed517 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sat, 5 Oct 2019 00:11:09 +0200 Subject: [PATCH 157/188] Update template --- init.lua | 4 ++-- locale/template | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/init.lua b/init.lua index 481f32c..c90b21a 100644 --- a/init.lua +++ b/init.lua @@ -1218,7 +1218,7 @@ local function register_drops(name, def) craftguide.register_craft({ type = "digging", items = {name}, - output = item .. " " .. count, + output = fmt("%s %u", item, count), }) end @@ -1226,7 +1226,7 @@ local function register_drops(name, def) craftguide.register_craft({ type = "digging_chance", items = {name}, - output = item .. " " .. count, + output = fmt("%s %u", item, count), }) end end diff --git a/locale/template b/locale/template index 842dec9..20cfdc9 100644 --- a/locale/template +++ b/locale/template @@ -21,12 +21,6 @@ Show recipe(s) of the pointed node= No node pointed= You don't know a recipe or usage for this item= No recipe or usage for this item= -Node= -Entity= -Craftitem= -Tool= Name= -Type= -Groups= -Unknown= -None= +Digging= +Digging Chance= From 90adfb42c1d361fe3c00f4f1716834b11be12ebe Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sat, 5 Oct 2019 00:32:22 +0200 Subject: [PATCH 158/188] Minor refactoring --- init.lua | 71 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/init.lua b/init.lua index c90b21a..9b6d995 100644 --- a/init.lua +++ b/init.lua @@ -1161,29 +1161,20 @@ core.register_craft = function(def) end end -local function register_drops(name, def) +local function handle_drops_table(name, drop) -- Code borrowed and modified from unified_inventory -- https://github.com/minetest-mods/unified_inventory/blob/master/api.lua - local drop = def.drop + local drop_sure, drop_maybe = {}, {} + local drop_items = drop.items or {} + local max_items_left = drop.max_items + local max_start = true - if is_str(drop) and drop ~= name then - craftguide.register_craft({ - type = "digging", - items = {name}, - output = drop, - }) + for i = 1, #drop_items do + if max_items_left and max_items_left <= 0 then break end + local di = drop_items[i] - elseif is_table(drop) then - local drop_sure, drop_maybe = {}, {} - local drop_items = drop.items or {} - local max_items_left = drop.max_items - local max_start = true - - for i = 1, #drop_items do - if max_items_left and max_items_left <= 0 then break end - local di = drop_items[i] - - for j = 1, #di.items do + for j = 1, #di.items do + if is_str(di.items[j]) then local dname, dcount = match(di.items[j], "(.*)%s*(%d*)") dcount = dcount and tonumber(dcount) or 1 @@ -1213,22 +1204,36 @@ local function register_drops(name, def) end end end + end - for item, count in pairs(drop_sure) do - craftguide.register_craft({ - type = "digging", - items = {name}, - output = fmt("%s %u", item, count), - }) - end + for item, count in pairs(drop_sure) do + craftguide.register_craft({ + type = "digging", + items = {name}, + output = fmt("%s %u", item, count), + }) + end - for item, count in pairs(drop_maybe) do - craftguide.register_craft({ - type = "digging_chance", - items = {name}, - output = fmt("%s %u", item, count), - }) - end + for item, count in pairs(drop_maybe) do + craftguide.register_craft({ + type = "digging_chance", + items = {name}, + output = fmt("%s %u", item, count), + }) + end +end + +local function register_drops(name, def) + local drop = def.drop + + if is_str(drop) and drop ~= name then + craftguide.register_craft({ + type = "digging", + items = {name}, + output = drop, + }) + elseif is_table(drop) then + handle_drops_table(name, drop) end end From e16c23c29c48d4c93e1c954e1c848c8ae20d4d66 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sat, 5 Oct 2019 00:36:56 +0200 Subject: [PATCH 159/188] Minor refactoring --- init.lua | 70 +++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/init.lua b/init.lua index 9b6d995..8a1be26 100644 --- a/init.lua +++ b/init.lua @@ -176,26 +176,25 @@ local function table_eq(T1, T2) end avoid_loops[t1] = t2 - local t2keys = {} - local t2tablekeys = {} + local t2k, t2kv = {}, {} for k in pairs(t2) do - if type(k) == "table" then - insert(t2tablekeys, k) + if is_table(k) then + insert(t2kv, k) end - t2keys[k] = true + t2k[k] = true end for k1, v1 in pairs(t1) do local v2 = t2[k1] if type(k1) == "table" then local ok - for i = 1, #t2tablekeys do - local tk = t2tablekeys[i] + for i = 1, #t2kv do + local tk = t2kv[i] if table_eq(k1, tk) and recurse(v1, t2[tk]) then - remove(t2tablekeys, i) - t2keys[tk] = nil + remove(t2kv, i) + t2k[tk] = nil ok = true break end @@ -204,12 +203,12 @@ local function table_eq(T1, T2) if not ok then return end else if v2 == nil then return end - t2keys[k1] = nil + t2k[k1] = nil if not recurse(v1, v2) then return end end end - if next(t2keys) then return end + if next(t2k) then return end return true end @@ -1174,33 +1173,32 @@ local function handle_drops_table(name, drop) local di = drop_items[i] for j = 1, #di.items do - if is_str(di.items[j]) then - local dname, dcount = match(di.items[j], "(.*)%s*(%d*)") - dcount = dcount and tonumber(dcount) or 1 + if not is_str(di.items[j]) then break end + local dname, dcount = match(di.items[j], "(.*)%s*(%d*)") + dcount = dcount and tonumber(dcount) or 1 - if dname ~= name then - if #di.items == 1 and di.rarity == 1 and max_start then - if not drop_sure[dname] then - drop_sure[dname] = 0 - end - - drop_sure[dname] = drop_sure[dname] + dcount - - if max_items_left then - max_items_left = max_items_left - 1 - if max_items_left <= 0 then break end - end - else - if max_items_left then - max_start = false - end - - if not drop_maybe[dname] then - drop_maybe[dname] = 0 - end - - drop_maybe[dname] = drop_maybe[dname] + dcount + if dname ~= name then + if #di.items == 1 and di.rarity == 1 and max_start then + if not drop_sure[dname] then + drop_sure[dname] = 0 end + + drop_sure[dname] = drop_sure[dname] + dcount + + if max_items_left then + max_items_left = max_items_left - 1 + if max_items_left <= 0 then break end + end + else + if max_items_left then + max_start = false + end + + if not drop_maybe[dname] then + drop_maybe[dname] = 0 + end + + drop_maybe[dname] = drop_maybe[dname] + dcount end end end From abd9274798aa222f8a661426ea75d15a344f1cbf Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 8 Oct 2019 00:38:37 +0200 Subject: [PATCH 160/188] Fix crash in progressive mode + refacto --- init.lua | 268 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 136 insertions(+), 132 deletions(-) diff --git a/init.lua b/init.lua index 8a1be26..d5ae522 100644 --- a/init.lua +++ b/init.lua @@ -535,10 +535,12 @@ local function get_recipes(item, data, player) if not sfinv_only or (sfinv_only and data.show_usages) then usages = apply_recipe_filters(usages, player) - if usages and #usages == 0 then return end end - return recipes, usages + local no_usages = not usages or #usages == 0 + + return not no_recipes and recipes or nil, + not no_usages and usages or nil end local function groups_to_items(groups, get_all) @@ -652,7 +654,7 @@ local function get_output_fs(fs, L) end end - local arrow_X = L.rightest + (L.s_btn_size or 1.1) + local arrow_X = L.rightest + (L._btn_size or 1.1) local output_X = arrow_X + 0.9 fs[#fs + 1] = fmt(FMT.image, @@ -703,17 +705,17 @@ local function pretty_wrap(str, limit) return #str > limit + 3 and sub(str, 1, limit) .. "..." or str end -local function get_itemdef_fs(fs, L) +local function get_itemdef_fs(fs, item, last_y) fs[#fs + 1] = CORE_VERSION >= 510 and fmt("background9[8.1,%f;6.6,2.19;%s;false;%d]", - L.y, PNG.bg_full, 10) or - fmt("background[8.1,%f;6.6,2.19;%s;false]", L.y, PNG.bg_full) + last_y, PNG.bg_full, 10) or + fmt("background[8.1,%f;6.6,2.19;%s;false]", last_y, PNG.bg_full) local specs = { ESC(S("Name")), } - local namestr = fmt("%s (%s)", pretty_wrap(get_desc(L.item), 25), L.item) + local namestr = fmt("%s (%s)", pretty_wrap(get_desc(item), 25), item) local tstr = "" for i = 1, #specs do @@ -727,13 +729,129 @@ local function get_itemdef_fs(fs, L) ]] fs[#fs + 1] = fmt("table[8.1,%f;6.3,1.8;itemdef;" .. tstr .. ";0]", - L.y + 0.08, namestr) + last_y + 0.08, namestr) end -local function get_info_fs(data, fs) +local function get_grid_fs(fs, rcp, spacing) + local width = rcp.width or 1 + local replacements = rcp.replacements + local rightest, btn_size, _btn_size = 0, 1.1 + local cooktime, shapeless + + if rcp.type == "cooking" then + cooktime, width = width, 1 + elseif width == 0 and not rcp.custom then + shapeless = true + local n = #rcp.items + width = (n < 5 and n > 1) and 2 or min(3, max(1, n)) + end + + local rows = ceil(maxn(rcp.items) / width) + + if width > WH_LIMIT or rows > WH_LIMIT then + fs[#fs + 1] = fmt(FMT.label, + XOFFSET + (sfinv_only and -1.5 or -1.6), + YOFFSET + (sfinv_only and 0.5 or spacing), + ESC(S("Recipe's too big to be displayed (@1x@2)", + width, rows))) + + return concat(fs) + end + + local large_recipe = width > 3 or rows > 3 + + if large_recipe then + fs[#fs + 1] = "style_type[item_image_button;border=true]" + end + + for i = 1, width * rows do + local item = rcp.items[i] or "" + local X = ceil((i - 1) % width - width) + XOFFSET + local Y = ceil(i / width) + YOFFSET - min(2, rows) + spacing + + if large_recipe then + local xof = 1 - 4 / width + local yof = 1 - 4 / rows + local x_y = width > rows and xof or yof + + btn_size = width > rows and + (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows + _btn_size = btn_size + + X = (btn_size * ((i - 1) % width) + XOFFSET - + (sfinv_only and 2.83 or 0.5)) * (0.83 - (x_y / 5)) + Y = (btn_size * floor((i - 1) / width) + + (sfinv_only and 5.81 or 4) + x_y) * (0.86 - (x_y / 5)) + end + + if X > rightest then + rightest = X + end + + local groups + + if is_group(item) then + groups = extract_groups(item) + local items = groups_to_items(groups) + item = items[1] or items + end + + local label = groups and "\nG" or "" + local replace + + if replacements then + for j = 1, #replacements do + local replacement = replacements[j] + if replacement[1] == item then + label = "\nR" + replace = replacement[2] + end + end + end + + fs[#fs + 1] = fmt(FMT.item_image_button, + X, Y + (sfinv_only and 0.7 or 0), + btn_size, btn_size, item, clean_str(item), ESC(label)) + + local infos = { + unknown = not reg_items[item], + groups = groups, + burntime = fuel_cache[item], + cooktime = cooktime, + replace = replace, + } + + for _, info in pairs(infos) do + if info then + fs[#fs + 1] = get_tooltip(item, infos) + break + end + end + + if CORE_VERSION >= 510 and not large_recipe then + fs[#fs + 1] = fmt(FMT.image, + X, Y + (sfinv_only and 0.7 or 0), + btn_size, btn_size, "craftguide_selected.png") + end + + if large_recipe then + fs[#fs + 1] = "style_type[item_image_button;border=false]" + end + end + + get_output_fs(fs, { + recipe = rcp, + shapeless = shapeless, + rightest = rightest, + btn_size = btn_size, + _btn_size = _btn_size, + spacing = spacing, + }) +end + +local function get_panels(data, fs) local panels = {recipes = data.recipes, usages = data.usages} - local infonum = 0 - local last_y + local x, last_y = 0 if sfinv_only then panels = data.show_usages and @@ -741,25 +859,9 @@ local function get_info_fs(data, fs) end for k, v in pairs(panels) do - infonum = infonum + 1 - local spacing = (infonum - 1) * 3.6 - last_y = -0.2 + infonum * 3.6 - - local rcp = k == "recipes" and v[data.rnum] or v[data.unum] - local width = rcp.width or 1 - local replacements = rcp.replacements - local cooktime, shapeless - - if rcp.type == "cooking" then - cooktime, width = width, 1 - elseif width == 0 and not rcp.custom then - shapeless = true - local n = #rcp.items - width = (n < 5 and n > 1) and 2 or min(3, max(1, n)) - end - - local rows = ceil(maxn(rcp.items) / width) - local rightest, btn_size, s_btn_size = 0, 1.1 + x = x + 1 + local spacing = (x - 1) * 3.6 + last_y = -0.2 + x * 3.6 if not sfinv_only then fs[#fs + 1] = CORE_VERSION >= 510 and @@ -801,110 +903,12 @@ local function get_info_fs(data, fs) fmt("next_%s", btn_suffix), PNG.next) end - if width > WH_LIMIT or rows > WH_LIMIT then - fs[#fs + 1] = fmt(FMT.label, - sfinv_only and 2 or 3, 7, - ESC(S("Recipe's too big to be displayed (@1x@2)", width, rows))) - - return concat(fs) - end - - local large_recipe = width > 3 or rows > 3 - - if large_recipe then - fs[#fs + 1] = "style_type[item_image_button;border=true]" - end - - for i = 1, width * rows do - local item = rcp.items[i] or "" - local X = ceil((i - 1) % width - width) + XOFFSET - local Y = ceil(i / width) + YOFFSET - min(2, rows) + spacing - - if large_recipe then - local xof = 1 - 4 / width - local yof = 1 - 4 / rows - local x_y = width > rows and xof or yof - - btn_size = width > rows and - (3.5 + (xof * 2)) / width or (3.5 + (yof * 2)) / rows - s_btn_size = btn_size - - X = (btn_size * ((i - 1) % width) + XOFFSET - - (sfinv_only and 2.83 or 0.5)) * (0.83 - (x_y / 5)) - Y = (btn_size * floor((i - 1) / width) + - (sfinv_only and 5.81 or 4) + x_y) * (0.86 - (x_y / 5)) - end - - if X > rightest then - rightest = X - end - - local groups - - if is_group(item) then - groups = extract_groups(item) - local items = groups_to_items(groups) - item = items[1] or items - end - - local label = groups and "\nG" or "" - local replace - - if replacements then - for j = 1, #replacements do - local replacement = replacements[j] - if replacement[1] == item then - label = "\nR" - replace = replacement[2] - end - end - end - - fs[#fs + 1] = fmt(FMT.item_image_button, - X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, clean_str(item), ESC(label)) - - local infos = { - unknown = not reg_items[item], - groups = groups, - burntime = fuel_cache[item], - cooktime = cooktime, - replace = replace, - } - - for _, info in pairs(infos) do - if info then - fs[#fs + 1] = get_tooltip(item, infos) - break - end - end - - if CORE_VERSION >= 510 and not large_recipe then - fs[#fs + 1] = fmt(FMT.image, - X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, "craftguide_selected.png") - end - end - - if large_recipe then - fs[#fs + 1] = "style_type[item_image_button;border=false]" - end - - get_output_fs(fs, { - recipe = rcp, - shapeless = shapeless, - rightest = rightest, - btn_size = btn_size, - s_btn_size = s_btn_size, - spacing = spacing, - }) + local rcp = k == "recipes" and v[data.rnum] or v[data.unum] + get_grid_fs(fs, rcp, spacing) end if not sfinv_only then - get_itemdef_fs(fs, { - item = data.query_item, - y = last_y, - }) + get_itemdef_fs(fs, data.query_item, last_y) end end @@ -989,7 +993,7 @@ local function make_formspec(name) end if (data.recipes and #data.recipes > 0) or (data.usages and #data.usages > 0) then - get_info_fs(data, fs) + get_panels(data, fs) end return concat(fs) From 41021895cef2ed178bd29772f38eafb121998696 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 8 Oct 2019 14:56:45 +0200 Subject: [PATCH 161/188] Minor cleaning --- init.lua | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/init.lua b/init.lua index d5ae522..59bcbbd 100644 --- a/init.lua +++ b/init.lua @@ -74,16 +74,17 @@ local XOFFSET = sfinv_only and 3.83 or 11.2 local YOFFSET = sfinv_only and 6 or 1 local PNG = { - bg = "craftguide_bg.png", - bg_full = "craftguide_bg_full.png", - search = "craftguide_search_icon.png", - clear = "craftguide_clear_icon.png", - prev = "craftguide_next_icon.png^\\[transformFX", - next = "craftguide_next_icon.png", - arrow = "craftguide_arrow.png", - fire = "craftguide_fire.png", - book = "craftguide_book.png", - sign = "craftguide_sign.png", + bg = "craftguide_bg.png", + bg_full = "craftguide_bg_full.png", + search = "craftguide_search_icon.png", + clear = "craftguide_clear_icon.png", + prev = "craftguide_next_icon.png^\\[transformFX", + next = "craftguide_next_icon.png", + arrow = "craftguide_arrow.png", + fire = "craftguide_fire.png", + book = "craftguide_book.png", + sign = "craftguide_sign.png", + selected = "craftguide_selected.png", } local FMT = { @@ -95,7 +96,7 @@ local FMT = { item_image = "item_image[%f,%f;%f,%f;%s]", image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]", - arrow = "image_button[%f,%f;0.8,0.8;%s;%s;;;false;%s^\\[colorize:yellow:255]" + arrow = "image_button[%f,%f;0.8,0.8;%s;%s;;;false;%s^\\[colorize:yellow:255]", } craftguide.group_stereotypes = { @@ -676,7 +677,7 @@ local function get_output_fs(fs, L) if CORE_VERSION >= 510 then fs[#fs + 1] = fmt(FMT.image, output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, - 1.1, 1.1, "craftguide_selected.png") + 1.1, 1.1, PNG.selected) end local burntime = fuel_cache[name] @@ -831,7 +832,7 @@ local function get_grid_fs(fs, rcp, spacing) if CORE_VERSION >= 510 and not large_recipe then fs[#fs + 1] = fmt(FMT.image, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, "craftguide_selected.png") + btn_size, btn_size, PNG.selected) end if large_recipe then @@ -988,7 +989,7 @@ local function make_formspec(name) fs[#fs + 1] = fmt(FMT.image, X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, Y - (Y * 0.1) - 0.1, - 1, 1, "craftguide_selected.png") + 1, 1, PNG.selected) end end From a8ad0435faae09b663b5e60dc41a9dea54c391da Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 9 Oct 2019 00:11:23 +0200 Subject: [PATCH 162/188] Add test file --- init.lua | 9 +++++++++ test.json | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 test.json diff --git a/init.lua b/init.lua index 59bcbbd..5fe3adb 100644 --- a/init.lua +++ b/init.lua @@ -1869,3 +1869,12 @@ register_command("craft", { return true, craftguide.show(name, node_name) end, }) + +print(core.write_json({ + result = "default:cobble 16", + items = { + "default:stone, default:stone, default:stone", + "default:stone, , default:stone", + "default:stone, default:stone, default:stone", + } +})) diff --git a/test.json b/test.json new file mode 100644 index 0000000..8b2e209 --- /dev/null +++ b/test.json @@ -0,0 +1,7 @@ +{ + "items":[ + "default:stone, default:stone, default:stone", + "default:stone, , default:stone", + "default:stone, default:stone, default:stone"], + "result":"default:cobble 16" +} \ No newline at end of file From 98a652259b22bac73f576aaf4e0163b5453afa78 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 9 Oct 2019 00:16:42 +0200 Subject: [PATCH 163/188] test --- init.lua | 18 ++++++++++-------- test.json | 7 ++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/init.lua b/init.lua index 5fe3adb..388cef5 100644 --- a/init.lua +++ b/init.lua @@ -20,6 +20,8 @@ local toolrepair local progressive_mode = core.settings:get_bool("craftguide_progressive_mode") local sfinv_only = core.settings:get_bool("craftguide_sfinv_only") and rawget(_G, "sfinv") +local http = core.request_http_api() + local reg_items = core.registered_items local reg_tools = core.registered_tools local reg_aliases = core.registered_aliases @@ -1870,11 +1872,11 @@ register_command("craft", { end, }) -print(core.write_json({ - result = "default:cobble 16", - items = { - "default:stone, default:stone, default:stone", - "default:stone, , default:stone", - "default:stone, default:stone, default:stone", - } -})) +if http then + local data = http.fetch_async({ + url = "https://raw.githubusercontent.com/minetest-mods/craftguide/master/test.json", + }) + + print(type(data)) + print(core.parse_json(data)) +end \ No newline at end of file diff --git a/test.json b/test.json index 8b2e209..860d318 100644 --- a/test.json +++ b/test.json @@ -1,7 +1,8 @@ { - "items":[ + "items": [ "default:stone, default:stone, default:stone", "default:stone, , default:stone", - "default:stone, default:stone, default:stone"], - "result":"default:cobble 16" + "default:stone, default:stone, default:stone" + ], + "result": "default:cobble 16" } \ No newline at end of file From 4fb4fe17632aa230c431309630ac08d820e13dae Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 10 Oct 2019 00:49:02 +0200 Subject: [PATCH 164/188] Add support for dropped items + support for URL fetched recipes + bugfixes --- .luacheckrc | 1 + API.md | 52 +++++++++++- README.md | 2 +- init.lua | 220 ++++++++++++++++++++++++++---------------------- locale/template | 4 +- 5 files changed, 174 insertions(+), 105 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 8ecfd80..8067e73 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -9,6 +9,7 @@ read_globals = { "vector", "string", "table", + "ItemStack", } globals = { diff --git a/API.md b/API.md index 7e490c9..794795f 100644 --- a/API.md +++ b/API.md @@ -35,7 +35,7 @@ craftguide.register_craft({ }) ``` -Recipes can also be registered in a Minecraft-like way: +Recipes can be registered in a Minecraft-like way: ```Lua craftguide.register_craft({ @@ -53,6 +53,47 @@ craftguide.register_craft({ }) ``` +Multiples recipes can also be registered: + +```Lua +craftguide.register_craft({ + { + result = "default:mese", + items = { + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + } + }, + + { + result = "default:mese 2", + items = { + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + } + }, + + big = { + result = "default:mese 4", + items = { + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + } + }, +}) +``` + +Recipes can be registered via an URL (HTTP support is required¹): + +```Lua +craftguide.register_craft({ + url = https://raw.githubusercontent.com/minetest-mods/craftguide/master/test.json +}) +``` + --- ### Recipe filters @@ -168,3 +209,12 @@ You can add a stereotype like so: ```Lua craftguide.group_stereotypes.radioactive = "mod:item" ``` + +#### `craftguide.http_post_data` + +If set, the mod will export all the cached recipes and usages in a JSON format +to the given URL (HTTP support is required¹). + +--- + +**¹** Add `craftguide` to the `secure.http_mods` or `secure.trusted_mods` setting in `minetest.conf`. diff --git a/README.md b/README.md index 135906c..f1d2e9e 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,4 @@ For developers, `craftguide` also has a [modding API](https://github.com/minetes Love this mod? Donations are appreciated: https://www.paypal.me/jpg84240 -![Preview2](https://i.imgur.com/GVQvufb.png) +![Preview2](https://i.imgur.com/w7KMS9G.png) diff --git a/init.lua b/init.lua index 388cef5..30897bd 100644 --- a/init.lua +++ b/init.lua @@ -29,6 +29,8 @@ local reg_aliases = core.registered_aliases local log = core.log local after = core.after local clr = core.colorize +local parse_json = core.parse_json +local write_json = core.write_json local chat_send = core.chat_send_player local show_formspec = core.show_formspec local globalstep = core.register_globalstep @@ -119,12 +121,13 @@ local function msg(name, str) return chat_send(name, fmt("[craftguide] %s", clr("#FFFF00", str))) end -local function clean_str(str) - return match(str, "%S*") -end local function is_str(x) - return type(x) == "string" and clean_str(x) + return type(x) == "string" +end + +local function true_str(str) + return is_str(str) and str ~= "" end local function is_table(x) @@ -249,7 +252,7 @@ end local craft_types = {} function craftguide.register_craft_type(name, def) - if not is_str(name) then + if not true_str(name) then return err("craftguide.register_craft_type(): name missing") end @@ -265,19 +268,43 @@ function craftguide.register_craft_type(name, def) end function craftguide.register_craft(def) - def.custom = true - def.width = 0 - local c = 0 + local width, c = 0, 0 + + if true_str(def.url) then + if not http then + return err("No HTTP support for this mod. " .. + "Add it to the `secure.http_mods` or `secure.trusted_mods` setting.") + end + + http.fetch({url = def.url}, function(result) + if result.succeeded then + local t = parse_json(result.data) + if is_table(t) then + return craftguide.register_craft(t) + end + end + end) + + return + end if not is_table(def) or not next(def) then return err("craftguide.register_craft(): craft definition missing") end - if def.result then - def.output = def.result -- Backward compatibility + if #def > 1 then + for _, v in pairs(def) do + craftguide.register_craft(v) + end + return end - if not is_str(def.output) then + if def.result then + def.output = def.result -- Backward compatibility + def.result = nil + end + + if not true_str(def.output) then return err("craftguide.register_craft(): output missing") end @@ -299,10 +326,10 @@ function craftguide.register_craft(def) return #a > #b end) - def.width = #cp[1] + width = #cp[1] for i = 1, #def.grid do - while #def.grid[i] < def.width do + while #def.grid[i] < width do def.grid[i] = def.grid[i] .. " " end end @@ -319,32 +346,35 @@ function craftguide.register_craft(def) items[i] = items[i]:gsub(",", ", ") local rlen = #split(items[i], ",") - if rlen > def.width then - def.width = rlen + if rlen > width then + width = rlen end end for i = 1, len do - while #split(items[i], ",") < def.width do + while #split(items[i], ",") < width do items[i] = items[i] .. ", " end end for name in gmatch(concat(items, ","), "[%s%w_:]+") do c = c + 1 - def.items[c] = clean_str(name) + def.items[c] = match(name, "%S+") end end - local output = clean_str(def.output) + local output = match(def.output, "%S+") recipes_cache[output] = recipes_cache[output] or {} + + def.custom = true + def.width = width insert(recipes_cache[output], def) end local recipe_filters = {} function craftguide.add_recipe_filter(name, f) - if not is_str(name) then + if not true_str(name) then return err("craftguide.add_recipe_filter(): name missing") elseif not is_func(f) then return err("craftguide.add_recipe_filter(): function missing") @@ -382,7 +412,7 @@ end local search_filters = {} function craftguide.add_search_filter(name, f) - if not is_str(name) then + if not true_str(name) then return err("craftguide.add_search_filter(): name missing") elseif not is_func(f) then return err("craftguide.add_search_filter(): function missing") @@ -630,6 +660,11 @@ local function get_tooltip(item, info) tooltip = add(S("Repairable by step of @1", clr("yellow", toolrepair .. "%"))) end + if info.rarity then + local chance = (1 / info.rarity) * 100 + tooltip = add(S("@1 of chance to drop", clr("yellow", chance .. "%"))) + end + return fmt("tooltip[%s;%s]", item, ESC(tooltip)) end @@ -670,7 +705,7 @@ local function get_output_fs(fs, L) 1.1, 1.1, PNG.fire) else local item = L.recipe.output - local name = clean_str(item) + local name = match(item, "%S*") fs[#fs + 1] = fmt(FMT.item_image_button, output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, @@ -682,17 +717,17 @@ local function get_output_fs(fs, L) 1.1, 1.1, PNG.selected) end - local burntime = fuel_cache[name] - local repair = repairable(name) + local infos = { + burntime = fuel_cache[name], + repair = repairable(name), + rarity = L.rarity, + } - if burntime or repair then - fs[#fs + 1] = get_tooltip(name, { - burntime = burntime, - repair = repair, - }) + if next(infos) then + fs[#fs + 1] = get_tooltip(name, infos) end - if burntime then + if infos.burntime then fs[#fs + 1] = fmt(FMT.image, output_X + 1, YOFFSET + (sfinv_only and 0.7 or 0.1) + L.spacing, 0.6, 0.4, PNG.arrow) @@ -704,40 +739,11 @@ local function get_output_fs(fs, L) end end -local function pretty_wrap(str, limit) - return #str > limit + 3 and sub(str, 1, limit) .. "..." or str -end - -local function get_itemdef_fs(fs, item, last_y) - fs[#fs + 1] = CORE_VERSION >= 510 and - fmt("background9[8.1,%f;6.6,2.19;%s;false;%d]", - last_y, PNG.bg_full, 10) or - fmt("background[8.1,%f;6.6,2.19;%s;false]", last_y, PNG.bg_full) - - local specs = { - ESC(S("Name")), - } - - local namestr = fmt("%s (%s)", pretty_wrap(get_desc(item), 25), item) - - local tstr = "" - for i = 1, #specs do - tstr = tstr .. "#6389FF," .. specs[i] .. ",#FFFFFF,%s," - end - tstr = sub(tstr, 1, -2) - - fs[#fs + 1] = [[ - tableoptions[background=#00000000;highlight=#00000000;border=false] - tablecolumns[color;text] - ]] - - fs[#fs + 1] = fmt("table[8.1,%f;6.3,1.8;itemdef;" .. tstr .. ";0]", - last_y + 0.08, namestr) -end - local function get_grid_fs(fs, rcp, spacing) + if not rcp then return end local width = rcp.width or 1 local replacements = rcp.replacements + local rarity = rcp.rarity local rightest, btn_size, _btn_size = 0, 1.1 local cooktime, shapeless @@ -755,8 +761,7 @@ local function get_grid_fs(fs, rcp, spacing) fs[#fs + 1] = fmt(FMT.label, XOFFSET + (sfinv_only and -1.5 or -1.6), YOFFSET + (sfinv_only and 0.5 or spacing), - ESC(S("Recipe's too big to be displayed (@1x@2)", - width, rows))) + ESC(S("Recipe's too big to be displayed (@1x@2)", width, rows))) return concat(fs) end @@ -784,7 +789,7 @@ local function get_grid_fs(fs, rcp, spacing) X = (btn_size * ((i - 1) % width) + XOFFSET - (sfinv_only and 2.83 or 0.5)) * (0.83 - (x_y / 5)) Y = (btn_size * floor((i - 1) / width) + - (sfinv_only and 5.81 or 4) + x_y) * (0.86 - (x_y / 5)) + (sfinv_only and 5.81 or 5.5) + x_y) * (0.86 - (x_y / 5)) end if X > rightest then @@ -814,21 +819,18 @@ local function get_grid_fs(fs, rcp, spacing) fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, clean_str(item), ESC(label)) + btn_size, btn_size, item, match(item, "%S*"), ESC(label)) local infos = { - unknown = not reg_items[item], + unknown = reg_items[item] and nil, groups = groups, burntime = fuel_cache[item], cooktime = cooktime, replace = replace, } - for _, info in pairs(infos) do - if info then - fs[#fs + 1] = get_tooltip(item, infos) - break - end + if next(infos) then + fs[#fs + 1] = get_tooltip(item, infos) end if CORE_VERSION >= 510 and not large_recipe then @@ -836,10 +838,10 @@ local function get_grid_fs(fs, rcp, spacing) X, Y + (sfinv_only and 0.7 or 0), btn_size, btn_size, PNG.selected) end + end - if large_recipe then - fs[#fs + 1] = "style_type[item_image_button;border=false]" - end + if large_recipe then + fs[#fs + 1] = "style_type[item_image_button;border=false]" end get_output_fs(fs, { @@ -849,12 +851,13 @@ local function get_grid_fs(fs, rcp, spacing) btn_size = btn_size, _btn_size = _btn_size, spacing = spacing, + rarity = rarity, }) end local function get_panels(data, fs) - local panels = {recipes = data.recipes, usages = data.usages} - local x, last_y = 0 + local panels = {recipes = data.recipes or {}, usages = data.usages or {}} + local x = 0.33 if sfinv_only then panels = data.show_usages and @@ -864,7 +867,6 @@ local function get_panels(data, fs) for k, v in pairs(panels) do x = x + 1 local spacing = (x - 1) * 3.6 - last_y = -0.2 + x * 3.6 if not sfinv_only then fs[#fs + 1] = CORE_VERSION >= 510 and @@ -876,7 +878,11 @@ local function get_panels(data, fs) local btn_lab - if (not sfinv_only and k == "recipes") or + if not sfinv_only and #v == 0 then + btn_lab = clr("red", k == "recipes" and + ESC(S("No recipes")) or ESC(S("No usages"))) + + elseif (not sfinv_only and k == "recipes") or (sfinv_only and not data.show_usages) then btn_lab = ESC(S("Recipe @1 of @2", data.rnum, #v)) @@ -909,10 +915,6 @@ local function get_panels(data, fs) local rcp = k == "recipes" and v[data.rnum] or v[data.unum] get_grid_fs(fs, rcp, spacing) end - - if not sfinv_only then - get_itemdef_fs(fs, data.query_item, last_y) - end end local function make_formspec(name) @@ -1109,9 +1111,9 @@ core.register_craft = function(def) toolrepair = def.additional_wear * -100 end - local output = def.output or is_str(def.recipe) + local output = def.output or (true_str(def.recipe) and def.recipe) or nil if not output then return end - output = {clean_str(output)} + output = {match(output, "%S+")} local groups @@ -1180,11 +1182,12 @@ local function handle_drops_table(name, drop) local di = drop_items[i] for j = 1, #di.items do - if not is_str(di.items[j]) then break end - local dname, dcount = match(di.items[j], "(.*)%s*(%d*)") - dcount = dcount and tonumber(dcount) or 1 + local dstack = ItemStack(di.items[j]) + local dname = dstack:get_name() + + if not dstack:is_empty() and dname ~= name then + local dcount = dstack:get_count() - if dname ~= name then if #di.items == 1 and di.rarity == 1 and max_start then if not drop_sure[dname] then drop_sure[dname] = 0 @@ -1202,10 +1205,17 @@ local function handle_drops_table(name, drop) end if not drop_maybe[dname] then - drop_maybe[dname] = 0 + drop_maybe[dname] = {} end - drop_maybe[dname] = drop_maybe[dname] + dcount + if not drop_maybe[dname].output then + drop_maybe[dname].output = 0 + end + + drop_maybe[dname] = { + output = drop_maybe[dname].output + dcount, + rarity = di.rarity, + } end end end @@ -1219,19 +1229,21 @@ local function handle_drops_table(name, drop) }) end - for item, count in pairs(drop_maybe) do + for item, data in pairs(drop_maybe) do craftguide.register_craft({ type = "digging_chance", items = {name}, - output = fmt("%s %u", item, count), + output = fmt("%s %u", item, data.output), + rarity = data.rarity, }) end end local function register_drops(name, def) local drop = def.drop + local dstack = ItemStack(drop) - if is_str(drop) and drop ~= name then + if not dstack:is_empty() and dstack:get_name() ~= name then craftguide.register_craft({ type = "digging", items = {name}, @@ -1308,6 +1320,19 @@ local function get_init_items() handle_aliases(hash) sort(init_items) + + if http and true_str(craftguide.http_post_data) then + local post_data = { + recipes = recipes_cache, + usages = usages_cache, + fuel = fuel_cache, + } + + http.fetch_async({ + url = craftguide.http_post_data, + post_data = write_json(post_data), + }) + end end local function init_data(name) @@ -1808,7 +1833,7 @@ on_leaveplayer(function(player) end) function craftguide.show(name, item, show_usages) - if not is_str(name) then + if not true_str(name)then return err("craftguide.show(): player name missing") end @@ -1871,12 +1896,3 @@ register_command("craft", { return true, craftguide.show(name, node_name) end, }) - -if http then - local data = http.fetch_async({ - url = "https://raw.githubusercontent.com/minetest-mods/craftguide/master/test.json", - }) - - print(type(data)) - print(core.parse_json(data)) -end \ No newline at end of file diff --git a/locale/template b/locale/template index 20cfdc9..4edbd45 100644 --- a/locale/template +++ b/locale/template @@ -5,6 +5,8 @@ Crafting Guide= Crafting Guide Sign= Usage @1 of @2= Recipe @1 of @2= +No recipes= +No usages= Burning time: @1= Cooking time: @1= Replaced by @1 on smelting= @@ -21,6 +23,6 @@ Show recipe(s) of the pointed node= No node pointed= You don't know a recipe or usage for this item= No recipe or usage for this item= -Name= Digging= Digging Chance= +@1 of chance to drop= From ee1eac039e24e082735a19e28cd249fd061c1978 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 10 Oct 2019 17:46:12 +0200 Subject: [PATCH 165/188] Minor cleaning --- API.md | 11 +---------- init.lua | 5 +++-- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/API.md b/API.md index 794795f..7aa0379 100644 --- a/API.md +++ b/API.md @@ -65,15 +65,6 @@ craftguide.register_craft({ } }, - { - result = "default:mese 2", - items = { - "default:mese_crystal, default:mese_crystal", - "default:mese_crystal, default:mese_crystal", - "default:mese_crystal, default:mese_crystal", - } - }, - big = { result = "default:mese 4", items = { @@ -90,7 +81,7 @@ Recipes can be registered via an URL (HTTP support is required¹): ```Lua craftguide.register_craft({ - url = https://raw.githubusercontent.com/minetest-mods/craftguide/master/test.json + url = "https://raw.githubusercontent.com/minetest-mods/craftguide/master/test.json" }) ``` diff --git a/init.lua b/init.lua index 30897bd..896f5b4 100644 --- a/init.lua +++ b/init.lua @@ -740,7 +740,6 @@ local function get_output_fs(fs, L) end local function get_grid_fs(fs, rcp, spacing) - if not rcp then return end local width = rcp.width or 1 local replacements = rcp.replacements local rarity = rcp.rarity @@ -913,7 +912,9 @@ local function get_panels(data, fs) end local rcp = k == "recipes" and v[data.rnum] or v[data.unum] - get_grid_fs(fs, rcp, spacing) + if rcp then + get_grid_fs(fs, rcp, spacing) + end end end From c9c2bf03deb6582d3197c6614c57a9364ab08f38 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 11 Oct 2019 02:39:07 +0200 Subject: [PATCH 166/188] Small precisions --- API.md | 5 ++++- init.lua | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/API.md b/API.md index 7aa0379..251afd5 100644 --- a/API.md +++ b/API.md @@ -5,6 +5,9 @@ Custom recipes are nonconventional crafts outside the main crafting grid. They can be registered in-game dynamically and have a size beyond 3x3 items. +**Note:** the registration format differs from the default registration format in everything. +The width is automatically calculated depending where you place the commas. Look at the examples attentively. + #### Registering a custom crafting type (example) ```Lua @@ -77,7 +80,7 @@ craftguide.register_craft({ }) ``` -Recipes can be registered via an URL (HTTP support is required¹): +Recipes can be registered from a given URL containing a JSON file (HTTP support is required¹): ```Lua craftguide.register_craft({ diff --git a/init.lua b/init.lua index 896f5b4..0301f8c 100644 --- a/init.lua +++ b/init.lua @@ -121,7 +121,6 @@ local function msg(name, str) return chat_send(name, fmt("[craftguide] %s", clr("#FFFF00", str))) end - local function is_str(x) return type(x) == "string" end From 270dc19ec10fcd02746dd279d13c1393eb1e6788 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sat, 12 Oct 2019 13:16:08 +0200 Subject: [PATCH 167/188] Fix crash with groups_to_items() --- init.lua | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/init.lua b/init.lua index 0301f8c..cdecb2f 100644 --- a/init.lua +++ b/init.lua @@ -592,11 +592,15 @@ local function groups_to_items(groups, get_all) local names = {} for name, def in pairs(reg_items) do if item_has_groups(def.groups, groups) then - names[#names + 1] = name + if get_all then + names[#names + 1] = name + else + return name + end end end - return names + return get_all and names or "" end local function repairable(tool) @@ -798,8 +802,7 @@ local function get_grid_fs(fs, rcp, spacing) if is_group(item) then groups = extract_groups(item) - local items = groups_to_items(groups) - item = items[1] or items + item = groups_to_items(groups) end local label = groups and "\nG" or "" From e707db9ab98b0d74653ce4dd59108d0dab785403 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 13 Oct 2019 00:27:31 +0200 Subject: [PATCH 168/188] Fix sfinv grid positioning --- init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index cdecb2f..5c0889e 100644 --- a/init.lua +++ b/init.lua @@ -75,7 +75,7 @@ local IPP = ROWS * LINES local WH_LIMIT = 8 local XOFFSET = sfinv_only and 3.83 or 11.2 -local YOFFSET = sfinv_only and 6 or 1 +local YOFFSET = sfinv_only and 4.9 or 1 local PNG = { bg = "craftguide_bg.png", @@ -898,13 +898,13 @@ local function get_panels(data, fs) fs[#fs + 1] = fmt(FMT.label, XOFFSET + (sfinv_only and 2.3 or 1.6), - YOFFSET + (sfinv_only and 2.2 or 1.5 + spacing), + YOFFSET + (sfinv_only and 3.35 or 1.5 + spacing), btn_lab) if #v > 1 then local btn_suffix = k == "recipes" and "recipe" or "usage" local x_arrow = XOFFSET + (sfinv_only and 1.7 or 1) - local y_arrow = YOFFSET + (sfinv_only and 2.1 or 1.4 + spacing) + local y_arrow = YOFFSET + (sfinv_only and 3.25 or 1.4 + spacing) fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, x_arrow, y_arrow, PNG.prev, From b12502a7da2f7b06b516b4d1a213f1a2fc9149d7 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 13 Oct 2019 18:31:46 +0200 Subject: [PATCH 169/188] Small fixes --- init.lua | 77 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/init.lua b/init.lua index 5c0889e..3819072 100644 --- a/init.lua +++ b/init.lua @@ -66,7 +66,7 @@ local fmt, find, gmatch, match, sub, split, upper, lower = string.sub, string.split, string.upper, string.lower local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil -local pairs, next, type = pairs, next, type +local pairs, next, type, tostring = pairs, next, type, tostring local vec_add, vec_mul = vector.add, vector.multiply local ROWS = 9 @@ -141,6 +141,14 @@ local function is_group(item) return sub(item, 1, 6) == "group:" end +local function clean_item(item) + if sub(item, 1, 1) == ":" then + item = sub(item, 2) + end + + return item +end + local function array_diff(t1, t2) local hash = {} @@ -616,7 +624,7 @@ local function get_desc(name) S("Unknown Item (@1)", name)) end -local function get_tooltip(item, info) +local function get_tooltip(name, info) local tooltip if info.groups then @@ -630,10 +638,10 @@ local function get_tooltip(item, info) groupstr = concat(groupstr, ", ") tooltip = S("Any item belonging to the group(s): @1", groupstr) - return fmt("tooltip[%s;%s]", item, ESC(tooltip)) + return fmt("tooltip[%s;%s]", name, ESC(tooltip)) end - tooltip = get_desc(item) + tooltip = get_desc(name) local function add(str) return fmt("%s\n%s", tooltip, str) @@ -668,7 +676,7 @@ local function get_tooltip(item, info) tooltip = add(S("@1 of chance to drop", clr("yellow", chance .. "%"))) end - return fmt("tooltip[%s;%s]", item, ESC(tooltip)) + return fmt("tooltip[%s;%s]", name, ESC(tooltip)) end local function get_output_fs(fs, L) @@ -708,11 +716,12 @@ local function get_output_fs(fs, L) 1.1, 1.1, PNG.fire) else local item = L.recipe.output + item = clean_item(item) local name = match(item, "%S*") fs[#fs + 1] = fmt(FMT.item_image_button, output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, - 1.1, 1.1, item, ESC(name), "") + 1.1, 1.1, item, name, "") if CORE_VERSION >= 510 then fs[#fs + 1] = fmt(FMT.image, @@ -721,6 +730,7 @@ local function get_output_fs(fs, L) end local infos = { + unknown = not reg_items[name] or nil, burntime = fuel_cache[name], repair = repairable(name), rarity = L.rarity, @@ -776,6 +786,9 @@ local function get_grid_fs(fs, rcp, spacing) for i = 1, width * rows do local item = rcp.items[i] or "" + item = clean_item(item) + local name = match(item, "%S*") + local X = ceil((i - 1) % width - width) + XOFFSET local Y = ceil(i / width) + YOFFSET - min(2, rows) + spacing @@ -800,8 +813,8 @@ local function get_grid_fs(fs, rcp, spacing) local groups - if is_group(item) then - groups = extract_groups(item) + if is_group(name) then + groups = extract_groups(name) item = groups_to_items(groups) end @@ -811,7 +824,7 @@ local function get_grid_fs(fs, rcp, spacing) if replacements then for j = 1, #replacements do local replacement = replacements[j] - if replacement[1] == item then + if replacement[1] == name then label = "\nR" replace = replacement[2] end @@ -820,18 +833,18 @@ local function get_grid_fs(fs, rcp, spacing) fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, match(item, "%S*"), ESC(label)) + btn_size, btn_size, item, name, ESC(label)) local infos = { - unknown = reg_items[item] and nil, + unknown = not reg_items[name] or nil, groups = groups, - burntime = fuel_cache[item], + burntime = fuel_cache[name], cooktime = cooktime, replace = replace, } if next(infos) then - fs[#fs + 1] = get_tooltip(item, infos) + fs[#fs + 1] = get_tooltip(name, infos) end if CORE_VERSION >= 510 and not large_recipe then @@ -877,43 +890,51 @@ local function get_panels(data, fs) -0.2 + spacing, PNG.bg_full) end + local rn = #v + local _rn = tostring(rn) + local xof_u = tostring(data.unum) .. _rn + local xof_r = tostring(data.rnum) .. _rn + xof_u = max(-0.3, -((#xof_u - 3) * 0.15)) + xof_r = max(-0.3, -((#xof_r - 3) * 0.15)) + + local is_recipe = k == "recipes" local btn_lab - if not sfinv_only and #v == 0 then - btn_lab = clr("red", k == "recipes" and + if not sfinv_only and rn == 0 then + btn_lab = clr("red", is_recipe and ESC(S("No recipes")) or ESC(S("No usages"))) - elseif (not sfinv_only and k == "recipes") or + elseif (not sfinv_only and is_recipe) or (sfinv_only and not data.show_usages) then - btn_lab = ESC(S("Recipe @1 of @2", data.rnum, #v)) + btn_lab = ESC(S("Recipe @1 of @2", data.rnum, rn)) elseif not sfinv_only or (sfinv_only and data.show_usages) then - btn_lab = ESC(S("Usage @1 of @2", data.unum, #v)) + btn_lab = ESC(S("Usage @1 of @2", data.unum, rn)) elseif sfinv_only then btn_lab = data.show_usages and - ESC(S("Usage @1 of @2", data.unum, #v)) or - ESC(S("Recipe @1 of @2", data.rnum, #v)) + ESC(S("Usage @1 of @2", data.unum, rn)) or + ESC(S("Recipe @1 of @2", data.rnum, rn)) end fs[#fs + 1] = fmt(FMT.label, - XOFFSET + (sfinv_only and 2.3 or 1.6), + XOFFSET + (sfinv_only and 2.3 or 1.6) + (is_recipe and xof_r or xof_u), YOFFSET + (sfinv_only and 3.35 or 1.5 + spacing), btn_lab) - if #v > 1 then - local btn_suffix = k == "recipes" and "recipe" or "usage" + if rn > 1 then + local btn_suffix = is_recipe and "recipe" or "usage" local x_arrow = XOFFSET + (sfinv_only and 1.7 or 1) local y_arrow = YOFFSET + (sfinv_only and 3.25 or 1.4 + spacing) fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, - x_arrow, y_arrow, PNG.prev, + x_arrow + (is_recipe and xof_r or xof_u), y_arrow, PNG.prev, fmt("prev_%s", btn_suffix), PNG.prev, x_arrow + 1.8, y_arrow, PNG.next, fmt("next_%s", btn_suffix), PNG.next) end - local rcp = k == "recipes" and v[data.rnum] or v[data.unum] + local rcp = is_recipe and v[data.rnum] or v[data.unum] if rcp then get_grid_fs(fs, rcp, spacing) end @@ -1287,7 +1308,7 @@ local function handle_aliases(hash) end end - if recipes_cache[oldname] and not hash[newname] then + if newname ~= "" and recipes_cache[oldname] and not hash[newname] then init_items[#init_items + 1] = newname end end @@ -1300,6 +1321,8 @@ local function show_item(def) end local function get_init_items() + print("[craftguide] Caching data. This may take a while...") + local hash = {} for name, def in pairs(reg_items) do if show_item(def) then @@ -1314,7 +1337,7 @@ local function get_init_items() cache_usages(name) register_drops(name, def) - if recipes_cache[name] or usages_cache[name] then + if name ~= "" and recipes_cache[name] or usages_cache[name] then init_items[#init_items + 1] = name hash[name] = true end From d6bd17f6b32f57a1cf6382ce4884bdf4b4f1f003 Mon Sep 17 00:00:00 2001 From: Hamlet <54187342+h4ml3t@users.noreply.github.com> Date: Tue, 15 Oct 2019 00:42:44 +0200 Subject: [PATCH 170/188] Updated Italian locale (#94) * Updated Italian locale --- locale/craftguide.it.tr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locale/craftguide.it.tr b/locale/craftguide.it.tr index 189f675..4a0c9ae 100644 --- a/locale/craftguide.it.tr +++ b/locale/craftguide.it.tr @@ -21,3 +21,6 @@ Show recipe(s) of the pointed node=Mostra la ricetta del nodo puntato No node pointed=Nessun nodo puntato You don't know a recipe for this node=Non conosci una ricetta per questo nodo No recipe for this node=Nessuna ricetta per questo nodo +Digging=Scavando +Digging Chance=Probabilità di scavare +@1 of chance to drop=@1 di probabilità di rilascio From 77dbe040b85dc025e7dda01e3e8d95c70c2b0504 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 15 Oct 2019 15:30:52 +0200 Subject: [PATCH 171/188] Fix tooltip --- init.lua | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index 3819072..6933094 100644 --- a/init.lua +++ b/init.lua @@ -637,12 +637,10 @@ local function get_tooltip(name, info) groupstr = concat(groupstr, ", ") tooltip = S("Any item belonging to the group(s): @1", groupstr) - - return fmt("tooltip[%s;%s]", name, ESC(tooltip)) + else + tooltip = get_desc(name) end - tooltip = get_desc(name) - local function add(str) return fmt("%s\n%s", tooltip, str) end @@ -825,7 +823,7 @@ local function get_grid_fs(fs, rcp, spacing) for j = 1, #replacements do local replacement = replacements[j] if replacement[1] == name then - label = "\nR" + label = (label ~= "" and "\n" or "") .. label .. "\nR" replace = replacement[2] end end @@ -833,7 +831,7 @@ local function get_grid_fs(fs, rcp, spacing) fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, item, name, ESC(label)) + btn_size, btn_size, item, item, ESC(label)) local infos = { unknown = not reg_items[name] or nil, @@ -844,7 +842,7 @@ local function get_grid_fs(fs, rcp, spacing) } if next(infos) then - fs[#fs + 1] = get_tooltip(name, infos) + fs[#fs + 1] = get_tooltip(item, infos) end if CORE_VERSION >= 510 and not large_recipe then From edbed14d9bb3a1890a89bc689a68de9a90782b08 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 22 Oct 2019 12:53:47 +0200 Subject: [PATCH 172/188] Fix non-shown recipes --- init.lua | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/init.lua b/init.lua index 6933094..df2117d 100644 --- a/init.lua +++ b/init.lua @@ -1034,21 +1034,6 @@ local show_fs = function(player, name) end end -craftguide.add_search_filter("groups", function(item, groups) - local itemdef = reg_items[item] - local has_groups = true - - for i = 1, #groups do - local group = groups[i] - if not itemdef.groups[group] then - has_groups = nil - break - end - end - - return has_groups -end) - craftguide.register_craft_type("digging", { description = ESC(S("Digging")), icon = "default_tool_steelpick.png", @@ -1067,7 +1052,7 @@ local function search(data) return end - local opt = "^(.-)%+([%w_]+)=([%w_,]+)" + local opt = "^(.-)%+([%w_]*)=*([%w_,]*)" local search_filter = next(search_filters) and match(filter, opt) local filters = {} @@ -1091,9 +1076,11 @@ local function search(data) if search_filter then for filter_name, values in pairs(filters) do - local func = search_filters[filter_name] - to_add = func(item, values) and (search_filter == "" or - find(search_in, search_filter, 1, true)) + if values then + local func = search_filters[filter_name] + to_add = func(item, values) and (search_filter == "" or + find(search_in, search_filter, 1, true)) + end end else to_add = find(search_in, filter, 1, true) @@ -1117,6 +1104,21 @@ local function search(data) data.items = filtered_list end +craftguide.add_search_filter("groups", function(item, groups) + local def = reg_items[item] + local has_groups = true + + for i = 1, #groups do + local group = groups[i] + if not def.groups[group] then + has_groups = nil + break + end + end + + return has_groups +end) + --[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not return the replacements and toolrepair, we have to override `core.register_craft` and do some reverse engineering. @@ -1278,7 +1280,7 @@ end local function handle_aliases(hash) for oldname, newname in pairs(reg_aliases) do - local recipes = recipes_cache[oldname] + local recipes = recipes_cache[oldname] or get_all_recipes(oldname) if recipes then if not recipes_cache[newname] then recipes_cache[newname] = {} From 35b2ecfdc17af9da9d0550d2f392afdc2658943a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 25 Oct 2019 01:15:51 +0200 Subject: [PATCH 173/188] Implement visual feedbacks on nav buttons --- init.lua | 73 +++++++++++++++++++++------- textures/craftguide_search_icon.png | Bin 1908 -> 5873 bytes 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/init.lua b/init.lua index df2117d..a2ee5c5 100644 --- a/init.lua +++ b/init.lua @@ -89,6 +89,11 @@ local PNG = { book = "craftguide_book.png", sign = "craftguide_sign.png", selected = "craftguide_selected.png", + + search_hover = "craftguide_search_icon_hover.png", + clear_hover = "craftguide_clear_icon_hover.png", + prev_hover = "craftguide_next_icon_hover.png^\\[transformFX", + next_hover = "craftguide_next_icon_hover.png", } local FMT = { @@ -100,7 +105,7 @@ local FMT = { item_image = "item_image[%f,%f;%f,%f;%s]", image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]", - arrow = "image_button[%f,%f;0.8,0.8;%s;%s;;;false;%s^\\[colorize:yellow:255]", + arrow = "image_button[%f,%f;0.8,0.8;%s;%s;;;false;%s]", } craftguide.group_stereotypes = { @@ -922,14 +927,29 @@ local function get_panels(data, fs) if rn > 1 then local btn_suffix = is_recipe and "recipe" or "usage" + local prev_name = fmt("prev_%s", btn_suffix) + local next_name = fmt("next_%s", btn_suffix) local x_arrow = XOFFSET + (sfinv_only and 1.7 or 1) local y_arrow = YOFFSET + (sfinv_only and 3.25 or 1.4 + spacing) - fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, - x_arrow + (is_recipe and xof_r or xof_u), y_arrow, PNG.prev, - fmt("prev_%s", btn_suffix), PNG.prev, - x_arrow + 1.8, y_arrow, PNG.next, - fmt("next_%s", btn_suffix), PNG.next) + if CORE_VERSION >= 520 then + fs[#fs + 1] = fmt([[ + style[%s;border=false;bgimg=%s;bgimg_hovered=%s] + style[%s;border=false;bgimg=%s;bgimg_hovered=%s] + ]], + prev_name, PNG.prev, PNG.prev_hover, + next_name, PNG.next, PNG.next_hover) + + fs[#fs + 1] = fmt(FMT.button .. FMT.button, + x_arrow + (is_recipe and xof_r or xof_u), + y_arrow, 0.8, 0.8, prev_name, "", + x_arrow + 1.8, y_arrow, 0.8, 0.8, next_name, "") + else + fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, + x_arrow + (is_recipe and xof_r or xof_u), + y_arrow, PNG.prev, prev_name, PNG.prev_hover, + x_arrow + 1.8, y_arrow, PNG.next, next_name, PNG.next_hover) + end end local rcp = is_recipe and v[data.rnum] or v[data.unum] @@ -968,23 +988,42 @@ local function make_formspec(name) ]], sfinv_only and 2.76 or 2.72, ESC(data.filter)) - fs[#fs + 1] = fmt([[ - image_button[%f,-0.05;0.85,0.85;%s;search;;;false;%s^\[colorize:yellow:255] - image_button[%f,-0.05;0.85,0.85;%s;clear;;;false;%s^\[colorize:red:255] + if CORE_VERSION >= 520 then + fs[#fs + 1] = fmt([[ + style[search;border=false;bgimg=%s;bgimg_hovered=%s] + style[clear;border=false;bgimg=%s;bgimg_hovered=%s] + style[prev_page;border=false;bgimg=%s;bgimg_hovered=%s] + style[next_page;border=false;bgimg=%s;bgimg_hovered=%s] ]], - sfinv_only and 2.6 or 2.54, PNG.search, PNG.search, - sfinv_only and 3.3 or 3.25, PNG.clear, PNG.clear) + PNG.search, PNG.search_hover, + PNG.clear, PNG.clear_hover, + PNG.prev, PNG.prev_hover, + PNG.next, PNG.next_hover) + + fs[#fs + 1] = fmt(FMT.button .. FMT.button .. FMT.button .. FMT.button, + sfinv_only and 2.6 or 2.54, -0.12, 0.85, 1, "search", "", + sfinv_only and 3.3 or 3.25, -0.12, 0.85, 1, "clear", "", + sfinv_only and 5.45 or (ROWS * 6.83) / 11, -0.12, 0.85, 1, "prev_page", "", + sfinv_only and 7.2 or (ROWS * 8.75) / 11, -0.12, 0.85, 1, "next_page", "") + else + fs[#fs + 1] = fmt([[ + image_button[%f,-0.12;0.85,1;%s;search;;;false;%s] + image_button[%f,-0.12;0.85,1;%s;clear;;;false;%s] + ]], + sfinv_only and 2.6 or 2.54, PNG.search, PNG.search_hover, + sfinv_only and 3.3 or 3.25, PNG.clear, PNG.clear_hover) + + fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, + sfinv_only and 5.45 or (ROWS * 6.83) / 11, + -0.05, PNG.prev, "prev_page", PNG.prev, + sfinv_only and 7.2 or (ROWS * 8.75) / 11, + -0.05, PNG.next, "next_page", PNG.next) + end fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", sfinv_only and 6.35 or (ROWS * 7.85) / 11, 0.06, clr("yellow", data.pagenum), data.pagemax) - fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, - sfinv_only and 5.45 or (ROWS * 6.83) / 11, - -0.05, PNG.prev, "prev_page", PNG.prev, - sfinv_only and 7.2 or (ROWS * 8.75) / 11, - -0.05, PNG.next, "next_page", PNG.next) - if #data.items == 0 then local no_item = S("No item to show") local pos = ROWS / 3 diff --git a/textures/craftguide_search_icon.png b/textures/craftguide_search_icon.png index aace8044ac235bcf5935ed8a72c4cb136746a916..4c4dd41f786e1bc8e2e1be8009ce867c5742e76f 100644 GIT binary patch delta 4005 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 LYF+pJu_03jxNF44 delta 11 ScmeyU`-N|U^5zBnf$RVv!vu~1 From 8b4ef8a4b784fd072c53f7c00acc6875dac7fdaa Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 25 Oct 2019 01:42:04 +0200 Subject: [PATCH 174/188] Improve search filter accuracy --- init.lua | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/init.lua b/init.lua index a2ee5c5..1f5c2a5 100644 --- a/init.lua +++ b/init.lua @@ -1083,6 +1083,16 @@ craftguide.register_craft_type("digging_chance", { icon = "default_tool_mesepick.png", }) +local function sfind(str, filter) + if filter == "" then + return 0 + end + + if find(str, filter, 1, true) then + return #str - #filter + end +end + local function search(data) local filter = data.filter @@ -1091,7 +1101,7 @@ local function search(data) return end - local opt = "^(.-)%+([%w_]*)=*([%w_,]*)" + local opt = "^(.-)%+([%w_]+)=([%w_,]+)" local search_filter = next(search_filters) and match(filter, opt) local filters = {} @@ -1104,30 +1114,28 @@ local function search(data) end end - local filtered_list, c = {}, 0 + local filtered_list, order, c = {}, {}, 0 for i = 1, #data.items_raw do local item = data.items_raw[i] local def = reg_items[item] local desc = (def and def.description) and lower(def.description) or "" - local search_in = fmt("%s %s", item, desc) local to_add if search_filter then for filter_name, values in pairs(filters) do - if values then - local func = search_filters[filter_name] - to_add = func(item, values) and (search_filter == "" or - find(search_in, search_filter, 1, true)) - end + local func = search_filters[filter_name] + to_add = func(item, values) and (search_filter == "" or + (sfind(item, search_filter) or sfind(desc, search_filter))) end else - to_add = find(search_in, filter, 1, true) + to_add = sfind(item, filter) or sfind(desc, filter) end if to_add then c = c + 1 filtered_list[c] = item + order[item] = to_add end end @@ -1140,6 +1148,10 @@ local function search(data) end end + sort(filtered_list, function(a, b) + return order[a] < order[b] + end) + data.items = filtered_list end From 62d2b302ed9a72fd7e22a6566694ef6fe22c9987 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 25 Oct 2019 13:38:26 +0200 Subject: [PATCH 175/188] Add more accurate caching information --- init.lua | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/init.lua b/init.lua index 1f5c2a5..934b141 100644 --- a/init.lua +++ b/init.lua @@ -66,7 +66,7 @@ local fmt, find, gmatch, match, sub, split, upper, lower = string.sub, string.split, string.upper, string.lower local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil -local pairs, next, type, tostring = pairs, next, type, tostring +local pairs, next, type, tostring, io = pairs, next, type, tostring, io local vec_add, vec_mul = vector.add, vector.multiply local ROWS = 9 @@ -1331,7 +1331,9 @@ end local function handle_aliases(hash) for oldname, newname in pairs(reg_aliases) do - local recipes = recipes_cache[oldname] or get_all_recipes(oldname) + cache_recipes(oldname) + local recipes = recipes_cache[oldname] + if recipes then if not recipes_cache[newname] then recipes_cache[newname] = {} @@ -1371,11 +1373,34 @@ local function show_item(def) def.description and def.description ~= "" end -local function get_init_items() - print("[craftguide] Caching data. This may take a while...") +local function tablelen(t) + local c = 0 + for _ in pairs(t) do + c = c + 1 + end + return c +end + +local function get_init_items() + local ic, it, last_str = 0, tablelen(reg_items), "" local hash = {} + + local function iop(str) + io.write(("\b \b"):rep(#last_str)) + io.write(str) + io.flush() + last_str = str + end + for name, def in pairs(reg_items) do + ic = ic + 1 + if ic < it then + iop(fmt("[craftguide] Caching data: %u/%u items", ic, it)) + else + iop("[craftguide] Caching data: done\r\n") + end + if show_item(def) then if not fuel_cache[name] then cache_fuel(name) From 92c5b1ab8ee1c91e731c0d9428148627342ee59c Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Thu, 31 Oct 2019 23:39:20 +0100 Subject: [PATCH 176/188] Add progress bar info --- init.lua | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index 934b141..b74c40c 100644 --- a/init.lua +++ b/init.lua @@ -189,8 +189,8 @@ local function table_eq(T1, T2) return t1 == t2 end - if avoid_loops[t1] then return - avoid_loops[t1] == t2 + if avoid_loops[t1] then + return avoid_loops[t1] == t2 end avoid_loops[t1] = t2 @@ -1393,14 +1393,22 @@ local function get_init_items() last_str = str end + local full_char, empty_char = "▰", "▱" + for name, def in pairs(reg_items) do ic = ic + 1 - if ic < it then - iop(fmt("[craftguide] Caching data: %u/%u items", ic, it)) - else - iop("[craftguide] Caching data: done\r\n") + local percent, bar, len = (ic * 100) / it, "", 20 + + for i = 1, len do + if i <= percent / (100 / len) then + bar = bar .. full_char + else + bar = bar .. empty_char + end end + iop(fmt("[craftguide] Caching data %s (%u%%)\r", bar, percent)) + if show_item(def) then if not fuel_cache[name] then cache_fuel(name) @@ -1435,6 +1443,8 @@ local function get_init_items() post_data = write_json(post_data), }) end + + print() end local function init_data(name) From 70d38d1c636b5b8bdc271c317a207a07290555b7 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 1 Nov 2019 00:56:49 +0100 Subject: [PATCH 177/188] Minor cleaning --- init.lua | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/init.lua b/init.lua index b74c40c..a2447bf 100644 --- a/init.lua +++ b/init.lua @@ -108,6 +108,17 @@ local FMT = { arrow = "image_button[%f,%f;0.8,0.8;%s;%s;;;false;%s]", } +local function mul_elem(elem, n) + local fstr, elems = "", {} + + for i = 1, n do + fstr = fstr .. "%s" + elems[i] = elem + end + + return fmt(fstr, unpack(elems)) +end + craftguide.group_stereotypes = { dye = "dye:white", wool = "wool:white", @@ -940,12 +951,12 @@ local function get_panels(data, fs) prev_name, PNG.prev, PNG.prev_hover, next_name, PNG.next, PNG.next_hover) - fs[#fs + 1] = fmt(FMT.button .. FMT.button, + fs[#fs + 1] = fmt(mul_elem(FMT.button, 2), x_arrow + (is_recipe and xof_r or xof_u), y_arrow, 0.8, 0.8, prev_name, "", x_arrow + 1.8, y_arrow, 0.8, 0.8, next_name, "") else - fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, + fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), x_arrow + (is_recipe and xof_r or xof_u), y_arrow, PNG.prev, prev_name, PNG.prev_hover, x_arrow + 1.8, y_arrow, PNG.next, next_name, PNG.next_hover) @@ -1000,7 +1011,7 @@ local function make_formspec(name) PNG.prev, PNG.prev_hover, PNG.next, PNG.next_hover) - fs[#fs + 1] = fmt(FMT.button .. FMT.button .. FMT.button .. FMT.button, + fs[#fs + 1] = fmt(mul_elem(FMT.button, 4), sfinv_only and 2.6 or 2.54, -0.12, 0.85, 1, "search", "", sfinv_only and 3.3 or 3.25, -0.12, 0.85, 1, "clear", "", sfinv_only and 5.45 or (ROWS * 6.83) / 11, -0.12, 0.85, 1, "prev_page", "", @@ -1013,7 +1024,7 @@ local function make_formspec(name) sfinv_only and 2.6 or 2.54, PNG.search, PNG.search_hover, sfinv_only and 3.3 or 3.25, PNG.clear, PNG.clear_hover) - fs[#fs + 1] = fmt(FMT.arrow .. FMT.arrow, + fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), sfinv_only and 5.45 or (ROWS * 6.83) / 11, -0.05, PNG.prev, "prev_page", PNG.prev, sfinv_only and 7.2 or (ROWS * 8.75) / 11, @@ -1400,11 +1411,7 @@ local function get_init_items() local percent, bar, len = (ic * 100) / it, "", 20 for i = 1, len do - if i <= percent / (100 / len) then - bar = bar .. full_char - else - bar = bar .. empty_char - end + bar = bar .. (i <= percent / (100 / len) and full_char or empty_char) end iop(fmt("[craftguide] Caching data %s (%u%%)\r", bar, percent)) From 4241c89c179c4950bcfb3400a283c183547b1e9f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 1 Nov 2019 02:04:35 +0100 Subject: [PATCH 178/188] http_post_data -> export_url --- API.md | 2 +- init.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/API.md b/API.md index 251afd5..82c92f4 100644 --- a/API.md +++ b/API.md @@ -204,7 +204,7 @@ You can add a stereotype like so: craftguide.group_stereotypes.radioactive = "mod:item" ``` -#### `craftguide.http_post_data` +#### `craftguide.export_url` If set, the mod will export all the cached recipes and usages in a JSON format to the given URL (HTTP support is required¹). diff --git a/init.lua b/init.lua index a2447bf..3703148 100644 --- a/init.lua +++ b/init.lua @@ -1438,7 +1438,7 @@ local function get_init_items() handle_aliases(hash) sort(init_items) - if http and true_str(craftguide.http_post_data) then + if http and true_str(craftguide.export_url) then local post_data = { recipes = recipes_cache, usages = usages_cache, @@ -1446,7 +1446,7 @@ local function get_init_items() } http.fetch_async({ - url = craftguide.http_post_data, + url = craftguide.export_url, post_data = write_json(post_data), }) end From 7a7bb8dc515309db8a6f56b7e74ba91ffe49e246 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 3 Nov 2019 19:16:29 +0100 Subject: [PATCH 179/188] Remove brackets --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 3703148..fcaaaba 100644 --- a/init.lua +++ b/init.lua @@ -1414,7 +1414,7 @@ local function get_init_items() bar = bar .. (i <= percent / (100 / len) and full_char or empty_char) end - iop(fmt("[craftguide] Caching data %s (%u%%)\r", bar, percent)) + iop(fmt("[craftguide] Caching data %s %u%%\r", bar, percent)) if show_item(def) then if not fuel_cache[name] then From 0d2af529efe1a61911825ea30a1f38aeae2a221b Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 5 Nov 2019 18:33:46 +0100 Subject: [PATCH 180/188] Add forgotten files --- textures/craftguide_clear_icon_hover.png | Bin 0 -> 4721 bytes textures/craftguide_next_icon_hover.png | Bin 0 -> 2916 bytes textures/craftguide_search_icon_hover.png | Bin 0 -> 7262 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 textures/craftguide_clear_icon_hover.png create mode 100644 textures/craftguide_next_icon_hover.png create mode 100644 textures/craftguide_search_icon_hover.png diff --git a/textures/craftguide_clear_icon_hover.png b/textures/craftguide_clear_icon_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..dccf37384b7b681f7448f165b18365d8c73008fa GIT binary patch literal 4721 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 Hee{0->0*1I literal 0 HcmV?d00001 diff --git a/textures/craftguide_search_icon_hover.png b/textures/craftguide_search_icon_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..dd30668c729073d50284d223e4d5a816a85c1612 GIT binary patch literal 7262 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%0Aw5?bYvXC9)OA|#_hyriBUI6_g1CP*mTuNtO@`r z^5cgOVpN`5#mEVVUsej1Ru!fZoKhemYbd*tWx3!wC5kSp-(9%g4GL#VUgmz72PR^^8O4oT17 zPqAwp#pQ@IbDA$4jz;vpf-RoLO&vxk89CtgIdN#LCDYxm0fTPpcMT4DDB;VlVk(5V z)TY_&09!(9R%MEZzI4PPr7Ut%n7%G+LU;bZoh`#na{gPlynITn+zDM+o3J`yC=C}$?n-uKg^1uwTd{6ktHFx@Cc0Jqz>LGA?gI_Th_Gm^P2x4hYgaHg{a1`H zPA0B6VSfW@rr|<%FJ@z(0Z1BGoXUFuPr)2j0f8Jug#l#XY8Y9B7i5p}C641{;}?S! z)qB`ZO8PrA!7xn{xdKp^k&#L6v<>0A|87KZD&nXfv7NTEY3KqQ*>>=u0N23K2DYtE zmZ{Tlk9fbgvZLEO3z=DH#GqvPuwP4$;D55AkK3m;CUux~gGKa;<bdA@%DDc@iH`z{Jz$f@yE`{@Sm$HPO`SHi#vD~-=NFC^|pbJJ?56U+Um%aeOm zodji%fO?{f*Z2?B-14C>mWlE)n5cxjw`B&&xMFK%c=I7heoKawkQNF6jO3mD(Wnzv zW<6T@;;!K|C{9#U=fkP!KF>*e9*9J-0^D3Ny5rx(eT;~Ec5?kJQHcA(1pyqGKd2l| z?dZd^vNaWpHJu8NUZH~etk0CX6dcWa|6)4sv7KM#Ia<_1LuKV5#r<{OC%icRsmtpSIfGF54gXRw<%fJsaKcrL#BqDOM150cs2DHDnu5cI7T+gjPos|Eg8Ogz z|A-u`4pfI#N1cUK6@v_-$U>^o{o^mc_jr)}UNwT%iYMq7uJLukSQ!g+<1Api1!KvL z*tVtHJdjlf#bbhj7lxTA*Ix%B4PhZRD#tN6|NqR2llm{cX!cq%e+8&1X(`q!SVjI1P{{oS literal 0 HcmV?d00001 From 89059f20b6b32ad8ebcb4252000a425ca635ffb6 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Sun, 10 Nov 2019 16:11:29 +0100 Subject: [PATCH 181/188] Reorder formspec elements --- init.lua | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/init.lua b/init.lua index fcaaaba..ac90ba4 100644 --- a/init.lua +++ b/init.lua @@ -733,16 +733,16 @@ local function get_output_fs(fs, L) item = clean_item(item) local name = match(item, "%S*") - fs[#fs + 1] = fmt(FMT.item_image_button, - output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, - 1.1, 1.1, item, name, "") - if CORE_VERSION >= 510 then fs[#fs + 1] = fmt(FMT.image, output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, 1.1, 1.1, PNG.selected) end + fs[#fs + 1] = fmt(FMT.item_image_button, + output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, + 1.1, 1.1, item, name, "") + local infos = { unknown = not reg_items[name] or nil, burntime = fuel_cache[name], @@ -845,6 +845,12 @@ local function get_grid_fs(fs, rcp, spacing) end end + if CORE_VERSION >= 510 and not large_recipe then + fs[#fs + 1] = fmt(FMT.image, + X, Y + (sfinv_only and 0.7 or 0), + btn_size, btn_size, PNG.selected) + end + fs[#fs + 1] = fmt(FMT.item_image_button, X, Y + (sfinv_only and 0.7 or 0), btn_size, btn_size, item, item, ESC(label)) @@ -860,12 +866,6 @@ local function get_grid_fs(fs, rcp, spacing) if next(infos) then fs[#fs + 1] = get_tooltip(item, infos) end - - if CORE_VERSION >= 510 and not large_recipe then - fs[#fs + 1] = fmt(FMT.image, - X, Y + (sfinv_only and 0.7 or 0), - btn_size, btn_size, PNG.selected) - end end if large_recipe then @@ -1056,17 +1056,17 @@ local function make_formspec(name) local X = i % ROWS local Y = (i % IPP - X) / ROWS + 1 - fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s_inv;]", - X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, - Y - (Y * 0.1) - 0.1, - 1, 1, item, item) - if CORE_VERSION >= 510 and data.query_item == item then fs[#fs + 1] = fmt(FMT.image, X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, Y - (Y * 0.1) - 0.1, 1, 1, PNG.selected) end + + fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s_inv;]", + X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, + Y - (Y * 0.1) - 0.1, + 1, 1, item, item) end if (data.recipes and #data.recipes > 0) or (data.usages and #data.usages > 0) then @@ -1350,7 +1350,7 @@ local function handle_aliases(hash) recipes_cache[newname] = {} end - local is_similar + local similar for i = 1, #recipes_cache[oldname] do local rcp_old = recipes_cache[oldname][i] @@ -1361,12 +1361,12 @@ local function handle_aliases(hash) rcp_new.method = nil if table_eq(rcp_old, rcp_new) then - is_similar = true + similar = true break end end - if not is_similar then + if not similar then insert(recipes_cache[newname], rcp_old) end end From 303aa3ef91c27aaa6c154cf5a882094df589667a Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Wed, 27 Nov 2019 13:36:06 +0100 Subject: [PATCH 182/188] Style cleaning --- init.lua | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/init.lua b/init.lua index ac90ba4..97cd96f 100644 --- a/init.lua +++ b/init.lua @@ -671,13 +671,12 @@ local function get_tooltip(name, info) if info.replace then local desc = clr("yellow", get_desc(info.replace)) + tooltip = add(S("Replaced by @1 on crafting", desc)) if info.cooktime then tooltip = add(S("Replaced by @1 on smelting", desc)) elseif info.burntime then tooltip = add(S("Replaced by @1 on burning", desc)) - else - tooltip = add(S("Replaced by @1 on crafting", desc)) end end @@ -710,7 +709,7 @@ local function get_output_fs(fs, L) fs[#fs + 1] = fmt(FMT.image, pos_x, pos_y + L.spacing, 0.5, 0.5, icon) local tooltip = custom_recipe and custom_recipe.description or - L.shapeless and S("Shapeless") or S("Cooking") + L.shapeless and S"Shapeless" or S"Cooking" if CORE_VERSION >= 500 then fs[#fs + 1] = fmt(FMT.tooltip, pos_x, pos_y + L.spacing, 0.5, 0.5, ESC(tooltip)) @@ -916,7 +915,7 @@ local function get_panels(data, fs) if not sfinv_only and rn == 0 then btn_lab = clr("red", is_recipe and - ESC(S("No recipes")) or ESC(S("No usages"))) + ESC(S"No recipes") or ESC(S"No usages")) elseif (not sfinv_only and is_recipe) or (sfinv_only and not data.show_usages) then @@ -1027,7 +1026,7 @@ local function make_formspec(name) fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), sfinv_only and 5.45 or (ROWS * 6.83) / 11, -0.05, PNG.prev, "prev_page", PNG.prev, - sfinv_only and 7.2 or (ROWS * 8.75) / 11, + sfinv_only and 7.2 or (ROWS * 8.75) / 11, -0.05, PNG.next, "next_page", PNG.next) end @@ -1036,11 +1035,11 @@ local function make_formspec(name) 0.06, clr("yellow", data.pagenum), data.pagemax) if #data.items == 0 then - local no_item = S("No item to show") + local no_item = S"No item to show" local pos = ROWS / 3 if next(recipe_filters) and #init_items > 0 and data.filter == "" then - no_item = S("Collect items to reveal more recipes") + no_item = S"Collect items to reveal more recipes" pos = pos - 1 end @@ -1085,12 +1084,12 @@ local show_fs = function(player, name) end craftguide.register_craft_type("digging", { - description = ESC(S("Digging")), + description = ESC(S"Digging"), icon = "default_tool_steelpick.png", }) craftguide.register_craft_type("digging_chance", { - description = ESC(S("Digging Chance")), + description = ESC(S"Digging Chance"), icon = "default_tool_mesepick.png", }) @@ -1564,7 +1563,7 @@ end if sfinv_only then sfinv.register_page("craftguide:craftguide", { - title = S("Craft Guide"), + title = S"Craft Guide", get = function(self, player, context) local name = player:get_player_name() @@ -1607,7 +1606,7 @@ else end core.register_craftitem("craftguide:book", { - description = S("Crafting Guide"), + description = S"Crafting Guide", inventory_image = PNG.book, wield_image = PNG.book, stack_max = 1, @@ -1618,7 +1617,7 @@ else }) core.register_node("craftguide:sign", { - description = S("Crafting Guide Sign"), + description = S"Crafting Guide Sign", drawtype = "nodebox", tiles = {PNG.sign}, inventory_image = PNG.sign, @@ -1670,8 +1669,8 @@ else if rawget(_G, "sfinv_buttons") then sfinv_buttons.register_button("craftguide", { - title = S("Crafting Guide"), - tooltip = S("Shows a list of available crafting recipes, cooking recipes and fuels"), + title = S"Crafting Guide", + tooltip = S"Shows a list of available crafting recipes, cooking recipes and fuels", image = PNG.book, action = function(player) on_use(player) @@ -1968,12 +1967,12 @@ function craftguide.show(name, item, show_usages) if not recipes and not usages then if not recipes_cache[item] and not usages_cache[item] then return false, msg(name, fmt("%s: %s", - S("No recipe or usage for this item"), + S"No recipe or usage for this item", get_desc(item))) end return false, msg(name, fmt("%s: %s", - S("You don't know a recipe or usage for this item"), + S"You don't know a recipe or usage for this item", get_desc(item))) end @@ -1989,7 +1988,7 @@ function craftguide.show(name, item, show_usages) end register_command("craft", { - description = S("Show recipe(s) of the pointed node"), + description = S"Show recipe(s) of the pointed node", func = function(name) local player = get_player_by_name(name) local dir = player:get_look_dir() @@ -2009,7 +2008,7 @@ register_command("craft", { end if not node_name then - return false, msg(name, S("No node pointed")) + return false, msg(name, S"No node pointed") end return true, craftguide.show(name, node_name) From 00a79d26e5860aca4f4847e8050377ef92ac347a Mon Sep 17 00:00:00 2001 From: bell07 Date: Tue, 3 Dec 2019 13:54:56 +0100 Subject: [PATCH 183/188] Fix comparing items with their aliases (#95) --- init.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/init.lua b/init.lua index 97cd96f..1e98402 100644 --- a/init.lua +++ b/init.lua @@ -466,8 +466,10 @@ local function extract_groups(str) end local function item_in_recipe(item, recipe) + local clean_item = reg_aliases[item] or item for _, recipe_item in pairs(recipe.items) do - if recipe_item == item then + local clean_recipe_item = reg_aliases[recipe_item] or recipe_item + if clean_recipe_item == clean_item then return true end end @@ -575,9 +577,9 @@ local function cache_recipes(output) end local function get_recipes(item, data, player) - local recipes = recipes_cache[item] - local usages = usages_cache[item] - + local clean_item = reg_aliases[item] or item + local recipes = recipes_cache[clean_item] + local usages = usages_cache[clean_item] if recipes then recipes = apply_recipe_filters(recipes, player) end @@ -1540,6 +1542,8 @@ local function fields(player, _f) item = sub(item, 1, -5) end + item = reg_aliases[item] or item + if sfinv_only then if item ~= data.query_item then data.show_usages = nil From 9fb5a93b2b6e0150f442c7c0c64f48e44e398973 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Mon, 9 Dec 2019 21:16:41 +0100 Subject: [PATCH 184/188] Style --- init.lua | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/init.lua b/init.lua index 97cd96f..70302c2 100644 --- a/init.lua +++ b/init.lua @@ -905,35 +905,33 @@ local function get_panels(data, fs) local rn = #v local _rn = tostring(rn) - local xof_u = tostring(data.unum) .. _rn - local xof_r = tostring(data.rnum) .. _rn - xof_u = max(-0.3, -((#xof_u - 3) * 0.15)) - xof_r = max(-0.3, -((#xof_r - 3) * 0.15)) + local xu = tostring(data.unum) .. _rn + local xr = tostring(data.rnum) .. _rn + xu = max(-0.3, -((#xu - 3) * 0.15)) + xr = max(-0.3, -((#xr - 3) * 0.15)) local is_recipe = k == "recipes" - local btn_lab + local lbl if not sfinv_only and rn == 0 then - btn_lab = clr("red", is_recipe and - ESC(S"No recipes") or ESC(S"No usages")) + lbl = clr("red", is_recipe and ESC(S"No recipes") or ESC(S"No usages")) elseif (not sfinv_only and is_recipe) or (sfinv_only and not data.show_usages) then - btn_lab = ESC(S("Recipe @1 of @2", data.rnum, rn)) + lbl = ESC(S("Recipe @1 of @2", data.rnum, rn)) elseif not sfinv_only or (sfinv_only and data.show_usages) then - btn_lab = ESC(S("Usage @1 of @2", data.unum, rn)) + lbl = ESC(S("Usage @1 of @2", data.unum, rn)) elseif sfinv_only then - btn_lab = data.show_usages and + lbl = data.show_usages and ESC(S("Usage @1 of @2", data.unum, rn)) or ESC(S("Recipe @1 of @2", data.rnum, rn)) end fs[#fs + 1] = fmt(FMT.label, - XOFFSET + (sfinv_only and 2.3 or 1.6) + (is_recipe and xof_r or xof_u), - YOFFSET + (sfinv_only and 3.35 or 1.5 + spacing), - btn_lab) + XOFFSET + (sfinv_only and 2.3 or 1.6) + (is_recipe and xr or xu), + YOFFSET + (sfinv_only and 3.35 or 1.5 + spacing), lbl) if rn > 1 then local btn_suffix = is_recipe and "recipe" or "usage" @@ -951,12 +949,12 @@ local function get_panels(data, fs) next_name, PNG.next, PNG.next_hover) fs[#fs + 1] = fmt(mul_elem(FMT.button, 2), - x_arrow + (is_recipe and xof_r or xof_u), + x_arrow + (is_recipe and xr or xu), y_arrow, 0.8, 0.8, prev_name, "", x_arrow + 1.8, y_arrow, 0.8, 0.8, next_name, "") else fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), - x_arrow + (is_recipe and xof_r or xof_u), + x_arrow + (is_recipe and xr or xu), y_arrow, PNG.prev, prev_name, PNG.prev_hover, x_arrow + 1.8, y_arrow, PNG.next, next_name, PNG.next_hover) end From 97036d9f9a1619d7be62dc8bf036e9be6f273bb0 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 17 Dec 2019 01:33:40 +0100 Subject: [PATCH 185/188] New formspec style --- init.lua | 83 +++++++++++++++----------------- textures/craftguide_bg_full.png | Bin 1150 -> 5924 bytes 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/init.lua b/init.lua index 1c0bdd9..86a622a 100644 --- a/init.lua +++ b/init.lua @@ -134,7 +134,7 @@ local function err(str) end local function msg(name, str) - return chat_send(name, fmt("[craftguide] %s", clr("#FFFF00", str))) + return chat_send(name, fmt("[craftguide] %s", clr("#f00", str))) end local function is_str(x) @@ -157,7 +157,7 @@ local function is_group(item) return sub(item, 1, 6) == "group:" end -local function clean_item(item) +local function clean_name(item) if sub(item, 1, 1) == ":" then item = sub(item, 2) end @@ -580,6 +580,7 @@ local function get_recipes(item, data, player) local clean_item = reg_aliases[item] or item local recipes = recipes_cache[clean_item] local usages = usages_cache[clean_item] + if recipes then recipes = apply_recipe_filters(recipes, player) end @@ -650,7 +651,7 @@ local function get_tooltip(name, info) for i = 1, #info.groups do c = c + 1 - groupstr[c] = clr("yellow", info.groups[i]) + groupstr[c] = clr("#ff0", info.groups[i]) end groupstr = concat(groupstr, ", ") @@ -664,31 +665,32 @@ local function get_tooltip(name, info) end if info.cooktime then - tooltip = add(S("Cooking time: @1", clr("yellow", info.cooktime))) + tooltip = add(S("Cooking time: @1", clr("#ff0", info.cooktime))) end if info.burntime then - tooltip = add(S("Burning time: @1", clr("yellow", info.burntime))) + tooltip = add(S("Burning time: @1", clr("#ff0", info.burntime))) end if info.replace then - local desc = clr("yellow", get_desc(info.replace)) - tooltip = add(S("Replaced by @1 on crafting", desc)) + local desc = clr("#ff0", get_desc(info.replace)) if info.cooktime then tooltip = add(S("Replaced by @1 on smelting", desc)) elseif info.burntime then tooltip = add(S("Replaced by @1 on burning", desc)) + else + tooltip = add(S("Replaced by @1 on crafting", desc)) end end if info.repair then - tooltip = add(S("Repairable by step of @1", clr("yellow", toolrepair .. "%"))) + tooltip = add(S("Repairable by step of @1", clr("#ff0", toolrepair .. "%"))) end if info.rarity then local chance = (1 / info.rarity) * 100 - tooltip = add(S("@1 of chance to drop", clr("yellow", chance .. "%"))) + tooltip = add(S("@1 of chance to drop", clr("#ff0", chance .. "%"))) end return fmt("tooltip[%s;%s]", name, ESC(tooltip)) @@ -731,7 +733,7 @@ local function get_output_fs(fs, L) 1.1, 1.1, PNG.fire) else local item = L.recipe.output - item = clean_item(item) + item = clean_name(item) local name = match(item, "%S*") if CORE_VERSION >= 510 then @@ -801,7 +803,7 @@ local function get_grid_fs(fs, rcp, spacing) for i = 1, width * rows do local item = rcp.items[i] or "" - item = clean_item(item) + item = clean_name(item) local name = match(item, "%S*") local X = ceil((i - 1) % width - width) + XOFFSET @@ -916,7 +918,7 @@ local function get_panels(data, fs) local lbl if not sfinv_only and rn == 0 then - lbl = clr("red", is_recipe and ESC(S"No recipes") or ESC(S"No usages")) + lbl = clr("#f00", is_recipe and ESC(S"No recipes") or ESC(S"No usages")) elseif (not sfinv_only and is_recipe) or (sfinv_only and not data.show_usages) then @@ -943,17 +945,10 @@ local function get_panels(data, fs) local y_arrow = YOFFSET + (sfinv_only and 3.25 or 1.4 + spacing) if CORE_VERSION >= 520 then - fs[#fs + 1] = fmt([[ - style[%s;border=false;bgimg=%s;bgimg_hovered=%s] - style[%s;border=false;bgimg=%s;bgimg_hovered=%s] - ]], - prev_name, PNG.prev, PNG.prev_hover, - next_name, PNG.next, PNG.next_hover) - - fs[#fs + 1] = fmt(mul_elem(FMT.button, 2), - x_arrow + (is_recipe and xr or xu), - y_arrow, 0.8, 0.8, prev_name, "", - x_arrow + 1.8, y_arrow, 0.8, 0.8, next_name, "") + fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), + x_arrow + (is_recipe and xr or xu), y_arrow, + PNG.prev, prev_name, "", + x_arrow + 1.8, y_arrow, PNG.next, next_name, "") else fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), x_arrow + (is_recipe and xr or xu), @@ -971,8 +966,6 @@ end local function make_formspec(name) local data = pdata[name] - data.pagemax = max(1, ceil(#data.items / IPP)) - local fs = {} if not sfinv_only then @@ -980,9 +973,10 @@ local function make_formspec(name) size[%f,%f] no_prepend[] bgcolor[#0000] + style_type[image_button;border=false] + style_type[item_image_button;border=false;bgimg_hovered=%s] ]], - ROWS + (data.query_item and 6.7 or 0) - 1.2, - LINES - 0.3) + ROWS + (data.query_item and 6.7 or 0) - 1.2, LINES - 0.3, PNG.selected) fs[#fs + 1] = CORE_VERSION >= 510 and fmt("background9[-0.15,-0.2;%f,%f;%s;false;%d]", @@ -992,29 +986,28 @@ local function make_formspec(name) end fs[#fs + 1] = fmt([[ - style_type[item_image_button;border=false] field[0.25,0.2;%f,1;filter;;%s] field_close_on_enter[filter;false] - ]], - sfinv_only and 2.76 or 2.72, ESC(data.filter)) + ]], + sfinv_only and 2.76 or 2.72, ESC(data.filter)) if CORE_VERSION >= 520 then fs[#fs + 1] = fmt([[ - style[search;border=false;bgimg=%s;bgimg_hovered=%s] - style[clear;border=false;bgimg=%s;bgimg_hovered=%s] - style[prev_page;border=false;bgimg=%s;bgimg_hovered=%s] - style[next_page;border=false;bgimg=%s;bgimg_hovered=%s] + style[search;fgimg=%s;fgimg_hovered=%s] + style[clear;fgimg=%s;fgimg_hovered=%s] + style[prev_page;fgimg=%s;fgimg_hovered=%s] + style[next_page;fgimg=%s;fgimg_hovered=%s] ]], PNG.search, PNG.search_hover, - PNG.clear, PNG.clear_hover, - PNG.prev, PNG.prev_hover, - PNG.next, PNG.next_hover) + PNG.clear, PNG.clear_hover, + PNG.prev, PNG.prev_hover, + PNG.next, PNG.next_hover) - fs[#fs + 1] = fmt(mul_elem(FMT.button, 4), - sfinv_only and 2.6 or 2.54, -0.12, 0.85, 1, "search", "", - sfinv_only and 3.3 or 3.25, -0.12, 0.85, 1, "clear", "", - sfinv_only and 5.45 or (ROWS * 6.83) / 11, -0.12, 0.85, 1, "prev_page", "", - sfinv_only and 7.2 or (ROWS * 8.75) / 11, -0.12, 0.85, 1, "next_page", "") + fs[#fs + 1] = fmt(mul_elem(FMT.image_button, 4), + sfinv_only and 2.6 or 2.54, -0.06, 0.85, 0.85, "", "search", "", + sfinv_only and 3.3 or 3.25, -0.06, 0.85, 0.85, "", "clear", "", + sfinv_only and 5.45 or (ROWS * 6.83) / 11, -0.06, 0.85, 0.85, "", "prev_page", "", + sfinv_only and 7.2 or (ROWS * 8.75) / 11, -0.06, 0.85, 0.85, "", "next_page", "") else fs[#fs + 1] = fmt([[ image_button[%f,-0.12;0.85,1;%s;search;;;false;%s] @@ -1030,9 +1023,11 @@ local function make_formspec(name) -0.05, PNG.next, "next_page", PNG.next) end + data.pagemax = max(1, ceil(#data.items / IPP)) + fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", sfinv_only and 6.35 or (ROWS * 7.85) / 11, - 0.06, clr("yellow", data.pagenum), data.pagemax) + 0.06, clr("#ff0", data.pagenum), data.pagemax) if #data.items == 0 then local no_item = S"No item to show" @@ -1903,7 +1898,7 @@ if progressive_mode then hud_elem_type = "text", position = {x = 0.84, y = 1.04}, alignment = {x = 1, y = 1}, - number = 0xFFFFFF, + number = 0xfff, text = "", }), } diff --git a/textures/craftguide_bg_full.png b/textures/craftguide_bg_full.png index f17ff55add1585916afb2df6876c073b270cae57..a3c41bad3ebee80065a6e4fe905cba902388993f 100644 GIT binary patch literal 5924 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 XzTrl)tmGSTT0n}h=+GULQx^UU7V@#; delta 38 ucmZ3Y_m5+OG7ke&lDE4HgU6+=R}&^*6_V%VWaBp#(>!+W_vXJs>MQ^NPz|5} From 937b40aae4df5b49c7aa787d623304259a09df1f Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 17 Dec 2019 01:46:22 +0100 Subject: [PATCH 186/188] Remove recipe from caches after calling clear_craft() --- init.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/init.lua b/init.lua index 86a622a..10837ae 100644 --- a/init.lua +++ b/init.lua @@ -1249,6 +1249,20 @@ core.register_craft = function(def) end end +local old_clear_craft = core.clear_craft + +core.clear_craft = function(def) + old_clear_craft(def) + + if true_str(def) then + recipes_cache[def] = nil + fuel_cache[def] = nil + + elseif is_table(def) then + return -- TODO + end +end + local function handle_drops_table(name, drop) -- Code borrowed and modified from unified_inventory -- https://github.com/minetest-mods/unified_inventory/blob/master/api.lua From 55f919ab8fa6debd2b9193444cf9b31b5a6919fd Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 17 Dec 2019 01:51:55 +0100 Subject: [PATCH 187/188] Minor fix --- init.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index 10837ae..2d8d5d2 100644 --- a/init.lua +++ b/init.lua @@ -1010,17 +1010,17 @@ local function make_formspec(name) sfinv_only and 7.2 or (ROWS * 8.75) / 11, -0.06, 0.85, 0.85, "", "next_page", "") else fs[#fs + 1] = fmt([[ - image_button[%f,-0.12;0.85,1;%s;search;;;false;%s] - image_button[%f,-0.12;0.85,1;%s;clear;;;false;%s] + image_button[%f,-0.06;0.85,0.85;%s;search;;;false;%s] + image_button[%f,-0.06;0.85,0.85;%s;clear;;;false;%s] ]], sfinv_only and 2.6 or 2.54, PNG.search, PNG.search_hover, sfinv_only and 3.3 or 3.25, PNG.clear, PNG.clear_hover) fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), - sfinv_only and 5.45 or (ROWS * 6.83) / 11, - -0.05, PNG.prev, "prev_page", PNG.prev, - sfinv_only and 7.2 or (ROWS * 8.75) / 11, - -0.05, PNG.next, "next_page", PNG.next) + sfinv_only and 5.45 or (ROWS * 6.83) / 11, -0.05, + PNG.prev, "prev_page", PNG.prev, + sfinv_only and 7.2 or (ROWS * 8.75) / 11, -0.05, + PNG.next, "next_page", PNG.next) end data.pagemax = max(1, ceil(#data.items / IPP)) From 3c3733a226c11dccd4a93ab6e3fa1c849a33250b Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Tue, 17 Dec 2019 02:09:40 +0100 Subject: [PATCH 188/188] Minor cleaning --- init.lua | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/init.lua b/init.lua index 2d8d5d2..d90fcc9 100644 --- a/init.lua +++ b/init.lua @@ -57,6 +57,10 @@ local S = CORE_VERSION >= 500 and core.get_translator("craftguide") or end) end +local ES = function(...) + return ESC(S(...)) +end + local maxn, sort, concat, copy, insert, remove = table.maxn, table.sort, table.concat, table.copy, table.insert, table.remove @@ -276,7 +280,7 @@ local craft_types = {} function craftguide.register_craft_type(name, def) if not true_str(name) then - return err("craftguide.register_craft_type(): name missing") + return err"craftguide.register_craft_type(): name missing" end if not is_str(def.description) then @@ -295,8 +299,8 @@ function craftguide.register_craft(def) if true_str(def.url) then if not http then - return err("No HTTP support for this mod. " .. - "Add it to the `secure.http_mods` or `secure.trusted_mods` setting.") + return err"No HTTP support for this mod. " .. + "Add it to the `secure.http_mods` or `secure.trusted_mods` setting." end http.fetch({url = def.url}, function(result) @@ -312,7 +316,7 @@ function craftguide.register_craft(def) end if not is_table(def) or not next(def) then - return err("craftguide.register_craft(): craft definition missing") + return err"craftguide.register_craft(): craft definition missing" end if #def > 1 then @@ -328,7 +332,7 @@ function craftguide.register_craft(def) end if not true_str(def.output) then - return err("craftguide.register_craft(): output missing") + return err"craftguide.register_craft(): output missing" end if not is_table(def.items) then @@ -398,9 +402,9 @@ local recipe_filters = {} function craftguide.add_recipe_filter(name, f) if not true_str(name) then - return err("craftguide.add_recipe_filter(): name missing") + return err"craftguide.add_recipe_filter(): name missing" elseif not is_func(f) then - return err("craftguide.add_recipe_filter(): function missing") + return err"craftguide.add_recipe_filter(): function missing" end recipe_filters[name] = f @@ -408,9 +412,9 @@ end function craftguide.set_recipe_filter(name, f) if not is_str(name) then - return err("craftguide.set_recipe_filter(): name missing") + return err"craftguide.set_recipe_filter(): name missing" elseif not is_func(f) then - return err("craftguide.set_recipe_filter(): function missing") + return err"craftguide.set_recipe_filter(): function missing" end recipe_filters = {[name] = f} @@ -436,9 +440,9 @@ local search_filters = {} function craftguide.add_search_filter(name, f) if not true_str(name) then - return err("craftguide.add_search_filter(): name missing") + return err"craftguide.add_search_filter(): name missing" elseif not is_func(f) then - return err("craftguide.add_search_filter(): function missing") + return err"craftguide.add_search_filter(): function missing" end search_filters[name] = f @@ -790,7 +794,7 @@ local function get_grid_fs(fs, rcp, spacing) fs[#fs + 1] = fmt(FMT.label, XOFFSET + (sfinv_only and -1.5 or -1.6), YOFFSET + (sfinv_only and 0.5 or spacing), - ESC(S("Recipe's too big to be displayed (@1x@2)", width, rows))) + ES("Recipe's too big to be displayed (@1x@2)", width, rows)) return concat(fs) end @@ -891,8 +895,7 @@ local function get_panels(data, fs) local x = 0.33 if sfinv_only then - panels = data.show_usages and - {usages = data.usages} or {recipes = data.recipes} + panels = data.show_usages and {usages = data.usages} or {recipes = data.recipes} end for k, v in pairs(panels) do @@ -918,19 +921,19 @@ local function get_panels(data, fs) local lbl if not sfinv_only and rn == 0 then - lbl = clr("#f00", is_recipe and ESC(S"No recipes") or ESC(S"No usages")) + lbl = clr("#f00", is_recipe and ES"No recipes" or ES"No usages") elseif (not sfinv_only and is_recipe) or (sfinv_only and not data.show_usages) then - lbl = ESC(S("Recipe @1 of @2", data.rnum, rn)) + lbl = ES("Recipe @1 of @2", data.rnum, rn) elseif not sfinv_only or (sfinv_only and data.show_usages) then - lbl = ESC(S("Usage @1 of @2", data.unum, rn)) + lbl = ES("Usage @1 of @2", data.unum, rn) elseif sfinv_only then lbl = data.show_usages and - ESC(S("Usage @1 of @2", data.unum, rn)) or - ESC(S("Recipe @1 of @2", data.rnum, rn)) + ES("Usage @1 of @2", data.unum, rn) or + ES("Recipe @1 of @2", data.rnum, rn) end fs[#fs + 1] = fmt(FMT.label, @@ -1079,12 +1082,12 @@ local show_fs = function(player, name) end craftguide.register_craft_type("digging", { - description = ESC(S"Digging"), + description = ES"Digging", icon = "default_tool_steelpick.png", }) craftguide.register_craft_type("digging_chance", { - description = ESC(S"Digging Chance"), + description = ES"Digging Chance", icon = "default_tool_mesepick.png", }) @@ -1963,7 +1966,7 @@ end) function craftguide.show(name, item, show_usages) if not true_str(name)then - return err("craftguide.show(): player name missing") + return err"craftguide.show(): player name missing" end local data = pdata[name]