Compare commits

..

10 Commits

10 changed files with 69 additions and 79 deletions

16
API.md
View File

@ -12,23 +12,31 @@ Custom tabs can be added to the `i3` inventory as follow (example):
```Lua
i3.new_tab("stuff", {
description = "Stuff",
image = "image.png", -- Optional, adds an image next to the tab description
image = "image.png", -- Optional, add an image next to the tab description
-- Determine if the tab is visible by a player, `false` or `nil` hide the tab
--
-- The functions below are all optional
--
-- Determine if the tab is visible by a player, return false to hide the tab
access = function(player, data)
local name = player:get_player_name()
return name == "singleplayer"
end,
formspec = function(player, data, fs)
fs"label[3,1;This is just a test]"
fs("label", 3, 1, "Just a test")
fs"label[3,2;Lorem Ipsum]"
-- No need to return anything
end,
-- Events handling happens here
fields = function(player, data, fields)
if fields.mybutton then
do_things()
-- Do things
end
i3.set_fs(player) -- Update the formspec, mandatory
end,
})
```

View File

@ -20,7 +20,7 @@ local function lf(path)
end
i3 = {
version = 1121,
version = 1123,
data = core.deserialize(storage:get_string"data") or {},
settings = {
@ -111,6 +111,7 @@ i3 = {
i3.files.common()
i3.files.api(http)
i3.files.compress()
i3.files.detached()
i3.files.groups()
i3.files.callbacks(http, storage)
@ -120,7 +121,7 @@ end
if i3.settings.debug_mode then
lf("/tests/test_tabs.lua")()
lf("/tests/test_operators.lua")()
-- lf("/tests/test_operators.lua")()
lf("/tests/test_compression.lua")()
lf("/tests/test_custom_recipes.lua")()
end

View File

@ -1,7 +1,6 @@
local http, storage = ...
local init_bags = i3.files.bags()
local fill_caches = i3.files.caches(http)
local init_detached = i3.files.detached()
local init_hud = i3.files.hud()
local set_fs = i3.set_fs
@ -203,16 +202,14 @@ local function init_data(player, info)
local name = player:get_player_name()
i3.data[name] = i3.data[name] or {}
local data = i3.data[name]
local default = {}
for k, v in pairs(i3.default_data) do
default[k] = data[k]
if data[k] == nil then
default[k] = v
local val = data[k]
if val == nil then
val = v
end
data[k] = default[k]
data[k] = val
end
data.player_name = name
@ -264,7 +261,6 @@ insert(core.registered_on_joinplayers, 1, function(player)
init_data(player, info)
init_bags(player)
init_detached(player)
init_hud(player)
end)

View File

@ -327,8 +327,12 @@ local function apply_recipe_filters(recipes, player)
return recipes
end
local function recipe_filter_set()
return next(i3.recipe_filters)
end
local function compression_active(data)
return data.collapse and not next(i3.recipe_filters) and data.filter == ""
return data.collapse and not recipe_filter_set() and data.filter == ""
end
local function compressible(item, data)
@ -684,6 +688,7 @@ local _ = {
get_recipes = get_recipes,
sort_inventory = sort_inventory,
sort_by_category = sort_by_category,
recipe_filter_set = recipe_filter_set,
apply_recipe_filters = apply_recipe_filters,
-- Type checks

View File

@ -1,5 +1,5 @@
local set_fs = i3.set_fs
IMPORT("fmt", "play_sound", "create_inventory")
IMPORT("play_sound", "create_inventory")
local trash = create_inventory("i3_trash", {
allow_put = function(_, _, _, stack)
@ -22,15 +22,3 @@ local trash = create_inventory("i3_trash", {
})
trash:set_size("main", 1)
local function init_detached(player)
local name = player:get_player_name()
local output_rcp = create_inventory(fmt("i3_output_rcp_%s", name), {}, name)
output_rcp:set_size("main", 1)
local output_usg = create_inventory(fmt("i3_output_usg_%s", name), {}, name)
output_usg:set_size("main", 1)
end
return init_detached

View File

@ -10,11 +10,11 @@ local VoxelArea, VoxelManip = VoxelArea, VoxelManip
IMPORT("vec", "vec_round")
IMPORT("find", "match", "sub", "upper")
IMPORT("clr", "ESC", "msg", "check_privs")
IMPORT("compression_active", "compressible")
IMPORT("min", "max", "floor", "ceil", "round")
IMPORT("true_str", "is_fav", "is_num", "str_to_pos")
IMPORT("reg_items", "reg_nodes", "reg_tools", "reg_entities")
IMPORT("get_bag_description", "get_detached_inv", "get_recipes")
IMPORT("compression_active", "compressible", "recipe_filter_set")
IMPORT("S", "ES", "translate", "ItemStack", "toupper", "utf8_len")
IMPORT("maxn", "sort", "concat", "copy", "insert", "remove", "unpack")
IMPORT("extract_groups", "groups_to_items", "is_group", "item_has_groups", "get_group")
@ -297,7 +297,7 @@ local function get_isometric_view(fs, pos, X, Y, t, cubes, depth, high)
end
shift += (base_depth and 0.45 or 0.95)
image(2.7, Y + shift, 0.3, 0.3, PNG.flag)
animated_image(2.75, Y + shift, 3/14, 0.3, "i3_flag_anim.png", 4, 150)
end
local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
@ -380,9 +380,9 @@ local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
fs"style_type[label;font=normal;font_size=16;textcolor=#fff]"
end
local function get_bag_fs(fs, data, name, esc_name, bag_size, yextra)
fs("list[detached:i3_bag_%s;main;0,%f;1,1;]", esc_name, yextra + 0.7)
local bag = get_detached_inv("bag", name)
local function get_bag_fs(fs, data, bag_size, yextra)
fs("list[detached:i3_bag_%s;main;0,%f;1,1;]", data.player_name, yextra + 0.7)
local bag = get_detached_inv("bag", data.player_name)
if bag:is_empty"main" then return end
local v = {{1.9, 2, 0.12}, {3.05, 5, 0.06}, {4.2, 10}, {4.75, 10}}
@ -416,12 +416,13 @@ local function get_bag_fs(fs, data, name, esc_name, bag_size, yextra)
end
fs("style_type[list;size=%f;spacing=%f]", size, spacing)
fs("list[detached:i3_bag_content_%s;main;%f,%f;4,%u;]", esc_name, x, yextra + 1.3, bag_size)
fs("list[detached:i3_bag_content_%s;main;%f,%f;4,%u;]", data.player_name, x, yextra + 1.3, bag_size)
fs"style_type[list;size=1;spacing=0.15]"
end
local function get_container(fs, data, player, yoffset, ctn_len, award_list, awards_unlocked, award_list_nb, bag_size)
local name = data.player_name
local nametag = player:get_nametag_attributes()
local name = true_str(nametag.text) and nametag.text or data.player_name
local esc_name = ESC(name)
add_subtitle(fs, "player_name", 0, ctn_len, 22, true, esc_name)
@ -474,14 +475,14 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
end
if data.subcat == 1 then
get_bag_fs(fs, data, name, esc_name, bag_size, yextra)
get_bag_fs(fs, data, bag_size, yextra)
elseif data.subcat == 2 then
if not i3.modules.armor then
return not_installed "3d_armor"
end
local armor_def = armor.def[name]
local armor_def = armor.def[data.player_name]
local _, armor_inv = armor:get_valid_player(player, "3d_armor")
fs("list[detached:%s_armor;armor;0,%f;5,1;]", esc_name, yextra + 0.7)
@ -522,7 +523,7 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
return not_installed "skinsdb"
end
local _skins = skins.get_skinlist_for_player(name)
local _skins = skins.get_skinlist_for_player(data.player_name)
local skin_name = skins.get_player_skin(player).name
local spp, add_y = 24, 0
@ -608,7 +609,7 @@ local function show_settings(fs, data)
local X = 2.5
button(X, 9.1, 1.6, 0.55, "setting_home", "Home")
button(X + 1.7, 9.1, 1.6, 0.55, "setting_style", "Style")
button(X + 3.38, 9.1, 1.6, 0.55, "setting_sorting", "Sorting")
button(X + 3.4, 9.1, 1.6, 0.55, "setting_sorting", "Sorting")
image_button(X + 5.12, 9.2, 0.25, 0.25, PNG.cancel_hover .. "^\\[brighten", "close_settings", "")
if show_home then
@ -631,8 +632,8 @@ local function show_settings(fs, data)
checkbox(2.6, 10.4, "cb_legacy_inventory", "Legacy inventory", tostring(data.legacy_inventory))
checkbox(2.6, 10.85, "cb_wielditem_hud", "HUD description", tostring(data.wielditem_hud))
if not next(i3.recipe_filters) then
checkbox(5.3, 10.85, "cb_collapse", "Collapse inventory", tostring(data.collapse))
if not recipe_filter_set() then
checkbox(5.3, 10.85, "cb_collapse", "Collapse list", tostring(data.collapse))
end
local sign = (data.font_size > 0 and "+") or (data.font_size > 0 and "-") or ""
@ -640,7 +641,7 @@ local function show_settings(fs, data)
local range = 5
fs("scrollbaroptions[min=-%u;max=%u;smallstep=1;largestep=1;thumbsize=2]", range, range)
fs("scrollbar[5.3,10.2;2.45,0.3;horizontal;sb_font_size;%d]", data.font_size)
fs("scrollbar[5.3,10.2;2.55,0.3;horizontal;sb_font_size;%d]", data.font_size)
fs("tooltip[cb_hide_tabs;%s;#707070;#fff]",
ES"Enable this option to change the style of the right panel")
@ -649,7 +650,7 @@ local function show_settings(fs, data)
fs("tooltip[cb_wielditem_hud;%s;#707070;#fff]",
ES"Enable this option to show the wielded item description in your HUD")
fs("tooltip[cb_collapse;%s;#707070;#fff]",
ES"Enable this option to collapse certain items in your inventory")
ES"Enable this option to collapse the inventory list by grouping some items")
elseif show_sorting then
checkbox(2.6, 9.95, "cb_inv_compress", "Compression", tostring(data.inv_compress))
@ -790,7 +791,7 @@ local function get_inventory_fs(player, data, fs)
show_settings(fs, data)
end
local function get_tooltip(item, info, pos, lang_code)
local function get_tooltip(item, info, lang_code)
local tooltip
if info.groups then
@ -863,11 +864,6 @@ local function get_tooltip(item, info, pos, lang_code)
end
end
if pos then
local btn_size = i3.settings.item_btn_size
return fmt("tooltip", pos.x, pos.y, btn_size, btn_size, ESC(tooltip))
end
return fmt("tooltip[%s;%s]", item, ESC(tooltip))
end
@ -939,28 +935,16 @@ local function get_output_fs(fs, data, rcp, is_recipe, is_usage, shapeless, righ
local meta = item:get_meta()
local name = item:get_name()
local count = item:get_count()
local wear = item:get_wear()
local _name = fmt("_%s", name)
local pos
if meta:get_string"color" ~= "" or meta:get_string"palette_index" ~= "" then
local rcp_usg = is_recipe and "rcp" or "usg"
local size = BTN_SIZE * 1.2
slot(X, Y - 0.11, size, size)
fs("style_type[list;size=%f]", BTN_SIZE)
fs"listcolors[#bababa50;#bababa99]"
fs("list[detached:i3_output_%s_%s;main;%f,%f;1,1;]", rcp_usg, data.player_name, X + 0.11, Y)
button(X + 0.11, Y, BTN_SIZE, BTN_SIZE, _name, "")
count = get_true_count(data, count, is_recipe, is_usage)
item:set_count(count)
local inv = get_detached_inv(fmt("output_%s", rcp_usg), data.player_name)
inv:set_stack("main", 1, item)
pos = {x = X + 0.11, y = Y}
else
local size = BTN_SIZE * 1.2
slot(X, Y - 0.11, size, size)
count = get_true_count(data, count, is_recipe, is_usage)
item_image_button(X + 0.11, Y, BTN_SIZE, BTN_SIZE, fmt("%s %u %u", name, count, wear), _name, "")
end
local itemstr = ESC(item:to_string())
item_image_button(X + 0.11, Y, BTN_SIZE, BTN_SIZE, itemstr, _name, "")
local def = reg_items[name]
local unknown = not def or nil
@ -983,7 +967,7 @@ local function get_output_fs(fs, data, rcp, is_recipe, is_usage, shapeless, righ
}
if next(infos) then
fs(get_tooltip(_name, infos, pos, data.lang_code))
fs(get_tooltip(_name, infos, data.lang_code))
end
end
@ -1100,7 +1084,10 @@ local function get_grid_fs(fs, data, rcp, is_recipe, is_usage)
label(X + 0.8, Y + 0.9, count)
end
else
item_image_button(X, Y, btn_size, btn_size, fmt("%s %u", name, count), btn_name, label)
item:set_name(name)
item:set_count(count)
local itemstr = ESC(item:to_string())
item_image_button(X, Y, btn_size, btn_size, itemstr, btn_name, label)
end
local def = reg_items[name]
@ -1125,7 +1112,7 @@ local function get_grid_fs(fs, data, rcp, is_recipe, is_usage)
}
if next(infos) then
fs(get_tooltip(btn_name, infos, nil, data.lang_code))
fs(get_tooltip(btn_name, infos, data.lang_code))
end
end
@ -1140,9 +1127,13 @@ local function get_rcp_lbl(fs, data, panel, rn, is_recipe, is_usage)
local rcp = is_recipe and panel.rcp[data.rnum] or panel.rcp[data.unum]
if rcp.custom then
local desc = i3.craft_types[rcp.type].description
hypertext(data.inv_width + 4.8, data.yoffset + 0.12, 3, 1, "custom_rcp",
fmt("<right><i><global size=16>%s\n<global size=15>%s</i></right>", ES"Custom recipe", desc))
local craft_type = i3.craft_types[rcp.type]
if craft_type then
local desc = craft_type.description
hypertext(data.inv_width + 4.8, data.yoffset + 0.12, 3, 1, "custom_rcp",
fmt("<right><i><global size=16>%s\n<global size=15>%s</i></right>",
ES"Custom recipe", ESC(desc)))
end
end
local lbl = ES("Usage @1 of @2", data.unum, rn)
@ -1365,7 +1356,7 @@ local function hide_items(player, data)
data.items = new
end
if not core.is_creative_enabled(data.player_name) and not next(i3.recipe_filters) then
if not core.is_creative_enabled(data.player_name) and not recipe_filter_set() then
local new = {}
for i = 1, #data.items do
@ -1499,7 +1490,7 @@ local function get_items_fs(fs, data, player, full_height)
local lbl = ES"No item to show"
local icon, width, offset = PNG.no_result, 4, 2
if next(i3.recipe_filters) and #i3.init_items > 0 and data.filter == "" then
if recipe_filter_set() and #i3.init_items > 0 and data.filter == "" then
lbl = ES"Collect items to reveal more recipes" -- Progressive mode, etc.
icon, width, offset = PNG.find_more, 2.5, 2.75
end
@ -1524,7 +1515,7 @@ local function get_items_fs(fs, data, player, full_height)
local item_btn = fmt("item_image_button", X, Y, size, size, name, item, "")
if next(i3.recipe_filters) then
if recipe_filter_set() then
if data.items_progress[item] then
insert(fs, item_btn)
else
@ -1705,7 +1696,7 @@ local function make_fs(player, data)
local tab = i3.tabs[data.tab]
if tab then
if tab and tab.formspec then
tab.formspec(player, data, fs)
end

View File

@ -44,7 +44,7 @@ local PNG = {
nonvisible = "i3_non_visible.png",
exit = "i3_exit.png",
home = "i3_home.png",
flag = "i3_flag.png",
flag = "i3_flag_anim.png",
edit = "i3_edit.png",
no_result = "i3_no_result.png",
find_more = "i3_find_more.png",

View File

@ -3,7 +3,8 @@ i3.new_tab("test1", {
image = "i3_heart.png",
formspec = function(player, data, fs)
fs("label[3,1;Test 1]")
fs("label", 3, 1, "Just a test")
fs"label[3,2;Lorem Ipsum]"
end,
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 745 B

BIN
textures/i3_flag_anim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B