Progresive mod conflict resolved

This commit is contained in:
Daretmavi
2021-07-01 10:26:38 +02:00
13 changed files with 795 additions and 340 deletions

598
init.lua
View File

@ -1,12 +1,12 @@
i3 = {}
local modpath = core.get_modpath "i3"
local storage = core.get_mod_storage()
local slz, dslz = core.serialize, core.deserialize
local pdata = dslz(storage:get_string "pdata") or {}
-- Caches
local init_items = {}
local searches = {}
local recipes_cache = {}
local usages_cache = {}
local fuel_cache = {}
@ -15,7 +15,13 @@ local toolrepair
local tabs = {}
local model_aliases = loadfile(modpath .. "/etc/model_aliases.lua")()
local PNG, styles, fs_elements = loadfile(modpath .. "/etc/styles.lua")()
local compress_groups, compressed = loadfile(modpath .. "/etc/compress.lua")()
local group_stereotypes, group_names = loadfile(modpath .. "/etc/groups.lua")()
local progressive_mode = core.settings:get_bool "i3_progressive_mode" and not(core.is_creative_enabled())
local item_compression = core.settings:get_bool "i3_item_compression"
local damage_enabled = core.settings:get_bool "enable_damage"
local __3darmor, __skinsdb, __awards
@ -25,6 +31,9 @@ local __unified_inventory, old_unified_inventory_fn
local http = core.request_http_api()
local singleplayer = core.is_singleplayer()
local after = core.after
local clr = core.colorize
local reg_items = core.registered_items
local reg_nodes = core.registered_nodes
local reg_craftitems = core.registered_craftitems
@ -32,29 +41,9 @@ local reg_tools = core.registered_tools
local reg_entities = core.registered_entities
local reg_aliases = core.registered_aliases
local log = core.log
local after = core.after
local clr = core.colorize
local parse_json = core.parse_json
local write_json = core.write_json
local get_inv = core.get_inventory
local chat_send = core.chat_send_player
local show_formspec = core.show_formspec
local pos_to_string = core.pos_to_string
local check_privs = core.check_player_privs
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 translate = minetest.get_translated_string
local on_joinplayer = core.register_on_joinplayer
local get_all_recipes = core.get_all_craft_recipes
local on_leaveplayer = core.register_on_leaveplayer
local on_mods_loaded = core.register_on_mods_loaded
local get_player_info = core.get_player_information
local translate = core.get_translated_string
local create_inventory = core.create_detached_inventory
local on_receive_fields = core.register_on_player_receive_fields
local ESC = core.formspec_escape
local S = core.get_translator "i3"
@ -109,117 +98,6 @@ local SUBCAT = {
"waypoints",
}
local PNG = {
bg = "i3_bg.png",
bg_full = "i3_bg_full.png",
bar = "i3_bar.png",
hotbar = "i3_hotbar.png",
search = "i3_search.png",
heart = "i3_heart.png",
heart_half = "i3_heart_half.png",
heart_grey = "i3_heart_grey.png",
prev = "i3_next.png^\\[transformFX",
next = "i3_next.png",
arrow = "i3_arrow.png",
trash = "i3_trash.png",
sort_az = "i3_sort_az.png",
sort_za = "i3_sort_za.png",
compress = "i3_compress.png",
fire = "i3_fire.png",
fire_anim = "i3_fire_anim.png",
book = "i3_book.png",
sign = "i3_sign.png",
cancel = "i3_cancel.png",
export = "i3_export.png",
slot = "i3_slot.png",
tab = "i3_tab.png",
tab_top = "i3_tab.png^\\[transformFY",
furnace_anim = "i3_furnace_anim.png",
bag = "i3_bag.png",
armor = "i3_armor.png",
awards = "i3_award.png",
skins = "i3_skin.png",
waypoints = "i3_waypoint.png",
teleport = "i3_teleport.png",
add = "i3_add.png",
refresh = "i3_refresh.png",
visible = "i3_visible.png^\\[brighten",
nonvisible = "i3_non_visible.png",
exit = "i3_exit.png",
cancel_hover = "i3_cancel.png^\\[brighten",
search_hover = "i3_search.png^\\[brighten",
export_hover = "i3_export.png^\\[brighten",
trash_hover = "i3_trash.png^\\[brighten^\\[colorize:#f00:100",
compress_hover = "i3_compress.png^\\[brighten",
sort_az_hover = "i3_sort_az.png^\\[brighten",
sort_za_hover = "i3_sort_za.png^\\[brighten",
prev_hover = "i3_next_hover.png^\\[transformFX",
next_hover = "i3_next_hover.png",
tab_hover = "i3_tab_hover.png",
tab_hover_top = "i3_tab_hover.png^\\[transformFY",
bag_hover = "i3_bag_hover.png",
armor_hover = "i3_armor_hover.png",
awards_hover = "i3_award_hover.png",
skins_hover = "i3_skin_hover.png",
waypoints_hover = "i3_waypoint_hover.png",
teleport_hover = "i3_teleport.png^\\[brighten",
add_hover = "i3_add.png^\\[brighten",
refresh_hover = "i3_refresh.png^\\[brighten",
exit_hover = "i3_exit.png^\\[brighten",
}
local fs_elements = {
label = "label[%f,%f;%s]",
box = "box[%f,%f;%f,%f;%s]",
image = "image[%f,%f;%f,%f;%s]",
tooltip = "tooltip[%f,%f;%f,%f;%s]",
button = "button[%f,%f;%f,%f;%s;%s]",
item_image = "item_image[%f,%f;%f,%f;%s]",
hypertext = "hypertext[%f,%f;%f,%f;%s;%s]",
bg9 = "background9[%f,%f;%f,%f;%s;false;%u]",
scrollbar = "scrollbar[%f,%f;%f,%f;%s;%s;%u]",
model = "model[%f,%f;%f,%f;%s;%s;%s;%s;%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]",
item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]",
}
local styles = sprintf([[
style_type[field;border=false;bgcolor=transparent]
style_type[label,field;font_size=16]
style_type[button;border=false;content_offset=0]
style_type[image_button,item_image_button;border=false;sound=i3_click]
style_type[item_image_button;bgimg_hovered=%s]
style[pagenum,no_item,no_rcp;font=bold;font_size=18]
style[exit;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[cancel;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[search;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[prev_page;fgimg=%s;fgimg_hovered=%s]
style[next_page;fgimg=%s;fgimg_hovered=%s]
style[prev_recipe;fgimg=%s;fgimg_hovered=%s]
style[next_recipe;fgimg=%s;fgimg_hovered=%s]
style[prev_usage;fgimg=%s;fgimg_hovered=%s]
style[next_usage;fgimg=%s;fgimg_hovered=%s]
style[waypoint_add;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[btn_bag,btn_armor,btn_skins;font=bold;font_size=18;content_offset=0;sound=i3_click]
style[craft_rcp,craft_usg;noclip=true;font_size=16;sound=i3_craft;
bgimg=i3_btn9.png;bgimg_hovered=i3_btn9_hovered.png;
bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6]
]],
PNG.slot,
PNG.exit, PNG.exit_hover,
PNG.cancel, PNG.cancel_hover,
PNG.search, PNG.search_hover,
PNG.prev, PNG.prev_hover,
PNG.next, PNG.next_hover,
PNG.prev, PNG.prev_hover,
PNG.next, PNG.next_hover,
PNG.prev, PNG.prev_hover,
PNG.next, PNG.next_hover,
PNG.add, PNG.add_hover)
local function get_lang_code(info)
return info and info.lang_code
end
@ -233,92 +111,25 @@ local function outdated(name)
PNG.book,
"Your Minetest client is outdated.\nGet the latest version on minetest.net to use i3")
show_formspec(name, "i3", fs)
core.show_formspec(name, "i3", fs)
end
local old_is_creative_enabled = core.is_creative_enabled
function core.is_creative_enabled(name)
if name == "" then
return old_is_creative_enabled(name)
end
return check_privs(name, {creative = true}) or old_is_creative_enabled(name)
end
i3.group_stereotypes = {
dye = "dye:white",
wool = "wool:white",
wood = "default:wood",
tree = "default:tree",
sand = "default:sand",
glass = "default:glass",
stick = "default:stick",
stone = "default:stone",
leaves = "default:leaves",
coal = "default:coal_lump",
vessel = "vessels:glass_bottle",
flower = "flowers:dandelion_yellow",
water_bucket = "bucket:bucket_water",
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
}
local group_names = {
dye = S"Any dye",
coal = S"Any coal",
sand = S"Any sand",
tree = S"Any tree",
wool = S"Any wool",
glass = S"Any glass",
stick = S"Any stick",
stone = S"Any stone",
carpet = S"Any carpet",
flower = S"Any flower",
leaves = S"Any leaves",
vessel = S"Any vessel",
wood = S"Any wood planks",
mushroom = S"Any mushroom",
["color_red,flower"] = S"Any red flower",
["color_blue,flower"] = S"Any blue flower",
["color_black,flower"] = S"Any black flower",
["color_white,flower"] = S"Any white flower",
["color_green,flower"] = S"Any green flower",
["color_orange,flower"] = S"Any orange flower",
["color_yellow,flower"] = S"Any yellow flower",
["color_violet,flower"] = S"Any violet flower",
["color_red,dye"] = S"Any red dye",
["color_blue,dye"] = S"Any blue dye",
["color_grey,dye"] = S"Any grey dye",
["color_pink,dye"] = S"Any pink dye",
["color_cyan,dye"] = S"Any cyan dye",
["color_black,dye"] = S"Any black dye",
["color_white,dye"] = S"Any white dye",
["color_brown,dye"] = S"Any brown dye",
["color_green,dye"] = S"Any green dye",
["color_orange,dye"] = S"Any orange dye",
["color_yellow,dye"] = S"Any yellow dye",
["color_violet,dye"] = S"Any violet dye",
["color_magenta,dye"] = S"Any magenta dye",
["color_dark_grey,dye"] = S"Any dark grey dye",
["color_dark_green,dye"] = S"Any dark green dye",
}
i3.model_alias = {
["boats:boat"] = {name = "boats:boat", drawtype = "entity"},
["carts:cart"] = {name = "carts:cart", drawtype = "entity", frames = "0,0"},
["default:chest"] = {name = "default:chest_open"},
["default:chest_locked"] = {name = "default:chest_locked_open"},
["doors:door_wood"] = {name = "doors:door_wood_a"},
["doors:door_glass"] = {name = "doors:door_glass_a"},
["doors:door_obsidian_glass"] = {name = "doors:door_obsidian_glass_a"},
["doors:door_steel"] = {name = "doors:door_steel_a"},
["xpanes:door_steel_bar"] = {name = "xpanes:door_steel_bar_a"},
}
local function err(str)
return log("error", str)
return core.log("error", str)
end
local function msg(name, str)
return chat_send(name, sprintf("[i3] %s", str))
return core.chat_send_player(name, sprintf("[i3] %s", str))
end
local function is_num(x)
@ -354,7 +165,7 @@ local function fmt(elem, ...)
end
local function clean_name(item)
if sub(item, 1, 1) == ":" or sub(item, 1, 1) == " " then
if sub(item, 1, 1) == ":" or sub(item, 1, 1) == " " or sub(item, 1, 1) == "_" then
item = sub(item, 2)
end
@ -500,7 +311,7 @@ function i3.register_craft(def)
http.fetch({url = def.url}, function(result)
if result.succeeded then
local t = parse_json(result.data)
local t = core.parse_json(result.data)
if is_table(t) then
return i3.register_craft(t)
end
@ -615,7 +426,7 @@ function i3.set_recipe_filter(name, f)
recipe_filters = {[name] = f}
end
function i3.delete_recipe_filter(name)
function i3.remove_recipe_filter(name)
recipe_filters[name] = nil
end
@ -651,6 +462,14 @@ function i3.get_search_filters()
return search_filters
end
local function compression_active(data)
return item_compression and not next(recipe_filters) and data.filter == ""
end
local function compressible(item, data)
return compression_active(data) and compress_groups[item]
end
local function weird_desc(str)
return not true_str(str) or find(str, "\n") or not find(str, "%u")
end
@ -734,7 +553,7 @@ local function get_filtered_items(player, data)
end
local function get_burntime(item)
return get_craft_result{method = "fuel", items = {item}}.time
return core.get_craft_result{method = "fuel", items = {item}}.time
end
local function cache_fuel(item)
@ -754,19 +573,22 @@ local function show_item(def)
def.description and def.description ~= ""
end
local function reset_compression(data)
data.alt_items = nil
data.expand = ""
end
local function search(data)
reset_compression(data)
local filter = data.filter
if searches[filter] then
data.items = searches[filter]
return
end
local opt = "^(.-)%+([%w_]+)=([%w_,]+)"
local search_filter = next(search_filters) and match(filter, opt)
local filters = {}
if search_filter then
search_filter = search_filter:trim()
for filter_name, values in gmatch(filter, sub(opt, 6)) do
if search_filters[filter_name] then
values = split(values, ",")
@ -800,7 +622,18 @@ local function search(data)
end
end
else
to_add = find(search_in, filter, 1, true)
local ok = true
for keyword in gmatch(filter, "%S+") do
if not find(search_in, keyword, 1, true) then
ok = nil
break
end
end
if ok then
to_add = true
end
end
if to_add then
@ -809,16 +642,36 @@ local function search(data)
end
end
if not next(recipe_filters) then
-- Cache the results only if searched 2 times
if searches[filter] == nil then
searches[filter] = false
else
searches[filter] = filtered_list
data.items = filtered_list
end
local function sort_by_category(data)
reset_compression(data)
local items = data.items_raw
if data.filter ~= "" then
search(data)
items = data.items
end
local new = {}
for i = 1, #items do
local item = items[i]
local to_add = true
if data.current_itab == 2 then
to_add = reg_nodes[item]
elseif data.current_itab == 3 then
to_add = reg_craftitems[item] or reg_tools[item]
end
if to_add then
new[#new + 1] = item
end
end
data.items = filtered_list
data.items = new
end
local function get_item_usages(item, recipe, added)
@ -923,7 +776,7 @@ local function cache_drops(name, drop)
end
local function cache_recipes(item)
local recipes = get_all_recipes(item)
local recipes = core.get_all_craft_recipes(item)
if replacements[item] then
local _recipes = {}
@ -978,15 +831,16 @@ end
local function groups_to_items(groups, get_all)
if not get_all and #groups == 1 then
local group = groups[1]
local stereotype = i3.group_stereotypes[group]
local stereotype = group_stereotypes[group]
local def = reg_items[stereotype]
if def and show_item(def) then
if show_item(def) then
return stereotype
end
end
local names = {}
for name, def in pairs(reg_items) do
if show_item(def) and item_has_groups(def.groups, groups) then
if get_all then
@ -1241,36 +1095,84 @@ local function select_item(player, name, data, _f)
end
end
if not item then
return
elseif sub(item, 1, 1) == "_" then
item = sub(item, 2)
elseif sub(item, 1, 6) == "group|" then
item = match(item, "([%w:_]+)$")
if not item then return end
if compressible(item, data) then
local idx
for i = 1, #data.items do
local it = data.items[i]
if it == item then
idx = i
break
end
end
if data.expand ~= "" then
data.alt_items = nil
if item == data.expand then
data.expand = nil
return
end
end
if idx and item ~= data.expand then
data.alt_items = copy(data.items)
data.expand = item
if compress_groups[item] then
local items = copy(compress_groups[item])
insert(items, fmt("_%s", item))
sort(items, function(a, b)
if a:sub(1, 1) == "_" then
a = a:sub(2)
end
return a < b
end)
local i = 1
for _, v in ipairs(items) do
if show_item(reg_items[clean_name(v)]) then
insert(data.alt_items, idx + i, v)
i = i + 1
end
end
end
end
else
if 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 not reg_items[item] then return end
if core.is_creative_enabled(name) then
local stack = ItemStack(item)
local stackmax = stack:get_stack_max()
stack = fmt("%s %s", item, stackmax)
return get_stack(player, stack, clr("#ff0", fmt("%u x %s", stackmax, get_desc(item))))
end
if item == data.query_item then return end
local recipes, usages = get_recipes(player, item)
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
item = reg_aliases[item] or item
if not reg_items[item] then return end
if core.is_creative_enabled(name) then
local stack = ItemStack(item)
local stackmax = stack:get_stack_max()
stack = fmt("%s %s", item, stackmax)
return get_stack(player, stack, clr("#ff0", fmt("%u x %s", stackmax, get_desc(item))))
end
if item == data.query_item then return end
local recipes, usages = get_recipes(player, item)
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)
@ -1421,7 +1323,11 @@ local function get_output_fs(fs, data, rcp, is_recipe, shapeless, right, btn_siz
fs(fmt("list[detached:i3_output_%s;main;%f,%f;1,1;]", rcp_usg, X + 0.11, Y))
fs("button", X + 0.11, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, _name, "")
local inv = get_inv {type = "detached", name = fmt("i3_output_%s", rcp_usg)}
local inv = core.get_inventory {
type = "detached",
name = fmt("i3_output_%s", rcp_usg)
}
inv:set_stack("main", 1, item)
pos = {x = X + 0.11, y = Y}
else
@ -1708,7 +1614,7 @@ local function get_header(fs, data)
fs("style_type[label;font=normal;font_size=16]")
local def = reg_items[data.query_item]
local model_alias = i3.model_alias[data.query_item]
local model_alias = model_aliases[data.query_item]
if def.drawtype == "mesh" or model_alias then
get_model_fs(fs, data, def, model_alias)
@ -1788,9 +1694,22 @@ local function get_rcp_extra(player, fs, data, panel, is_recipe, is_usage)
fs("container_end[]")
end
local function get_items_fs(fs, data, extend)
local rows = 8
local lines = extend and 12 or 9
local function get_items_fs(fs, data, full_height)
if compression_active(data) then
local new = {}
for i = 1, #data.items do
local item = data.items[i]
if not compressed[item] then
new[#new + 1] = item
end
end
data.items = new
end
local items = data.alt_items or data.items
local rows, lines = 8, 12
local ipp = rows * lines
local size = 0.85
@ -1799,17 +1718,17 @@ local function get_items_fs(fs, data, extend)
fmt("field[%f,0.2;2.95,0.6;filter;;%s]", data.inv_width + 0.35, ESC(data.filter)),
"field_close_on_enter[filter;false]")
fs("image_button", data.inv_width + 3.35, 0.35, 0.3, 0.3, "", "cancel", "")
fs("image_button", data.inv_width + 3.35, 0.35, 0.3, 0.3, "", "cancel", "")
fs("image_button", data.inv_width + 3.85, 0.32, 0.35, 0.35, "", "search", "")
fs("image_button", data.inv_width + 5.27, 0.3, 0.35, 0.35, "", "prev_page", "")
fs("image_button", data.inv_width + 7.45, 0.3, 0.35, 0.35, "", "next_page", "")
fs("image_button", data.inv_width + 5.27, 0.3, 0.35, 0.35, "", "prev_page", "")
fs("image_button", data.inv_width + 7.45, 0.3, 0.35, 0.35, "", "next_page", "")
data.pagemax = max(1, ceil(#data.items / ipp))
data.pagemax = max(1, ceil(#items / ipp))
fs("button", data.inv_width + 5.6, 0.14, 1.88, 0.7, "pagenum",
fmt("%s / %u", clr("#ff0", data.pagenum), data.pagemax))
if #data.items == 0 then
if #items == 0 then
local lbl = ES"No item to show"
if next(recipe_filters) and #init_items > 0 and data.filter == "" then
@ -1817,21 +1736,49 @@ local function get_items_fs(fs, data, extend)
end
fs("button", data.inv_width + 0.1, 3, 8, 1, "no_item", lbl)
else
local first_item = (data.pagenum - 1) * ipp
for i = first_item, first_item + ipp - 1 do
local item = items[i + 1]
if not item then break end
local _compressed = item:sub(1, 1) == "_"
local name = _compressed and item:sub(2) or item
local X = i % rows
X = X - (X * 0.045) + data.inv_width + 0.28
local Y = round((i % ipp - X) / rows + 1, 0)
Y = Y - (Y * 0.085) + 0.95
fs[#fs + 1] = fmt("item_image_button", X, Y, size, size, name, item, "")
if compressible(item, data) then
local expand = data.expand == name
fs(fmt("tooltip[%s;%s]", item, expand and ES"Click to hide" or ES"Click to expand"))
fs("style_type[label;font=bold;font_size=20]")
fs("label", X + 0.65, Y + 0.7, expand and "-" or "+")
fs("style_type[label;font=normal;font_size=16]")
end
end
end
local first_item = (data.pagenum - 1) * ipp
local _tabs = {"All", "Nodes", "Items"}
local tab_len, tab_hgh = 1.8, 0.5
for i = first_item, first_item + ipp - 1 do
local item = data.items[i + 1]
if not item then break end
for i, title in ipairs(_tabs) do
local selected = i == data.current_itab
local X = i % rows
X = X - (X * 0.045) + data.inv_width + 0.28
fs(fmt([[style_type[image_button;fgimg=%s;fgimg_hovered=%s;noclip=true;
font_size=16;textcolor=%s;content_offset=0;sound=i3_tab] ]],
selected and PNG.tab_small_hover or PNG.tab_small,
PNG.tab_small_hover, selected and "#fff" or "#ddd"))
local Y = round((i % ipp - X) / rows + 1, 0)
Y = Y - (Y * (extend and 0.085 or 0.035)) + 0.95
fs[#fs + 1] = fmt("item_image_button", X, Y, size, size, item, item, "")
fs("style_type[image_button:hovered;textcolor=#fff]")
fs("image_button", (data.inv_width - 0.65) + (i * (tab_len + 0.1)),
full_height, tab_len, tab_hgh, "", fmt("itab_%u", i), title)
end
end
@ -1854,21 +1801,15 @@ end
local function get_panels(player, data, fs, full_height)
local _title = {name = "title", height = 1.4}
local _favs = {name = "favs", height = 2.23}
local _items = {name = "items", height = 9.69}
local _items = {name = "items", height = full_height}
local _recipes = {name = "recipes", rcp = data.recipes, height = 4.045}
local _usages = {name = "usages", rcp = data.usages, height = 4.045}
local panels, extend
local panels
if data.query_item then
panels = {_title, _recipes, _usages, _favs}
else
panels = {_items, _favs}
if #data.favs == 0 then
extend = true
remove(panels, 2)
_items.height = full_height
end
panels = {_items}
end
for idx = 1, #panels do
@ -1888,7 +1829,7 @@ local function get_panels(player, data, fs, full_height)
if is_recipe or is_usage then
get_rcp_extra(player, fs, data, panel, is_recipe, is_usage)
elseif panel.name == "items" then
get_items_fs(fs, data, extend)
get_items_fs(fs, data, full_height)
elseif panel.name == "title" then
get_header(fs, data)
elseif panel.name == "favs" then
@ -2008,7 +1949,7 @@ local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
fs("tooltip", 0, y, ctn_len - 2.5, 0.65,
fmt("Name: %s\nPosition:%s", clr("#ff0", v.name),
pos_to_string(v.pos, 0):sub(2,-2):gsub("(%-*%d+)", clr("#ff0", " %1"))))
core.pos_to_string(v.pos, 0):sub(2,-2):gsub("(%-*%d+)", clr("#ff0", " %1"))))
local del = fmt("waypoint_%u_delete", i)
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", del, PNG.trash, PNG.trash_hover))
@ -2287,9 +2228,9 @@ function i3.get_tabs()
return tabs
end
function i3.delete_tab(tabname)
function i3.remove_tab(tabname)
if not true_str(tabname) then
return err "i3.delete_tab: tab name missing"
return err "i3.remove_tab: tab name missing"
end
for i, def in ipairs(tabs) do
@ -2356,15 +2297,18 @@ local function init_data(player, info)
data.favs = {}
data.export_counts = {}
data.current_tab = 1
data.current_itab = 1
data.subcat = 1
data.scrbar_inv = 0
data.lang_code = get_lang_code(info)
data.fs_version = info.formspec_version
after(0, set_fs, player)
end
local function reset_data(data)
data.filter = ""
data.expand = ""
data.pagenum = 1
data.rnum = 1
data.unum = 1
@ -2375,7 +2319,12 @@ local function reset_data(data)
data.usages = nil
data.export_rcp = nil
data.export_usg = nil
data.alt_items = nil
data.items = data.items_raw
if data.current_itab > 1 then
sort_by_category(data)
end
end
local function rcp_fields(player, data, fields)
@ -2402,6 +2351,10 @@ local function rcp_fields(player, data, fields)
search(data)
if data.current_itab > 1 then
sort_by_category(data)
end
elseif fields.prev_page or fields.next_page then
if data.pagemax == 1 then return end
data.pagenum = data.pagenum - (fields.prev_page and 1 or -1)
@ -2515,9 +2468,9 @@ local function get_inventory_fs(player, data, fs)
local textures = concat(t, ","):gsub("!", ",")
--fs("style[player_model;bgcolor=black]")
fs("model", 0.2, 0.2, armor_skin and 4 or 3.4, armor_skin and ctn_hgt or 6.1,
fs("model", 0.2, 0.2, armor_skin and 4 or 3.4, ctn_hgt,
"player_model", props.mesh, textures, "0,-150", "false", "false",
fmt("%u,%u", anim.x, anim.y))
fmt("%u,%u%s", anim.x, anim.y, data.fs_version >= 5 and ";30" or ""))
else
local size = 2.5
fs("image", 0.7, 0.2, size, size * props.visual_size.y, props.textures[1])
@ -2565,9 +2518,7 @@ local function get_inventory_fs(player, data, fs)
(max_val * 4) / 12, max_val, 9.8, ctn_hgt, data.scrbar_inv))
fs(fmt("scroll_container[3.9,0.2;%f,%f;scrbar_inv;vertical]", ctn_len, ctn_hgt))
get_ctn_content(fs, data, player, yoffset, ctn_len, award_list, awards_unlocked, award_list_nb)
get_ctn_content(fs, data, player, yoffset, ctn_len, award_list, awards_unlocked, award_list_nb)
fs("scroll_container_end[]")
local btn = {
@ -2812,18 +2763,6 @@ i3.add_search_filter("groups", function(item, groups)
return has_groups
end)
i3.add_search_filter("types", function(item, drawtypes)
local t = {}
for i, dt in ipairs(drawtypes) do
t[i] = (dt == "node" and reg_nodes[item] and 1) or
(dt == "item" and reg_craftitems[item] and 1) or
(dt == "tool" and reg_tools[item] and 1) or nil
end
return #t > 0
end)
--[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not
return the fuel, replacements and toolrepair recipes, we have to
override `core.register_craft` and do some reverse engineering.
@ -2943,14 +2882,14 @@ local function get_init_items()
usages = usages_cache,
}
http.fetch_async{
http.fetch_async {
url = i3.export_url,
post_data = write_json(post_data),
post_data = core.write_json(post_data),
}
end
end
on_mods_loaded(function()
core.register_on_mods_loaded(function()
get_init_items()
__sfinv = rawget(_G, "sfinv")
@ -2974,7 +2913,7 @@ local function init_backpack(player)
local data = pdata[name]
local inv = player:get_inventory()
inv:set_size("main", INV_SIZE)
inv:set_size("main", data.bag_size and BAG_SIZES[data.bag_size] or INV_SIZE)
data.bag = create_inventory(fmt("%s_backpack", name), {
allow_put = function(_inv, listname, _, stack)
@ -3015,7 +2954,6 @@ local function init_backpack(player)
if data.bag_size then
data.bag:set_stack("main", 1, fmt("i3:bag_%s", data.bag_size))
inv:set_size("main", BAG_SIZES[data.bag_size])
end
end
@ -3040,11 +2978,11 @@ local function init_waypoints(player)
end
end
on_joinplayer(function(player)
core.register_on_joinplayer(function(player)
local name = player:get_player_name()
local info = get_player_info(name)
local info = core.get_player_information and core.get_player_information(name)
if get_formspec_version(info) < MIN_FORMSPEC_VERSION then
if not info or get_formspec_version(info) < MIN_FORMSPEC_VERSION then
if __sfinv then
sfinv.set_player_inventory_formspec = old_sfinv_fn
sfinv.enabled = true
@ -3058,6 +2996,8 @@ on_joinplayer(function(player)
end
end
pdata[name] = nil
return outdated(name)
end
@ -3111,12 +3051,12 @@ local function save_data(player_name)
storage:set_string("pdata", slz(_pdata))
end
on_leaveplayer(function(player)
core.register_on_leaveplayer(function(player)
local name = player:get_player_name()
save_data(name)
end)
on_shutdown(save_data)
core.register_on_shutdown(save_data)
local function routine()
save_data()
@ -3125,7 +3065,7 @@ end
after(SAVE_INTERVAL, routine)
on_receive_fields(function(player, formname, fields)
core.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "" then
return false
end
@ -3139,6 +3079,10 @@ on_receive_fields(function(player, formname, fields)
local tabname = sub(f, 5)
set_tab(player, tabname)
break
elseif sub(f, 1, 5) == "itab_" then
data.pagenum = 1
data.current_itab = tonum(f:sub(-1))
sort_by_category(data)
end
end
@ -3170,6 +3114,7 @@ if progressive_mode then
if is_group(item) then
local groups = extract_groups(item)
for i = 1, inv_items_size do
local def = reg_items[inv_items[i]]
@ -3236,6 +3181,7 @@ if progressive_mode then
for i = 1, #stacks do
local stack = stacks[i]
if not stack:is_empty() then
local name = stack:get_name()
if reg_items[name] then
@ -3326,7 +3272,8 @@ if progressive_mode then
-- Workaround. Need an engine call to detect when the contents of
-- the player inventory changed, instead.
local function poll_new_items()
local players = get_players()
local players = core.get_connected_players()
for i = 1, #players do
local player = players[i]
local name = player:get_player_name()
@ -3346,6 +3293,8 @@ if progressive_mode then
end
data.items_raw = items
data.current_itab = 1
search(data)
set_fs(player)
end
@ -3356,8 +3305,9 @@ if progressive_mode then
poll_new_items()
globalstep(function()
local players = get_players()
core.register_globalstep(function()
local players = core.get_connected_players()
for i = 1, #players do
local player = players[i]
local name = player:get_player_name()
@ -3371,7 +3321,7 @@ if progressive_mode then
i3.add_recipe_filter("Default progressive filter", progressive_filter)
on_joinplayer(function(player)
core.register_on_joinplayer(function(player)
local name = player:get_player_name()
local data = pdata[name]
@ -3417,5 +3367,5 @@ for size, rcp in pairs(bag_recipes) do
core.register_craft {type = "fuel", recipe = bagname, burntime = 3}
end
--dofile(core.get_modpath("i3") .. "/test_tabs.lua")
--dofile(core.get_modpath("i3") .. "/test_custom_recipes.lua")
--dofile(modpath .. "/tests/test_tabs.lua")
--dofile(modpath .. "/tests/test_custom_recipes.lua")