Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
b980dccaee | |||
4c02a5e5f5 | |||
f8b7a72635 | |||
1034fd7c0e | |||
4bca02f0db | |||
4b97b08aa7 | |||
7745ccd863 | |||
65b51ad3e5 | |||
897fc3a21d | |||
e1eedb69bb | |||
f188580b8c | |||
783a84d3c6 | |||
74a2750a4d | |||
9da500ce2c | |||
610117de08 | |||
53833af635 | |||
b2a7f5430a | |||
0b4f202ffb | |||
eff2fa82f3 | |||
8630fccaea | |||
4d4e8f7d50 | |||
6d3f8ce32a | |||
ed861ea1b9 |
@ -6,4 +6,5 @@ read_globals = {
|
|||||||
"default",
|
"default",
|
||||||
"sfinv",
|
"sfinv",
|
||||||
"sfinv_buttons",
|
"sfinv_buttons",
|
||||||
|
"vector",
|
||||||
}
|
}
|
||||||
|
36
LICENSE
@ -1,3 +1,6 @@
|
|||||||
|
License of source code
|
||||||
|
----------------------
|
||||||
|
|
||||||
« Copyright © 2015-2018, Jean-Patrick Guerrero <jeanpatrick.guerrero@gmail.com>
|
« Copyright © 2015-2018, Jean-Patrick Guerrero <jeanpatrick.guerrero@gmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
@ -7,3 +10,36 @@ The above copyright notice and this permission notice shall be included in all c
|
|||||||
The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders X be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
|
The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders X be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
|
||||||
|
|
||||||
Except as contained in this notice, the name of the <copyright holders> shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the <copyright holders>. »
|
Except as contained in this notice, the name of the <copyright holders> shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the <copyright holders>. »
|
||||||
|
|
||||||
|
Licenses of media (textures)
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Copyright © Diego Martínez (kaeza): craftguide_*_icon.png (CC BY-SA 3.0)
|
||||||
|
|
||||||
|
You are free to:
|
||||||
|
Share — copy and redistribute the material in any medium or format.
|
||||||
|
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||||
|
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||||
|
|
||||||
|
Under the following terms:
|
||||||
|
|
||||||
|
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||||
|
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||||
|
that suggests the licensor endorses you or your use.
|
||||||
|
|
||||||
|
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||||
|
your contributions under the same license as the original.
|
||||||
|
|
||||||
|
No additional restrictions — You may not apply legal terms or technological measures that
|
||||||
|
legally restrict others from doing anything the license permits.
|
||||||
|
|
||||||
|
Notices:
|
||||||
|
|
||||||
|
You do not have to comply with the license for elements of the material in the public
|
||||||
|
domain or where your use is permitted by an applicable exception or limitation.
|
||||||
|
No warranties are given. The license may not give you all of the permissions necessary
|
||||||
|
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||||
|
rights may limit how you use the material.
|
||||||
|
|
||||||
|
For more details:
|
||||||
|
http://creativecommons.org/licenses/by-sa/3.0/
|
||||||
|
31
README.md
@ -3,13 +3,36 @@
|
|||||||
#### `craftguide` is the most comprehensive crafting guide on Minetest. ####
|
#### `craftguide` is the most comprehensive crafting guide on Minetest. ####
|
||||||
#### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details. ####
|
#### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details. ####
|
||||||
|
|
||||||
#### This crafting guide is usable with a blue book named *"Crafting Guide"* ####
|
This crafting guide is a blue book named *"Crafting Guide"* or a wooden sign.
|
||||||
|
|
||||||
#### This crafting guide features two modes : Standard and Progressive. ####
|
This crafting guide features a **progressive mode**.
|
||||||
The Progressive mode is a Terraria-like system that only shows recipes you can craft from items in inventory.
|
The progressive mode is a Terraria-like system that only shows recipes you can craft from items in inventory.
|
||||||
The progressive mode can be enabled with `craftguide_progressive_mode = true` in `minetest.conf`.
|
The progressive mode can be enabled with `craftguide_progressive_mode = true` in `minetest.conf`.
|
||||||
|
|
||||||
`craftguide` is also integrated in `sfinv` (Minetest Game inventory) when you enable it with
|
`craftguide` is also integrated in `sfinv` (Minetest Game inventory) when you enable it with
|
||||||
`craftguide_sfinv_only = true` in `minetest.conf`.
|
`craftguide_sfinv_only = true` in `minetest.conf`.
|
||||||
|
|
||||||

