mirror of
https://github.com/minetest-mods/craftguide.git
synced 2025-07-06 10:00:32 +02:00
Cache recipes and fuel definitions
And refactor lots of related stuff
This commit is contained in:
273
init.lua
273
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,24 +80,9 @@ 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]
|
||||
if custom_craft.output:match("%S*") == output then
|
||||
@ -103,7 +90,22 @@ local function get_recipes(output)
|
||||
end
|
||||
end
|
||||
|
||||
return recipes
|
||||
if #recipes > 0 then
|
||||
recipes_cache[output] = recipes
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
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 color_codes = {
|
||||
@ -116,10 +118,6 @@ local function colorize(str, color)
|
||||
return mt.colorize(color_codes[color], str)
|
||||
end
|
||||
|
||||
local function get_fueltime(item)
|
||||
return get_result({method = "fuel", width = 1, items = {item}}).time
|
||||
end
|
||||
|
||||
local function extract_groups(str)
|
||||
return str:sub(7):split(",")
|
||||
end
|
||||
@ -154,85 +152,59 @@ 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] = colorize(groups[i])
|
||||
end
|
||||
groupstr = concat(groupstr, ", ")
|
||||
tooltip = S("Any item belonging to the group(s):") .. " " .. groupstr
|
||||
else
|
||||
tooltip = reg_items[item].description
|
||||
end
|
||||
|
||||
tooltip = tooltip ..
|
||||
S("Any item belonging to the group(s)") .. ": " .. groupstr
|
||||
if cooktime then
|
||||
tooltip = tooltip .. "\n" .. S("Cooking time:") .. " " ..
|
||||
colorize(cooktime)
|
||||
end
|
||||
|
||||
if recipe_type == "cooking" then
|
||||
tooltip = tooltip .. item_desc .. "\n" ..
|
||||
S("Cooking time") .. ": " .. colorize(cooktime)
|
||||
if burntime then
|
||||
tooltip = tooltip .. "\n" .. S("Burning time:") .. " " ..
|
||||
colorize(burntime)
|
||||
end
|
||||
|
||||
if fueltime > 0 then
|
||||
tooltip = tooltip .. item_desc .. "\n" ..
|
||||
S("Burning time") .. ": " .. colorize(fueltime)
|
||||
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
|
||||
|
||||
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
|
||||
local cooktime
|
||||
if recipe.type == "cooking" then
|
||||
cooktime, width = width, 1
|
||||
elseif width == 0 then
|
||||
width = min(3, #items)
|
||||
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 +227,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,7 +237,11 @@ 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]
|
||||
@ -289,12 +264,9 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage)
|
||||
0.5,
|
||||
0.5,
|
||||
custom_recipe and custom_recipe.description or
|
||||
recipe_type:gsub("^%l", string.upper))
|
||||
recipe.type:gsub("^%l", string.upper))
|
||||
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 +277,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,19 +285,20 @@ 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)
|
||||
end
|
||||
recipe.output,
|
||||
output_name)
|
||||
|
||||
fs[#fs + 1] = get_tooltip(output_s)
|
||||
if burntime then
|
||||
fs[#fs + 1] = get_tooltip(output_name, nil, nil, burntime)
|
||||
|
||||
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),
|
||||
@ -340,6 +313,18 @@ local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage)
|
||||
0.6,
|
||||
"craftguide_fire.png")
|
||||
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 S("Usage") or S("Recipe"),
|
||||
data.rnum,
|
||||
S("of"),
|
||||
#data.recipes)
|
||||
|
||||
return concat(fs)
|
||||
end
|
||||
@ -383,8 +368,6 @@ local function make_formspec(player_name)
|
||||
",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
|
||||
fs[#fs + 1] = fmt("label[%f,%f;%s]",
|
||||
(data.iX / 2) - 1,
|
||||
@ -411,14 +394,8 @@ local function make_formspec(player_name)
|
||||
name)
|
||||
end
|
||||
|
||||
if 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)
|
||||
@ -494,7 +471,7 @@ local function get_item_usages(item)
|
||||
get_recipe(name).items and
|
||||
def.description and def.description ~= "" then
|
||||
|
||||
local recipes = get_recipes(name)
|
||||
local recipes = recipes_cache[name]
|
||||
for i = 1, #recipes do
|
||||
local recipe = recipes[i]
|
||||
if item_in_recipe(item, recipe) then
|
||||
@ -504,6 +481,10 @@ local function get_item_usages(item)
|
||||
end
|
||||
end
|
||||
|
||||
if fuel_cache[item] then
|
||||
usages[#usages + 1] = {type = "fuel", width = 1, items = {item}}
|
||||
end
|
||||
|
||||
return usages
|
||||
end
|
||||
|
||||
@ -605,13 +586,15 @@ 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 then
|
||||
recipes = apply_progressive_filters(recipes, player)
|
||||
if #recipes > 0 then
|
||||
items[#items + 1] = item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return items
|
||||
end
|
||||
@ -628,22 +611,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.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
|
||||
@ -663,18 +646,12 @@ local function on_receive_fields(player, fields)
|
||||
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,7 +679,7 @@ local function on_receive_fields(player, fields)
|
||||
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
|
||||
@ -720,50 +697,42 @@ local function on_receive_fields(player, fields)
|
||||
item = item:sub(1,-5)
|
||||
end
|
||||
|
||||
local is_fuel = get_fueltime(item) > 0
|
||||
local recipes = get_recipes(item)
|
||||
if progressive_mode then
|
||||
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 next(recipes)
|
||||
local no_recipes = not recipes or #recipes == 0
|
||||
if no_recipes and not is_fuel then
|
||||
return
|
||||
end
|
||||
|
||||
if item ~= data.input then
|
||||
data.show_usage = nil
|
||||
if item ~= data.query_item then
|
||||
data.show_usages = nil
|
||||
else
|
||||
data.show_usage = not data.show_usage
|
||||
data.show_usages = not data.show_usages
|
||||
end
|
||||
|
||||
if is_fuel and no_recipes then
|
||||
data.show_usage = true
|
||||
data.show_usages = 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 data.show_usages then
|
||||
recipes = get_item_usages(item)
|
||||
|
||||
if progressive_mode then
|
||||
data.usages = apply_progressive_filters(data.usages, player)
|
||||
recipes = apply_progressive_filters(recipes, player)
|
||||
end
|
||||
|
||||
if not next(data.usages) then
|
||||
data.show_usage = nil
|
||||
if not next(recipes) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
data.input = item
|
||||
data.recipes_item = recipes
|
||||
data.query_item = item
|
||||
data.recipes = recipes
|
||||
data.rnum = 1
|
||||
|
||||
show_fs(player, player_name)
|
||||
@ -923,9 +892,9 @@ 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") ..
|
||||
@ -934,23 +903,15 @@ if not progressive_mode then
|
||||
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 next(recipes) 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,
|
||||
|
Reference in New Issue
Block a user