mirror of
https://github.com/minetest-mods/i3.git
synced 2024-12-25 18:30:38 +01:00
Add new buttons to main inventory, add inventory sorting methods + API
This commit is contained in:
parent
8d7ca9df18
commit
9276598e3e
34
API.md
34
API.md
@ -235,6 +235,40 @@ A map of search filters, indexed by name.
|
||||
|
||||
---
|
||||
|
||||
### Sorting methods
|
||||
|
||||
Sorting methods are used to filter the player's main inventory.
|
||||
|
||||
#### `i3.add_sorting_method(def)`
|
||||
|
||||
Adds a player inventory sorting method.
|
||||
|
||||
- `def` is the method definition.
|
||||
|
||||
Example:
|
||||
|
||||
```Lua
|
||||
i3.add_sorting_method {
|
||||
name = "test",
|
||||
description = "Cool sorting method",
|
||||
func = function(player, data)
|
||||
local inv = player:get_inventory()
|
||||
local list = inv:get_list("main")
|
||||
table.sort(list)
|
||||
|
||||
-- An array of items must be returned
|
||||
return list
|
||||
end,
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### `i3.sorting_methods`
|
||||
|
||||
A table containing all sorting methods.
|
||||
|
||||
---
|
||||
|
||||
### Item list compression
|
||||
|
||||
`i3` can reduce the item list size by compressing a group of items.
|
||||
|
@ -15,10 +15,10 @@ This mod requires **Minetest 5.4+**
|
||||
- Quick Crafting
|
||||
- Backpacks
|
||||
- 3D Player Model Preview
|
||||
- Inventory Sorting (alphabetical + item stack compression)
|
||||
- Inventory Sorting (with optional compression)
|
||||
- Item Bookmarks
|
||||
- Waypoints
|
||||
- Item List Compression (**`moreblocks`** supported)
|
||||
- Item List Compression (**`moreblocks`** is supported)
|
||||
|
||||
**¹** *This mode is a Terraria-like system that shows recipes you can craft from items you ever had in your inventory.
|
||||
To enable it: `i3_progressive_mode = true` in `minetest.conf`.*
|
||||
|
67
etc/api.lua
67
etc/api.lua
@ -2,6 +2,7 @@ local make_fs = i3.files.gui()
|
||||
|
||||
local gmatch, match, split = i3.get("gmatch", "match", "split")
|
||||
local S, err, fmt, reg_items = i3.get("S", "err", "fmt", "reg_items")
|
||||
local name_sort, count_sort, sort_inventory = i3.get("name_sort", "count_sort", "sort_inventory")
|
||||
local sort, concat, copy, insert, remove = i3.get("sort", "concat", "copy", "insert", "remove")
|
||||
local true_str, true_table, is_str, is_func, is_table, clean_name =
|
||||
i3.get("true_str", "true_table", "is_str", "is_func", "is_table", "clean_name")
|
||||
@ -166,6 +167,10 @@ function i3.set_fs(player, _fs)
|
||||
local data = i3.data[name]
|
||||
if not data then return end
|
||||
|
||||
if data.auto_sorting then
|
||||
sort_inventory(player, data)
|
||||
end
|
||||
|
||||
local fs = fmt("%s%s", make_fs(player, data), _fs or "")
|
||||
player:set_inventory_formspec(fs)
|
||||
end
|
||||
@ -289,3 +294,65 @@ function i3.compress(item, def)
|
||||
i3.compressed[it] = true
|
||||
end
|
||||
end
|
||||
|
||||
function i3.add_sorting_method(def)
|
||||
if not true_table(def) then
|
||||
return err "i3.add_sorting_method: definition missing"
|
||||
elseif not true_str(def.name) then
|
||||
return err "i3.add_sorting_method: name missing"
|
||||
elseif not is_func(def.func) then
|
||||
return err "i3.add_sorting_method: function missing"
|
||||
end
|
||||
|
||||
insert(i3.sorting_methods, def)
|
||||
end
|
||||
|
||||
local function pre_sorting(player)
|
||||
local inv = player:get_inventory()
|
||||
local list = inv:get_list("main")
|
||||
local size = inv:get_size("main")
|
||||
local new_inv, stack_meta = {}, {}
|
||||
|
||||
for i = 1, size do
|
||||
local stack = list[i]
|
||||
local name = stack:get_name()
|
||||
local count = stack:get_count()
|
||||
local empty = stack:is_empty()
|
||||
local meta = stack:get_meta():to_table()
|
||||
local wear = stack:get_wear() > 0
|
||||
|
||||
if not empty then
|
||||
if next(meta.fields) or wear then
|
||||
stack_meta[#stack_meta + 1] = stack
|
||||
else
|
||||
new_inv[#new_inv + 1] = ItemStack(fmt("%s %u", name, count))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #stack_meta do
|
||||
new_inv[#new_inv + 1] = stack_meta[i]
|
||||
end
|
||||
|
||||
return new_inv
|
||||
end
|
||||
|
||||
i3.add_sorting_method {
|
||||
name = "alphabetical",
|
||||
description = S"Sort items by name (A-Z)",
|
||||
func = function(player, data)
|
||||
local new_inv = pre_sorting(player)
|
||||
name_sort(new_inv, data.reverse_sorting)
|
||||
return new_inv
|
||||
end
|
||||
}
|
||||
|
||||
i3.add_sorting_method {
|
||||
name = "numerical",
|
||||
description = S"Sort items by number of items per stack",
|
||||
func = function(player, data)
|
||||
local new_inv = pre_sorting(player)
|
||||
count_sort(new_inv, data.reverse_sorting)
|
||||
return new_inv
|
||||
end,
|
||||
}
|
||||
|
112
etc/common.lua
112
etc/common.lua
@ -1,6 +1,6 @@
|
||||
local translate = core.get_translated_string
|
||||
local insert, remove, floor, vec_add, vec_mul =
|
||||
table.insert, table.remove, math.floor, vector.add, vector.mul
|
||||
local insert, remove, sort, vec_add, vec_mul =
|
||||
table.insert, table.remove, table.sort, vector.add, vector.mul
|
||||
local fmt, find, gmatch, match, sub, split, lower =
|
||||
string.format, string.find, string.gmatch, string.match, string.sub, string.split, string.lower
|
||||
local reg_items, reg_nodes, reg_craftitems, reg_tools =
|
||||
@ -297,7 +297,7 @@ end
|
||||
|
||||
local function round(num, decimal)
|
||||
local mul = 10 ^ decimal
|
||||
return floor(num * mul + 0.5) / mul
|
||||
return math.floor(num * mul + 0.5) / mul
|
||||
end
|
||||
|
||||
local function is_fav(favs, query_item)
|
||||
@ -351,9 +351,107 @@ local function spawn_item(player, stack)
|
||||
core.add_item(look_at, stack)
|
||||
end
|
||||
|
||||
local function name_sort(inv, reverse)
|
||||
return sort(inv, function(a, b)
|
||||
a, b = a:get_name(), b:get_name()
|
||||
|
||||
if reverse then
|
||||
return a > b
|
||||
end
|
||||
|
||||
return a < b
|
||||
end)
|
||||
end
|
||||
|
||||
local function count_sort(inv, reverse)
|
||||
return sort(inv, function(a, b)
|
||||
a, b = a:get_count(), b:get_count()
|
||||
|
||||
if reverse then
|
||||
return a > b
|
||||
end
|
||||
|
||||
return a < b
|
||||
end)
|
||||
end
|
||||
|
||||
local function get_sorting_idx(name)
|
||||
local idx = 1
|
||||
|
||||
for i, def in ipairs(i3.sorting_methods) do
|
||||
if name == def.name then
|
||||
idx = i
|
||||
end
|
||||
end
|
||||
|
||||
return idx
|
||||
end
|
||||
|
||||
local function compress_items(player)
|
||||
local inv = player:get_inventory()
|
||||
local list = inv:get_list("main")
|
||||
local size = inv:get_size("main")
|
||||
local new_inv, _new_inv, special = {}, {}, {}
|
||||
|
||||
for i = 1, size do
|
||||
local stack = list[i]
|
||||
local name = stack:get_name()
|
||||
local count = stack:get_count()
|
||||
local stackmax = stack:get_stack_max()
|
||||
local empty = stack:is_empty()
|
||||
local meta = stack:get_meta():to_table()
|
||||
local wear = stack:get_wear() > 0
|
||||
|
||||
if not empty then
|
||||
if next(meta.fields) or wear or count >= stackmax then
|
||||
special[#special + 1] = stack
|
||||
else
|
||||
new_inv[name] = new_inv[name] or 0
|
||||
new_inv[name] = new_inv[name] + count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for name, count in pairs(new_inv) do
|
||||
local stackmax = ItemStack(name):get_stack_max()
|
||||
local iter = math.ceil(count / stackmax)
|
||||
local leftover = count
|
||||
|
||||
for _ = 1, iter do
|
||||
_new_inv[#_new_inv + 1] = fmt("%s %u", name, math.min(stackmax, leftover))
|
||||
leftover = leftover - stackmax
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #special do
|
||||
_new_inv[#_new_inv + 1] = special[i]
|
||||
end
|
||||
|
||||
inv:set_list("main", _new_inv)
|
||||
end
|
||||
|
||||
local function sort_inventory(player, data)
|
||||
if data.inv_compress then
|
||||
compress_items(player)
|
||||
end
|
||||
|
||||
local sorts = {}
|
||||
|
||||
for _, def in ipairs(i3.sorting_methods) do
|
||||
sorts[def.name] = def.func
|
||||
end
|
||||
|
||||
local new_inv = sorts[data.sort](player, data)
|
||||
|
||||
if new_inv then
|
||||
local inv = player:get_inventory()
|
||||
inv:set_list("main", new_inv)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local registry = {
|
||||
local _ = {
|
||||
-- Groups
|
||||
is_group = is_group,
|
||||
extract_groups = extract_groups,
|
||||
@ -366,6 +464,10 @@ local registry = {
|
||||
|
||||
-- Sorting
|
||||
search = search,
|
||||
name_sort = name_sort,
|
||||
count_sort = count_sort,
|
||||
sort_inventory = sort_inventory,
|
||||
get_sorting_idx = get_sorting_idx,
|
||||
sort_by_category = sort_by_category,
|
||||
apply_recipe_filters = apply_recipe_filters,
|
||||
|
||||
@ -446,7 +548,7 @@ function i3.get(...)
|
||||
local t = {}
|
||||
|
||||
for i, var in ipairs{...} do
|
||||
t[i] = registry[var]
|
||||
t[i] = _[var]
|
||||
end
|
||||
|
||||
return unpack(t)
|
||||
|
107
etc/gui.lua
107
etc/gui.lua
@ -8,13 +8,14 @@ local clr, ESC, check_privs = i3.get("clr", "ESC", "check_privs")
|
||||
local min, max, floor, ceil, round = i3.get("min", "max", "floor", "ceil", "round")
|
||||
local sprintf, find, match, sub, upper = i3.get("fmt", "find", "match", "sub", "upper")
|
||||
local reg_items, reg_tools, reg_entities = i3.get("reg_items", "reg_tools", "reg_entities")
|
||||
local maxn, sort, concat, copy, insert, remove = i3.get("maxn", "sort", "concat", "copy", "insert", "remove")
|
||||
local maxn, sort, concat, copy, insert, remove =
|
||||
i3.get("maxn", "sort", "concat", "copy", "insert", "remove")
|
||||
|
||||
local true_str, is_fav, is_num = i3.get("true_str", "is_fav", "is_num")
|
||||
local is_group, extract_groups, item_has_groups =
|
||||
i3.get("is_group", "extract_groups", "item_has_groups")
|
||||
local groups_to_items, compression_active, compressible =
|
||||
i3.get("groups_to_items", "compression_active", "compressible")
|
||||
local get_sorting_idx, is_group, extract_groups, item_has_groups =
|
||||
i3.get("get_sorting_idx", "is_group", "extract_groups", "item_has_groups")
|
||||
|
||||
local function fmt(elem, ...)
|
||||
if not fs_elements[elem] then
|
||||
@ -404,6 +405,84 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
|
||||
end
|
||||
end
|
||||
|
||||
local function show_popup(fs, data)
|
||||
if data.confirm_trash then
|
||||
fs("style_type[box;colors=#999,#999,#808080,#808080]")
|
||||
|
||||
for _ = 1, 3 do
|
||||
fs("box", 2.97, 10.75, 4.3, 0.5, "")
|
||||
end
|
||||
|
||||
fs("label", 3.12, 11, "Confirm trash?")
|
||||
fs("image_button", 5.17, 10.75, 1, 0.5, "", "confirm_trash_yes", "Yes")
|
||||
fs("image_button", 6.27, 10.75, 1, 0.5, "", "confirm_trash_no", "No")
|
||||
|
||||
elseif data.show_settings then
|
||||
fs("style_type[box;colors=#999,#999,#808080,#808080]")
|
||||
|
||||
for _ = 1, 3 do
|
||||
fs("box", 2.1, 9.25, 6, 2, "")
|
||||
end
|
||||
|
||||
for _ = 1, 3 do
|
||||
fs("box", 2.1, 9.25, 6, 0.5, "#707070")
|
||||
end
|
||||
|
||||
fs("image_button", 7.75, 9.35, 0.25, 0.25, PNG.cancel_hover .. "^\\[brighten", "close_settings", "")
|
||||
|
||||
local show_home = data.show_setting == "home"
|
||||
local show_sorting = data.show_setting == "sorting"
|
||||
local show_misc = data.show_setting == "misc"
|
||||
|
||||
fs(fmt("style[setting_home;textcolor=%s;sound=i3_click]", show_home and "#ff0" or "#fff"))
|
||||
fs(fmt("style[setting_sorting;textcolor=%s;sound=i3_click]", show_sorting and "#ff0" or "#fff"))
|
||||
fs(fmt("style[setting_misc;textcolor=%s;sound=i3_click]", show_misc and "#ff0" or "#fff"))
|
||||
|
||||
fs("button", 2.2, 9.25, 1.8, 0.55, "setting_home", "Home")
|
||||
fs("button", 4, 9.25, 1.8, 0.55, "setting_sorting", "Sorting")
|
||||
fs("button", 5.8, 9.25, 1.8, 0.55, "setting_misc", "Misc.")
|
||||
|
||||
if show_home then
|
||||
local home_pos = data.home or ""
|
||||
home_pos = home_pos:gsub(",", ", "):gsub("%(", ""):gsub("%)", "")
|
||||
local home_str = fmt("Home position: %s", home_pos)
|
||||
home_str = data.home and home_str or ES"No home set"
|
||||
|
||||
fs("button", 2.1, 9.7, 6, 0.8, "", home_str)
|
||||
fs("image_button", 4.2, 10.4, 1.8, 0.7, "", "set_home", "Set home")
|
||||
|
||||
elseif show_sorting then
|
||||
fs("button", 2.1, 9.7, 6, 0.8, "", ES"Select the inventory sorting method:")
|
||||
|
||||
fs(fmt("style[prev_sort;fgimg=%s;fgimg_hovered=%s]", PNG.prev, PNG.prev_hover))
|
||||
fs(fmt("style[next_sort;fgimg=%s;fgimg_hovered=%s]", PNG.next, PNG.next_hover))
|
||||
|
||||
fs("image_button", 2.2, 10.6, 0.35, 0.35, "", "prev_sort", "")
|
||||
fs("image_button", 7.65, 10.6, 0.35, 0.35, "", "next_sort", "")
|
||||
|
||||
fs("style[sort_method;font=bold;font_size=20]")
|
||||
fs("button", 2.55, 10.35, 5.1, 0.8, "sort_method", data.sort:gsub("^%l", upper))
|
||||
|
||||
local idx = get_sorting_idx(data.sort)
|
||||
local desc = i3.sorting_methods[idx].description
|
||||
|
||||
if desc then
|
||||
fs(fmt("tooltip[%s;%s]", "sort_method", desc))
|
||||
end
|
||||
|
||||
elseif show_misc then
|
||||
fs("checkbox", 2.4, 10.05,
|
||||
"inv_compress", ES"Inventory compression", tostring(data.inv_compress))
|
||||
|
||||
fs("checkbox", 2.4, 10.5,
|
||||
"auto_sorting", ES"Automatic sorting", tostring(data.auto_sorting))
|
||||
|
||||
fs("checkbox", 2.4, 10.95,
|
||||
"reverse_sorting", ES"Reverse sorting", tostring(data.reverse_sorting))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_inventory_fs(player, data, fs)
|
||||
fs("listcolors[#bababa50;#bababa99]")
|
||||
|
||||
@ -481,10 +560,10 @@ local function get_inventory_fs(player, data, fs)
|
||||
fs("scroll_container_end[]")
|
||||
|
||||
local btn = {
|
||||
{"trash", ES"Clear inventory"},
|
||||
{"sort_az", ES"Sort items (A-Z)"},
|
||||
{"sort_za", ES"Sort items (Z-A)"},
|
||||
{"compress", ES"Compress items"},
|
||||
{"trash", ES"Clear inventory"},
|
||||
{"sort", ES"Sort items"},
|
||||
{"settings", ES"Settings"},
|
||||
{"home", ES"Go home"},
|
||||
}
|
||||
|
||||
for i, v in ipairs(btn) do
|
||||
@ -493,21 +572,11 @@ local function get_inventory_fs(player, data, fs)
|
||||
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]",
|
||||
btn_name, PNG[btn_name], PNG[fmt("%s_hover", btn_name)]))
|
||||
|
||||
fs("image_button", i + 3.447 - (i * 0.4), 11.43, 0.35, 0.35, "", btn_name, "")
|
||||
fs("image_button", i + 3.43 - (i * 0.4), 11.43, 0.35, 0.35, "", btn_name, "")
|
||||
fs(fmt("tooltip[%s;%s]", btn_name, tooltip))
|
||||
end
|
||||
|
||||
if data.confirm_trash then
|
||||
fs("style_type[box;colors=#999,#999,#808080,#808080]")
|
||||
|
||||
for _ = 1, 3 do
|
||||
fs("box", 2.97, 10.75, 4.3, 0.5, "")
|
||||
end
|
||||
|
||||
fs("label", 3.12, 11, "Confirm trash?")
|
||||
fs("image_button", 5.17, 10.75, 1, 0.5, "", "confirm_trash_yes", "Yes")
|
||||
fs("image_button", 6.27, 10.75, 1, 0.5, "", "confirm_trash_no", "No")
|
||||
end
|
||||
show_popup(fs, data)
|
||||
end
|
||||
|
||||
local function get_tooltip(item, info, pos)
|
||||
|
@ -7,11 +7,11 @@ local fmt, find, match, sub, lower = i3.get("fmt", "find", "match", "sub", "lowe
|
||||
local vec_new, vec_mul, vec_eq, vec_round = i3.get("vec_new", "vec_mul", "vec_eq", "vec_round")
|
||||
local sort, copy, insert, remove, indexof = i3.get("sort", "copy", "insert", "remove", "indexof")
|
||||
|
||||
local msg, is_str, is_fav = i3.get("msg", "is_str", "is_fav")
|
||||
local msg, is_fav = i3.get("msg", "is_fav")
|
||||
local is_group, extract_groups, groups_to_items =
|
||||
i3.get("is_group", "extract_groups", "groups_to_items")
|
||||
local search, sort_by_category, apply_recipe_filters =
|
||||
i3.get("search", "sort_by_category", "apply_recipe_filters")
|
||||
local search, get_sorting_idx, sort_inventory, sort_by_category, apply_recipe_filters =
|
||||
i3.get("search", "get_sorting_idx", "sort_inventory", "sort_by_category", "apply_recipe_filters")
|
||||
local show_item, spawn_item, clean_name, compressible, check_privs =
|
||||
i3.get("show_item", "spawn_item", "clean_name", "compressible", "check_privs")
|
||||
|
||||
@ -40,6 +40,8 @@ local function reset_data(data)
|
||||
data.export_usg = nil
|
||||
data.alt_items = nil
|
||||
data.confirm_trash = nil
|
||||
data.show_settings = nil
|
||||
data.show_setting = "home"
|
||||
data.items = data.items_raw
|
||||
|
||||
if data.current_itab > 1 then
|
||||
@ -66,104 +68,6 @@ local function get_recipes(player, item)
|
||||
not no_usages and usages or nil
|
||||
end
|
||||
|
||||
local function __sort(inv, reverse)
|
||||
sort(inv, function(a, b)
|
||||
if not is_str(a) then
|
||||
a = a:get_name()
|
||||
end
|
||||
|
||||
if not is_str(b) then
|
||||
b = b:get_name()
|
||||
end
|
||||
|
||||
if reverse then
|
||||
return a > b
|
||||
end
|
||||
|
||||
return a < b
|
||||
end)
|
||||
end
|
||||
|
||||
local function sort_itemlist(player, az)
|
||||
local inv = player:get_inventory()
|
||||
local list = inv:get_list("main")
|
||||
local size = inv:get_size("main")
|
||||
local new_inv, stack_meta = {}, {}
|
||||
|
||||
for i = 1, size do
|
||||
local stack = list[i]
|
||||
local name = stack:get_name()
|
||||
local count = stack:get_count()
|
||||
local empty = stack:is_empty()
|
||||
local meta = stack:get_meta():to_table()
|
||||
local wear = stack:get_wear() > 0
|
||||
|
||||
if not empty then
|
||||
if next(meta.fields) or wear then
|
||||
stack_meta[#stack_meta + 1] = stack
|
||||
else
|
||||
new_inv[#new_inv + 1] = fmt("%s %u", name, count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #stack_meta do
|
||||
new_inv[#new_inv + 1] = stack_meta[i]
|
||||
end
|
||||
|
||||
if az then
|
||||
__sort(new_inv)
|
||||
else
|
||||
__sort(new_inv, true)
|
||||
end
|
||||
|
||||
inv:set_list("main", new_inv)
|
||||
end
|
||||
|
||||
local function compress_items(player)
|
||||
local inv = player:get_inventory()
|
||||
local list = inv:get_list("main")
|
||||
local size = inv:get_size("main")
|
||||
local new_inv, _new_inv, special = {}, {}, {}
|
||||
|
||||
for i = 1, size do
|
||||
local stack = list[i]
|
||||
local name = stack:get_name()
|
||||
local count = stack:get_count()
|
||||
local stackmax = stack:get_stack_max()
|
||||
local empty = stack:is_empty()
|
||||
local meta = stack:get_meta():to_table()
|
||||
local wear = stack:get_wear() > 0
|
||||
|
||||
if not empty then
|
||||
if next(meta.fields) or wear or count >= stackmax then
|
||||
special[#special + 1] = stack
|
||||
else
|
||||
new_inv[name] = new_inv[name] or 0
|
||||
new_inv[name] = new_inv[name] + count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for name, count in pairs(new_inv) do
|
||||
local stackmax = ItemStack(name):get_stack_max()
|
||||
local iter = ceil(count / stackmax)
|
||||
local leftover = count
|
||||
|
||||
for _ = 1, iter do
|
||||
_new_inv[#_new_inv + 1] = fmt("%s %u", name, min(stackmax, leftover))
|
||||
leftover = leftover - stackmax
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #special do
|
||||
_new_inv[#_new_inv + 1] = special[i]
|
||||
end
|
||||
|
||||
__sort(_new_inv)
|
||||
inv:set_list("main", _new_inv)
|
||||
end
|
||||
|
||||
local function get_stack(player, stack)
|
||||
local inv = player:get_inventory()
|
||||
|
||||
@ -174,6 +78,13 @@ local function get_stack(player, stack)
|
||||
end
|
||||
end
|
||||
|
||||
local function safe_teleport(player, pos)
|
||||
pos.y = pos.y + 0.5
|
||||
local vel = player:get_velocity()
|
||||
player:add_velocity(vec_mul(vel, -1))
|
||||
player:set_pos(pos)
|
||||
end
|
||||
|
||||
i3.new_tab {
|
||||
name = "inventory",
|
||||
description = S"Inventory",
|
||||
@ -181,6 +92,7 @@ i3.new_tab {
|
||||
|
||||
fields = function(player, data, fields)
|
||||
local name = player:get_player_name()
|
||||
local inv = player:get_inventory()
|
||||
local sb_inv = fields.scrbar_inv
|
||||
|
||||
if fields.skins then
|
||||
@ -194,6 +106,9 @@ i3.new_tab {
|
||||
data.subcat = indexof(i3.SUBCAT, sub(field, 5))
|
||||
break
|
||||
|
||||
elseif sub(field, 1, 8) == "setting_" then
|
||||
data.show_setting = match(field, "_(%w+)$")
|
||||
|
||||
elseif find(field, "waypoint_%d+") then
|
||||
local id, action = match(field, "_(%d+)_(%w+)$")
|
||||
id = tonumber(id)
|
||||
@ -206,12 +121,7 @@ i3.new_tab {
|
||||
|
||||
elseif action == "teleport" then
|
||||
local pos = vec_new(waypoint.pos)
|
||||
pos.y = pos.y + 0.5
|
||||
|
||||
local vel = player:get_velocity()
|
||||
player:add_velocity(vec_mul(vel, -1))
|
||||
player:set_pos(pos)
|
||||
|
||||
safe_teleport(player, pos)
|
||||
msg(name, fmt("Teleported to %s", clr("#ff0", waypoint.name)))
|
||||
|
||||
elseif action == "refresh" then
|
||||
@ -242,23 +152,79 @@ i3.new_tab {
|
||||
end
|
||||
end
|
||||
|
||||
if fields.trash then
|
||||
if fields.quit then
|
||||
data.confirm_trash = nil
|
||||
data.show_settings = nil
|
||||
|
||||
elseif fields.trash then
|
||||
data.show_settings = nil
|
||||
data.confirm_trash = true
|
||||
|
||||
elseif fields.settings then
|
||||
data.confirm_trash = nil
|
||||
data.show_settings = true
|
||||
|
||||
elseif fields.confirm_trash_yes or fields.confirm_trash_no then
|
||||
if fields.confirm_trash_yes then
|
||||
local inv = player:get_inventory()
|
||||
inv:set_list("main", {})
|
||||
inv:set_list("craft", {})
|
||||
end
|
||||
|
||||
data.confirm_trash = nil
|
||||
|
||||
elseif fields.compress then
|
||||
compress_items(player)
|
||||
elseif fields.close_settings then
|
||||
data.show_settings = nil
|
||||
|
||||
elseif fields.sort_az or fields.sort_za then
|
||||
sort_itemlist(player, fields.sort_az)
|
||||
elseif fields.sort then
|
||||
sort_inventory(player, data)
|
||||
|
||||
elseif fields.prev_sort or fields.next_sort then
|
||||
local idx = get_sorting_idx(data.sort)
|
||||
local tot = #i3.sorting_methods
|
||||
|
||||
idx = idx - (fields.prev_sort and 1 or -1)
|
||||
|
||||
if idx > tot then
|
||||
idx = 1
|
||||
elseif idx == 0 then
|
||||
idx = tot
|
||||
end
|
||||
|
||||
data.sort = i3.sorting_methods[idx].name
|
||||
|
||||
elseif fields.inv_compress then
|
||||
data.inv_compress = false
|
||||
|
||||
if fields.inv_compress == "true" then
|
||||
data.inv_compress = true
|
||||
end
|
||||
|
||||
elseif fields.auto_sorting then
|
||||
data.auto_sorting = false
|
||||
|
||||
if fields.auto_sorting == "true" then
|
||||
data.auto_sorting = true
|
||||
end
|
||||
|
||||
elseif fields.reverse_sorting then
|
||||
data.reverse_sorting = false
|
||||
|
||||
if fields.reverse_sorting == "true" then
|
||||
data.reverse_sorting = true
|
||||
end
|
||||
|
||||
elseif fields.home then
|
||||
if not data.home then
|
||||
return msg(name, "No home set")
|
||||
elseif not check_privs(name, {home = true}) then
|
||||
return msg(name, "'home' privilege missing")
|
||||
end
|
||||
|
||||
safe_teleport(player, core.string_to_pos(data.home))
|
||||
msg(name, S"Welcome back home!")
|
||||
|
||||
elseif fields.set_home then
|
||||
data.home = core.pos_to_string(player:get_pos(), 1)
|
||||
|
||||
elseif sb_inv and sub(sb_inv, 1, 3) == "CHG" then
|
||||
data.scrbar_inv = tonumber(match(sb_inv, "%d+"))
|
||||
|
@ -11,8 +11,8 @@ local PNG = {
|
||||
next = "i3_next.png",
|
||||
arrow = "i3_arrow.png",
|
||||
trash = "i3_trash.png",
|
||||
sort_az = "i3_sort_az.png",
|
||||
sort_za = "i3_sort_za.png",
|
||||
sort = "i3_sort.png",
|
||||
settings = "i3_settings.png",
|
||||
compress = "i3_compress.png",
|
||||
fire = "i3_fire.png",
|
||||
fire_anim = "i3_fire_anim.png",
|
||||
@ -36,14 +36,15 @@ local PNG = {
|
||||
visible = "i3_visible.png^\\[brighten",
|
||||
nonvisible = "i3_non_visible.png",
|
||||
exit = "i3_exit.png",
|
||||
home = "i3_home.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",
|
||||
sort_hover = "i3_sort.png^\\[brighten",
|
||||
settings_hover = "i3_settings.png^\\[brighten",
|
||||
prev_hover = "i3_next_hover.png^\\[transformFX",
|
||||
next_hover = "i3_next_hover.png",
|
||||
tab_hover = "i3_tab_hover.png",
|
||||
@ -58,13 +59,14 @@ local PNG = {
|
||||
add_hover = "i3_add.png^\\[brighten",
|
||||
refresh_hover = "i3_refresh.png^\\[brighten",
|
||||
exit_hover = "i3_exit.png^\\[brighten",
|
||||
home_hover = "i3_home.png^\\[brighten",
|
||||
}
|
||||
|
||||
local styles = string.format([[
|
||||
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[image_button,item_image_button,checkbox;border=false;sound=i3_click]
|
||||
style_type[item_image_button;bgimg_hovered=%s]
|
||||
|
||||
style[pagenum,no_item,no_rcp;font=bold;font_size=18]
|
||||
@ -82,7 +84,7 @@ local styles = string.format([[
|
||||
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]
|
||||
style[confirm_trash_yes,confirm_trash_no;noclip=true;font_size=16;
|
||||
style[confirm_trash_yes,confirm_trash_no,set_home;noclip=true;font_size=16;
|
||||
bgimg=i3_btn9.png;bgimg_hovered=i3_btn9_hovered.png;
|
||||
bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6]
|
||||
]],
|
||||
@ -104,6 +106,7 @@ local fs_elements = {
|
||||
image = "image[%f,%f;%f,%f;%s]",
|
||||
tooltip = "tooltip[%f,%f;%f,%f;%s]",
|
||||
button = "button[%f,%f;%f,%f;%s;%s]",
|
||||
checkbox = "checkbox[%f,%f;%s;%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]",
|
||||
|
46
init.lua
46
init.lua
@ -30,6 +30,7 @@ i3 = {
|
||||
},
|
||||
|
||||
META_SAVES = {
|
||||
home = true,
|
||||
bag_item = true,
|
||||
bag_size = true,
|
||||
waypoints = true,
|
||||
@ -38,14 +39,17 @@ i3 = {
|
||||
},
|
||||
|
||||
-- Caches
|
||||
init_items = {},
|
||||
recipes_cache = {},
|
||||
usages_cache = {},
|
||||
fuel_cache = {},
|
||||
init_items = {},
|
||||
fuel_cache = {},
|
||||
usages_cache = {},
|
||||
recipes_cache = {},
|
||||
|
||||
tabs = {},
|
||||
craft_types = {},
|
||||
|
||||
recipe_filters = {},
|
||||
search_filters = {},
|
||||
craft_types = {},
|
||||
tabs = {},
|
||||
sorting_methods = {},
|
||||
|
||||
files = {
|
||||
api = lf("/etc/api.lua"),
|
||||
@ -140,18 +144,24 @@ local function init_data(player, info)
|
||||
i3.data[name] = i3.data[name] or {}
|
||||
local data = i3.data[name]
|
||||
|
||||
data.filter = ""
|
||||
data.pagenum = 1
|
||||
data.items = i3.init_items
|
||||
data.items_raw = i3.init_items
|
||||
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
|
||||
data.filter = ""
|
||||
data.pagenum = 1
|
||||
data.items = i3.init_items
|
||||
data.items_raw = i3.init_items
|
||||
data.favs = {}
|
||||
data.sort = "alphabetical"
|
||||
data.show_setting = "home"
|
||||
data.auto_sorting = false
|
||||
data.reverse_sorting = false
|
||||
data.inv_compress = true
|
||||
data.export_counts = {}
|
||||
data.current_tab = 1
|
||||
data.current_itab = 1
|
||||
data.subcat = 1
|
||||
data.scrbar_inv = 0
|
||||
data.compress = true
|
||||
data.lang_code = get_lang_code(info)
|
||||
data.fs_version = info.formspec_version
|
||||
|
||||
core.after(0, i3.set_fs, player)
|
||||
end
|
||||
|
BIN
textures/i3_home.png
Normal file
BIN
textures/i3_home.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
BIN
textures/i3_settings.png
Normal file
BIN
textures/i3_settings.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
BIN
textures/i3_sort.png
Normal file
BIN
textures/i3_sort.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.5 KiB |
Loading…
Reference in New Issue
Block a user