Done! export & craft recipes
465
init.lua
@ -58,7 +58,9 @@ local sprintf, find, gmatch, match, sub, split, upper, lower =
|
|||||||
string.sub, string.split, string.upper, string.lower
|
string.sub, string.split, string.upper, string.lower
|
||||||
|
|
||||||
local min, max, floor, ceil, abs = math.min, math.max, math.floor, math.ceil, math.abs
|
local min, max, floor, ceil, abs = math.min, math.max, math.floor, math.ceil, math.abs
|
||||||
local pairs, ipairs, next, type, setmetatable = pairs, ipairs, next, type, setmetatable
|
local pairs, ipairs, next, type, setmetatable, tonum =
|
||||||
|
pairs, ipairs, next, type, setmetatable, tonumber
|
||||||
|
|
||||||
local vec_add, vec_mul = vector.add, vector.multiply
|
local vec_add, vec_mul = vector.add, vector.multiply
|
||||||
|
|
||||||
local ROWS, _ROWS = 9
|
local ROWS, _ROWS = 9
|
||||||
@ -66,6 +68,7 @@ local LINES = 10
|
|||||||
local IPP = ROWS * LINES
|
local IPP = ROWS * LINES
|
||||||
local MAX_FAVS = 6
|
local MAX_FAVS = 6
|
||||||
local ITEM_BTN_SIZE = 1.1
|
local ITEM_BTN_SIZE = 1.1
|
||||||
|
local SPACING = 0
|
||||||
|
|
||||||
-- Progressive mode
|
-- Progressive mode
|
||||||
local POLL_FREQ = 0.25
|
local POLL_FREQ = 0.25
|
||||||
@ -106,6 +109,7 @@ local fs_elements = {
|
|||||||
model = "model[%f,%f;%f,%f;%s;%s;%s;0,0;true]",
|
model = "model[%f,%f;%f,%f;%s;%s;%s;0,0;true]",
|
||||||
image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]",
|
image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]",
|
||||||
animated_image = "animated_image[%f,%f;%f,%f;;%s;%u;%u]",
|
animated_image = "animated_image[%f,%f;%f,%f;;%s;%u;%u]",
|
||||||
|
scrollbar = "scrollbar[%f,%f;%f,%f;horizontal;%s;%u]",
|
||||||
item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]",
|
item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]",
|
||||||
arrow = "image_button[%f,%f;0.7,0.7;%s;%s;;;false;%s]",
|
arrow = "image_button[%f,%f;0.7,0.7;%s;%s;;;false;%s]",
|
||||||
}
|
}
|
||||||
@ -113,7 +117,6 @@ local fs_elements = {
|
|||||||
local styles = sprintf([[
|
local styles = sprintf([[
|
||||||
style_type[label,field;font_size=+0]
|
style_type[label,field;font_size=+0]
|
||||||
style_type[image_button;border=false;sound=craftguide_click]
|
style_type[image_button;border=false;sound=craftguide_click]
|
||||||
style_type[button;border=false;font=bold;font_size=+2;content_offset=0]
|
|
||||||
style_type[item_image_button;border=false;bgimg_hovered=%s;bgimg_pressed=%s;sound=craftguide_click]
|
style_type[item_image_button;border=false;bgimg_hovered=%s;bgimg_pressed=%s;sound=craftguide_click]
|
||||||
|
|
||||||
style[filter;border=false]
|
style[filter;border=false]
|
||||||
@ -125,6 +128,9 @@ local styles = sprintf([[
|
|||||||
style[next_recipe;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]
|
style[next_recipe;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]
|
||||||
style[prev_usage;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]
|
style[prev_usage;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]
|
||||||
style[next_usage;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]
|
style[next_usage;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]
|
||||||
|
style[pagenum,no_item,no_rcp;border=false;font=bold;font_size=+2;content_offset=0]
|
||||||
|
style[craft_rcp,craft_usg;border=false;noclip=true;font_size=+0;sound=craftguide_click;bgimg=craftguide_btn9.png;
|
||||||
|
bgimg_hovered=craftguide_btn9_hovered.png;bgimg_pressed=craftguide_btn9_pressed.png;bgimg_middle=4,6]
|
||||||
]],
|
]],
|
||||||
PNG.selected, PNG.selected,
|
PNG.selected, PNG.selected,
|
||||||
PNG.search, PNG.search_hover,
|
PNG.search, PNG.search_hover,
|
||||||
@ -791,6 +797,142 @@ local function groups_to_items(groups, get_all)
|
|||||||
return get_all and names or ""
|
return get_all and names or ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function get_stack_max(data, is_recipe, rcp)
|
||||||
|
local inv = data.player:get_inventory()
|
||||||
|
local list = inv:get_list("main")
|
||||||
|
local size = inv:get_size("main")
|
||||||
|
local counts_inv, counts_rcp, counts = {}, {}, {}
|
||||||
|
local rcp_usg = is_recipe and "recipe" or "usage"
|
||||||
|
|
||||||
|
for _, it in pairs(rcp.items) do
|
||||||
|
counts_rcp[it] = (counts_rcp[it] or 0) + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
data.export_counts[rcp_usg] = {}
|
||||||
|
data.export_counts[rcp_usg].rcp = counts_rcp
|
||||||
|
|
||||||
|
for i = 1, size do
|
||||||
|
local stack = list[i]
|
||||||
|
|
||||||
|
if not stack:is_empty() then
|
||||||
|
local item = stack:get_name()
|
||||||
|
local count = stack:get_count()
|
||||||
|
|
||||||
|
for name in pairs(counts_rcp) do
|
||||||
|
if is_group(name) then
|
||||||
|
local def = reg_items[item]
|
||||||
|
local groups = extract_groups(name)
|
||||||
|
|
||||||
|
if item_has_groups(def.groups, groups) then
|
||||||
|
counts_inv[name] = (counts_inv[name] or 0) + count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
counts_inv[item] = (counts_inv[item] or 0) + count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
data.export_counts[rcp_usg].inv = counts_inv
|
||||||
|
|
||||||
|
for name in pairs(counts_rcp) do
|
||||||
|
counts[name] = floor((counts_inv[name] or 0) / (counts_rcp[name] or 0))
|
||||||
|
end
|
||||||
|
|
||||||
|
local max_stacks = math.huge
|
||||||
|
|
||||||
|
for _, count in pairs(counts) do
|
||||||
|
if count < max_stacks then
|
||||||
|
max_stacks = count
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return max_stacks
|
||||||
|
end
|
||||||
|
|
||||||
|
local function craft_stack(player, pname, data, _f)
|
||||||
|
local inv = player:get_inventory()
|
||||||
|
local rcp_usg = _f.craft_rcp and "recipe" or "usage"
|
||||||
|
local output = _f.craft_rcp and
|
||||||
|
data.recipes[data.rnum].output or data.usages[data.unum].output
|
||||||
|
output = ItemStack(output)
|
||||||
|
local stackname, stackcount = output:get_name(), output:get_count()
|
||||||
|
local scrbar_val = data[sprintf("scrbar_%s", _f.craft_rcp and "rcp" or "usg")]
|
||||||
|
|
||||||
|
for name, count in pairs(data.export_counts[rcp_usg].rcp) do
|
||||||
|
if is_group(name) then
|
||||||
|
local groups = extract_groups(name)
|
||||||
|
local items = groups_to_items(groups, true)
|
||||||
|
|
||||||
|
for _, item in ipairs(items) do
|
||||||
|
for _name, _count in pairs(data.export_counts[rcp_usg].inv) do
|
||||||
|
if item == _name and _count >= count then
|
||||||
|
name = _name
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
inv:remove_item("main", sprintf("%s %s", name, count * scrbar_val))
|
||||||
|
end
|
||||||
|
|
||||||
|
local count = stackcount * scrbar_val
|
||||||
|
local stack = ItemStack(sprintf("%s %s", stackname, count))
|
||||||
|
local message = clr("#ff0", sprintf("%s x %s", count, stackname))
|
||||||
|
|
||||||
|
if inv:room_for_item("main", stack) then
|
||||||
|
inv:add_item("main", stack)
|
||||||
|
msg(pname, sprintf("%s added to your inventory!", message))
|
||||||
|
else
|
||||||
|
local dir = player:get_look_dir()
|
||||||
|
local ppos = player:get_pos()
|
||||||
|
ppos.y = ppos.y + 1.625
|
||||||
|
local look_at = vec_add(ppos, vec_mul(dir, 1))
|
||||||
|
|
||||||
|
core.add_item(look_at, stack)
|
||||||
|
msg(pname, sprintf("%s crafted!", message))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function show_recipes(player, data, _f)
|
||||||
|
local item
|
||||||
|
for field in pairs(_f) do
|
||||||
|
if find(field, ":") then
|
||||||
|
item = field
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not item then
|
||||||
|
return
|
||||||
|
elseif sub(item, -4) == "_inv" then
|
||||||
|
item = sub(item, 1, -5)
|
||||||
|
elseif sub(item, 1, 1) == "_" then
|
||||||
|
item = sub(item, 2)
|
||||||
|
elseif sub(item, 1, 6) == "group|" then
|
||||||
|
item = match(item, "([%w:_]+)$")
|
||||||
|
end
|
||||||
|
|
||||||
|
item = reg_aliases[item] or item
|
||||||
|
|
||||||
|
if item == data.query_item then return end
|
||||||
|
|
||||||
|
local recipes, usages = get_recipes(item, data, player)
|
||||||
|
if not recipes and not usages then return end
|
||||||
|
if data.show_usages and not usages then return end
|
||||||
|
|
||||||
|
data.query_item = item
|
||||||
|
data.recipes = recipes
|
||||||
|
data.usages = usages
|
||||||
|
data.rnum = 1
|
||||||
|
data.unum = 1
|
||||||
|
data.scrbar_rcp = 1
|
||||||
|
data.scrbar_usg = 1
|
||||||
|
data.export_rcp = nil
|
||||||
|
data.export_usg = nil
|
||||||
|
end
|
||||||
|
|
||||||
local function repairable(tool)
|
local function repairable(tool)
|
||||||
local def = reg_tools[tool]
|
local def = reg_tools[tool]
|
||||||
return toolrepair and def and def.groups and def.groups.disable_repair ~= 1
|
return toolrepair and def and def.groups and def.groups.disable_repair ~= 1
|
||||||
@ -927,7 +1069,7 @@ local function get_tooltip(item, info)
|
|||||||
return sprintf("tooltip[%s;%s]", item, ESC(tooltip))
|
return sprintf("tooltip[%s;%s]", item, ESC(tooltip))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_output_fs(fs, rcp, shapeless, right, btn_size, _btn_size, spacing)
|
local function get_output_fs(fs, rcp, shapeless, right, btn_size, _btn_size)
|
||||||
local custom_recipe = craft_types[rcp.type]
|
local custom_recipe = craft_types[rcp.type]
|
||||||
|
|
||||||
if custom_recipe or shapeless or rcp.type == "cooking" then
|
if custom_recipe or shapeless or rcp.type == "cooking" then
|
||||||
@ -939,7 +1081,7 @@ local function get_output_fs(fs, rcp, shapeless, right, btn_size, _btn_size, spa
|
|||||||
end
|
end
|
||||||
|
|
||||||
local pos_x = right + btn_size + 0.42
|
local pos_x = right + btn_size + 0.42
|
||||||
local pos_y = spacing + 0.9
|
local pos_y = SPACING + 0.9
|
||||||
|
|
||||||
if sub(icon, 1, 18) == "craftguide_furnace" then
|
if sub(icon, 1, 18) == "craftguide_furnace" then
|
||||||
fs(fmt("animated_image", pos_x, pos_y, 0.5, 0.5, PNG.furnace_anim, 8, 180))
|
fs(fmt("animated_image", pos_x, pos_y, 0.5, 0.5, PNG.furnace_anim, 8, 180))
|
||||||
@ -955,7 +1097,7 @@ local function get_output_fs(fs, rcp, shapeless, right, btn_size, _btn_size, spa
|
|||||||
|
|
||||||
local arrow_X = right + 0.2 + (_btn_size or ITEM_BTN_SIZE)
|
local arrow_X = right + 0.2 + (_btn_size or ITEM_BTN_SIZE)
|
||||||
local X = arrow_X + 1.2
|
local X = arrow_X + 1.2
|
||||||
local Y = spacing + 1.4
|
local Y = SPACING + 1.4
|
||||||
|
|
||||||
fs(fmt("image", arrow_X, Y + 0.06, 1, 1, PNG.arrow))
|
fs(fmt("image", arrow_X, Y + 0.06, 1, 1, PNG.arrow))
|
||||||
|
|
||||||
@ -994,7 +1136,7 @@ local function get_output_fs(fs, rcp, shapeless, right, btn_size, _btn_size, spa
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_grid_fs(fs, rcp, spacing)
|
local function get_grid_fs(fs, rcp)
|
||||||
local width = rcp.width or 1
|
local width = rcp.width or 1
|
||||||
local right, btn_size, _btn_size = 0, ITEM_BTN_SIZE
|
local right, btn_size, _btn_size = 0, ITEM_BTN_SIZE
|
||||||
local cooktime, shapeless
|
local cooktime, shapeless
|
||||||
@ -1023,7 +1165,7 @@ local function get_grid_fs(fs, rcp, spacing)
|
|||||||
X = X + (X * 0.2) + _ROWS + 3.9
|
X = X + (X * 0.2) + _ROWS + 3.9
|
||||||
|
|
||||||
local Y = ceil(i / width) - min(2, rows)
|
local Y = ceil(i / width) - min(2, rows)
|
||||||
Y = Y + (Y * 0.15) + spacing + 1.4
|
Y = Y + (Y * 0.15) + SPACING + 1.4
|
||||||
|
|
||||||
if large_recipe then
|
if large_recipe then
|
||||||
btn_size = (3 / width) * (3 / rows) + 0.3
|
btn_size = (3 / width) * (3 / rows) + 0.3
|
||||||
@ -1033,7 +1175,7 @@ local function get_grid_fs(fs, rcp, spacing)
|
|||||||
local yi = floor((i - 1) / width)
|
local yi = floor((i - 1) / width)
|
||||||
|
|
||||||
X = btn_size * xi + _ROWS + 0.3 + (xi * 0.05)
|
X = btn_size * xi + _ROWS + 0.3 + (xi * 0.05)
|
||||||
Y = btn_size * yi + spacing + 0.2 + (yi * 0.05)
|
Y = btn_size * yi + SPACING + 0.2 + (yi * 0.05)
|
||||||
end
|
end
|
||||||
|
|
||||||
if X > right then
|
if X > right then
|
||||||
@ -1104,10 +1246,10 @@ local function get_grid_fs(fs, rcp, spacing)
|
|||||||
fs("style_type[item_image_button;border=false]")
|
fs("style_type[item_image_button;border=false]")
|
||||||
end
|
end
|
||||||
|
|
||||||
get_output_fs(fs, rcp, shapeless, right, btn_size, _btn_size, spacing)
|
get_output_fs(fs, rcp, shapeless, right, btn_size, _btn_size)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_rcp_lbl(fs, data, panel, spacing, rn, is_recipe)
|
local function get_rcp_lbl(fs, data, panel, rn, is_recipe)
|
||||||
local lbl = ES("Usage @1 of @2", data.unum, rn)
|
local lbl = ES("Usage @1 of @2", data.unum, rn)
|
||||||
|
|
||||||
if is_recipe then
|
if is_recipe then
|
||||||
@ -1118,27 +1260,69 @@ local function get_rcp_lbl(fs, data, panel, spacing, rn, is_recipe)
|
|||||||
local lbl_len = #_lbl:gsub("[\128-\191]", "") -- Count chars, not bytes in UTF-8 strings
|
local lbl_len = #_lbl:gsub("[\128-\191]", "") -- Count chars, not bytes in UTF-8 strings
|
||||||
local shift = min(0.9, abs(12 - max(12, lbl_len)) * 0.15)
|
local shift = min(0.9, abs(12 - max(12, lbl_len)) * 0.15)
|
||||||
|
|
||||||
fs(fmt("label", _ROWS + 5.65 - shift, spacing + 3.37, lbl))
|
fs(fmt("label", _ROWS + 5.65 - shift, SPACING + 3.37, lbl))
|
||||||
|
|
||||||
if rn > 1 then
|
if rn > 1 then
|
||||||
local btn_suffix = is_recipe and "recipe" or "usage"
|
local btn_suffix = is_recipe and "recipe" or "usage"
|
||||||
local prev_name = sprintf("prev_%s", btn_suffix)
|
local prev_name = sprintf("prev_%s", btn_suffix)
|
||||||
local next_name = sprintf("next_%s", btn_suffix)
|
local next_name = sprintf("next_%s", btn_suffix)
|
||||||
local x_arrow = _ROWS + 4.9
|
local x_arrow = _ROWS + 4.9
|
||||||
local y_arrow = spacing + 3
|
local y_arrow = SPACING + 3
|
||||||
|
|
||||||
fs(fmt("arrow", x_arrow - shift, y_arrow, PNG.prev, prev_name, ""),
|
fs(fmt("arrow", x_arrow - shift, y_arrow, PNG.prev, prev_name, ""),
|
||||||
fmt("arrow", x_arrow + 2.3, y_arrow, PNG.next, next_name, ""))
|
fmt("arrow", x_arrow + 2.3, y_arrow, PNG.next, next_name, ""))
|
||||||
end
|
end
|
||||||
|
|
||||||
local rcp = is_recipe and panel.rcp[data.rnum] or panel.rcp[data.unum]
|
local rcp = is_recipe and panel.rcp[data.rnum] or panel.rcp[data.unum]
|
||||||
get_grid_fs(fs, rcp, spacing)
|
get_grid_fs(fs, rcp)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_title_fs(query_item, favs, lang_code, fs, spacing)
|
local function get_model_fs(fs, def, model_alias)
|
||||||
|
if model_alias then
|
||||||
|
if model_alias.drawtype == "entity" then
|
||||||
|
def = reg_entities[model_alias.name]
|
||||||
|
local init_props = def.initial_properties
|
||||||
|
def.textures = init_props and init_props.textures or def.textures
|
||||||
|
def.mesh = init_props and init_props.mesh or def.mesh
|
||||||
|
else
|
||||||
|
def = reg_items[model_alias.name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local tiles = def.tiles or def.textures or {}
|
||||||
|
local t = {}
|
||||||
|
|
||||||
|
for _, v in ipairs(tiles) do
|
||||||
|
local _name
|
||||||
|
|
||||||
|
if v.color then
|
||||||
|
local hex = sprintf("%02x", v.color)
|
||||||
|
|
||||||
|
while #hex < 8 do
|
||||||
|
hex = "0" .. hex
|
||||||
|
end
|
||||||
|
|
||||||
|
_name = sprintf("%s^[multiply:%s", v.name,
|
||||||
|
sprintf("#%s%s", sub(hex, 3), sub(hex, 1, 2)))
|
||||||
|
|
||||||
|
elseif v.animation then
|
||||||
|
_name = sprintf("%s^[verticalframe:%u:0", v.name, v.animation.aspect_h)
|
||||||
|
end
|
||||||
|
|
||||||
|
t[#t + 1] = _name or v.name or v
|
||||||
|
end
|
||||||
|
|
||||||
|
while #t < 6 do
|
||||||
|
t[#t + 1] = t[#t]
|
||||||
|
end
|
||||||
|
|
||||||
|
fs(fmt("model", _ROWS + 6.6, SPACING + 0.05, 1.3, 1.3, "", def.mesh, concat(t, ",")))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_title_fs(fs, query_item, favs, lang_code)
|
||||||
local fav = is_fav(favs, query_item)
|
local fav = is_fav(favs, query_item)
|
||||||
local nfavs = #favs
|
local nfavs = #favs
|
||||||
local star_x, star_y, star_size = _ROWS + 0.4, spacing + 0.5, 0.4
|
local star_x, star_y, star_size = _ROWS + 0.4, SPACING + 0.5, 0.4
|
||||||
|
|
||||||
if nfavs < MAX_FAVS or (nfavs == MAX_FAVS and fav) then
|
if nfavs < MAX_FAVS or (nfavs == MAX_FAVS and fav) then
|
||||||
local fav_marked = sprintf("craftguide_fav%s.png", fav and "_off" or "")
|
local fav_marked = sprintf("craftguide_fav%s.png", fav and "_off" or "")
|
||||||
@ -1156,62 +1340,97 @@ local function get_title_fs(query_item, favs, lang_code, fs, spacing)
|
|||||||
end
|
end
|
||||||
|
|
||||||
fs("style_type[label;font=bold;font_size=+6]",
|
fs("style_type[label;font=bold;font_size=+6]",
|
||||||
fmt("label", _ROWS + 1.05, spacing + 0.47, snip(ESC(get_desc(query_item, lang_code)), 32)),
|
fmt("label", _ROWS + 1.05, SPACING + 0.47, snip(ESC(get_desc(query_item, lang_code)), 32)),
|
||||||
"style_type[label;font=mono;font_size=+0]",
|
"style_type[label;font=mono;font_size=+0]",
|
||||||
fmt("label", _ROWS + 1.05, spacing + 0.97, clr("#7bf", snip(query_item, 34))),
|
fmt("label", _ROWS + 1.05, SPACING + 0.97, clr("#7bf", snip(query_item, 34))),
|
||||||
"style_type[label;font=normal]")
|
"style_type[label;font=normal]")
|
||||||
|
|
||||||
local def = reg_items[query_item]
|
local def = reg_items[query_item]
|
||||||
local model_alias = craftguide.model_alias[query_item]
|
local model_alias = craftguide.model_alias[query_item]
|
||||||
|
|
||||||
if def.drawtype == "mesh" or model_alias then
|
if def.drawtype == "mesh" or model_alias then
|
||||||
if model_alias then
|
get_model_fs(fs, def, model_alias)
|
||||||
if model_alias.drawtype == "entity" then
|
|
||||||
def = reg_entities[model_alias.name]
|
|
||||||
local init_props = def.initial_properties
|
|
||||||
def.textures = init_props and init_props.textures or def.textures
|
|
||||||
def.mesh = init_props and init_props.mesh or def.mesh
|
|
||||||
else
|
|
||||||
def = reg_items[model_alias.name]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local tiles = def.tiles or def.textures or {}
|
|
||||||
local t = {}
|
|
||||||
|
|
||||||
for _, v in ipairs(tiles) do
|
|
||||||
local _name
|
|
||||||
|
|
||||||
if v.color then
|
|
||||||
local hex = sprintf("%02x", v.color)
|
|
||||||
|
|
||||||
while #hex < 8 do
|
|
||||||
hex = "0" .. hex
|
|
||||||
end
|
|
||||||
|
|
||||||
_name = sprintf("%s^[multiply:%s", v.name,
|
|
||||||
sprintf("#%s%s", sub(hex, 3), sub(hex, 1, 2)))
|
|
||||||
|
|
||||||
elseif v.animation then
|
|
||||||
_name = sprintf("%s^[verticalframe:%u:0", v.name,
|
|
||||||
v.animation.aspect_h)
|
|
||||||
end
|
|
||||||
|
|
||||||
t[#t + 1] = _name or v.name or v
|
|
||||||
end
|
|
||||||
|
|
||||||
while #t < 6 do
|
|
||||||
t[#t + 1] = t[#t]
|
|
||||||
end
|
|
||||||
|
|
||||||
--fs("style_type[model;bgcolor=black]")
|
|
||||||
fs(fmt("model", _ROWS + 6.6, spacing + 0.05, 1.3, 1.3, "", def.mesh, concat(t, ",")))
|
|
||||||
else
|
else
|
||||||
fs(fmt("item_image", _ROWS + 6.8, spacing + 0.17, 1.1, 1.1, query_item))
|
fs(fmt("item_image", _ROWS + 6.8, SPACING + 0.17, 1.1, 1.1, query_item))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_panels(data, fs)
|
local function get_export_fs(fs, data, panel, is_recipe, is_usage, max_stacks_rcp, max_stacks_usg)
|
||||||
|
local name = is_recipe and "rcp" or "usg"
|
||||||
|
local show_export = (is_recipe and data.export_rcp) or (is_usage and data.export_usg)
|
||||||
|
|
||||||
|
fs(sprintf("style[export_%s;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]",
|
||||||
|
name, sprintf("craftguide_export%s.png", show_export and "" or "_off"),
|
||||||
|
"craftguide_export.png", "craftguide_export.png"),
|
||||||
|
fmt("image_button",
|
||||||
|
_ROWS + 7.35, SPACING + 0.2, 0.45, 0.45, "", sprintf("export_%s", name), ""),
|
||||||
|
sprintf("tooltip[export_%s;%s]", name, ES"Craft this item"))
|
||||||
|
|
||||||
|
if not show_export then return end
|
||||||
|
|
||||||
|
local item = (is_recipe and panel.rcp[data.rnum].output) or
|
||||||
|
(is_usage and panel.rcp[data.unum].output)
|
||||||
|
item = clean_name(item)
|
||||||
|
local _name = match(item, "%S*")
|
||||||
|
local stack = ItemStack(_name)
|
||||||
|
local stack_max = stack:get_stack_max()
|
||||||
|
local stack_fs = (is_recipe and data.scrbar_rcp) or (is_usage and data.scrbar_usg) or 1
|
||||||
|
|
||||||
|
fs(sprintf("style[scrbar_%s;noclip=true]", name),
|
||||||
|
sprintf("scrollbaroptions[min=1;max=%u;smallstep=1]",
|
||||||
|
min((is_recipe and max_stacks_rcp or max_stacks_usg), stack_max)),
|
||||||
|
fmt("scrollbar", _ROWS + 8.1, SPACING, 3, 0.35, sprintf("scrbar_%s", name), stack_fs),
|
||||||
|
fmt("button", _ROWS + 8.1, SPACING + 0.4, 3, 0.7, sprintf("craft_%s", name),
|
||||||
|
sprintf("%s", stack_fs == 1 and ES"Craft stack" or
|
||||||
|
sprintf(ES"Craft %u stacks", stack_fs))))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_rcp_extra(fs, data, panel, is_recipe, is_usage)
|
||||||
|
local rn = panel.rcp and #panel.rcp
|
||||||
|
|
||||||
|
if rn then
|
||||||
|
local rcp_normal = is_recipe and panel.rcp[data.rnum].type == "normal"
|
||||||
|
local usg_normal = is_usage and panel.rcp[data.unum].type == "normal"
|
||||||
|
local max_stacks_rcp, max_stacks_usg = 0, 0
|
||||||
|
|
||||||
|
if rcp_normal then
|
||||||
|
max_stacks_rcp = get_stack_max(data, is_recipe, panel.rcp[data.rnum])
|
||||||
|
end
|
||||||
|
|
||||||
|
if usg_normal then
|
||||||
|
max_stacks_usg = get_stack_max(data, is_recipe, panel.rcp[data.unum])
|
||||||
|
end
|
||||||
|
|
||||||
|
if max_stacks_rcp > 0 or max_stacks_usg > 0 then
|
||||||
|
get_export_fs(fs, data, panel, is_recipe, is_usage, max_stacks_rcp,
|
||||||
|
max_stacks_usg)
|
||||||
|
end
|
||||||
|
|
||||||
|
get_rcp_lbl(fs, data, panel, rn, is_recipe)
|
||||||
|
else
|
||||||
|
local lbl = is_recipe and ES"No recipes" or ES"No usages"
|
||||||
|
fs(fmt("button",
|
||||||
|
_ROWS + 0.1, SPACING + (panel.height / 2) - 0.5, 7.8, 1, "no_rcp", lbl))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_favs(fs, data)
|
||||||
|
fs(fmt("label", _ROWS + 0.4, SPACING + 0.4, ES"Bookmarks"))
|
||||||
|
|
||||||
|
for i = 1, #data.favs do
|
||||||
|
local item = data.favs[i]
|
||||||
|
local X = _ROWS - 0.7 + (i * 1.2)
|
||||||
|
local Y = SPACING + 0.8
|
||||||
|
|
||||||
|
if data.query_item == item then
|
||||||
|
fs(fmt("image", X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, PNG.selected))
|
||||||
|
end
|
||||||
|
|
||||||
|
fs(fmt("item_image_button", X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, item, item, ""))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_panels(fs, data)
|
||||||
local _title = {name = "title", height = 1.4}
|
local _title = {name = "title", height = 1.4}
|
||||||
local _favs = {name = "favs", height = 2.2}
|
local _favs = {name = "favs", height = 2.2}
|
||||||
local _recipes = {name = "recipes", rcp = data.recipes, height = 3.9}
|
local _recipes = {name = "recipes", rcp = data.recipes, height = 3.9}
|
||||||
@ -1219,48 +1438,25 @@ local function get_panels(data, fs)
|
|||||||
local panels = {_title, _recipes, _usages, _favs}
|
local panels = {_title, _recipes, _usages, _favs}
|
||||||
|
|
||||||
for idx = 1, #panels do
|
for idx = 1, #panels do
|
||||||
local panel, spacing = panels[idx], 0
|
local panel = panels[idx]
|
||||||
|
SPACING = 0
|
||||||
|
|
||||||
if idx > 1 then
|
if idx > 1 then
|
||||||
for _idx = idx - 1, 1, -1 do
|
for _idx = idx - 1, 1, -1 do
|
||||||
spacing = spacing + panels[_idx].height + 0.1
|
SPACING = SPACING + panels[_idx].height + 0.1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local rn = panel.rcp and #panel.rcp
|
fs(fmt("bg9", _ROWS + 0.1, SPACING, 7.9, panel.height, PNG.bg_full, 10))
|
||||||
local is_recipe = panel.name == "recipes"
|
|
||||||
local recipe_or_usage = panel.name == "recipes" or panel.name == "usages"
|
|
||||||
|
|
||||||
if rn then
|
local is_recipe, is_usage = panel.name == "recipes", panel.name == "usages"
|
||||||
get_rcp_lbl(fs, data, panel, spacing, rn, is_recipe)
|
|
||||||
end
|
|
||||||
|
|
||||||
fs(fmt("bg9", _ROWS + 0.1, spacing, 7.9, panel.height, PNG.bg_full, 10))
|
|
||||||
|
|
||||||
if recipe_or_usage and not rn then
|
|
||||||
local lbl = is_recipe and ES"No recipes" or ES"No usages"
|
|
||||||
fs(fmt("button",
|
|
||||||
_ROWS + 0.1, spacing + (panel.height / 2) - 0.5, 7.8, 1, "", lbl))
|
|
||||||
|
|
||||||
|
if is_recipe or is_usage then
|
||||||
|
get_rcp_extra(fs, data, panel, is_recipe, is_usage)
|
||||||
elseif panel.name == "title" then
|
elseif panel.name == "title" then
|
||||||
get_title_fs(data.query_item, data.favs, data.lang_code, fs, spacing)
|
get_title_fs(fs, data.query_item, data.favs, data.lang_code)
|
||||||
|
|
||||||
elseif panel.name == "favs" then
|
elseif panel.name == "favs" then
|
||||||
fs(fmt("label", _ROWS + 0.4, spacing + 0.4, ES"Bookmarks"))
|
get_favs(fs, data)
|
||||||
|
|
||||||
for i = 1, #data.favs do
|
|
||||||
local item = data.favs[i]
|
|
||||||
local X = _ROWS - 0.7 + (i * 1.2)
|
|
||||||
local Y = spacing + 0.8
|
|
||||||
|
|
||||||
if data.query_item == item then
|
|
||||||
fs(fmt("image",
|
|
||||||
X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, PNG.selected))
|
|
||||||
end
|
|
||||||
|
|
||||||
fs(fmt("item_image_button",
|
|
||||||
X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, item, item, ""))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1309,7 +1505,7 @@ local function make_fs(data)
|
|||||||
lbl = ES"Collect items to reveal more recipes"
|
lbl = ES"Collect items to reveal more recipes"
|
||||||
end
|
end
|
||||||
|
|
||||||
fs(fmt("button", 0, 3, _ROWS, 1, "", lbl))
|
fs(fmt("button", 0, 3, _ROWS, 1, "no_item", lbl))
|
||||||
end
|
end
|
||||||
|
|
||||||
local first_item = (data.pagenum - 1) * IPP
|
local first_item = (data.pagenum - 1) * IPP
|
||||||
@ -1332,7 +1528,7 @@ local function make_fs(data)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (data.recipes and #data.recipes > 0) or (data.usages and #data.usages > 0) then
|
if (data.recipes and #data.recipes > 0) or (data.usages and #data.usages > 0) then
|
||||||
get_panels(data, fs)
|
get_panels(fs, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
return concat(fs)
|
return concat(fs)
|
||||||
@ -1562,13 +1758,15 @@ local function init_data(name)
|
|||||||
local info = get_player_info(name)
|
local info = get_player_info(name)
|
||||||
|
|
||||||
pdata[name] = {
|
pdata[name] = {
|
||||||
filter = "",
|
filter = "",
|
||||||
pagenum = 1,
|
pagenum = 1,
|
||||||
items = init_items,
|
items = init_items,
|
||||||
items_raw = init_items,
|
items_raw = init_items,
|
||||||
favs = {},
|
favs = {},
|
||||||
lang_code = get_lang_code(info),
|
export_counts = {},
|
||||||
fs_version = get_formspec_version(info),
|
lang_code = get_lang_code(info),
|
||||||
|
fs_version = get_formspec_version(info),
|
||||||
|
player = get_player_by_name(name),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1577,10 +1775,14 @@ local function reset_data(data)
|
|||||||
data.pagenum = 1
|
data.pagenum = 1
|
||||||
data.rnum = 1
|
data.rnum = 1
|
||||||
data.unum = 1
|
data.unum = 1
|
||||||
|
data.scrbar_rcp = 1
|
||||||
|
data.scrbar_usg = 1
|
||||||
data.query_item = nil
|
data.query_item = nil
|
||||||
data.recipes = nil
|
data.recipes = nil
|
||||||
data.usages = nil
|
data.usages = nil
|
||||||
data.show_usages = nil
|
data.show_usages = nil
|
||||||
|
data.export_rcp = nil
|
||||||
|
data.export_usg = nil
|
||||||
data.items = data.items_raw
|
data.items = data.items_raw
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1601,16 +1803,23 @@ local function fields(player, _f)
|
|||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local data = pdata[name]
|
local data = pdata[name]
|
||||||
|
|
||||||
|
local scrbar_rcp_CHG = _f.scrbar_rcp and sub(_f.scrbar_rcp, 1, 3) == "CHG"
|
||||||
|
local scrbar_usg_CHG = _f.scrbar_usg and sub(_f.scrbar_usg, 1, 3) == "CHG"
|
||||||
|
|
||||||
if _f.clear then
|
if _f.clear then
|
||||||
reset_data(data)
|
reset_data(data)
|
||||||
|
|
||||||
elseif _f.prev_recipe or _f.next_recipe then
|
elseif _f.prev_recipe or _f.next_recipe then
|
||||||
local num = data.rnum + (_f.prev_recipe and -1 or 1)
|
local num = data.rnum + (_f.prev_recipe and -1 or 1)
|
||||||
data.rnum = data.recipes[num] and num or (_f.prev_recipe and #data.recipes or 1)
|
data.rnum = data.recipes[num] and num or (_f.prev_recipe and #data.recipes or 1)
|
||||||
|
data.export_rcp = nil
|
||||||
|
data.scrbar_rcp = 1
|
||||||
|
|
||||||
elseif _f.prev_usage or _f.next_usage then
|
elseif _f.prev_usage or _f.next_usage then
|
||||||
local num = data.unum + (_f.prev_usage and -1 or 1)
|
local num = data.unum + (_f.prev_usage and -1 or 1)
|
||||||
data.unum = data.usages[num] and num or (_f.prev_usage and #data.usages or 1)
|
data.unum = data.usages[num] and num or (_f.prev_usage and #data.usages or 1)
|
||||||
|
data.export_usg = nil
|
||||||
|
data.scrbar_usg = 1
|
||||||
|
|
||||||
elseif _f.key_enter_field == "filter" or _f.search then
|
elseif _f.key_enter_field == "filter" or _f.search then
|
||||||
if _f.filter == "" then
|
if _f.filter == "" then
|
||||||
@ -1623,6 +1832,7 @@ local function fields(player, _f)
|
|||||||
|
|
||||||
data.filter = str
|
data.filter = str
|
||||||
data.pagenum = 1
|
data.pagenum = 1
|
||||||
|
|
||||||
search(data)
|
search(data)
|
||||||
|
|
||||||
elseif _f.prev_page or _f.next_page then
|
elseif _f.prev_page or _f.next_page then
|
||||||
@ -1644,38 +1854,22 @@ local function fields(player, _f)
|
|||||||
elseif fav then
|
elseif fav then
|
||||||
remove(data.favs, i)
|
remove(data.favs, i)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
elseif _f.export_rcp or _f.export_usg then
|
||||||
|
if _f.export_rcp then
|
||||||
|
data.export_rcp = not data.export_rcp
|
||||||
|
else
|
||||||
|
data.export_usg = not data.export_usg
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif scrbar_rcp_CHG or scrbar_usg_CHG then
|
||||||
|
data.scrbar_rcp = _f.scrbar_rcp and tonum(match(_f.scrbar_rcp, "%d+"))
|
||||||
|
data.scrbar_usg = _f.scrbar_usg and tonum(match(_f.scrbar_usg, "%d+"))
|
||||||
|
|
||||||
|
elseif _f.craft_rcp or _f.craft_usg then
|
||||||
|
craft_stack(player, name, data, _f)
|
||||||
else
|
else
|
||||||
local item
|
show_recipes(player, data, _f)
|
||||||
for field in pairs(_f) do
|
|
||||||
if find(field, ":") then
|
|
||||||
item = field
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not item then
|
|
||||||
return
|
|
||||||
elseif sub(item, -4) == "_inv" then
|
|
||||||
item = sub(item, 1, -5)
|
|
||||||
elseif sub(item, 1, 1) == "_" then
|
|
||||||
item = sub(item, 2)
|
|
||||||
elseif sub(item, 1, 6) == "group|" then
|
|
||||||
item = match(item, "([%w:_]+)$")
|
|
||||||
end
|
|
||||||
|
|
||||||
item = reg_aliases[item] or item
|
|
||||||
|
|
||||||
if item == data.query_item then return end
|
|
||||||
|
|
||||||
local recipes, usages = get_recipes(item, data, player)
|
|
||||||
if not recipes and not usages then return end
|
|
||||||
if data.show_usages and not usages then return end
|
|
||||||
|
|
||||||
data.query_item = item
|
|
||||||
data.recipes = recipes
|
|
||||||
data.usages = usages
|
|
||||||
data.rnum = 1
|
|
||||||
data.unum = 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return true, show_fs(player, name)
|
return true, show_fs(player, name)
|
||||||
@ -1780,8 +1974,7 @@ if progressive_mode then
|
|||||||
local def = reg_items[inv_items[i]]
|
local def = reg_items[inv_items[i]]
|
||||||
|
|
||||||
if def then
|
if def then
|
||||||
local item_groups = def.groups
|
if item_has_groups(def.groups, groups) then
|
||||||
if item_has_groups(item_groups, groups) then
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1795,8 +1988,8 @@ if progressive_mode then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function recipe_in_inv(recipe, inv_items)
|
local function recipe_in_inv(rcp, inv_items)
|
||||||
for _, item in pairs(recipe.items) do
|
for _, item in pairs(rcp.items) do
|
||||||
if not item_in_inv(item, inv_items) then return end
|
if not item_in_inv(item, inv_items) then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
BIN
textures/craftguide_btn9.png
Normal file
After Width: | Height: | Size: 146 B |
BIN
textures/craftguide_btn9_hovered.png
Normal file
After Width: | Height: | Size: 146 B |
BIN
textures/craftguide_btn9_pressed.png
Normal file
After Width: | Height: | Size: 146 B |
BIN
textures/craftguide_export.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
textures/craftguide_export_off.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.1 KiB |