|
Use the command `/craft` to show the recipe(s) of the pointed node.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`craftguide` has an API to register **custom recipes**. Demos:
|
||||||
|
#### Registering a custom crafting type ####
|
||||||
|
```Lua
|
||||||
|
craftguide.register_craft_type("digging", {
|
||||||
|
description = "Digging",
|
||||||
|
icon = "default_tool_steelpick.png",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Registering a custom crafting recipe ####
|
||||||
|
```Lua
|
||||||
|
craftguide.register_craft({
|
||||||
|
type = "digging",
|
||||||
|
width = 1,
|
||||||
|
output = "default:cobble 2",
|
||||||
|
items = {"default:stone"},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
770
init.lua
@ -1,4 +1,10 @@
|
|||||||
local craftguide, datas, mt = {}, {searches = {}}, minetest
|
craftguide = {
|
||||||
|
custom_crafts = {},
|
||||||
|
craft_types = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
local mt = minetest
|
||||||
|
local datas = {searches = {}}
|
||||||
|
|
||||||
local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode")
|
local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode")
|
||||||
local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only")
|
local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only")
|
||||||
@ -7,7 +13,7 @@ local get_recipe, get_recipes = mt.get_craft_recipe, mt.get_all_craft_recipes
|
|||||||
local get_result, show_formspec = mt.get_craft_result, mt.show_formspec
|
local get_result, show_formspec = mt.get_craft_result, mt.show_formspec
|
||||||
local reg_items = mt.registered_items
|
local reg_items = mt.registered_items
|
||||||
|
|
||||||
craftguide.path = minetest.get_modpath("craftguide")
|
craftguide.path = mt.get_modpath("craftguide")
|
||||||
|
|
||||||
-- Intllib
|
-- Intllib
|
||||||
local S = dofile(craftguide.path .. "/intllib.lua")
|
local S = dofile(craftguide.path .. "/intllib.lua")
|
||||||
@ -15,14 +21,17 @@ craftguide.intllib = S
|
|||||||
|
|
||||||
-- Lua 5.3 removed `table.maxn`, use this alternative in case of breakage:
|
-- Lua 5.3 removed `table.maxn`, use this alternative in case of breakage:
|
||||||
-- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1
|
-- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1
|
||||||
local remove, maxn, sort = table.remove, table.maxn, table.sort
|
local remove, maxn, sort, concat = table.remove, table.maxn, table.sort, table.concat
|
||||||
|
local vector_add, vector_mul = vector.add, vector.multiply
|
||||||
local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil
|
local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil
|
||||||
|
local fmt = string.format
|
||||||
|
|
||||||
local DEFAULT_SIZE = 10
|
local DEFAULT_SIZE = 10
|
||||||
local MIN_LIMIT, MAX_LIMIT = 9, 12
|
local MIN_LIMIT, MAX_LIMIT = 10, 12
|
||||||
DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE))
|
DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE))
|
||||||
|
|
||||||
local GRID_LIMIT = 5
|
local GRID_LIMIT = 5
|
||||||
|
local BUTTON_SIZE = 1.1
|
||||||
|
|
||||||
local group_stereotypes = {
|
local group_stereotypes = {
|
||||||
wool = "wool:white",
|
wool = "wool:white",
|
||||||
@ -34,7 +43,99 @@ local group_stereotypes = {
|
|||||||
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
|
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
|
||||||
}
|
}
|
||||||
|
|
||||||
function craftguide:group_to_item(item)
|
local function extract_groups(str)
|
||||||
|
if str:sub(1,6) ~= "group:" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
return str:sub(7):split(",")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function __func()
|
||||||
|
return debug.getinfo(2, "n").name
|
||||||
|
end
|
||||||
|
|
||||||
|
function craftguide.register_craft_type(name, def)
|
||||||
|
local func = "craftguide." .. __func() .. "(): "
|
||||||
|
assert(name, func .. "'name' field missing")
|
||||||
|
assert(def.description, func .. "'description' field missing")
|
||||||
|
assert(def.icon, func .. "'icon' field missing")
|
||||||
|
|
||||||
|
if not craftguide.craft_types[name] then
|
||||||
|
craftguide.craft_types[name] = def
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
craftguide.register_craft_type("digging", {
|
||||||
|
description = S("Digging"),
|
||||||
|
icon = "default_tool_steelpick.png",
|
||||||
|
})
|
||||||
|
|
||||||
|
function craftguide.register_craft(def)
|
||||||
|
local func = "craftguide." .. __func() .. "(): "
|
||||||
|
assert(def.type, func .. "'type' field missing")
|
||||||
|
assert(def.width, func .. "'width' field missing")
|
||||||
|
assert(def.output, func .. "'output' field missing")
|
||||||
|
assert(def.items, func .. "'items' field missing")
|
||||||
|
|
||||||
|
craftguide.custom_crafts[#craftguide.custom_crafts + 1] = def
|
||||||
|
end
|
||||||
|
|
||||||
|
craftguide.register_craft({
|
||||||
|
type = "digging",
|
||||||
|
width = 1,
|
||||||
|
output = "default:cobble",
|
||||||
|
items = {"default:stone"},
|
||||||
|
})
|
||||||
|
|
||||||
|
local color_codes = {
|
||||||
|
red = "#FF0000",
|
||||||
|
yellow = "#FFFF00",
|
||||||
|
}
|
||||||
|
|
||||||
|
local function colorize(str, color)
|
||||||
|
color = color or "yellow"
|
||||||
|
return mt.colorize(color_codes[color], str)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_fueltime(item)
|
||||||
|
return get_result({method = "fuel", width = 1, items = {item}}).time
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reset_datas(data)
|
||||||
|
data.show_usage = nil
|
||||||
|
data.filter = ""
|
||||||
|
data.input = nil
|
||||||
|
data.pagenum = 1
|
||||||
|
data.rnum = 1
|
||||||
|
data.items = progressive_mode and data.init_filter_items or datas.init_items
|
||||||
|
end
|
||||||
|
|
||||||
|
local function in_table(T)
|
||||||
|
for i = 1, #T do
|
||||||
|
if T[i] then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function group_to_items(group)
|
||||||
|
local items_with_group, counter = {}, 0
|
||||||
|
for name, def in pairs(reg_items) do
|
||||||
|
if def.groups[group:sub(7)] then
|
||||||
|
counter = counter + 1
|
||||||
|
items_with_group[counter] = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return items_with_group
|
||||||
|
end
|
||||||
|
|
||||||
|
local function item_in_inv(inv, item)
|
||||||
|
return inv:contains_item("main", item)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function group_to_item(item)
|
||||||
if item:sub(1,6) == "group:" then
|
if item:sub(1,6) == "group:" then
|
||||||
local itemsub = item:sub(7)
|
local itemsub = item:sub(7)
|
||||||
if group_stereotypes[itemsub] then
|
if group_stereotypes[itemsub] then
|
||||||
@ -53,20 +154,7 @@ function craftguide:group_to_item(item)
|
|||||||
return item:sub(1,6) == "group:" and "" or item
|
return item:sub(1,6) == "group:" and "" or item
|
||||||
end
|
end
|
||||||
|
|
||||||
local function extract_groups(str)
|
local function get_tooltip(item, recipe_type, cooktime, groups)
|
||||||
if str:sub(1,6) ~= "group:" then return end
|
|
||||||
return str:sub(7):split(",")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function colorize(str)
|
|
||||||
return mt.colorize("#FFFF00", str)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_fueltime(item)
|
|
||||||
return get_result({method = "fuel", width = 1, items = {item}}).time
|
|
||||||
end
|
|
||||||
|
|
||||||
function craftguide:get_tooltip(item, recipe_type, cooktime, groups)
|
|
||||||
local tooltip, item_desc = "tooltip[" .. item .. ";", ""
|
local tooltip, item_desc = "tooltip[" .. item .. ";", ""
|
||||||
local fueltime = get_fueltime(item)
|
local fueltime = get_fueltime(item)
|
||||||
local has_extras = groups or recipe_type == "cooking" or fueltime > 0
|
local has_extras = groups or recipe_type == "cooking" or fueltime > 0
|
||||||
@ -103,73 +191,158 @@ function craftguide:get_tooltip(item, recipe_type, cooktime, groups)
|
|||||||
return has_extras and tooltip .. "]" or ""
|
return has_extras and tooltip .. "]" or ""
|
||||||
end
|
end
|
||||||
|
|
||||||
function craftguide:get_recipe(iY, xoffset, recipe_num, recipes, show_usage)
|
local function get_recipe_fs(iX, iY, xoffset, recipe_num, recipes, show_usage)
|
||||||
local formspec, recipes_total = "", #recipes
|
if not recipes[1] then
|
||||||
if recipes_total > 1 then
|
return ""
|
||||||
formspec = formspec ..
|
|
||||||
"button[0," .. (iY + (sfinv_only and 3.8 or 3.3)) ..
|
|
||||||
";2,1;alternate;" .. S("Alternate") .. "]" ..
|
|
||||||
"label[0," .. (iY + (sfinv_only and 3.3 or 2.8)) .. ";" ..
|
|
||||||
(show_usage and S("Usage") or S("Recipe")) .. " " ..
|
|
||||||
S("@1 of @2", recipe_num, recipes_total) .. "]"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local fs = {}
|
||||||
|
|
||||||
|
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 recipe_type = recipes[recipe_num].type
|
||||||
local items = recipes[recipe_num].items
|
local items = recipes[recipe_num].items
|
||||||
local width = recipes[recipe_num].width
|
local width = recipes[recipe_num].width
|
||||||
|
|
||||||
if recipe_type == "cooking" or (recipe_type == "normal" and width == 0) then
|
local cooktime = width
|
||||||
local icon = recipe_type == "cooking" and "furnace" or "shapeless"
|
if recipe_type == "cooking" then
|
||||||
formspec = formspec ..
|
width = 1
|
||||||
"image[" .. (xoffset - 0.8) .. "," .. (iY + (sfinv_only and 2.2 or 1.7)) ..
|
elseif width == 0 then
|
||||||
";0.5,0.5;craftguide_" .. icon .. ".png]"
|
|
||||||
end
|
|
||||||
|
|
||||||
if width == 0 then
|
|
||||||
width = min(3, #items)
|
width = min(3, #items)
|
||||||
end
|
end
|
||||||
|
|
||||||
local rows = ceil(maxn(items) / width)
|
local rows = ceil(maxn(items) / width)
|
||||||
|
local rightest, s_btn_size = 0
|
||||||
|
|
||||||
if recipe_type == "normal" and (width > GRID_LIMIT or rows > GRID_LIMIT) then
|
if recipe_type ~= "cooking" and (width > GRID_LIMIT or rows > GRID_LIMIT) then
|
||||||
formspec = formspec ..
|
fs[#fs + 1] = fmt("label[%f,%f;%s]",
|
||||||
"label[" .. xoffset .. "," .. (iY + 2) .. ";" ..
|
(iX / 2) - 2,
|
||||||
S("Recipe is too big to\nbe displayed (@1x@2)", width, rows) .. "]"
|
iY + 2.2,
|
||||||
|
S("Recipe is too big to be displayed (@1x@2)", width, rows))
|
||||||
|
|
||||||
|
return concat(fs)
|
||||||
else
|
else
|
||||||
local btn_size = 1
|
|
||||||
for i, v in pairs(items) do
|
for i, v in pairs(items) do
|
||||||
local X = (i - 1) % width + xoffset
|
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))
|
local Y = ceil(i / width + (iY + 2) - min(2, rows))
|
||||||
|
|
||||||
if recipe_type == "normal" and (width > 3 or rows > 3) then
|
if recipe_type ~= "cooking" and (width > 3 or rows > 3) then
|
||||||
btn_size = width > 3 and 3 / width or 3 / rows
|
BUTTON_SIZE = width > 3 and 3 / width or 3 / rows
|
||||||
X = btn_size * (i % width) + xoffset
|
s_btn_size = BUTTON_SIZE
|
||||||
Y = btn_size * floor((i - 1) / width) + (iY + 3) - min(2, rows)
|
X = BUTTON_SIZE * (i % width) + xoffset - 2.65
|
||||||
|
Y = BUTTON_SIZE * floor((i - 1) / width) + (iY + 3) - min(2, rows)
|
||||||
|
end
|
||||||
|
|
||||||
|
if X > rightest then
|
||||||
|
rightest = X
|
||||||
end
|
end
|
||||||
|
|
||||||
local groups = extract_groups(v)
|
local groups = extract_groups(v)
|
||||||
local label = groups and "\nG" or ""
|
local label = groups and "\nG" or ""
|
||||||
local item_r = self:group_to_item(v)
|
local item_r = group_to_item(v)
|
||||||
local tltip = self:get_tooltip(item_r, recipe_type, width, groups)
|
local tltp = get_tooltip(item_r, recipe_type, cooktime, groups)
|
||||||
|
|
||||||
formspec = formspec ..
|
fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]",
|
||||||
"item_image_button[" .. X .. "," ..
|
X,
|
||||||
(Y + (sfinv_only and 0.7 or 0.2)) .. ";" ..
|
Y + (sfinv_only and 0.7 or 0.2),
|
||||||
btn_size .. "," .. btn_size .. ";" .. item_r ..
|
BUTTON_SIZE,
|
||||||
";" .. item_r .. ";" .. label .. "]" .. tltip
|
BUTTON_SIZE,
|
||||||
|
item_r,
|
||||||
|
item_r:match("%S*"),
|
||||||
|
label)
|
||||||
|
|
||||||
|
fs[#fs + 1] = tltp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
BUTTON_SIZE = 1.1
|
||||||
end
|
end
|
||||||
|
|
||||||
local output = recipes[recipe_num].output:match("%S+")
|
local custom_recipe = craftguide.craft_types[recipe_type]
|
||||||
return formspec ..
|
if recipe_type == "cooking" or custom_recipe or
|
||||||
"image[" .. (xoffset - 1) .. "," .. (iY + (sfinv_only and 2.85 or 2.35)) ..
|
(recipe_type == "normal" and width == 0) then
|
||||||
";0.9,0.7;craftguide_arrow.png]" ..
|
|
||||||
"item_image_button[" .. (xoffset - 2) .. "," ..
|
local icon = recipe_type == "cooking" and "furnace" or "shapeless"
|
||||||
(iY + (sfinv_only and 2.7 or 2.2)) .. ";1,1;" ..
|
|
||||||
output .. ";" .. output .. ";]" .. self:get_tooltip(output)
|
fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]",
|
||||||
|
rightest + 1.2,
|
||||||
|
iY + (sfinv_only and 2.2 or 1.7),
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
custom_recipe and custom_recipe.icon or
|
||||||
|
"craftguide_" .. icon .. ".png^[resize:16x16")
|
||||||
|
|
||||||
|
fs[#fs + 1] = fmt("tooltip[%f,%f;%f,%f;%s]",
|
||||||
|
rightest + 1.2,
|
||||||
|
iY + (sfinv_only and 2.2 or 1.7),
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
custom_recipe and custom_recipe.description or
|
||||||
|
recipe_type:gsub("^%l", string.upper))
|
||||||
|
end
|
||||||
|
|
||||||
|
local output = recipes[recipe_num].output
|
||||||
|
local output_s = output:match("%S+")
|
||||||
|
|
||||||
|
local arrow_X = rightest + (s_btn_size or BUTTON_SIZE)
|
||||||
|
local output_X = arrow_X + 0.9
|
||||||
|
|
||||||
|
fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]",
|
||||||
|
arrow_X,
|
||||||
|
iY + (sfinv_only and 2.85 or 2.35),
|
||||||
|
0.9,
|
||||||
|
0.7,
|
||||||
|
"craftguide_arrow.png")
|
||||||
|
|
||||||
|
if output == "BURN" then
|
||||||
|
fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]",
|
||||||
|
output_X,
|
||||||
|
iY + (sfinv_only and 2.68 or 2.18),
|
||||||
|
1.1,
|
||||||
|
1.1,
|
||||||
|
"craftguide_fire.png")
|
||||||
|
else
|
||||||
|
fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]",
|
||||||
|
output_X,
|
||||||
|
iY + (sfinv_only and 2.7 or 2.2),
|
||||||
|
BUTTON_SIZE,
|
||||||
|
BUTTON_SIZE,
|
||||||
|
output,
|
||||||
|
output_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
fs[#fs + 1] = get_tooltip(output_s)
|
||||||
|
|
||||||
|
local output_is_fuel = get_fueltime(output) > 0
|
||||||
|
if output_is_fuel then
|
||||||
|
fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]",
|
||||||
|
output_X + 1,
|
||||||
|
iY + (sfinv_only and 2.83 or 2.33),
|
||||||
|
0.6,
|
||||||
|
0.4,
|
||||||
|
"craftguide_arrow.png")
|
||||||
|
|
||||||
|
fs[#fs + 1] = fmt("image[%f,%f;%f,%f;%s]",
|
||||||
|
output_X + 1.6,
|
||||||
|
iY + (sfinv_only and 2.68 or 2.18),
|
||||||
|
0.6,
|
||||||
|
0.6,
|
||||||
|
"craftguide_fire.png")
|
||||||
|
end
|
||||||
|
|
||||||
|
return concat(fs)
|
||||||
end
|
end
|
||||||
|
|
||||||
function craftguide:get_formspec(player_name, is_fuel)
|
local function get_formspec(player_name)
|
||||||
local data = datas[player_name]
|
local data = datas[player_name]
|
||||||
local iY = sfinv_only and 4 or data.iX - 5
|
local iY = sfinv_only and 4 or data.iX - 5
|
||||||
local ipp = data.iX * iY
|
local ipp = data.iX * iY
|
||||||
@ -180,110 +353,95 @@ function craftguide:get_formspec(player_name, is_fuel)
|
|||||||
|
|
||||||
data.pagemax = max(1, ceil(#data.items / ipp))
|
data.pagemax = max(1, ceil(#data.items / ipp))
|
||||||
|
|
||||||
local formspec = ""
|
local fs = {}
|
||||||
if not sfinv_only then
|
if not sfinv_only then
|
||||||
formspec = formspec ..
|
fs[#fs + 1] = "size[" .. (data.iX - 0.35) .. "," .. (iY + 4) .. ";]"
|
||||||
"size[" .. (data.iX - 0.35) .. "," .. (iY + 4) .. ";]" ..
|
fs[#fs + 1] = "tooltip[size_inc;" .. S("Increase window size") .. "]"
|
||||||
"background[1,1;1,1;craftguide_bg.png;true]" ..
|
fs[#fs + 1] = "tooltip[size_dec;" .. S("Decrease window size") .. "]"
|
||||||
"tooltip[size_inc;" .. S("Increase window size") .. "]" ..
|
fs[#fs + 1] = "image_button[" .. (data.iX * 0.47) ..
|
||||||
"tooltip[size_dec;" .. S("Decrease window size") .. "]" ..
|
",0.12;0.8,0.8;craftguide_zoomin_icon.png;size_inc;]"
|
||||||
"button[" .. (data.iX * 0.48) .. ",-0.02;0.7,1;size_inc;+]" ..
|
fs[#fs + 1] = "image_button[" .. ((data.iX * 0.47) + 0.6) ..
|
||||||
"button[" .. ((data.iX * 0.48) + 0.5) .. ",-0.02;0.7,1;size_dec;-]"
|
",0.12;0.8,0.8;craftguide_zoomout_icon.png;size_dec;]"
|
||||||
end
|
end
|
||||||
|
|
||||||
formspec = formspec .. [[
|
fs[#fs + 1] = [[
|
||||||
button[2.4,0.23;0.8,0.5;search;?]
|
"background[1,1;1,1;craftguide_bg.png;true]"
|
||||||
button[3.05,0.23;0.8,0.5;clear;X]
|
image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;]
|
||||||
field_close_on_enter[filter;false]
|
image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;]
|
||||||
]] ..
|
field_close_on_enter[filter;false]
|
||||||
"tooltip[search;" .. S("Search") .. "]" ..
|
]]
|
||||||
"tooltip[clear;" .. S("Reset") .. "]" ..
|
|
||||||
"tooltip[prev;" .. S("Previous page") .. "]" ..
|
|
||||||
"tooltip[next;" .. S("Next page") .. "]" ..
|
|
||||||
"button[" .. (data.iX - 3.1) .. ",0;0.8,0.95;prev;<]" ..
|
|
||||||
"label[" .. (data.iX - 2.2) .. ",0.18;" ..
|
|
||||||
colorize(data.pagenum) .. " / " .. data.pagemax .. "]" ..
|
|
||||||
"button[" .. (data.iX - 1.2) .. ",0;0.8,0.95;next;>]" ..
|
|
||||||
"field[0.3,0.32;2.5,1;filter;;" .. mt.formspec_escape(data.filter) .. "]"
|
|
||||||
|
|
||||||
local even_num = data.iX % 2 == 0
|
fs[#fs + 1] = "tooltip[search;" .. S("Search") .. "]"
|
||||||
local xoffset = data.iX / 2 + (even_num and 0.5 or 0)
|
fs[#fs + 1] = "tooltip[clear;" .. S("Reset") .. "]"
|
||||||
|
fs[#fs + 1] = "tooltip[prev;" .. S("Previous page") .. "]"
|
||||||
|
fs[#fs + 1] = "tooltip[next;" .. S("Next page") .. "]"
|
||||||
|
fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 2.6 or 3.1)) ..
|
||||||
|
",0.12;0.8,0.8;craftguide_prev_icon.png;prev;]"
|
||||||
|
fs[#fs + 1] = "label[" .. (data.iX - (sfinv_only and 1.7 or 2.2)) ..
|
||||||
|
",0.22;" .. colorize(data.pagenum) .. " / " .. data.pagemax .. "]"
|
||||||
|
fs[#fs + 1] = "image_button[" .. (data.iX - (sfinv_only and 0.7 or 1.2) -
|
||||||
|
(data.iX >= 11 and 0.08 or 0)) ..
|
||||||
|
",0.12;0.8,0.8;craftguide_next_icon.png;next;]"
|
||||||
|
fs[#fs + 1] = "field[0.3,0.32;2.5,1;filter;;" .. mt.formspec_escape(data.filter) .. "]"
|
||||||
|
|
||||||
|
local xoffset = data.iX / 2.15
|
||||||
|
|
||||||
if not next(data.items) then
|
if not next(data.items) then
|
||||||
formspec = formspec ..
|
fs[#fs + 1] = fmt("label[%f,%f;%s]",
|
||||||
"label[" .. (xoffset - (even_num and 1.5 or 1)) .. ",2;" ..
|
(data.iX / 2) - 1,
|
||||||
S("No item to show") .. "]"
|
2,
|
||||||
|
S("No item to show"))
|
||||||
end
|
end
|
||||||
|
|
||||||
local first_item = (data.pagenum - 1) * ipp
|
local first_item = (data.pagenum - 1) * ipp
|
||||||
for i = first_item, first_item + ipp - 1 do
|
for i = first_item, first_item + ipp - 1 do
|
||||||
local name = data.items[i + 1]
|
local name = data.items[i + 1]
|
||||||
if not name then break end
|
if not name then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
local X = i % data.iX
|
local X = i % data.iX
|
||||||
local Y = (i % ipp - X) / data.iX + 1
|
local Y = (i % ipp - X) / data.iX + 1
|
||||||
|
|
||||||
formspec = formspec ..
|
fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;]",
|
||||||
"item_image_button[" .. (X - (X * 0.05)) .. "," .. Y .. ";1.1,1.1;" ..
|
X - (sfinv_only and 0 or (X * 0.05)),
|
||||||
name .. ";" .. name .. "_inv;]"
|
Y,
|
||||||
|
BUTTON_SIZE,
|
||||||
|
BUTTON_SIZE,
|
||||||
|
name,
|
||||||
|
name)
|
||||||
end
|
end
|
||||||
|
|
||||||
if data.item and reg_items[data.item] then
|
if data.input and reg_items[data.input] then
|
||||||
if not data.recipes_item or (is_fuel and not get_recipe(data.item).items) then
|
local usage = data.show_usage
|
||||||
formspec = formspec ..
|
fs[#fs + 1] = get_recipe_fs(data.iX,
|
||||||
"image[" .. (xoffset - 1) .. "," ..
|
iY,
|
||||||
(iY + (sfinv_only and 2.85 or 2.35)) ..
|
xoffset,
|
||||||
";0.9,0.7;craftguide_arrow.png]" ..
|
data.rnum,
|
||||||
"item_image_button[" .. xoffset .. "," ..
|
(usage and data.usages or data.recipes_item),
|
||||||
(iY + (sfinv_only and 2.7 or 2.2)) ..
|
usage)
|
||||||
";1,1;" .. data.item .. ";" .. data.item .. ";]" ..
|
|
||||||
self:get_tooltip(data.item) ..
|
|
||||||
"image[" .. (xoffset - 2) .. "," ..
|
|
||||||
(iY + (sfinv_only and 2.68 or 2.18)) ..
|
|
||||||
";1,1;craftguide_fire.png]"
|
|
||||||
else
|
|
||||||
local show_usage = data.show_usage
|
|
||||||
formspec = formspec ..
|
|
||||||
self:get_recipe(iY, xoffset,
|
|
||||||
data.rnum,
|
|
||||||
(show_usage and data.usages or data.recipes_item),
|
|
||||||
show_usage)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
data.formspec = formspec
|
fs = concat(fs)
|
||||||
|
data.formspec = fs
|
||||||
|
|
||||||
if sfinv_only then
|
if sfinv_only then
|
||||||
return formspec
|
return fs
|
||||||
else
|
else
|
||||||
show_formspec(player_name, "craftguide", formspec)
|
show_formspec(player_name, "craftguide", fs)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function player_has_item(T)
|
local show_fs = function(player, player_name)
|
||||||
for i = 1, #T do
|
if sfinv_only then
|
||||||
if T[i] then
|
local context = sfinv.get_or_create_context(player)
|
||||||
return true
|
sfinv.set_player_inventory_formspec(player, context)
|
||||||
end
|
else
|
||||||
|
get_formspec(player_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function group_to_items(group)
|
local function recipe_in_inv(inv, item_name, recipes_f)
|
||||||
local items_with_group, counter = {}, 0
|
|
||||||
for name, def in pairs(reg_items) do
|
|
||||||
if def.groups[group:sub(7)] then
|
|
||||||
counter = counter + 1
|
|
||||||
items_with_group[counter] = name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return items_with_group
|
|
||||||
end
|
|
||||||
|
|
||||||
local function item_in_inv(inv, item)
|
|
||||||
return inv:contains_item("main", item)
|
|
||||||
end
|
|
||||||
|
|
||||||
function craftguide:recipe_in_inv(inv, item_name, recipes_f)
|
|
||||||
local recipes = recipes_f or get_recipes(item_name) or {}
|
local recipes = recipes_f or get_recipes(item_name) or {}
|
||||||
local show_item_recipes = {}
|
local show_item_recipes = {}
|
||||||
|
|
||||||
@ -299,6 +457,7 @@ function craftguide:recipe_in_inv(inv, item_name, recipes_f)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not group_in_inv and not item_in_inv(inv, item) then
|
if not group_in_inv and not item_in_inv(inv, item) then
|
||||||
show_item_recipes[i] = false
|
show_item_recipes[i] = false
|
||||||
end
|
end
|
||||||
@ -311,28 +470,10 @@ function craftguide:recipe_in_inv(inv, item_name, recipes_f)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return recipes, player_has_item(show_item_recipes)
|
return recipes, in_table(show_item_recipes)
|
||||||
end
|
end
|
||||||
|
|
||||||
function craftguide:get_init_items()
|
local function get_filter_items(data, player)
|
||||||
local items_list, counter = {}, 0
|
|
||||||
for name, def in pairs(reg_items) do
|
|
||||||
local is_fuel = get_fueltime(name) > 0
|
|
||||||
if (not (def.groups.not_in_craft_guide == 1 or
|
|
||||||
def.groups.not_in_creative_inventory == 1)) and
|
|
||||||
(get_recipe(name).items or is_fuel) and
|
|
||||||
def.description and def.description ~= "" then
|
|
||||||
|
|
||||||
counter = counter + 1
|
|
||||||
items_list[counter] = name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
sort(items_list)
|
|
||||||
datas.init_items = items_list
|
|
||||||
end
|
|
||||||
|
|
||||||
function craftguide:get_filter_items(data, player)
|
|
||||||
local filter = data.filter
|
local filter = data.filter
|
||||||
if datas.searches[filter] then
|
if datas.searches[filter] then
|
||||||
data.items = datas.searches[filter]
|
data.items = datas.searches[filter]
|
||||||
@ -353,7 +494,7 @@ function craftguide:get_filter_items(data, player)
|
|||||||
filtered_list[counter] = item
|
filtered_list[counter] = item
|
||||||
end
|
end
|
||||||
elseif progressive_mode then
|
elseif progressive_mode then
|
||||||
local _, has_item = self:recipe_in_inv(inv, item)
|
local _, has_item = recipe_in_inv(inv, item)
|
||||||
if has_item then
|
if has_item then
|
||||||
counter = counter + 1
|
counter = counter + 1
|
||||||
filtered_list[counter] = item
|
filtered_list[counter] = item
|
||||||
@ -377,7 +518,73 @@ function craftguide:get_filter_items(data, player)
|
|||||||
data.items = filtered_list
|
data.items = filtered_list
|
||||||
end
|
end
|
||||||
|
|
||||||
function craftguide:get_item_usages(item)
|
local function init_datas(user, name)
|
||||||
|
datas[name] = {filter = "", pagenum = 1, iX = sfinv_only and 8 or DEFAULT_SIZE}
|
||||||
|
if progressive_mode then
|
||||||
|
get_filter_items(datas[name], user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function add_custom_recipes(item, recipes)
|
||||||
|
for j = 1, #craftguide.custom_crafts do
|
||||||
|
local craft = craftguide.custom_crafts[j]
|
||||||
|
if craft.output:match("%S*") == item then
|
||||||
|
recipes[#recipes + 1] = {
|
||||||
|
type = craft.type,
|
||||||
|
width = craft.width,
|
||||||
|
items = craft.items,
|
||||||
|
output = craft.output,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return recipes
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_init_items()
|
||||||
|
local items_list, c = {}, 0
|
||||||
|
local function list(name)
|
||||||
|
c = c + 1
|
||||||
|
items_list[c] = name
|
||||||
|
end
|
||||||
|
|
||||||
|
for name, def in pairs(reg_items) do
|
||||||
|
local is_fuel = get_fueltime(name) > 0
|
||||||
|
if (not (def.groups.not_in_craft_guide == 1 or
|
||||||
|
def.groups.not_in_creative_inventory == 1)) and
|
||||||
|
(get_recipe(name).items or is_fuel) and
|
||||||
|
def.description and def.description ~= "" then
|
||||||
|
list(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, #craftguide.custom_crafts do
|
||||||
|
local craft = craftguide.custom_crafts[i]
|
||||||
|
local output = craft.output:match("%S*")
|
||||||
|
local listed
|
||||||
|
|
||||||
|
for j = 1, #items_list do
|
||||||
|
local listed_item = items_list[j]
|
||||||
|
if output == listed_item then
|
||||||
|
listed = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not listed then
|
||||||
|
list(output)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sort(items_list)
|
||||||
|
datas.init_items = items_list
|
||||||
|
end
|
||||||
|
|
||||||
|
mt.register_on_mods_loaded(function()
|
||||||
|
get_init_items()
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function get_item_usages(item)
|
||||||
local usages = {}
|
local usages = {}
|
||||||
for name, def in pairs(reg_items) do
|
for name, def in pairs(reg_items) do
|
||||||
if not (def.groups.not_in_craft_guide == 1 or
|
if not (def.groups.not_in_craft_guide == 1 or
|
||||||
@ -414,101 +621,111 @@ local function get_fields(player, ...)
|
|||||||
formname, fields = args[1], args[2]
|
formname, fields = args[1], args[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
if not sfinv_only and formname ~= "craftguide" then return end
|
if not sfinv_only and formname ~= "craftguide" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
local data = datas[player_name]
|
local data = datas[player_name]
|
||||||
|
|
||||||
local show_fs = function(is_fuel)
|
|
||||||
if sfinv_only then
|
|
||||||
local context = sfinv.get_or_create_context(player)
|
|
||||||
context.fuel = is_fuel
|
|
||||||
sfinv.set_player_inventory_formspec(player, context)
|
|
||||||
else
|
|
||||||
craftguide:get_formspec(player_name, is_fuel)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.clear then
|
if fields.clear then
|
||||||
data.show_usage = nil
|
reset_datas(data)
|
||||||
data.filter = ""
|
show_fs(player, player_name)
|
||||||
data.item = nil
|
|
||||||
data.pagenum = 1
|
|
||||||
data.rnum = 1
|
|
||||||
|
|
||||||
data.items = progressive_mode and data.init_filter_items or datas.init_items
|
|
||||||
show_fs()
|
|
||||||
|
|
||||||
elseif fields.alternate then
|
elseif fields.alternate then
|
||||||
local num
|
if #(data.show_usage and data.usages or data.recipes_item) == 1 then
|
||||||
if data.show_usage then
|
return
|
||||||
num = data.usages[data.rnum + 1]
|
|
||||||
else
|
|
||||||
num = data.recipes_item[data.rnum + 1]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
data.rnum = num and data.rnum + 1 or 1
|
local next_i
|
||||||
show_fs()
|
if data.show_usage then
|
||||||
|
next_i = data.usages[data.rnum + 1]
|
||||||
|
else
|
||||||
|
next_i = data.recipes_item[data.rnum + 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
data.rnum = next_i and data.rnum + 1 or 1
|
||||||
|
show_fs(player, player_name)
|
||||||
|
|
||||||
elseif (fields.key_enter_field == "filter" or fields.search) and
|
elseif (fields.key_enter_field == "filter" or fields.search) and
|
||||||
fields.filter ~= "" then
|
fields.filter ~= "" then
|
||||||
data.filter = fields.filter:lower()
|
data.filter = fields.filter:lower()
|
||||||
data.pagenum = 1
|
data.pagenum = 1
|
||||||
craftguide:get_filter_items(data, player)
|
get_filter_items(data, player)
|
||||||
show_fs()
|
show_fs(player, player_name)
|
||||||
|
|
||||||
elseif fields.prev or fields.next then
|
elseif fields.prev or fields.next then
|
||||||
data.pagenum = data.pagenum - (fields.prev and 1 or -1)
|
data.pagenum = data.pagenum - (fields.prev and 1 or -1)
|
||||||
|
|
||||||
if data.pagenum > data.pagemax then
|
if data.pagenum > data.pagemax then
|
||||||
data.pagenum = 1
|
data.pagenum = 1
|
||||||
elseif data.pagenum == 0 then
|
elseif data.pagenum == 0 then
|
||||||
data.pagenum = data.pagemax
|
data.pagenum = data.pagemax
|
||||||
end
|
end
|
||||||
|
|
||||||
show_fs()
|
show_fs(player, player_name)
|
||||||
|
|
||||||
elseif (fields.size_inc and data.iX < MAX_LIMIT) or
|
elseif (fields.size_inc and data.iX < MAX_LIMIT) or
|
||||||
(fields.size_dec and data.iX > MIN_LIMIT) then
|
(fields.size_dec and data.iX > MIN_LIMIT) then
|
||||||
data.pagenum = 1
|
data.pagenum = 1
|
||||||
data.iX = data.iX - (fields.size_dec and 1 or -1)
|
data.iX = data.iX - (fields.size_dec and 1 or -1)
|
||||||
show_fs()
|
show_fs(player, player_name)
|
||||||
|
|
||||||
else for item in pairs(fields) do
|
else for item in pairs(fields) do
|
||||||
if item:find(":") then
|
if item:find(":") then
|
||||||
if item:sub(-4) == "_inv" then
|
if item:find("%s") then
|
||||||
item = item:sub(1,-5)
|
|
||||||
elseif item:find("%s") then
|
|
||||||
item = item:match("%S*")
|
item = item:match("%S*")
|
||||||
end
|
end
|
||||||
|
|
||||||
local is_fuel = get_fueltime(item) > 0
|
local is_fuel = get_fueltime(item) > 0
|
||||||
local recipes = get_recipes(item)
|
local recipes = get_recipes(item) or {}
|
||||||
if not recipes and not is_fuel then return end
|
recipes = add_custom_recipes(item, recipes)
|
||||||
|
|
||||||
if not data.show_usage and item == data.item and not progressive_mode then
|
local no_recipes = not next(recipes)
|
||||||
data.usages = craftguide:get_item_usages(item)
|
if no_recipes and not is_fuel then
|
||||||
if next(data.usages) then
|
return
|
||||||
data.show_usage = true
|
|
||||||
data.rnum = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
show_fs()
|
|
||||||
else
|
|
||||||
if progressive_mode then
|
|
||||||
local inv = player:get_inventory()
|
|
||||||
local _, has_item = craftguide:recipe_in_inv(inv, item)
|
|
||||||
|
|
||||||
if not has_item then return end
|
|
||||||
recipes = craftguide:recipe_in_inv(inv, item, recipes)
|
|
||||||
end
|
|
||||||
|
|
||||||
data.item = item
|
|
||||||
data.recipes_item = recipes
|
|
||||||
data.rnum = 1
|
|
||||||
data.show_usage = nil
|
|
||||||
|
|
||||||
show_fs(is_fuel)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if item ~= data.input then
|
||||||
|
data.show_usage = nil
|
||||||
|
else
|
||||||
|
data.show_usage = not data.show_usage
|
||||||
|
end
|
||||||
|
|
||||||
|
if not progressive_mode and is_fuel and no_recipes then
|
||||||
|
data.show_usage = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if data.show_usage then
|
||||||
|
data.usages = get_item_usages(item)
|
||||||
|
|
||||||
|
if is_fuel then
|
||||||
|
data.usages[#data.usages + 1] = {
|
||||||
|
width = 1,
|
||||||
|
type = "normal",
|
||||||
|
items = {item},
|
||||||
|
output = "BURN",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
if not next(data.usages) then
|
||||||
|
data.show_usage = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif progressive_mode then
|
||||||
|
local inv = player:get_inventory()
|
||||||
|
local has_item
|
||||||
|
recipes, has_item = recipe_in_inv(inv, item, recipes)
|
||||||
|
|
||||||
|
if not has_item then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
data.input = item
|
||||||
|
data.recipes_item = recipes
|
||||||
|
data.rnum = 1
|
||||||
|
|
||||||
|
show_fs(player, player_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -517,29 +734,25 @@ end
|
|||||||
if sfinv_only then
|
if sfinv_only then
|
||||||
sfinv.register_page("craftguide:craftguide", {
|
sfinv.register_page("craftguide:craftguide", {
|
||||||
title = "Craft Guide",
|
title = "Craft Guide",
|
||||||
|
|
||||||
get = function(self, player, context)
|
get = function(self, player, context)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
return sfinv.make_formspec(
|
return sfinv.make_formspec(
|
||||||
player,
|
player,
|
||||||
context,
|
context,
|
||||||
craftguide:get_formspec(player_name, context.fuel)
|
get_formspec(player_name)
|
||||||
)
|
)
|
||||||
end,
|
end,
|
||||||
on_enter = function(self, player, context)
|
|
||||||
if not datas.init_items then
|
|
||||||
craftguide:get_init_items()
|
|
||||||
end
|
|
||||||
|
|
||||||
|
on_enter = function(self, player, context)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
local data = datas[player_name]
|
local data = datas[player_name]
|
||||||
|
|
||||||
if progressive_mode or not data then
|
if progressive_mode or not data then
|
||||||
datas[player_name] = {filter = "", pagenum = 1, iX = 8}
|
init_datas(player, player_name)
|
||||||
if progressive_mode then
|
|
||||||
craftguide:get_filter_items(datas[player_name], player)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_player_receive_fields = function(self, player, context, fields)
|
on_player_receive_fields = function(self, player, context, fields)
|
||||||
get_fields(player, fields)
|
get_fields(player, fields)
|
||||||
end,
|
end,
|
||||||
@ -547,21 +760,13 @@ if sfinv_only then
|
|||||||
else
|
else
|
||||||
mt.register_on_player_receive_fields(get_fields)
|
mt.register_on_player_receive_fields(get_fields)
|
||||||
|
|
||||||
function craftguide:on_use(itemstack, user)
|
local function on_use(itemstack, user)
|
||||||
if not datas.init_items then
|
|
||||||
self:get_init_items()
|
|
||||||
end
|
|
||||||
|
|
||||||
local player_name = user:get_player_name()
|
local player_name = user:get_player_name()
|
||||||
local data = datas[player_name]
|
local data = datas[player_name]
|
||||||
|
|
||||||
if progressive_mode or not data then
|
if progressive_mode or not data then
|
||||||
datas[player_name] = {filter = "", pagenum = 1, iX = DEFAULT_SIZE}
|
init_datas(user, player_name)
|
||||||
if progressive_mode then
|
get_formspec(player_name)
|
||||||
self:get_filter_items(datas[player_name], user)
|
|
||||||
end
|
|
||||||
|
|
||||||
self:get_formspec(player_name)
|
|
||||||
else
|
else
|
||||||
show_formspec(player_name, "craftguide", data.formspec)
|
show_formspec(player_name, "craftguide", data.formspec)
|
||||||
end
|
end
|
||||||
@ -574,7 +779,7 @@ else
|
|||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
groups = {book = 1},
|
groups = {book = 1},
|
||||||
on_use = function(itemstack, user)
|
on_use = function(itemstack, user)
|
||||||
craftguide:on_use(itemstack, user)
|
on_use(itemstack, user)
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -594,12 +799,14 @@ else
|
|||||||
wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125},
|
wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125},
|
||||||
wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}
|
wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}
|
||||||
},
|
},
|
||||||
|
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = mt.get_meta(pos)
|
||||||
meta:set_string("infotext", S("Crafting Guide Sign"))
|
meta:set_string("infotext", S("Crafting Guide Sign"))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_rightclick = function(pos, node, user, itemstack)
|
on_rightclick = function(pos, node, user, itemstack)
|
||||||
craftguide:on_use(itemstack, user)
|
on_use(itemstack, user)
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -626,16 +833,81 @@ else
|
|||||||
recipe = "craftguide:sign",
|
recipe = "craftguide:sign",
|
||||||
burntime = 10
|
burntime = 10
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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"),
|
||||||
|
image = "craftguide_book.png",
|
||||||
|
action = function(player)
|
||||||
|
on_use(nil, player)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if rawget(_G, "sfinv_buttons") then
|
if not progressive_mode then
|
||||||
sfinv_buttons.register_button("craftguide", {
|
mt.register_chatcommand("craft", {
|
||||||
title = S("Crafting Guide"),
|
description = S("Show recipe(s) of the pointed node"),
|
||||||
tooltip = S("Shows a list of available crafting recipes, cooking recipes and fuels"),
|
func = function(name)
|
||||||
action = function(player)
|
local player = mt.get_player_by_name(name)
|
||||||
craftguide:on_use(nil, player)
|
local ppos = player:get_pos()
|
||||||
|
local dir = player:get_look_dir()
|
||||||
|
local eye_h = {x = ppos.x, y = ppos.y + 1.625, z = ppos.z}
|
||||||
|
local node_name
|
||||||
|
|
||||||
|
for i = 1, 10 do
|
||||||
|
local look_at = vector_add(eye_h, vector_mul(dir, i))
|
||||||
|
local node = mt.get_node(look_at)
|
||||||
|
|
||||||
|
if node.name ~= "air" then
|
||||||
|
node_name = node.name
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not node_name then
|
||||||
|
return false, colorize("[craftguide] ", "red") ..
|
||||||
|
S("No node pointed")
|
||||||
|
elseif not datas[name] then
|
||||||
|
init_datas(player, name)
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = datas[name]
|
||||||
|
reset_datas(data)
|
||||||
|
|
||||||
|
local is_fuel = get_fueltime(node_name) > 0
|
||||||
|
local recipes = get_recipes(node_name) or {}
|
||||||
|
recipes = add_custom_recipes(node_name, recipes)
|
||||||
|
local no_recipes = not next(recipes)
|
||||||
|
|
||||||
|
if no_recipes and not is_fuel then
|
||||||
|
return false, colorize("[craftguide] ", "red") ..
|
||||||
|
S("No recipe for this node:") .. " " ..
|
||||||
|
colorize(node_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_fuel and no_recipes then
|
||||||
|
data.usages = get_item_usages(node_name)
|
||||||
|
if is_fuel then
|
||||||
|
data.usages[#data.usages + 1] = {
|
||||||
|
width = 1,
|
||||||
|
type = "normal",
|
||||||
|
items = {node_name},
|
||||||
|
output = "BURN",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
if next(data.usages) then
|
||||||
|
data.show_usage = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
data.input = node_name
|
||||||
|
data.recipes_item = recipes
|
||||||
|
|
||||||
|
return true, show_fs(player, name)
|
||||||
end,
|
end,
|
||||||
image = "craftguide_book.png",
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 230 B |
BIN
textures/craftguide_clear_icon.png
Normal file
After Width: | Height: | Size: 708 B |
BIN
textures/craftguide_next_icon.png
Normal file
After Width: | Height: | Size: 727 B |
BIN
textures/craftguide_prev_icon.png
Normal file
After Width: | Height: | Size: 728 B |
BIN
textures/craftguide_search_icon.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 305 B |
BIN
textures/craftguide_zoomin_icon.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
textures/craftguide_zoomout_icon.png
Normal file
After Width: | Height: | Size: 2.9 KiB |