mirror of
https://github.com/minetest-mods/craftguide.git
synced 2025-06-29 14:40:49 +02:00
Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
a50a99836a | |||
e2134e479e | |||
3320fbdd6b | |||
19fb5e2691 | |||
9dd63cd83a | |||
07820fa37c | |||
29f87f2607 | |||
aef1fe0dc6 | |||
22ff82cc89 | |||
dd98cb2cb3 | |||
f184341663 | |||
3f9d7bc12d | |||
60b09a27f7 | |||
a936452e21 | |||
768e06e2d0 | |||
732535c9da | |||
7a8b8d19df | |||
9dcccadfc2 | |||
7c891ff2b6 | |||
06bef9777a | |||
738c2140a7 | |||
2ffef6794a | |||
fb1b0cf869 | |||
59b806c9c4 |
18
API.md
18
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
|
||||
@ -72,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.
|
||||
@ -160,7 +174,7 @@ craftguide.group_stereotypes.radioactive = "mod:item"
|
||||
You can set a custom background theme by overriding this variable:
|
||||
|
||||
```Lua
|
||||
craftguide.background = "<file_name.png>:<middle>"
|
||||
craftguide.background = "<file_name.png>#<middle>"
|
||||
|
||||
```
|
||||
|
||||
|
@ -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
|
||||
|
||||

|
||||
|
||||

