Compare commits

...

30 Commits

Author SHA1 Message Date
0463712cbb Change la barre de progression pendant le chargement du mod
Cette dernière n'était pas bien supportée par tous les terminaux.
2019-12-22 22:06:35 +01:00
1745cc0ba3 Merge branch 'master' of yunohost.local:minetest-mods/craftguide into nalc-1.2-dev 2019-12-22 12:26:18 +01:00
3c3733a226 Minor cleaning 2019-12-17 02:09:40 +01:00
55f919ab8f Minor fix 2019-12-17 01:51:55 +01:00
937b40aae4 Remove recipe from caches after calling clear_craft() 2019-12-17 01:46:22 +01:00
97036d9f9a New formspec style 2019-12-17 01:33:40 +01:00
17a8c5ddd8 Merge branch 'master' of https://github.com/minetest-mods/craftguide 2019-12-09 21:16:47 +01:00
9fb5a93b2b Style 2019-12-09 21:16:41 +01:00
00a79d26e5 Fix comparing items with their aliases (#95) 2019-12-03 13:54:56 +01:00
303aa3ef91 Style cleaning 2019-11-27 13:36:06 +01:00
89059f20b6 Reorder formspec elements 2019-11-10 16:11:29 +01:00
0d2af529ef Add forgotten files 2019-11-05 18:34:26 +01:00
7a7bb8dc51 Remove brackets 2019-11-03 19:16:29 +01:00
4241c89c17 http_post_data -> export_url 2019-11-01 02:04:35 +01:00
70d38d1c63 Minor cleaning 2019-11-01 01:56:35 +01:00
92c5b1ab8e Add progress bar info 2019-10-31 23:39:20 +01:00
62d2b302ed Add more accurate caching information 2019-10-25 13:41:56 +02:00
8b4ef8a4b7 Improve search filter accuracy 2019-10-25 01:43:40 +02:00
35b2ecfdc1 Implement visual feedbacks on nav buttons 2019-10-25 01:15:51 +02:00
edbed14d9b Fix non-shown recipes 2019-10-22 12:53:47 +02:00
4e4cb0625c Merge branch 'master' of https://github.com/minetest-mods/craftguide 2019-10-15 15:30:59 +02:00
77dbe040b8 Fix tooltip 2019-10-15 15:30:52 +02:00
d6bd17f6b3 Updated Italian locale (#94)
* Updated Italian locale
2019-10-15 00:42:44 +02:00
b12502a7da Small fixes 2019-10-13 18:31:46 +02:00
e707db9ab9 Fix sfinv grid positioning 2019-10-13 00:27:31 +02:00
270dc19ec1 Fix crash with groups_to_items() 2019-10-12 13:21:46 +02:00
c9c2bf03de Small precisions 2019-10-11 02:45:51 +02:00
ee1eac039e Minor cleaning 2019-10-10 17:50:29 +02:00
66fc47a1c3 Merge branch 'master' into nalc-1.2 2019-05-06 01:51:15 +02:00
d6542a2697 Ajoute message de chargement du mod dans le journal "action" 2018-12-24 01:25:12 +01:00
8 changed files with 297 additions and 166 deletions

18
API.md
View File

@ -5,6 +5,9 @@
Custom recipes are nonconventional crafts outside the main crafting grid. Custom recipes are nonconventional crafts outside the main crafting grid.
They can be registered in-game dynamically and have a size beyond 3x3 items. 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) #### Registering a custom crafting type (example)
```Lua ```Lua
@ -65,15 +68,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 = { big = {
result = "default:mese 4", result = "default:mese 4",
items = { items = {
@ -86,11 +80,11 @@ 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 ```Lua
craftguide.register_craft({ 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"
}) })
``` ```
@ -210,7 +204,7 @@ You can add a stereotype like so:
craftguide.group_stereotypes.radioactive = "mod:item" 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 If set, the mod will export all the cached recipes and usages in a JSON format
to the given URL (HTTP support is required¹). to the given URL (HTTP support is required¹).

432
init.lua
View File

@ -57,6 +57,10 @@ local S = CORE_VERSION >= 500 and core.get_translator("craftguide") or
end) end)
end end
local ES = function(...)
return ESC(S(...))
end
local maxn, sort, concat, copy, insert, remove = local maxn, sort, concat, copy, insert, remove =
table.maxn, table.sort, table.concat, table.copy, table.maxn, table.sort, table.concat, table.copy,
table.insert, table.remove table.insert, table.remove
@ -66,7 +70,7 @@ local fmt, find, gmatch, match, sub, split, upper, lower =
string.sub, string.split, string.upper, string.lower string.sub, string.split, string.upper, string.lower
local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil 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, io = pairs, next, type, tostring, io
local vec_add, vec_mul = vector.add, vector.multiply local vec_add, vec_mul = vector.add, vector.multiply
local ROWS = 9 local ROWS = 9
@ -75,7 +79,7 @@ local IPP = ROWS * LINES
local WH_LIMIT = 8 local WH_LIMIT = 8
local XOFFSET = sfinv_only and 3.83 or 11.2 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 = { local PNG = {
bg = "craftguide_bg.png", bg = "craftguide_bg.png",
@ -89,6 +93,11 @@ local PNG = {
book = "craftguide_book.png", book = "craftguide_book.png",
sign = "craftguide_sign.png", sign = "craftguide_sign.png",
selected = "craftguide_selected.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 = { local FMT = {
@ -100,9 +109,20 @@ local FMT = {
item_image = "item_image[%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]", image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]",
item_image_button = "item_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]",
} }
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 = { craftguide.group_stereotypes = {
dye = "dye:white", dye = "dye:white",
wool = "wool:white", wool = "wool:white",
@ -118,10 +138,9 @@ local function err(str)
end end
local function msg(name, str) 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 end
local function is_str(x) local function is_str(x)
return type(x) == "string" return type(x) == "string"
end end
@ -142,6 +161,14 @@ local function is_group(item)
return sub(item, 1, 6) == "group:" return sub(item, 1, 6) == "group:"
end end
local function clean_name(item)
if sub(item, 1, 1) == ":" then
item = sub(item, 2)
end
return item
end
local function array_diff(t1, t2) local function array_diff(t1, t2)
local hash = {} local hash = {}
@ -177,8 +204,8 @@ local function table_eq(T1, T2)
return t1 == t2 return t1 == t2
end end
if avoid_loops[t1] then return if avoid_loops[t1] then
avoid_loops[t1] == t2 return avoid_loops[t1] == t2
end end
avoid_loops[t1] = t2 avoid_loops[t1] = t2
@ -253,7 +280,7 @@ local craft_types = {}
function craftguide.register_craft_type(name, def) function craftguide.register_craft_type(name, def)
if not true_str(name) then if not true_str(name) then
return err("craftguide.register_craft_type(): name missing") return err"craftguide.register_craft_type(): name missing"
end end
if not is_str(def.description) then if not is_str(def.description) then
@ -272,8 +299,8 @@ function craftguide.register_craft(def)
if true_str(def.url) then if true_str(def.url) then
if not http then if not http then
return err("No HTTP support for this mod. " .. return err"No HTTP support for this mod. " ..
"Add it to the `secure.http_mods` or `secure.trusted_mods` setting.") "Add it to the `secure.http_mods` or `secure.trusted_mods` setting."
end end
http.fetch({url = def.url}, function(result) http.fetch({url = def.url}, function(result)
@ -289,7 +316,7 @@ function craftguide.register_craft(def)
end end
if not is_table(def) or not next(def) then 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 end
if #def > 1 then if #def > 1 then
@ -305,7 +332,7 @@ function craftguide.register_craft(def)
end end
if not true_str(def.output) then if not true_str(def.output) then
return err("craftguide.register_craft(): output missing") return err"craftguide.register_craft(): output missing"
end end
if not is_table(def.items) then if not is_table(def.items) then
@ -375,9 +402,9 @@ local recipe_filters = {}
function craftguide.add_recipe_filter(name, f) function craftguide.add_recipe_filter(name, f)
if not true_str(name) then 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 elseif not is_func(f) then
return err("craftguide.add_recipe_filter(): function missing") return err"craftguide.add_recipe_filter(): function missing"
end end
recipe_filters[name] = f recipe_filters[name] = f
@ -385,9 +412,9 @@ end
function craftguide.set_recipe_filter(name, f) function craftguide.set_recipe_filter(name, f)
if not is_str(name) then 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 elseif not is_func(f) then
return err("craftguide.set_recipe_filter(): function missing") return err"craftguide.set_recipe_filter(): function missing"
end end
recipe_filters = {[name] = f} recipe_filters = {[name] = f}
@ -413,9 +440,9 @@ local search_filters = {}
function craftguide.add_search_filter(name, f) function craftguide.add_search_filter(name, f)
if not true_str(name) then 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 elseif not is_func(f) then
return err("craftguide.add_search_filter(): function missing") return err"craftguide.add_search_filter(): function missing"
end end
search_filters[name] = f search_filters[name] = f
@ -443,8 +470,10 @@ local function extract_groups(str)
end end
local function item_in_recipe(item, recipe) local function item_in_recipe(item, recipe)
local clean_item = reg_aliases[item] or item
for _, recipe_item in pairs(recipe.items) do 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 return true
end end
end end
@ -552,8 +581,9 @@ local function cache_recipes(output)
end end
local function get_recipes(item, data, player) local function get_recipes(item, data, player)
local recipes = recipes_cache[item] local clean_item = reg_aliases[item] or item
local usages = usages_cache[item] local recipes = recipes_cache[clean_item]
local usages = usages_cache[clean_item]
if recipes then if recipes then
recipes = apply_recipe_filters(recipes, player) recipes = apply_recipe_filters(recipes, player)
@ -593,11 +623,15 @@ local function groups_to_items(groups, get_all)
local names = {} local names = {}
for name, def in pairs(reg_items) do for name, def in pairs(reg_items) do
if item_has_groups(def.groups, groups) then if item_has_groups(def.groups, groups) then
if get_all then
names[#names + 1] = name names[#names + 1] = name
else
return name
end
end end
end end
return names return get_all and names or ""
end end
local function repairable(tool) local function repairable(tool)
@ -613,7 +647,7 @@ local function get_desc(name)
S("Unknown Item (@1)", name)) S("Unknown Item (@1)", name))
end end
local function get_tooltip(item, info) local function get_tooltip(name, info)
local tooltip local tooltip
if info.groups then if info.groups then
@ -621,31 +655,29 @@ local function get_tooltip(item, info)
for i = 1, #info.groups do for i = 1, #info.groups do
c = c + 1 c = c + 1
groupstr[c] = clr("yellow", info.groups[i]) groupstr[c] = clr("#ff0", info.groups[i])
end end
groupstr = concat(groupstr, ", ") groupstr = concat(groupstr, ", ")
tooltip = S("Any item belonging to the group(s): @1", groupstr) tooltip = S("Any item belonging to the group(s): @1", groupstr)
else
return fmt("tooltip[%s;%s]", item, ESC(tooltip)) tooltip = get_desc(name)
end end
tooltip = get_desc(item)
local function add(str) local function add(str)
return fmt("%s\n%s", tooltip, str) return fmt("%s\n%s", tooltip, str)
end end
if info.cooktime then 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 end
if info.burntime then 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 end
if info.replace then if info.replace then
local desc = clr("yellow", get_desc(info.replace)) local desc = clr("#ff0", get_desc(info.replace))
if info.cooktime then if info.cooktime then
tooltip = add(S("Replaced by @1 on smelting", desc)) tooltip = add(S("Replaced by @1 on smelting", desc))
@ -657,15 +689,15 @@ local function get_tooltip(item, info)
end end
if info.repair then 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 end
if info.rarity then if info.rarity then
local chance = (1 / info.rarity) * 100 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 end
return fmt("tooltip[%s;%s]", item, ESC(tooltip)) return fmt("tooltip[%s;%s]", name, ESC(tooltip))
end end
local function get_output_fs(fs, L) local function get_output_fs(fs, L)
@ -685,7 +717,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) 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 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 if CORE_VERSION >= 500 then
fs[#fs + 1] = fmt(FMT.tooltip, pos_x, pos_y + L.spacing, 0.5, 0.5, ESC(tooltip)) fs[#fs + 1] = fmt(FMT.tooltip, pos_x, pos_y + L.spacing, 0.5, 0.5, ESC(tooltip))
@ -705,19 +737,21 @@ local function get_output_fs(fs, L)
1.1, 1.1, PNG.fire) 1.1, 1.1, PNG.fire)
else else
local item = L.recipe.output local item = L.recipe.output
item = clean_name(item)
local name = match(item, "%S*") 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), "")
if CORE_VERSION >= 510 then if CORE_VERSION >= 510 then
fs[#fs + 1] = fmt(FMT.image, fs[#fs + 1] = fmt(FMT.image,
output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing, output_X, YOFFSET + (sfinv_only and 0.7 or 0) + L.spacing,
1.1, 1.1, PNG.selected) 1.1, 1.1, PNG.selected)
end 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 = { local infos = {
unknown = not reg_items[name] or nil,
burntime = fuel_cache[name], burntime = fuel_cache[name],
repair = repairable(name), repair = repairable(name),
rarity = L.rarity, rarity = L.rarity,
@ -740,7 +774,6 @@ local function get_output_fs(fs, L)
end end
local function get_grid_fs(fs, rcp, spacing) local function get_grid_fs(fs, rcp, spacing)
if not rcp then return end
local width = rcp.width or 1 local width = rcp.width or 1
local replacements = rcp.replacements local replacements = rcp.replacements
local rarity = rcp.rarity local rarity = rcp.rarity
@ -761,7 +794,7 @@ local function get_grid_fs(fs, rcp, spacing)
fs[#fs + 1] = fmt(FMT.label, fs[#fs + 1] = fmt(FMT.label,
XOFFSET + (sfinv_only and -1.5 or -1.6), XOFFSET + (sfinv_only and -1.5 or -1.6),
YOFFSET + (sfinv_only and 0.5 or spacing), 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) return concat(fs)
end end
@ -774,6 +807,9 @@ local function get_grid_fs(fs, rcp, spacing)
for i = 1, width * rows do for i = 1, width * rows do
local item = rcp.items[i] or "" local item = rcp.items[i] or ""
item = clean_name(item)
local name = match(item, "%S*")
local X = ceil((i - 1) % width - width) + XOFFSET local X = ceil((i - 1) % width - width) + XOFFSET
local Y = ceil(i / width) + YOFFSET - min(2, rows) + spacing local Y = ceil(i / width) + YOFFSET - min(2, rows) + spacing
@ -798,10 +834,9 @@ local function get_grid_fs(fs, rcp, spacing)
local groups local groups
if is_group(item) then if is_group(name) then
groups = extract_groups(item) groups = extract_groups(name)
local items = groups_to_items(groups) item = groups_to_items(groups)
item = items[1] or items
end end
local label = groups and "\nG" or "" local label = groups and "\nG" or ""
@ -810,34 +845,34 @@ local function get_grid_fs(fs, rcp, spacing)
if replacements then if replacements then
for j = 1, #replacements do for j = 1, #replacements do
local replacement = replacements[j] local replacement = replacements[j]
if replacement[1] == item then if replacement[1] == name then
label = "\nR" label = (label ~= "" and "\n" or "") .. label .. "\nR"
replace = replacement[2] replace = replacement[2]
end end
end 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 infos = {
unknown = reg_items[item] and nil,
groups = groups,
burntime = fuel_cache[item],
cooktime = cooktime,
replace = replace,
}
if next(infos) then
fs[#fs + 1] = get_tooltip(item, infos)
end
if CORE_VERSION >= 510 and not large_recipe then if CORE_VERSION >= 510 and not large_recipe then
fs[#fs + 1] = fmt(FMT.image, fs[#fs + 1] = fmt(FMT.image,
X, Y + (sfinv_only and 0.7 or 0), X, Y + (sfinv_only and 0.7 or 0),
btn_size, btn_size, PNG.selected) btn_size, btn_size, PNG.selected)
end 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))
local infos = {
unknown = not reg_items[name] or nil,
groups = groups,
burntime = fuel_cache[name],
cooktime = cooktime,
replace = replace,
}
if next(infos) then
fs[#fs + 1] = get_tooltip(item, infos)
end
end end
if large_recipe then if large_recipe then
@ -860,8 +895,7 @@ local function get_panels(data, fs)
local x = 0.33 local x = 0.33
if sfinv_only then if sfinv_only then
panels = data.show_usages and panels = data.show_usages and {usages = data.usages} or {recipes = data.recipes}
{usages = data.usages} or {recipes = data.recipes}
end end
for k, v in pairs(panels) do for k, v in pairs(panels) do
@ -876,51 +910,65 @@ local function get_panels(data, fs)
-0.2 + spacing, PNG.bg_full) -0.2 + spacing, PNG.bg_full)
end end
local btn_lab local rn = #v
local _rn = tostring(rn)
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))
if not sfinv_only and #v == 0 then local is_recipe = k == "recipes"
btn_lab = clr("red", k == "recipes" and local lbl
ESC(S("No recipes")) or ESC(S("No usages")))
elseif (not sfinv_only and k == "recipes") or if not sfinv_only and rn == 0 then
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 (sfinv_only and not data.show_usages) then
btn_lab = ESC(S("Recipe @1 of @2", data.rnum, #v)) lbl = ES("Recipe @1 of @2", data.rnum, rn)
elseif not sfinv_only or (sfinv_only and data.show_usages) then elseif not sfinv_only or (sfinv_only and data.show_usages) then
btn_lab = ESC(S("Usage @1 of @2", data.unum, #v)) lbl = ES("Usage @1 of @2", data.unum, rn)
elseif sfinv_only then elseif sfinv_only then
btn_lab = data.show_usages and lbl = data.show_usages and
ESC(S("Usage @1 of @2", data.unum, #v)) or ES("Usage @1 of @2", data.unum, rn) or
ESC(S("Recipe @1 of @2", data.rnum, #v)) ES("Recipe @1 of @2", data.rnum, rn)
end end
fs[#fs + 1] = fmt(FMT.label, 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 xr or xu),
YOFFSET + (sfinv_only and 2.2 or 1.5 + spacing), YOFFSET + (sfinv_only and 3.35 or 1.5 + spacing), lbl)
btn_lab)
if #v > 1 then if rn > 1 then
local btn_suffix = k == "recipes" and "recipe" or "usage" 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 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, if CORE_VERSION >= 520 then
x_arrow, y_arrow, PNG.prev, fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2),
fmt("prev_%s", btn_suffix), PNG.prev, x_arrow + (is_recipe and xr or xu), y_arrow,
x_arrow + 1.8, y_arrow, PNG.next, PNG.prev, prev_name, "",
fmt("next_%s", btn_suffix), PNG.next) 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),
y_arrow, PNG.prev, prev_name, PNG.prev_hover,
x_arrow + 1.8, y_arrow, PNG.next, next_name, PNG.next_hover)
end
end 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) get_grid_fs(fs, rcp, spacing)
end end
end end
end
local function make_formspec(name) local function make_formspec(name)
local data = pdata[name] local data = pdata[name]
data.pagemax = max(1, ceil(#data.items / IPP))
local fs = {} local fs = {}
if not sfinv_only then if not sfinv_only then
@ -928,9 +976,10 @@ local function make_formspec(name)
size[%f,%f] size[%f,%f]
no_prepend[] no_prepend[]
bgcolor[#0000] 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, ROWS + (data.query_item and 6.7 or 0) - 1.2, LINES - 0.3, PNG.selected)
LINES - 0.3)
fs[#fs + 1] = CORE_VERSION >= 510 and fs[#fs + 1] = CORE_VERSION >= 510 and
fmt("background9[-0.15,-0.2;%f,%f;%s;false;%d]", fmt("background9[-0.15,-0.2;%f,%f;%s;false;%d]",
@ -940,35 +989,55 @@ local function make_formspec(name)
end end
fs[#fs + 1] = fmt([[ fs[#fs + 1] = fmt([[
style_type[item_image_button;border=false]
field[0.25,0.2;%f,1;filter;;%s] field[0.25,0.2;%f,1;filter;;%s]
field_close_on_enter[filter;false] 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([[ fs[#fs + 1] = fmt([[
image_button[%f,-0.05;0.85,0.85;%s;search;;;false;%s^\[colorize:yellow:255] style[search;fgimg=%s;fgimg_hovered=%s]
image_button[%f,-0.05;0.85,0.85;%s;clear;;;false;%s^\[colorize:red:255] style[clear;fgimg=%s;fgimg_hovered=%s]
style[prev_page;fgimg=%s;fgimg_hovered=%s]
style[next_page;fgimg=%s;fgimg_hovered=%s]
]], ]],
sfinv_only and 2.6 or 2.54, PNG.search, PNG.search, PNG.search, PNG.search_hover,
sfinv_only and 3.3 or 3.25, PNG.clear, PNG.clear) PNG.clear, PNG.clear_hover,
PNG.prev, PNG.prev_hover,
PNG.next, PNG.next_hover)
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.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)
end
data.pagemax = max(1, ceil(#data.items / IPP))
fs[#fs + 1] = fmt("label[%f,%f;%s / %u]", fs[#fs + 1] = fmt("label[%f,%f;%s / %u]",
sfinv_only and 6.35 or (ROWS * 7.85) / 11, 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)
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 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 local pos = ROWS / 3
if next(recipe_filters) and #init_items > 0 and data.filter == "" then 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 pos = pos - 1
end end
@ -984,17 +1053,17 @@ local function make_formspec(name)
local X = i % ROWS local X = i % ROWS
local Y = (i % IPP - X) / ROWS + 1 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 if CORE_VERSION >= 510 and data.query_item == item then
fs[#fs + 1] = fmt(FMT.image, fs[#fs + 1] = fmt(FMT.image,
X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05, X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05,
Y - (Y * 0.1) - 0.1, Y - (Y * 0.1) - 0.1,
1, 1, PNG.selected) 1, 1, PNG.selected)
end 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 end
if (data.recipes and #data.recipes > 0) or (data.usages and #data.usages > 0) then if (data.recipes and #data.recipes > 0) or (data.usages and #data.usages > 0) then
@ -1012,31 +1081,26 @@ local show_fs = function(player, name)
end end
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", { craftguide.register_craft_type("digging", {
description = ESC(S("Digging")), description = ES"Digging",
icon = "default_tool_steelpick.png", icon = "default_tool_steelpick.png",
}) })
craftguide.register_craft_type("digging_chance", { craftguide.register_craft_type("digging_chance", {
description = ESC(S("Digging Chance")), description = ES"Digging Chance",
icon = "default_tool_mesepick.png", 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 function search(data)
local filter = data.filter local filter = data.filter
@ -1058,28 +1122,28 @@ local function search(data)
end end
end end
local filtered_list, c = {}, 0 local filtered_list, order, c = {}, {}, 0
for i = 1, #data.items_raw do for i = 1, #data.items_raw do
local item = data.items_raw[i] local item = data.items_raw[i]
local def = reg_items[item] local def = reg_items[item]
local desc = (def and def.description) and lower(def.description) or "" local desc = (def and def.description) and lower(def.description) or ""
local search_in = fmt("%s %s", item, desc)
local to_add local to_add
if search_filter then if search_filter then
for filter_name, values in pairs(filters) do for filter_name, values in pairs(filters) do
local func = search_filters[filter_name] local func = search_filters[filter_name]
to_add = func(item, values) and (search_filter == "" or to_add = func(item, values) and (search_filter == "" or
find(search_in, search_filter, 1, true)) (sfind(item, search_filter) or sfind(desc, search_filter)))
end end
else else
to_add = find(search_in, filter, 1, true) to_add = sfind(item, filter) or sfind(desc, filter)
end end
if to_add then if to_add then
c = c + 1 c = c + 1
filtered_list[c] = item filtered_list[c] = item
order[item] = to_add
end end
end end
@ -1092,9 +1156,28 @@ local function search(data)
end end
end end
sort(filtered_list, function(a, b)
return order[a] < order[b]
end)
data.items = filtered_list data.items = filtered_list
end 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 --[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not
return the replacements and toolrepair, we have to override return the replacements and toolrepair, we have to override
`core.register_craft` and do some reverse engineering. `core.register_craft` and do some reverse engineering.
@ -1169,6 +1252,20 @@ core.register_craft = function(def)
end end
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) local function handle_drops_table(name, drop)
-- Code borrowed and modified from unified_inventory -- Code borrowed and modified from unified_inventory
-- https://github.com/minetest-mods/unified_inventory/blob/master/api.lua -- https://github.com/minetest-mods/unified_inventory/blob/master/api.lua
@ -1256,13 +1353,15 @@ end
local function handle_aliases(hash) local function handle_aliases(hash)
for oldname, newname in pairs(reg_aliases) do for oldname, newname in pairs(reg_aliases) do
cache_recipes(oldname)
local recipes = recipes_cache[oldname] local recipes = recipes_cache[oldname]
if recipes then if recipes then
if not recipes_cache[newname] then if not recipes_cache[newname] then
recipes_cache[newname] = {} recipes_cache[newname] = {}
end end
local is_similar local similar
for i = 1, #recipes_cache[oldname] do for i = 1, #recipes_cache[oldname] do
local rcp_old = recipes_cache[oldname][i] local rcp_old = recipes_cache[oldname][i]
@ -1273,18 +1372,18 @@ local function handle_aliases(hash)
rcp_new.method = nil rcp_new.method = nil
if table_eq(rcp_old, rcp_new) then if table_eq(rcp_old, rcp_new) then
is_similar = true similar = true
break break
end end
end end
if not is_similar then if not similar then
insert(recipes_cache[newname], rcp_old) insert(recipes_cache[newname], rcp_old)
end end
end end
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 init_items[#init_items + 1] = newname
end end
end end
@ -1296,9 +1395,38 @@ local function show_item(def)
def.description and def.description ~= "" def.description and def.description ~= ""
end end
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 function get_init_items()
local ic, it, last_str = 0, tablelen(reg_items), ""
local hash = {} local hash = {}
local function iop(str)
io.write(("\b \b"):rep(#last_str))
io.write(str)
io.flush()
last_str = str
end
local full_char, empty_char = "o", "."
for name, def in pairs(reg_items) do for name, def in pairs(reg_items) do
ic = ic + 1
local percent, bar, len = (ic * 100) / it, "", 20
for i = 1, len do
bar = bar .. (i <= percent / (100 / len) and full_char or empty_char)
end
iop(fmt("[craftguide] Caching data %s %u%%\n", bar, percent))
if show_item(def) then if show_item(def) then
if not fuel_cache[name] then if not fuel_cache[name] then
cache_fuel(name) cache_fuel(name)
@ -1311,7 +1439,7 @@ local function get_init_items()
cache_usages(name) cache_usages(name)
register_drops(name, def) 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 init_items[#init_items + 1] = name
hash[name] = true hash[name] = true
end end
@ -1321,7 +1449,7 @@ local function get_init_items()
handle_aliases(hash) handle_aliases(hash)
sort(init_items) 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 = { local post_data = {
recipes = recipes_cache, recipes = recipes_cache,
usages = usages_cache, usages = usages_cache,
@ -1329,10 +1457,12 @@ local function get_init_items()
} }
http.fetch_async({ http.fetch_async({
url = craftguide.http_post_data, url = craftguide.export_url,
post_data = write_json(post_data), post_data = write_json(post_data),
}) })
end end
print()
end end
local function init_data(name) local function init_data(name)
@ -1422,6 +1552,8 @@ local function fields(player, _f)
item = sub(item, 1, -5) item = sub(item, 1, -5)
end end
item = reg_aliases[item] or item
if sfinv_only then if sfinv_only then
if item ~= data.query_item then if item ~= data.query_item then
data.show_usages = nil data.show_usages = nil
@ -1445,7 +1577,7 @@ end
if sfinv_only then if sfinv_only then
sfinv.register_page("craftguide:craftguide", { sfinv.register_page("craftguide:craftguide", {
title = S("Craft Guide"), title = S"Craft Guide",
get = function(self, player, context) get = function(self, player, context)
local name = player:get_player_name() local name = player:get_player_name()
@ -1488,7 +1620,7 @@ else
end end
core.register_craftitem("craftguide:book", { core.register_craftitem("craftguide:book", {
description = S("Crafting Guide"), description = S"Crafting Guide",
inventory_image = PNG.book, inventory_image = PNG.book,
wield_image = PNG.book, wield_image = PNG.book,
stack_max = 1, stack_max = 1,
@ -1499,7 +1631,7 @@ else
}) })
core.register_node("craftguide:sign", { core.register_node("craftguide:sign", {
description = S("Crafting Guide Sign"), description = S"Crafting Guide Sign",
drawtype = "nodebox", drawtype = "nodebox",
tiles = {PNG.sign}, tiles = {PNG.sign},
inventory_image = PNG.sign, inventory_image = PNG.sign,
@ -1551,8 +1683,8 @@ else
if rawget(_G, "sfinv_buttons") then if rawget(_G, "sfinv_buttons") then
sfinv_buttons.register_button("craftguide", { sfinv_buttons.register_button("craftguide", {
title = S("Crafting Guide"), title = S"Crafting Guide",
tooltip = S("Shows a list of available crafting recipes, cooking recipes and fuels"), tooltip = S"Shows a list of available crafting recipes, cooking recipes and fuels",
image = PNG.book, image = PNG.book,
action = function(player) action = function(player)
on_use(player) on_use(player)
@ -1783,7 +1915,7 @@ if progressive_mode then
hud_elem_type = "text", hud_elem_type = "text",
position = {x = 0.84, y = 1.04}, position = {x = 0.84, y = 1.04},
alignment = {x = 1, y = 1}, alignment = {x = 1, y = 1},
number = 0xFFFFFF, number = 0xfff,
text = "", text = "",
}), }),
} }
@ -1834,7 +1966,7 @@ end)
function craftguide.show(name, item, show_usages) function craftguide.show(name, item, show_usages)
if not true_str(name)then if not true_str(name)then
return err("craftguide.show(): player name missing") return err"craftguide.show(): player name missing"
end end
local data = pdata[name] local data = pdata[name]
@ -1849,12 +1981,12 @@ function craftguide.show(name, item, show_usages)
if not recipes and not usages then if not recipes and not usages then
if not recipes_cache[item] and not usages_cache[item] then if not recipes_cache[item] and not usages_cache[item] then
return false, msg(name, fmt("%s: %s", 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))) get_desc(item)))
end end
return false, msg(name, fmt("%s: %s", 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))) get_desc(item)))
end end
@ -1870,7 +2002,7 @@ function craftguide.show(name, item, show_usages)
end end
register_command("craft", { register_command("craft", {
description = S("Show recipe(s) of the pointed node"), description = S"Show recipe(s) of the pointed node",
func = function(name) func = function(name)
local player = get_player_by_name(name) local player = get_player_by_name(name)
local dir = player:get_look_dir() local dir = player:get_look_dir()
@ -1890,9 +2022,11 @@ register_command("craft", {
end end
if not node_name then if not node_name then
return false, msg(name, S("No node pointed")) return false, msg(name, S"No node pointed")
end end
return true, craftguide.show(name, node_name) return true, craftguide.show(name, node_name)
end, end,
}) })
minetest.log("action", "[craftguide] loaded.")

View File

@ -21,3 +21,6 @@ Show recipe(s) of the pointed node=Mostra la ricetta del nodo puntato
No node pointed=Nessun nodo puntato No node pointed=Nessun nodo puntato
You don't know a recipe for this node=Non conosci una ricetta per questo nodo 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 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB