Compare commits

..

14 Commits
1.12 ... 1.13.1

20 changed files with 223 additions and 93 deletions

View File

@ -31,6 +31,7 @@ exclude_files = {
"tests/test_custom_recipes.lua", "tests/test_custom_recipes.lua",
"tests/test_operators.lua", "tests/test_operators.lua",
"tests/test_tabs.lua", "tests/test_tabs.lua",
"tests/test_waypoints.lua",
".install", ".install",
".luarocks", ".luarocks",

59
API.md
View File

@ -12,23 +12,31 @@ Custom tabs can be added to the `i3` inventory as follow (example):
```Lua ```Lua
i3.new_tab("stuff", { i3.new_tab("stuff", {
description = "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) access = function(player, data)
local name = player:get_player_name() local name = player:get_player_name()
return name == "singleplayer" return name == "singleplayer"
end, end,
formspec = function(player, data, fs) 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, end,
-- Events handling happens here -- Events handling happens here
fields = function(player, data, fields) fields = function(player, data, fields)
if fields.mybutton then if fields.mybutton then
do_things() -- Do things
end end
i3.set_fs(player) -- Update the formspec, mandatory
end, end,
}) })
``` ```
@ -301,6 +309,49 @@ A map of all compressed item groups, indexed by stereotypes.
--- ---
### Waypoints
`i3` allows you to manage the waypoints of a specific player.
#### `i3.add_waypoint(player_name, def)`
Add a waypoint to specific player.
- `player_name` is the player name.
- `def` is the waypoint definition table.
Example:
```Lua
i3.add_waypoint("Test", {
player = "singleplayer",
pos = {x = 0, y = 2, z = 0},
color = 0xffff00,
-- image = "heart.png" (optional)
})
```
#### `i3.remove_waypoint(player_name, waypoint_name)`
Remove a waypoint for specific player.
- `player_name` is the player name.
- `waypoint_name` is the waypoint name.
Example:
```Lua
i3.remove_waypoint("singleplayer", "Test")
```
#### `i3.get_waypoints(player_name)`
Return a table of all waypoints of a specific player.
- `player_name` is the player name.
---
### Miscellaneous ### Miscellaneous
#### `i3.hud_notif(name, msg[, img])` #### `i3.hud_notif(name, msg[, img])`

View File

@ -23,6 +23,14 @@ 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
Licenses of media (sounds)
--------------------------
Lone_Wolf (CC0):
i3_tab.ogg
i3_craft.ogg
i3_click.ogg
i3_cannot.ogg
Licenses of media (textures) Licenses of media (textures)
---------------------------- ----------------------------

View File

@ -1,6 +1,6 @@
![logo](https://user-images.githubusercontent.com/7883281/145490041-d91d6bd6-a654-438d-b208-4d5736845ab7.png) ![logo](https://user-images.githubusercontent.com/7883281/145490041-d91d6bd6-a654-438d-b208-4d5736845ab7.png)
[![MIT License](https://img.shields.io/apm/l/atomic-design-ui.svg?)](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs) [![GitHub Release](https://img.shields.io/github/release/minetest-mods/i3.svg?style=flat)]() ![workflow](https://github.com/minetest-mods/i3/actions/workflows/luacheck.yml/badge.svg) [![ContentDB](https://content.minetest.net/packages/jp/i3/shields/downloads/)](https://content.minetest.net/packages/jp/i3/) [![PayPal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/jpg84240) [![GitHub Release](https://img.shields.io/github/release/minetest-mods/i3.svg?style=flat)]() ![workflow](https://github.com/minetest-mods/i3/actions/workflows/luacheck.yml/badge.svg) [![ContentDB](https://content.minetest.net/packages/jp/i3/shields/downloads/)](https://content.minetest.net/packages/jp/i3/) [![PayPal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/jpg84240)
#### **`i3`** is a next-generation inventory for Minetest. #### **`i3`** is a next-generation inventory for Minetest.

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,10 +1,10 @@
local http = ... local http = ...
local make_fs, get_inventory_fs = i3.files.gui() local make_fs, get_inventory_fs = i3.files.gui()
IMPORT("gmatch", "split")
IMPORT("S", "err", "fmt", "reg_items")
IMPORT("sorter", "sort_inventory", "play_sound") IMPORT("sorter", "sort_inventory", "play_sound")
IMPORT("get_player_by_name", "add_hud_waypoint")
IMPORT("sort", "concat", "copy", "insert", "remove") IMPORT("sort", "concat", "copy", "insert", "remove")
IMPORT("gmatch", "split", "S", "err", "fmt", "reg_items", "pos_to_str")
IMPORT("true_str", "true_table", "is_str", "is_func", "is_table", "clean_name") IMPORT("true_str", "true_table", "is_str", "is_func", "is_table", "clean_name")
function i3.register_craft_type(name, def) function i3.register_craft_type(name, def)
@ -204,10 +204,10 @@ function i3.remove_tab(name)
return err "i3.remove_tab: tab name missing" return err "i3.remove_tab: tab name missing"
end end
for i, def in ipairs(i3.tabs) do for i = #i3.tabs, 1, -1 do
if name == def.name then local def = i3.tabs[i]
if def and name == def.name then
remove(i3.tabs, i) remove(i3.tabs, i)
break
end end
end end
end end
@ -315,7 +315,6 @@ function i3.hud_notif(name, msg, img)
end end
local data = i3.data[name] local data = i3.data[name]
if not data then if not data then
return err "i3.hud_notif: no player data initialized" return err "i3.hud_notif: no player data initialized"
end end
@ -358,3 +357,76 @@ i3.add_sorting_method("numerical", {
return list return list
end, end,
}) })
function i3.add_waypoint(name, def)
if not true_str(name) then
return err "i3.add_waypoint: name missing"
elseif not true_table(def) then
return err "i3.add_waypoint: definition missing"
elseif not true_str(def.player) then
return err "i3.add_waypoint: player name missing"
end
local data = i3.data[def.player]
if not data then
return err "i3.add_waypoint: no player data initialized"
end
local player = get_player_by_name(def.player)
local id = player and add_hud_waypoint(player, name, def.pos, def.color, def.image) or nil
insert(data.waypoints, {
name = name,
pos = pos_to_str(def.pos, 1),
color = def.color,
image = def.image,
id = id,
})
if data.subcat == 5 then
data.scrbar_inv += 1000
end
i3.set_fs(player)
end
function i3.remove_waypoint(player_name, name)
if not true_str(player_name) then
return err "i3.remove_waypoint: player name missing"
elseif not true_str(name) then
return err "i3.remove_waypoint: waypoint name missing"
end
local data = i3.data[player_name]
if not data then
return err "i3.remove_waypoint: no player data initialized"
end
local player = get_player_by_name(player_name)
for i = #data.waypoints, 1, -1 do
local waypoint = data.waypoints[i]
if waypoint and name == waypoint.name then
if player then
player:hud_remove(waypoint.id)
end
remove(data.waypoints, i)
end
end
i3.set_fs(player)
end
function i3.get_waypoints(player_name)
if not true_str(player_name) then
return err "i3.get_waypoints: player name missing"
end
local data = i3.data[player_name]
if not data then
return err "i3.get_waypoints: no player data initialized"
end
return data.waypoints
end

View File

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

View File

@ -327,8 +327,12 @@ local function apply_recipe_filters(recipes, player)
return recipes return recipes
end end
local function recipe_filter_set()
return next(i3.recipe_filters)
end
local function compression_active(data) 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 end
local function compressible(item, data) local function compressible(item, data)
@ -596,8 +600,8 @@ local function reset_data(data)
data.goto_page = nil data.goto_page = nil
data.recipes = nil data.recipes = nil
data.usages = nil data.usages = nil
data.crafting_rcp = nil data.crafting_rcp = nil
data.crafting_usg = nil data.crafting_usg = nil
data.alt_items = nil data.alt_items = nil
data.confirm_trash = nil data.confirm_trash = nil
data.show_settings = nil data.show_settings = nil
@ -609,13 +613,15 @@ local function reset_data(data)
end end
end end
local function add_hud_waypoint(player, name, pos, color) local function add_hud_waypoint(player, name, pos, color, image)
return player:hud_add { return player:hud_add {
hud_elem_type = "waypoint", hud_elem_type = image and "image_waypoint" or "waypoint",
name = name, name = name,
text = "m", text = image or "m",
scale = {x = 5, y = 5},
world_pos = pos, world_pos = pos,
number = color, number = color,
image = image,
z_index = -300, z_index = -300,
} }
end end
@ -684,6 +690,7 @@ local _ = {
get_recipes = get_recipes, get_recipes = get_recipes,
sort_inventory = sort_inventory, sort_inventory = sort_inventory,
sort_by_category = sort_by_category, sort_by_category = sort_by_category,
recipe_filter_set = recipe_filter_set,
apply_recipe_filters = apply_recipe_filters, apply_recipe_filters = apply_recipe_filters,
-- Type checks -- Type checks

View File

@ -1,5 +1,5 @@
local set_fs = i3.set_fs local set_fs = i3.set_fs
IMPORT("fmt", "play_sound", "create_inventory") IMPORT("play_sound", "create_inventory")
local trash = create_inventory("i3_trash", { local trash = create_inventory("i3_trash", {
allow_put = function(_, _, _, stack) allow_put = function(_, _, _, stack)
@ -22,15 +22,3 @@ local trash = create_inventory("i3_trash", {
}) })
trash:set_size("main", 1) 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("vec", "vec_round")
IMPORT("find", "match", "sub", "upper") IMPORT("find", "match", "sub", "upper")
IMPORT("clr", "ESC", "msg", "check_privs") IMPORT("clr", "ESC", "msg", "check_privs")
IMPORT("compression_active", "compressible")
IMPORT("min", "max", "floor", "ceil", "round") IMPORT("min", "max", "floor", "ceil", "round")
IMPORT("true_str", "is_fav", "is_num", "str_to_pos") IMPORT("true_str", "is_fav", "is_num", "str_to_pos")
IMPORT("reg_items", "reg_nodes", "reg_tools", "reg_entities") IMPORT("reg_items", "reg_nodes", "reg_tools", "reg_entities")
IMPORT("get_bag_description", "get_detached_inv", "get_recipes") 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("S", "ES", "translate", "ItemStack", "toupper", "utf8_len")
IMPORT("maxn", "sort", "concat", "copy", "insert", "remove", "unpack") IMPORT("maxn", "sort", "concat", "copy", "insert", "remove", "unpack")
IMPORT("extract_groups", "groups_to_items", "is_group", "item_has_groups", "get_group") 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 end
shift += (base_depth and 0.45 or 0.95) 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 end
local function get_waypoint_fs(fs, data, player, yextra, ctn_len) 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]" fs"style_type[label;font=normal;font_size=16;textcolor=#fff]"
end end
local function get_bag_fs(fs, data, name, esc_name, bag_size, yextra) local function get_bag_fs(fs, data, bag_size, yextra)
fs("list[detached:i3_bag_%s;main;0,%f;1,1;]", esc_name, yextra + 0.7) fs("list[detached:i3_bag_%s;main;0,%f;1,1;]", data.player_name, yextra + 0.7)
local bag = get_detached_inv("bag", name) local bag = get_detached_inv("bag", data.player_name)
if bag:is_empty"main" then return end 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}} 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 end
fs("style_type[list;size=%f;spacing=%f]", size, spacing) 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]" fs"style_type[list;size=1;spacing=0.15]"
end end
local function get_container(fs, data, player, yoffset, ctn_len, award_list, awards_unlocked, award_list_nb, bag_size) 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) local esc_name = ESC(name)
add_subtitle(fs, "player_name", 0, ctn_len, 22, true, 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 end
if data.subcat == 1 then 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 elseif data.subcat == 2 then
if not i3.modules.armor then if not i3.modules.armor then
return not_installed "3d_armor" return not_installed "3d_armor"
end 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") 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) 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" return not_installed "skinsdb"
end 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 skin_name = skins.get_player_skin(player).name
local spp, add_y = 24, 0 local spp, add_y = 24, 0
@ -608,7 +609,7 @@ local function show_settings(fs, data)
local X = 2.5 local X = 2.5
button(X, 9.1, 1.6, 0.55, "setting_home", "Home") 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 + 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", "") image_button(X + 5.12, 9.2, 0.25, 0.25, PNG.cancel_hover .. "^\\[brighten", "close_settings", "")
if show_home then 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.4, "cb_legacy_inventory", "Legacy inventory", tostring(data.legacy_inventory))
checkbox(2.6, 10.85, "cb_wielditem_hud", "HUD description", tostring(data.wielditem_hud)) checkbox(2.6, 10.85, "cb_wielditem_hud", "HUD description", tostring(data.wielditem_hud))
if not next(i3.recipe_filters) then if not recipe_filter_set() then
checkbox(5.3, 10.85, "cb_collapse", "Collapse inventory", tostring(data.collapse)) checkbox(5.3, 10.85, "cb_collapse", "Collapse list", tostring(data.collapse))
end end
local sign = (data.font_size > 0 and "+") or (data.font_size > 0 and "-") or "" 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 local range = 5
fs("scrollbaroptions[min=-%u;max=%u;smallstep=1;largestep=1;thumbsize=2]", range, range) 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]", fs("tooltip[cb_hide_tabs;%s;#707070;#fff]",
ES"Enable this option to change the style of the right panel") 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]", fs("tooltip[cb_wielditem_hud;%s;#707070;#fff]",
ES"Enable this option to show the wielded item description in your HUD") ES"Enable this option to show the wielded item description in your HUD")
fs("tooltip[cb_collapse;%s;#707070;#fff]", 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 elseif show_sorting then
checkbox(2.6, 9.95, "cb_inv_compress", "Compression", tostring(data.inv_compress)) 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) show_settings(fs, data)
end end
local function get_tooltip(item, info, pos, lang_code) local function get_tooltip(item, info, lang_code)
local tooltip local tooltip
if info.groups then if info.groups then
@ -863,11 +864,6 @@ local function get_tooltip(item, info, pos, lang_code)
end end
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)) return fmt("tooltip[%s;%s]", item, ESC(tooltip))
end 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 meta = item:get_meta()
local name = item:get_name() local name = item:get_name()
local count = item:get_count() local count = item:get_count()
local wear = item:get_wear()
local _name = fmt("_%s", name) local _name = fmt("_%s", name)
local pos
if meta:get_string"color" ~= "" or meta:get_string"palette_index" ~= "" then local size = BTN_SIZE * 1.2
local rcp_usg = is_recipe and "rcp" or "usg" slot(X, Y - 0.11, size, size)
fs("style_type[list;size=%f]", BTN_SIZE) count = get_true_count(data, count, is_recipe, is_usage)
fs"listcolors[#bababa50;#bababa99]" item:set_count(count)
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, "")
local inv = get_detached_inv(fmt("output_%s", rcp_usg), data.player_name) local itemstr = ESC(item:to_string())
inv:set_stack("main", 1, item) item_image_button(X + 0.11, Y, BTN_SIZE, BTN_SIZE, itemstr, _name, "")
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 def = reg_items[name] local def = reg_items[name]
local unknown = not def or nil 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 if next(infos) then
fs(get_tooltip(_name, infos, pos, data.lang_code)) fs(get_tooltip(_name, infos, data.lang_code))
end end
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) label(X + 0.8, Y + 0.9, count)
end end
else 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 end
local def = reg_items[name] 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 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
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] local rcp = is_recipe and panel.rcp[data.rnum] or panel.rcp[data.unum]
if rcp.custom then if rcp.custom then
local desc = i3.craft_types[rcp.type].description local craft_type = i3.craft_types[rcp.type]
hypertext(data.inv_width + 4.8, data.yoffset + 0.12, 3, 1, "custom_rcp", if craft_type then
fmt("<right><i><global size=16>%s\n<global size=15>%s</i></right>", ES"Custom recipe", desc)) 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 end
local lbl = ES("Usage @1 of @2", data.unum, rn) local lbl = ES("Usage @1 of @2", data.unum, rn)
@ -1365,7 +1356,7 @@ local function hide_items(player, data)
data.items = new data.items = new
end 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 = {} local new = {}
for i = 1, #data.items do 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 lbl = ES"No item to show"
local icon, width, offset = PNG.no_result, 4, 2 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. lbl = ES"Collect items to reveal more recipes" -- Progressive mode, etc.
icon, width, offset = PNG.find_more, 2.5, 2.75 icon, width, offset = PNG.find_more, 2.5, 2.75
end end
@ -1524,14 +1515,15 @@ local function get_items_fs(fs, data, player, full_height)
local item_btn = fmt("item_image_button", X, Y, size, size, name, item, "") 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 if data.items_progress[item] then
insert(fs, item_btn) insert(fs, item_btn)
else else
local col = "^\\[colorize:#232428^\\[opacity:245" local col = "^\\[colorize:#232428^\\[opacity:245"
local img = reg_items[item].inventory_image .. col local img = reg_items[item].inventory_image .. col
local nodedef = reg_nodes[item]
if reg_nodes[item] then if nodedef and not true_str(nodedef.inventory_image) then
img = PNG.cube .. col img = PNG.cube .. col
end end
@ -1704,7 +1696,7 @@ local function make_fs(player, data)
local tab = i3.tabs[data.tab] local tab = i3.tabs[data.tab]
if tab then if tab and tab.formspec then
tab.formspec(player, data, fs) tab.formspec(player, data, fs)
end end

View File

@ -165,7 +165,7 @@ local function init_waypoints(player)
for _, v in ipairs(data.waypoints) do for _, v in ipairs(data.waypoints) do
if not v.hide then if not v.hide then
local id = add_hud_waypoint(player, v.name, str_to_pos(v.pos), v.color) local id = add_hud_waypoint(player, v.name, str_to_pos(v.pos), v.color, v.image)
v.id = id v.id = id
end end
end end

View File

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

View File

@ -3,7 +3,8 @@ i3.new_tab("test1", {
image = "i3_heart.png", image = "i3_heart.png",
formspec = function(player, data, fs) 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, end,
}) })

12
tests/test_waypoints.lua Normal file
View File

@ -0,0 +1,12 @@
core.after(5, function()
i3.add_waypoint("Test", {
player = "singleplayer",
pos = {x = 0, y = 2, z = 0},
color = 0xffff00,
-- image = "heart.png",
})
core.after(5, function()
i3.remove_waypoint("singleplayer", "Test")
end)
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