|
||||
|
@ -1,2 +0,0 @@
|
||||
The most comprehensive Crafting Guide
|
||||
on Minetest.
|
498
init.lua
498
init.lua
@ -1,5 +1,12 @@
|
||||
craftguide = {}
|
||||
|
||||
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 = {}
|
||||
local init_items = {}
|
||||
@ -7,6 +14,7 @@ local searches = {}
|
||||
local recipes_cache = {}
|
||||
local usages_cache = {}
|
||||
local fuel_cache = {}
|
||||
local alias_cache = {}
|
||||
|
||||
local toolrepair
|
||||
|
||||
@ -22,16 +30,26 @@ 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
|
||||
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, 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
|
||||
@ -52,9 +70,7 @@ 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:10"
|
||||
craftguide.background = "craftguide_bg_full.png#10"
|
||||
|
||||
local PNG = {
|
||||
bg = "craftguide_bg.png",
|
||||
@ -80,12 +96,12 @@ local FMT = {
|
||||
}
|
||||
|
||||
craftguide.group_stereotypes = {
|
||||
wool = "wool:white",
|
||||
dye = "dye:white",
|
||||
water_bucket = "bucket:bucket_water",
|
||||
vessel = "vessels:glass_bottle",
|
||||
wool = "wool:white",
|
||||
coal = "default:coal_lump",
|
||||
vessel = "vessels:glass_bottle",
|
||||
flower = "flowers:dandelion_yellow",
|
||||
water_bucket = "bucket:bucket_water",
|
||||
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
|
||||
}
|
||||
|
||||
@ -117,12 +133,16 @@ local function table_replace(t, val, new)
|
||||
end
|
||||
end
|
||||
|
||||
local function is_str(x)
|
||||
return type(x) == "string"
|
||||
local function err(str)
|
||||
return log("error", str)
|
||||
end
|
||||
|
||||
local function is_num(x)
|
||||
return type(x) == "number"
|
||||
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)
|
||||
@ -140,8 +160,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
|
||||
@ -155,36 +175,36 @@ 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
|
||||
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
|
||||
|
||||
if not is_table(def.key) then
|
||||
def.key = {}
|
||||
end
|
||||
|
||||
local cp = copy(def.grid)
|
||||
sort(cp, function(a, b)
|
||||
return #a > #b
|
||||
@ -198,14 +218,36 @@ 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
|
||||
def.items[c] = def.key[symbol]
|
||||
end
|
||||
else
|
||||
local items, len = def.items, #def.items
|
||||
def.items = {}
|
||||
|
||||
for i = 1, len do
|
||||
items[i] = items[i]:gsub(",", ", ")
|
||||
local rlen = #split(items[i], ",")
|
||||
|
||||
if rlen > def.width then
|
||||
def.width = rlen
|
||||
end
|
||||
end
|
||||
|
||||
local output = match(def.output, "%S*")
|
||||
for i = 1, len do
|
||||
while #split(items[i], ",") < def.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)
|
||||
end
|
||||
end
|
||||
|
||||
local output = clean_str(def.output)
|
||||
recipes_cache[output] = recipes_cache[output] or {}
|
||||
insert(recipes_cache[output], def)
|
||||
end
|
||||
@ -213,15 +255,25 @@ 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
|
||||
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
|
||||
@ -241,10 +293,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
|
||||
@ -297,8 +349,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]
|
||||
@ -309,10 +360,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
|
||||
|
||||
if data then
|
||||
known = known + recipes + usages
|
||||
end
|
||||
end
|
||||
@ -320,9 +371,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)
|
||||
@ -331,7 +382,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
|
||||
@ -348,15 +398,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
|
||||
@ -364,6 +424,13 @@ local function cache_usages(item)
|
||||
end
|
||||
end
|
||||
|
||||
local function cache_recipes(output)
|
||||
local recipes = get_all_recipes(output) or {}
|
||||
if #recipes > 0 then
|
||||
recipes_cache[output] = recipes
|
||||
end
|
||||
end
|
||||
|
||||
local function get_recipes(item, data, player)
|
||||
local recipes = recipes_cache[item]
|
||||
local usages = usages_cache[item]
|
||||
@ -444,7 +511,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
|
||||
@ -494,8 +561,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)
|
||||
@ -511,14 +579,14 @@ 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 burntime = fuel_cache[name] and fuel_cache[name].burntime
|
||||
local name = clean_str(item)
|
||||
|
||||
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, {
|
||||
@ -541,13 +609,13 @@ 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
|
||||
|
||||
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))
|
||||
@ -612,7 +680,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
|
||||
@ -620,16 +688,14 @@ 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))
|
||||
|
||||
local burntime = fuel_cache[item] and fuel_cache[item].burntime
|
||||
btn_size, btn_size, item, clean_str(item), ESC(label))
|
||||
|
||||
local info = {
|
||||
unknown = not reg_items[item],
|
||||
groups = groups,
|
||||
burntime = burntime,
|
||||
burntime = fuel_cache[item],
|
||||
cooktime = cooktime,
|
||||
replace = replace,
|
||||
repair = nil,
|
||||
}
|
||||
|
||||
for _, v in pairs(info) do
|
||||
@ -656,17 +722,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([[
|
||||
@ -682,15 +750,13 @@ 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 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
|
||||
@ -777,7 +843,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
|
||||
@ -808,12 +874,140 @@ 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
|
||||
|
||||
--[[ 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)
|
||||
|
||||
if def.type == "toolrepair" then
|
||||
toolrepair = def.additional_wear * -100
|
||||
end
|
||||
|
||||
local output = def.output or is_str(def.recipe)
|
||||
if not output then return end
|
||||
output = {clean_str(output)}
|
||||
|
||||
local groups
|
||||
|
||||
if is_group(output[1]) then
|
||||
groups = extract_groups(output[1])
|
||||
output = groups_to_items(groups, true)
|
||||
end
|
||||
|
||||
for i = 1, #output do
|
||||
local name = output[i]
|
||||
|
||||
if def.type ~= "fuel" then
|
||||
def.items = {}
|
||||
end
|
||||
|
||||
if def.type == "fuel" then
|
||||
fuel_cache[name] = def.burntime
|
||||
fuel_cache.replacements[name] = def.replacements
|
||||
|
||||
elseif def.type == "cooking" then
|
||||
def.width = def.cooktime
|
||||
def.cooktime = nil
|
||||
def.items[1] = def.recipe
|
||||
|
||||
elseif def.type == "shapeless" then
|
||||
def.width = 0
|
||||
for j = 1, #def.recipe do
|
||||
def.items[#def.items + 1] = def.recipe[j]
|
||||
end
|
||||
else
|
||||
def.width = #def.recipe[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
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if def.type ~= "fuel" then
|
||||
def.recipe = nil
|
||||
recipes_cache[name] = recipes_cache[name] or {}
|
||||
insert(recipes_cache[name], 1, def)
|
||||
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 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
|
||||
|
||||
if not recipes_cache[name] then
|
||||
cache_recipes(name)
|
||||
end
|
||||
|
||||
cache_usages(name)
|
||||
|
||||
if recipes_cache[name] or usages_cache[name] then
|
||||
c = c + 1
|
||||
init_items[c] = name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sort(init_items)
|
||||
end
|
||||
|
||||
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 = init_items,
|
||||
items_raw = init_items,
|
||||
items = items,
|
||||
items_raw = items,
|
||||
}
|
||||
end
|
||||
|
||||
@ -827,110 +1021,9 @@ 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.
|
||||
|
||||
local old_register_alias = core.register_alias
|
||||
local current_alias = {}
|
||||
|
||||
core.register_alias = function(old, new)
|
||||
old_register_alias(old, new)
|
||||
current_alias = {old, new}
|
||||
end
|
||||
|
||||
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 * -100
|
||||
end
|
||||
|
||||
local output = recipe.output or
|
||||
(is_str(recipe.recipe) and recipe.recipe or "")
|
||||
|
||||
if output == "" then return end
|
||||
output = {clean_name(output)}
|
||||
local groups
|
||||
|
||||
if is_group(output[1]) then
|
||||
groups = extract_groups(output[1])
|
||||
output = groups_to_items(groups, true)
|
||||
end
|
||||
|
||||
for i = 1, #output do
|
||||
local item = output[i]
|
||||
if item == current_alias[1] then
|
||||
item = current_alias[2]
|
||||
end
|
||||
|
||||
recipe.items = {}
|
||||
|
||||
if recipe.type == "fuel" then
|
||||
fuel_cache[item] = recipe
|
||||
|
||||
elseif recipe.type == "cooking" then
|
||||
recipe.width = recipe.cooktime
|
||||
recipe.cooktime = nil
|
||||
recipe.items[1] = recipe.recipe
|
||||
|
||||
elseif recipe.type == "shapeless" then
|
||||
recipe.width = 0
|
||||
for j = 1, #recipe.recipe do
|
||||
recipe.items[#recipe.items + 1] = recipe.recipe[j]
|
||||
end
|
||||
else
|
||||
recipe.width = #recipe.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]
|
||||
|
||||
if it and it ~= "" then
|
||||
recipe.items[c] = it
|
||||
end
|
||||
|
||||
c = c + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if recipe.type ~= "fuel" then
|
||||
recipe.recipe = nil
|
||||
recipes_cache[item] = recipes_cache[item] or {}
|
||||
insert(recipes_cache[item], 1, recipe)
|
||||
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 c = 1
|
||||
for name, def in pairs(reg_items) do
|
||||
if show_item(def) then
|
||||
cache_usages(name)
|
||||
|
||||
if recipes_cache[name] or usages_cache[name] then
|
||||
init_items[c] = name
|
||||
c = c + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sort(init_items)
|
||||
end
|
||||
|
||||
if CORE_VERSION >= 500 then
|
||||
on_mods_loaded(get_init_items)
|
||||
end
|
||||
|
||||
on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
@ -1131,6 +1224,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 +1339,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 +1357,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 +1365,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
|
||||
|
||||
@ -1303,12 +1398,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
|
||||
|
||||
@ -1317,14 +1419,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)
|
||||
@ -1334,12 +1436,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({
|
||||
@ -1374,13 +1481,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
|
||||
|
||||
@ -1462,8 +1578,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]
|
||||
|
23
locale/craftguide.it.tr
Normal file
23
locale/craftguide.it.tr
Normal file
@ -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
|
Reference in New Issue
Block a user