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.
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
@ -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 = {
result = "default:mese 4",
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
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.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¹).

442
init.lua
View File

@ -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
@ -66,7 +70,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, io = pairs, next, type, tostring, io
local vec_add, vec_mul = vector.add, vector.multiply
local ROWS = 9
@ -75,7 +79,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",
@ -89,6 +93,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,9 +109,20 @@ 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]",
}
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",
@ -118,10 +138,9 @@ 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)
return type(x) == "string"
end
@ -142,6 +161,14 @@ local function is_group(item)
return sub(item, 1, 6) == "group:"
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 hash = {}
@ -177,8 +204,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
@ -253,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
@ -272,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)
@ -289,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
@ -305,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
@ -375,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
@ -385,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}
@ -413,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
@ -443,8 +470,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
@ -552,8 +581,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)
@ -593,11 +623,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)
@ -613,7 +647,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
@ -621,31 +655,29 @@ local function get_tooltip(item, 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, ", ")
tooltip = S("Any item belonging to the group(s): @1", groupstr)
return fmt("tooltip[%s;%s]", item, ESC(tooltip))
else
tooltip = get_desc(name)
end
tooltip = get_desc(item)
local function add(str)
return fmt("%s\n%s", tooltip, str)
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))
local desc = clr("#ff0", get_desc(info.replace))
if info.cooktime then
tooltip = add(S("Replaced by @1 on smelting", desc))
@ -657,15 +689,15 @@ local function get_tooltip(item, info)
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]", item, ESC(tooltip))
return fmt("tooltip[%s;%s]", name, ESC(tooltip))
end
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)
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))
@ -705,19 +737,21 @@ local function get_output_fs(fs, L)
1.1, 1.1, PNG.fire)
else
local item = L.recipe.output
item = clean_name(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), "")
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],
repair = repairable(name),
rarity = L.rarity,
@ -740,7 +774,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
@ -761,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
@ -774,6 +807,9 @@ local function get_grid_fs(fs, rcp, spacing)
for i = 1, width * rows do
local item = rcp.items[i] or ""
item = clean_name(item)
local name = match(item, "%S*")
local X = ceil((i - 1) % width - width) + XOFFSET
local Y = ceil(i / width) + YOFFSET - min(2, rows) + spacing
@ -798,10 +834,9 @@ local function get_grid_fs(fs, rcp, spacing)
local groups
if is_group(item) then
groups = extract_groups(item)
local items = groups_to_items(groups)
item = items[1] or items
if is_group(name) then
groups = extract_groups(name)
item = groups_to_items(groups)
end
local label = groups and "\nG" or ""
@ -810,34 +845,34 @@ 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
label = "\nR"
if replacement[1] == name 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 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
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))
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
if large_recipe then
@ -860,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
@ -876,51 +910,65 @@ local function get_panels(data, fs)
-0.2 + spacing, PNG.bg_full)
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
btn_lab = clr("red", k == "recipes" and
ESC(S("No recipes")) or ESC(S("No usages")))
local is_recipe = k == "recipes"
local lbl
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
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
btn_lab = ESC(S("Usage @1 of @2", data.unum, #v))
lbl = ES("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))
lbl = data.show_usages and
ES("Usage @1 of @2", data.unum, rn) or
ES("Recipe @1 of @2", data.rnum, rn)
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)
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 #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 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 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,
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(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),
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 = k == "recipes" and v[data.rnum] or v[data.unum]
get_grid_fs(fs, rcp, spacing)
local rcp = is_recipe and v[data.rnum] or v[data.unum]
if rcp then
get_grid_fs(fs, rcp, spacing)
end
end
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
@ -928,9 +976,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]",
@ -940,35 +989,55 @@ 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))
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;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]
]],
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(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]",
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)
0.06, clr("#ff0", 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
@ -984,17 +1053,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
@ -1012,31 +1081,26 @@ 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")),
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",
})
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
@ -1058,28 +1122,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
local func = search_filters[filter_name]
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
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
@ -1092,9 +1156,28 @@ local function search(data)
end
end
sort(filtered_list, function(a, b)
return order[a] < order[b]
end)
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.
@ -1169,6 +1252,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
@ -1256,13 +1353,15 @@ end
local function handle_aliases(hash)
for oldname, newname in pairs(reg_aliases) do
cache_recipes(oldname)
local recipes = recipes_cache[oldname]
if recipes then
if not recipes_cache[newname] then
recipes_cache[newname] = {}
end
local is_similar
local similar
for i = 1, #recipes_cache[oldname] do
local rcp_old = recipes_cache[oldname][i]
@ -1273,18 +1372,18 @@ 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
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
@ -1296,9 +1395,38 @@ local function show_item(def)
def.description and def.description ~= ""
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 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
local full_char, empty_char = "o", "."
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 not fuel_cache[name] then
cache_fuel(name)
@ -1311,7 +1439,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
@ -1321,7 +1449,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,
@ -1329,10 +1457,12 @@ local function get_init_items()
}
http.fetch_async({
url = craftguide.http_post_data,
url = craftguide.export_url,
post_data = write_json(post_data),
})
end
print()
end
local function init_data(name)
@ -1422,6 +1552,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
@ -1445,7 +1577,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()
@ -1488,7 +1620,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,
@ -1499,7 +1631,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,
@ -1551,8 +1683,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)
@ -1783,7 +1915,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 = "",
}),
}
@ -1834,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]
@ -1849,12 +1981,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
@ -1870,7 +2002,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()
@ -1890,9 +2022,11 @@ 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)
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
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

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