Compare commits

..

37 Commits
1.9 ... 1.12

Author SHA1 Message Date
7f437b21f4 Bump version 2022-09-25 17:22:38 +02:00
e8a811f72c Save more settings accross restarts 2022-09-25 17:22:36 +02:00
4c4911eb4f Fix 2022-09-25 16:55:41 +02:00
325d6f30be 🚀 Greatly improve Progressive Mode look 2022-09-25 16:23:11 +02:00
05995a22df Add sound for skins 2022-09-24 16:24:01 +02:00
32594e7552 Small fix 2022-09-24 14:30:45 +02:00
27ed1f02e6 More cleaning 2022-09-24 14:23:47 +02:00
916e80f2c3 Cleanup vectors 2022-09-24 13:46:50 +02:00
c42ea6c005 Minor tweak 2022-09-20 01:12:07 +02:00
da91223c4d Bump version 2022-09-18 14:24:45 +02:00
408267754c API.md: rewrite some parts 2022-09-15 12:28:23 +02:00
b4de48370a HUD: small tweak 2022-09-14 15:37:29 +02:00
477efe56d3 Bump version 2022-09-04 19:17:42 +02:00
8afb51dae8 Some cleaning 2022-09-04 19:12:57 +02:00
734b09b69f Minor cleaning 2022-08-29 11:29:09 +02:00
1560d59d4a Bump version 2022-08-28 16:36:30 +02:00
e4e175a775 Minor tweak 2022-08-28 16:36:08 +02:00
7a40f36611 Bump version 2022-08-28 15:36:44 +02:00
2467e8bb0b Fix sound play 2022-08-28 15:34:37 +02:00
9666834aed Minor tweak 2022-08-28 15:21:20 +02:00
7670356c8c Bump version (again) 2022-08-28 14:46:03 +02:00
646d16afd8 Hotfix HUD 2022-08-28 14:45:37 +02:00
6b54dbc934 Bump version 2022-08-28 14:23:36 +02:00
911bed3911 Add option in Style settings to show wielditem descriptions in HUD 2022-08-28 14:18:05 +02:00
75fdd57f2a Integrate Legacy Inventory option per-player in Settings popup 2022-08-28 13:31:01 +02:00
c8d6312772 Minor cleaning 2022-08-21 23:47:15 +02:00
a4e8fac0e6 Update preview screenshot 2022-08-20 17:45:44 +02:00
eac4a18df2 HOTFIX 2022-08-20 16:59:26 +02:00
2ddaa4ddfb Bump version 2022-08-20 16:20:44 +02:00
56b5cb78f2 Minor fix 2022-08-16 16:44:31 +02:00
813d27d2cc Minor cleaning 2022-08-16 14:25:02 +02:00
52464d4486 Add checkbox to change the panel style (preview: https://i.imgur.com/gNPLf0B.png) 2022-08-16 14:18:26 +02:00
e300539dd3 Cleaning 2022-08-15 18:19:02 +02:00
2cdd03b127 Redesign settings 2022-08-15 17:51:38 +02:00
8db3fb4a41 Minor fixes 2022-08-15 15:25:23 +02:00
d3ad413876 Minor cleaning 2022-08-15 01:00:34 +02:00
6219c2f64e Fix bug with Quick Crafting 2022-08-14 21:57:45 +02:00
29 changed files with 627 additions and 430 deletions

View File

@ -10,6 +10,7 @@ read_globals = {
"armor", "armor",
"skins", "skins",
"awards", "awards",
"hb",
"vector", "vector",
"string", "string",
"table", "table",

38
API.md
View File

@ -21,31 +21,33 @@ i3.new_tab("stuff", {
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;This is just a test]"
end, end,
-- Events handling happens here -- Events handling happens here
fields = function(player, data, fields) fields = function(player, data, fields)
if fields.mybutton then
do_things()
end
end, end,
}) })
``` ```
- `player` is an `ObjectRef` to the user. - `player` is an `ObjectRef` to the user.
- `data` are the user data. - `data` are the user data.
- `fs` is the formspec table which is callable with a metamethod. Each call adds a new entry. - `fs` is the formspec table which is callable with a metamethod. Every call adds a new entry.
#### `i3.set_fs(player)` #### `i3.set_fs(player)`
Updates the current formspec. Update the current formspec.
#### `i3.remove_tab(tabname)` #### `i3.remove_tab(tabname)`
Deletes a tab by name. Delete a tab by name.
#### `i3.get_current_tab(player)` #### `i3.get_current_tab(player)`
Returns the current player tab. `player` is an `ObjectRef` to the user. Return the current player tab. `player` is an `ObjectRef` to the user.
#### `i3.set_tab(player[, tabname])` #### `i3.set_tab(player[, tabname])`
@ -54,7 +56,7 @@ Sets the current tab by name. `player` is an `ObjectRef` to the user.
#### `i3.override_tab(tabname, def)` #### `i3.override_tab(tabname, def)`
Overrides a tab by name. `def` is the tab definition like seen in `i3.set_tab`. Override a tab by name. `def` is the tab definition like seen in `i3.set_tab`
#### `i3.tabs` #### `i3.tabs`
@ -68,9 +70,11 @@ Custom recipes are nonconventional crafts outside the main crafting grid.
They can be registered in-game dynamically and have a size beyond 3x3 items. They can be registered in-game dynamically and have a size beyond 3x3 items.
**Note:** the registration format differs from the default registration format in everything. **Note:** the registration format differs from the default registration format in everything.
The width is automatically calculated depending where you place the commas. Look at the examples attentively. The width is automatically calculated depending where you place the commas.
#### Registering a custom crafting type (example) Examples:
#### Registering a custom crafting type
```Lua ```Lua
i3.register_craft_type("digging", { i3.register_craft_type("digging", {
@ -79,7 +83,7 @@ i3.register_craft_type("digging", {
}) })
``` ```
#### Registering a custom crafting recipe (examples) #### Registering a custom crafting recipe
```Lua ```Lua
i3.register_craft { i3.register_craft {
@ -159,7 +163,7 @@ mode is implemented as a recipe filter.
#### `i3.add_recipe_filter(name, function(recipes, player))` #### `i3.add_recipe_filter(name, function(recipes, player))`
Adds a recipe filter with the given `name`. The filter function returns the Add a recipe filter with the given `name`. The filter function returns the
recipes to be displayed, given the available recipes and an `ObjectRef` to the recipes to be displayed, given the available recipes and an `ObjectRef` to the
user. Each recipe is a table of the form returned by user. Each recipe is a table of the form returned by
`minetest.get_craft_recipe`. `minetest.get_craft_recipe`.
@ -181,7 +185,7 @@ end)
#### `i3.set_recipe_filter(name, function(recipe, player))` #### `i3.set_recipe_filter(name, function(recipe, player))`
Removes all recipe filters and adds a new one. Remove all recipe filters and add a new one.
#### `i3.recipe_filters` #### `i3.recipe_filters`
@ -207,7 +211,7 @@ Notes:
#### `i3.add_search_filter(name, function(item, values))` #### `i3.add_search_filter(name, function(item, values))`
Adds a search filter. Add a search filter.
The search function must return a boolean value (whether the given item should be listed or not). The search function must return a boolean value (whether the given item should be listed or not).
- `name` is the filter name. - `name` is the filter name.
@ -241,7 +245,7 @@ Sorting methods are used to filter the player's main inventory.
#### `i3.add_sorting_method(name, def)` #### `i3.add_sorting_method(name, def)`
Adds a player inventory sorting method. Add a player inventory sorting method.
- `name` is the method name. - `name` is the method name.
- `def` is the method definition. - `def` is the method definition.
@ -276,7 +280,7 @@ A table containing all sorting methods.
#### `i3.compress(item, def)` #### `i3.compress(item, def)`
Adds a new group of items to compress. Add a new group of items to compress.
- `item` is the item which represent the group of compressed items. - `item` is the item which represent the group of compressed items.
- `def` is a table specifying the substring replace patterns to be used. - `def` is a table specifying the substring replace patterns to be used.
@ -301,7 +305,7 @@ A map of all compressed item groups, indexed by stereotypes.
#### `i3.hud_notif(name, msg[, img])` #### `i3.hud_notif(name, msg[, img])`
Shows a Steam-like HUD notification on the bottom-right corner of the screen (experimental). Show a Steam-like HUD notification on the bottom-right corner of the screen (experimental).
- `name` is the player name. - `name` is the player name.
- `msg` is the HUD message to show. - `msg` is the HUD message to show.
@ -309,7 +313,7 @@ Shows a Steam-like HUD notification on the bottom-right corner of the screen (ex
#### `i3.get_recipes(item)` #### `i3.get_recipes(item)`
Returns a table of recipes and usages of `item`. Return a table of recipes and usages of `item`.
#### `i3.export_url` #### `i3.export_url`

View File

@ -55,4 +55,4 @@ Report bugs on the [**Bug Tracker**](https://github.com/minetest-mods/i3/issues)
**Video review on YouTube:** https://www.youtube.com/watch?v=Xd14BCdEZ3o **Video review on YouTube:** https://www.youtube.com/watch?v=Xd14BCdEZ3o
![Preview](https://content.minetest.net/uploads/3abf3755de.png) ![Preview](https://user-images.githubusercontent.com/7883281/185755315-23c2fffa-203d-4115-9dc3-576c92615733.png)

View File

@ -20,7 +20,7 @@ local function lf(path)
end end
i3 = { i3 = {
version = 190, version = 112,
data = core.deserialize(storage:get_string"data") or {}, data = core.deserialize(storage:get_string"data") or {},
settings = { settings = {
@ -30,6 +30,7 @@ i3 = {
min_fs_version = 6, min_fs_version = 6,
item_btn_size = 1.1, item_btn_size = 1.1,
drop_bag_on_die = true, drop_bag_on_die = true,
wielditem_fade_after = 3,
save_interval = 600, -- Player data save interval (in seconds) save_interval = 600, -- Player data save interval (in seconds)
hud_speed = 1, hud_speed = 1,
@ -37,8 +38,6 @@ i3 = {
damage_enabled = core.settings:get_bool"enable_damage", damage_enabled = core.settings:get_bool"enable_damage",
progressive_mode = core.settings:get_bool"i3_progressive_mode", progressive_mode = core.settings:get_bool"i3_progressive_mode",
legacy_inventory = core.settings:get_bool"i3_legacy_inventory",
item_compression = core.settings:get_bool("i3_item_compression", true),
}, },
categories = { categories = {
@ -52,10 +51,26 @@ i3 = {
saves = { -- Metadata to save saves = { -- Metadata to save
bag = true, bag = true,
home = true, home = true,
sort = true,
collapse = true,
font_size = true, font_size = true,
hide_tabs = true,
waypoints = true, waypoints = true,
inv_items = true, inv_items = true,
auto_sorting = true,
inv_compress = true,
known_recipes = true, known_recipes = true,
wielditem_hud = true,
ignore_hotbar = true,
reverse_sorting = true,
legacy_inventory = true,
},
default_data = {
sort = 1,
font_size = 0,
collapse = true,
inv_compress = true,
}, },
files = { files = {
@ -93,9 +108,6 @@ i3 = {
sorting_methods = {}, sorting_methods = {},
} }
i3.settings.hotbar_len = i3.settings.legacy_inventory and 8 or 9
i3.settings.inv_size = 4 * i3.settings.hotbar_len
i3.files.common() i3.files.common()
i3.files.api(http) i3.files.api(http)
i3.files.compress() i3.files.compress()

View File

@ -1,4 +1,4 @@
name = i3 name = i3
description = Next-generation inventory description = Next-generation inventory
optional_depends = 3d_armor, skinsdb, awards optional_depends = 3d_armor, skinsdb, awards
min_minetest_version = 5.4 min_minetest_version = 5.6

View File

@ -1,8 +1,2 @@
# The progressive mode shows recipes you can craft from items you ever had in your inventory. # The progressive mode shows recipes you can craft from items you ever had in your inventory.
i3_progressive_mode (Learn crafting recipes progressively) bool false i3_progressive_mode (Learn crafting recipes progressively) bool false
# Regroup the items of the same type in the item list.
i3_item_compression (Regroup items of the same type) bool true
# Set the inventory size to common chests size (8*4).
i3_legacy_inventory (Legacy inventory size) bool false

BIN
sounds/i3_achievement.ogg Normal file

Binary file not shown.

BIN
sounds/i3_skin_change.ogg Normal file

Binary file not shown.

View File

@ -3,7 +3,7 @@ local make_fs, get_inventory_fs = i3.files.gui()
IMPORT("gmatch", "split") IMPORT("gmatch", "split")
IMPORT("S", "err", "fmt", "reg_items") IMPORT("S", "err", "fmt", "reg_items")
IMPORT("sorter", "sort_inventory") IMPORT("sorter", "sort_inventory", "play_sound")
IMPORT("sort", "concat", "copy", "insert", "remove") IMPORT("sort", "concat", "copy", "insert", "remove")
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")
@ -323,8 +323,10 @@ function i3.hud_notif(name, msg, img)
data.show_hud = true data.show_hud = true
data.hud_msg = msg data.hud_msg = msg
play_sound(name, "i3_achievement", 1.0)
if img then if img then
data.hud_img = fmt("%s^[resize:16x16", img) data.hud_img = fmt("%s^[resize:64x64", img)
end end
end end

View File

@ -2,7 +2,7 @@ local replacements = {fuel = {}}
local http = ... local http = ...
IMPORT("maxn", "copy", "insert", "sort", "match", "sub") IMPORT("maxn", "copy", "insert", "sort", "match", "sub")
IMPORT("true_str", "is_table", "valid_item", "table_merge", "table_replace", "rcp_eq") IMPORT("true_str", "is_table", "valid_item", "table_merge", "table_replace", "table_eq")
IMPORT("fmt", "reg_items", "reg_aliases", "reg_nodes", "is_cube", "get_cube", "ItemStack") IMPORT("fmt", "reg_items", "reg_aliases", "reg_nodes", "is_cube", "get_cube", "ItemStack")
IMPORT("is_group", "extract_groups", "item_has_groups", "groups_to_items", "get_group_stereotype") IMPORT("is_group", "extract_groups", "item_has_groups", "groups_to_items", "get_group_stereotype")
@ -248,11 +248,7 @@ local old_clear_craft = core.clear_craft
core.clear_craft = function(def) core.clear_craft = function(def)
old_clear_craft(def) old_clear_craft(def)
if true_str(def) then -- TODO: hide in crafting guide
return -- TODO
elseif is_table(def) then
return -- TODO
end
end end
local function resolve_aliases(hash) local function resolve_aliases(hash)
@ -274,7 +270,7 @@ local function resolve_aliases(hash)
local rcp_new = copy(i3.recipes_cache[newname][j]) local rcp_new = copy(i3.recipes_cache[newname][j])
rcp_new.output = oldname rcp_new.output = oldname
if rcp_eq(rcp_old, rcp_new) then if table_eq(rcp_old, rcp_new) then
similar = true similar = true
break break
end end

View File

@ -6,7 +6,7 @@ local init_hud = i3.files.hud()
local set_fs = i3.set_fs local set_fs = i3.set_fs
IMPORT("slz", "min", "insert", "copy", "ItemStack") IMPORT("slz", "min", "insert", "copy", "ItemStack")
IMPORT("spawn_item", "reset_data", "get_detached_inv", "play_sound") IMPORT("spawn_item", "reset_data", "get_detached_inv", "play_sound", "update_inv_size")
core.register_on_player_hpchange(function(player, hpchange) core.register_on_player_hpchange(function(player, hpchange)
local name = player:get_player_name() local name = player:get_player_name()
@ -203,6 +203,17 @@ 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
default[k] = data[k]
if data[k] == nil then
default[k] = v
end
data[k] = default[k]
end
data.player_name = name data.player_name = name
data.filter = "" data.filter = ""
@ -211,23 +222,16 @@ local function init_data(player, info)
data.items = i3.init_items data.items = i3.init_items
data.items_raw = i3.init_items data.items_raw = i3.init_items
data.favs = {} data.favs = {}
data.sort = "alphabetical"
data.show_setting = "home" data.show_setting = "home"
data.ignore_hotbar = false
data.auto_sorting = false
data.reverse_sorting = false
data.inv_compress = true
data.crafting_counts = {} data.crafting_counts = {}
data.tab = 1 data.tab = 1
data.itab = 1 data.itab = 1
data.subcat = 1 data.subcat = 1
data.scrbar_inv = 0 data.scrbar_inv = 0
data.font_size = data.font_size or 0
data.lang_code = get_lang_code(info) data.lang_code = get_lang_code(info)
data.fs_version = info.formspec_version data.fs_version = info.formspec_version
local inv = player:get_inventory() update_inv_size(player, data)
inv:set_size("main", i3.settings.inv_size)
core.after(0, set_fs, player) core.after(0, set_fs, player)
end end

View File

@ -1,8 +1,8 @@
local vec = vector.new
local ItemStack = ItemStack local ItemStack = ItemStack
local loadstring = loadstring local loadstring = loadstring
local reg_items = core.registered_items local reg_items = core.registered_items
local translate = core.get_translated_string local translate = core.get_translated_string
local vec_new, vec_add, vec_mul = vector.new, vector.add, vector.multiply
local sort, concat, insert = table.sort, table.concat, table.insert local sort, concat, insert = table.sort, table.concat, table.insert
local min, floor, ceil = math.min, math.floor, math.ceil local min, floor, ceil = math.min, math.floor, math.ceil
local fmt, find, match, gmatch, sub, split, lower, upper = local fmt, find, match, gmatch, sub, split, lower, upper =
@ -216,18 +216,22 @@ local function array_diff(t1, t2)
return diff return diff
end end
local function rcp_eq(rcp, rcp2) local function table_eq(t1, t2)
if rcp.type ~= rcp2.type then return end local ty1, ty2 = type(t1), type(t2)
if rcp.width ~= rcp2.width then return end if ty1 ~= ty2 then return end
if #rcp.items ~= #rcp2.items then return end
if rcp.output ~= rcp2.output then return end
for i, item in pairs(rcp.items) do if ty1 ~= "table" and ty2 ~= "table" then
if item ~= rcp2.items[i] then return end return t1 == t2
end end
for i, item in pairs(rcp2.items) do for k, v in pairs(t1) do
if item ~= rcp.items[i] then return end local v2 = t2[k]
if v2 == nil or not table_eq(v, v2) then return end
end
for k, v in pairs(t2) do
local v1 = t1[k]
if v1 == nil or not table_eq(v1, v) then return end
end end
return true return true
@ -324,7 +328,7 @@ local function apply_recipe_filters(recipes, player)
end end
local function compression_active(data) local function compression_active(data)
return i3.settings.item_compression and not next(i3.recipe_filters) and data.filter == "" return data.collapse and not next(i3.recipe_filters) and data.filter == ""
end end
local function compressible(item, data) local function compressible(item, data)
@ -372,7 +376,7 @@ local function spawn_item(player, stack)
local dir = player:get_look_dir() local dir = player:get_look_dir()
local ppos = player:get_pos() local ppos = player:get_pos()
ppos.y = ppos.y + player:get_properties().eye_height ppos.y = ppos.y + player:get_properties().eye_height
local look_at = vec_add(ppos, vec_mul(dir, 1)) local look_at = ppos + dir
core.add_item(look_at, stack) core.add_item(look_at, stack)
end end
@ -443,10 +447,8 @@ local function craft_stack(player, data, craft_rcp)
end end
if rcp_def.replacements then if rcp_def.replacements then
for _, v in ipairs(rcp_def.replacements) do for _, pair in ipairs(rcp_def.replacements) do
for _, item2 in ipairs(v) do get_stack(player, ItemStack(pair[2]))
get_stack(player, ItemStack(item2))
end
end end
end end
@ -471,26 +473,14 @@ local function safe_teleport(player, pos)
play_sound(name, "i3_teleport", 0.8) play_sound(name, "i3_teleport", 0.8)
local vel = player:get_velocity() local vel = player:get_velocity()
player:add_velocity(vec_mul(vel, -1)) player:add_velocity(-vel)
local p = vec_new(pos) local p = vec(pos)
p.y += 0.25 p.y += 0.25
player:set_pos(p) player:set_pos(p)
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 sorter(inv, data, mode) local function sorter(inv, data, mode)
sort(inv, function(a, b) sort(inv, function(a, b)
if mode == 1 then if mode == 1 then
@ -571,7 +561,7 @@ local function sort_inventory(player, data)
local inv = player:get_inventory() local inv = player:get_inventory()
local list = inv:get_list"main" local list = inv:get_list"main"
local size = inv:get_size"main" local size = inv:get_size"main"
local start_i = data.ignore_hotbar and (i3.settings.hotbar_len + 1) or 1 local start_i = data.ignore_hotbar and (data.hotbar_len + 1) or 1
if data.inv_compress then if data.inv_compress then
list = compress_items(list, start_i) list = compress_items(list, start_i)
@ -579,8 +569,7 @@ local function sort_inventory(player, data)
list = pre_sorting(list, start_i) list = pre_sorting(list, start_i)
end end
local idx = get_sorting_idx(data.sort) local new_inv = i3.sorting_methods[data.sort].func(list, data)
local new_inv = i3.sorting_methods[idx].func(list, data)
if not new_inv then return end if not new_inv then return end
if not data.ignore_hotbar then if not data.ignore_hotbar then
@ -638,6 +627,24 @@ local function get_detached_inv(name, player_name)
} }
end end
local function update_inv_size(player, data)
data.hotbar_len = data.legacy_inventory and 8 or 9
data.inv_size = 4 * data.hotbar_len
local inv = player:get_inventory()
inv:set_size("main", data.inv_size)
player:hud_set_hotbar_itemcount(data.hotbar_len)
core.after(0, function()
if data.legacy_inventory then
player:hud_set_hotbar_image"gui_hotbar.png"
else
player:hud_set_hotbar_image"i3_hotbar.png"
end
end)
end
-- Much faster implementation of `unpack` -- Much faster implementation of `unpack`
local function createunpack(n) local function createunpack(n)
local ret = {"local t = ... return "} local ret = {"local t = ... return "}
@ -676,7 +683,6 @@ local _ = {
sorter = sorter, sorter = sorter,
get_recipes = get_recipes, get_recipes = get_recipes,
sort_inventory = sort_inventory, sort_inventory = sort_inventory,
get_sorting_idx = get_sorting_idx,
sort_by_category = sort_by_category, sort_by_category = sort_by_category,
apply_recipe_filters = apply_recipe_filters, apply_recipe_filters = apply_recipe_filters,
@ -720,6 +726,7 @@ local _ = {
-- Inventory -- Inventory
get_stack = get_stack, get_stack = get_stack,
craft_stack = craft_stack, craft_stack = craft_stack,
update_inv_size = update_inv_size,
get_detached_inv = get_detached_inv, get_detached_inv = get_detached_inv,
get_bag_description = get_bag_description, get_bag_description = get_bag_description,
create_inventory = core.create_detached_inventory, create_inventory = core.create_detached_inventory,
@ -761,7 +768,7 @@ local _ = {
is_table = is_table, is_table = is_table,
table_merge = table_merge, table_merge = table_merge,
table_replace = table_replace, table_replace = table_replace,
rcp_eq = rcp_eq, table_eq = table_eq,
array_diff = array_diff, array_diff = array_diff,
-- Math -- Math
@ -773,12 +780,8 @@ local _ = {
random = math.random, random = math.random,
-- Vectors -- Vectors
vec_new = vector.new, vec = vector.new,
vec_add = vector.add,
vec_sub = vector.subtract,
vec_mul = vector.multiply,
vec_round = vector.round, vec_round = vector.round,
vec_eq = vector.equals,
} }
function i3.get(...) function i3.get(...)

View File

@ -10,6 +10,9 @@ local trash = create_inventory("i3_trash", {
inv:set_list(listname, {}) inv:set_list(listname, {})
local name = player:get_player_name() local name = player:get_player_name()
local data = i3.data[name]
data.armor_allow = nil
play_sound(name, "i3_trash", 1.0) play_sound(name, "i3_trash", 1.0)
if not core.is_creative_enabled(name) then if not core.is_creative_enabled(name) then

View File

@ -1,13 +1,13 @@
local set_fs = i3.set_fs local set_fs = i3.set_fs
IMPORT("min", "max", "vec_round")
IMPORT("reg_items", "reg_aliases") IMPORT("reg_items", "reg_aliases")
IMPORT("min", "max", "vec_eq", "vec_round")
IMPORT("S", "random", "translate", "ItemStack")
IMPORT("sort", "copy", "insert", "remove", "indexof") IMPORT("sort", "copy", "insert", "remove", "indexof")
IMPORT("S", "random", "translate", "compressible", "ItemStack")
IMPORT("fmt", "find", "match", "sub", "lower", "split", "toupper") IMPORT("fmt", "find", "match", "sub", "lower", "split", "toupper")
IMPORT("valid_item", "get_stack", "craft_stack", "clean_name", "check_privs", "safe_teleport")
IMPORT("msg", "is_fav", "pos_to_str", "str_to_pos", "add_hud_waypoint", "play_sound", "reset_data") IMPORT("msg", "is_fav", "pos_to_str", "str_to_pos", "add_hud_waypoint", "play_sound", "reset_data")
IMPORT("search", "get_sorting_idx", "sort_inventory", "sort_by_category", "get_recipes", "get_detached_inv") IMPORT("search", "sort_inventory", "sort_by_category", "get_recipes", "get_detached_inv", "update_inv_size")
IMPORT("valid_item", "get_stack", "craft_stack", "clean_name", "compressible", "check_privs", "safe_teleport")
local function inv_fields(player, data, fields) local function inv_fields(player, data, fields)
local name = data.player_name local name = data.player_name
@ -19,6 +19,12 @@ local function inv_fields(player, data, fields)
return return
end end
if fields.dd_sorting_method then
data.sort = tonumber(fields.dd_sorting_method)
elseif fields.sb_font_size then
data.font_size = tonumber(fields.sb_font_size:match"-?%d+$")
end
for field in pairs(fields) do for field in pairs(fields) do
if sub(field, 1, 4) == "btn_" then if sub(field, 1, 4) == "btn_" then
data.subcat = indexof(i3.categories, sub(field, 5)) data.subcat = indexof(i3.categories, sub(field, 5))
@ -32,12 +38,20 @@ local function inv_fields(player, data, fields)
data[str] = true data[str] = true
end end
if str == "legacy_inventory" then
update_inv_size(player, data)
elseif str == "collapse" then
search(data)
end
elseif sub(field, 1, 8) == "setting_" then elseif sub(field, 1, 8) == "setting_" then
data.show_setting = match(field, "_(%w+)$") data.show_setting = match(field, "_(%w+)$")
elseif sub(field, 1, 9) == "skin_btn_" then elseif sub(field, 1, 9) == "skin_btn_" then
local id = tonumber(field:match("%d+")) local id = tonumber(field:match("%d+"))
local _skins = skins.get_skinlist_for_player(name) local _skins = skins.get_skinlist_for_player(name)
play_sound(name, "i3_skin_change", 0.6)
skins.set_player_skin(player, _skins[id]) skins.set_player_skin(player, _skins[id])
elseif find(field, "waypoint_%d+") then elseif find(field, "waypoint_%d+") then
@ -124,20 +138,6 @@ local function inv_fields(player, data, fields)
elseif fields.sort then elseif fields.sort then
sort_inventory(player, data) 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 -= (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.home then elseif fields.home then
if not data.home then if not data.home then
return msg(name, "No home set") return msg(name, "No home set")
@ -154,9 +154,6 @@ local function inv_fields(player, data, fields)
elseif fields.bag_rename then elseif fields.bag_rename then
data.bag_rename = true data.bag_rename = true
elseif fields.sb_font_size then
data.font_size = tonumber(fields.sb_font_size:match"-?%d+$")
elseif fields.confirm_rename then elseif fields.confirm_rename then
local bag = get_detached_inv("bag", name) local bag = get_detached_inv("bag", name)
local bagstack = bag:get_stack("main", 1) local bagstack = bag:get_stack("main", 1)
@ -187,9 +184,9 @@ local function inv_fields(player, data, fields)
local pos = player:get_pos() local pos = player:get_pos()
for _, v in ipairs(data.waypoints) do for _, v in ipairs(data.waypoints) do
if vec_eq(vec_round(pos), vec_round(str_to_pos(v.pos))) then if vec_round(pos) == vec_round(str_to_pos(v.pos)) then
play_sound(name, "i3_cannot", 0.8) play_sound(name, "i3_cannot", 0.8)
return msg(name, S"You already set a waypoint at this position") return msg(name, S"You already have set a waypoint at this position")
end end
end end
@ -312,7 +309,7 @@ end
local function rcp_fields(player, data, fields) local function rcp_fields(player, data, fields)
local sb_rcp, sb_usg = fields.scrbar_rcp, fields.scrbar_usg local sb_rcp, sb_usg = fields.scrbar_rcp, fields.scrbar_usg
if fields.filter and fields.filter == "" then if not data.hide_tabs and fields.filter and fields.filter == "" then
data.enable_search = nil data.enable_search = nil
end end
@ -323,7 +320,11 @@ local function rcp_fields(player, data, fields)
data.query_item = nil data.query_item = nil
elseif fields.enable_search then elseif fields.enable_search then
if data.hide_tabs then
data.enable_search = not data.enable_search
else
data.enable_search = true data.enable_search = true
end
elseif fields.filter and (fields.key_enter_field == "filter" or fields.search) then elseif fields.filter and (fields.key_enter_field == "filter" or fields.search) then
if fields.filter == "" then if fields.filter == "" then
@ -431,18 +432,19 @@ core.register_on_player_receive_fields(function(player, formname, fields)
if formname == "i3_outdated" then if formname == "i3_outdated" then
return false, core.kick_player(name, return false, core.kick_player(name,
S"Come back when your Minetest client is up-to-date (www.minetest.net).") S"Your Minetest client needs updating (www.minetest.net)")
elseif formname ~= "" then elseif formname ~= "" then
return false return false
end end
-- No-op buttons -- No-op buttons
if fields.player_name or fields.awards or fields.home_pos or fields.no_item or if fields.player_name or fields.awards or fields.home_pos or fields.no_item or
fields.no_rcp or fields.select_sorting or fields.sort_method or fields.bg_content then fields.no_rcp or fields.select_sorting or fields.sort_method or fields.bg_content or
fields.quick_crafting then
return false return false
end end
--print(dump(fields)) -- print(dump(fields))
local data = i3.data[name] local data = i3.data[name]
if not data then return end if not data then return end

View File

@ -1,5 +1,4 @@
local damage_enabled = i3.settings.damage_enabled local damage_enabled = i3.settings.damage_enabled
local hotbar_len = i3.settings.hotbar_len
local debug_mode = i3.settings.debug_mode local debug_mode = i3.settings.debug_mode
local model_aliases = i3.files.model_alias() local model_aliases = i3.files.model_alias()
@ -8,13 +7,13 @@ local PNG, styles, fs_elements, colors = i3.files.styles()
local sprintf = string.format local sprintf = string.format
local VoxelArea, VoxelManip = VoxelArea, VoxelManip local VoxelArea, VoxelManip = VoxelArea, VoxelManip
IMPORT("vec", "vec_round")
IMPORT("find", "match", "sub", "upper") IMPORT("find", "match", "sub", "upper")
IMPORT("vec_new", "vec_sub", "vec_round")
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("reg_items", "reg_tools", "reg_entities")
IMPORT("true_str", "is_fav", "is_num", "str_to_pos") IMPORT("true_str", "is_fav", "is_num", "str_to_pos")
IMPORT("get_sorting_idx", "compression_active", "compressible") 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("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")
@ -128,10 +127,13 @@ local function get_stack_max(inv, data, is_recipe, rcp)
return max_stacks return max_stacks
end end
local function get_inv_slots(fs) local function get_inv_slots(data, fs)
local inv_x = i3.settings.legacy_inventory and 0.75 or 0.22 local legacy_inventory = data.legacy_inventory
local inv_y = 6.9 local hotbar_len = data.hotbar_len
local size, spacing = 1, 0.1 local inv_x = legacy_inventory and 0.23 or 0.22
local inv_y = legacy_inventory and 6.7 or 6.9
local spacing = legacy_inventory and 0.25 or 0.1
local size = 1
fs"style_type[box;colors=#77777710,#77777710,#777,#777]" fs"style_type[box;colors=#77777710,#77777710,#777,#777]"
@ -139,19 +141,20 @@ local function get_inv_slots(fs)
box(i * size + inv_x + (i * spacing), inv_y, size, size, "") box(i * size + inv_x + (i * spacing), inv_y, size, size, "")
end end
fs(fmt("style_type[list;size=%f;spacing=%f]", size, spacing), fs("style_type[list;size=%f;spacing=%f]", size, spacing)
fmt("list[current_player;main;%f,%f;%u,1;]", inv_x, inv_y, hotbar_len)) fs("list[current_player;main;%f,%f;%u,1;]", inv_x, inv_y, hotbar_len)
fs(fmt("style_type[list;size=%f;spacing=%f]", size, spacing), fs("style_type[list;size=%f;spacing=%f,%f]", size, spacing, legacy_inventory and 0.15 or spacing)
fmt("list[current_player;main;%f,%f;%u,%u;%u]", inv_x, inv_y + 1.15,
hotbar_len, i3.settings.inv_size / hotbar_len, hotbar_len),
"style_type[list;size=1;spacing=0.15]")
fs("list[current_player;main;%f,%f;%u,%u;%u]", inv_x, inv_y + (legacy_inventory and 1.25 or 1.15),
hotbar_len, data.inv_size / hotbar_len, hotbar_len)
fs"style_type[list;size=1;spacing=0.15]"
fs"listring[current_player;craft]listring[current_player;main]" fs"listring[current_player;craft]listring[current_player;main]"
end end
local function add_subtitle(fs, name, y, ctn_len, font_size, sep, label) local function add_subtitle(fs, name, y, ctn_len, font_size, sep, label)
fs(fmt("style[%s;font=bold;font_size=%u]", name, font_size)) fs("style[%s;font=bold;font_size=%u]", name, font_size)
button(0, y, ctn_len, 0.5, name, ESC(label)) button(0, y, ctn_len, 0.5, name, ESC(label))
if sep then if sep then
@ -237,8 +240,8 @@ local function get_isometric_view(fs, pos, X, Y, t, cubes, depth, high)
local max_depth = -7 local max_depth = -7
local height = base_depth and (base_height - 1) or depth local height = base_depth and (base_height - 1) or depth
local pos1 = vec_new(pos.x - width, pos.y + depth, pos.z - width) local pos1 = vec(pos.x - width, pos.y + depth, pos.z - width)
local pos2 = vec_new(pos.x + width, pos.y + height, pos.z + width) local pos2 = vec(pos.x + width, pos.y + height, pos.z + width)
local vm = VoxelManip(pos1, pos2) local vm = VoxelManip(pos1, pos2)
local emin, emax = vm:get_emerged_area() local emin, emax = vm:get_emerged_area()
@ -252,7 +255,7 @@ local function get_isometric_view(fs, pos, X, Y, t, cubes, depth, high)
if img then if img then
local p = area:position(idx) local p = area:position(idx)
p = vec_sub(p, pos) p -= pos
local size = 0.25 local size = 0.25
local x = 2 + (size / 2 * (p.z - p.x)) local x = 2 + (size / 2 * (p.z - p.x))
@ -298,14 +301,14 @@ local function get_isometric_view(fs, pos, X, Y, t, cubes, depth, high)
end end
local function get_waypoint_fs(fs, data, player, yextra, ctn_len) local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
fs(fmt("box[0,%f;4.9,0.6;#bababa25]", yextra + 1.1)) fs("box[0,%f;4.9,0.6;#bababa25]", yextra + 1.1)
label(0, yextra + 0.85, ES"Waypoint name:") label(0, yextra + 0.85, ES"New waypoint" .. ":")
fs(fmt("field[0.1,%f;4.8,0.6;waypoint_name;;]", yextra + 1.1)) fs("field[0.1,%f;4.8,0.6;waypoint_name;;]", yextra + 1.1)
image_button(5.1, yextra + 1.15, 0.5, 0.5, "", "waypoint_add", "") image_button(5.1, yextra + 1.15, 0.5, 0.5, "", "waypoint_add", "")
fs(fmt("tooltip[waypoint_add;%s]", ES"Add waypoint")) fs("tooltip[waypoint_add;%s]", ES"Add waypoint")
if #data.waypoints == 0 then return end if #data.waypoints == 0 then return end
fs("style_type[label;font=bold;font_size=17]") fs"style_type[label;font=bold;font_size=17]"
for i, v in ipairs(data.waypoints) do for i, v in ipairs(data.waypoints) do
local y = yextra + 1.35 + (i - (i * 0.3)) local y = yextra + 1.35 + (i - (i * 0.3))
@ -338,25 +341,25 @@ local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
tooltip(0, y, ctn_len - 2.1, 0.65, tooltip) tooltip(0, y, ctn_len - 2.1, 0.65, tooltip)
local del = fmt("waypoint_%u_delete", i) 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)) fs("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", del, PNG.trash, PNG.trash_hover)
image_button(ctn_len - 0.5, yi, icon_size, icon_size, "", del, "") image_button(ctn_len - 0.5, yi, icon_size, icon_size, "", del, "")
fs(fmt("tooltip[%s;%s]", del, ES"Remove waypoint")) fs("tooltip[%s;%s]", del, ES"Remove waypoint")
local rfs = fmt("waypoint_%u_refresh", i) local rfs = fmt("waypoint_%u_refresh", i)
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", rfs, PNG.refresh, PNG.refresh_hover)) fs("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", rfs, PNG.refresh, PNG.refresh_hover)
image_button(ctn_len - 1, yi, icon_size, icon_size, "", rfs, "") image_button(ctn_len - 1, yi, icon_size, icon_size, "", rfs, "")
fs(fmt("tooltip[%s;%s]", rfs, ES"Change color")) fs("tooltip[%s;%s]", rfs, ES"Change color")
local see = fmt("waypoint_%u_see", i) local see = fmt("waypoint_%u_see", i)
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", fs("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]",
see, waypoint_preview and PNG.search_hover or PNG.search, PNG.search, PNG.search_hover)) see, waypoint_preview and PNG.search_hover or PNG.search, PNG.search, PNG.search_hover)
image_button(ctn_len - 1.5, yi, icon_size, icon_size, "", see, "") image_button(ctn_len - 1.5, yi, icon_size, icon_size, "", see, "")
fs(fmt("tooltip[%s;%s]", see, ES"Preview the waypoint area")) fs("tooltip[%s;%s]", see, ES"Preview the waypoint area")
local vsb = fmt("waypoint_%u_hide", i) local vsb = fmt("waypoint_%u_hide", i)
fs(fmt("style[%s;fgimg=%s;content_offset=0]", vsb, v.hide and PNG.nonvisible or PNG.visible)) fs("style[%s;fgimg=%s;content_offset=0]", vsb, v.hide and PNG.nonvisible or PNG.visible)
image_button(ctn_len - 2, yi, icon_size, icon_size, "", vsb, "") image_button(ctn_len - 2, yi, icon_size, icon_size, "", vsb, "")
fs(fmt("tooltip[%s;%s]", vsb, v.hide and ES"Show waypoint" or ES"Hide waypoint")) fs("tooltip[%s;%s]", vsb, v.hide and ES"Show waypoint" or ES"Hide waypoint")
if teleport_priv then if teleport_priv then
local tp = fmt("waypoint_%u_teleport", i) local tp = fmt("waypoint_%u_teleport", i)
@ -378,7 +381,7 @@ local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
end end
local function get_bag_fs(fs, data, name, esc_name, bag_size, yextra) local function get_bag_fs(fs, data, name, esc_name, bag_size, yextra)
fs(fmt("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;]", esc_name, yextra + 0.7)
local bag = get_detached_inv("bag", name) local bag = get_detached_inv("bag", name)
if bag:is_empty"main" then return end if bag:is_empty"main" then return end
@ -389,18 +392,18 @@ local function get_bag_fs(fs, data, name, esc_name, bag_size, yextra)
local desc = ESC(get_bag_description(data, bagstack)) local desc = ESC(get_bag_description(data, bagstack))
image(0.5, yextra + 1.85, 0.6, 0.6, PNG.arrow_content) image(0.5, yextra + 1.85, 0.6, 0.6, PNG.arrow_content)
fs(fmt("style[bg_content;bgimg=%s;fgimg=i3_blank.png;bgimg_middle=10,%u;sound=]", PNG.bg_content, m)) fs("style[bg_content;bgimg=%s;fgimg=i3_blank.png;bgimg_middle=10,%u;sound=]", PNG.bg_content, m)
image_button(1.1, yextra + 0.5 + (yy or 0), 4.75, h, "", "bg_content", "") image_button(1.1, yextra + 0.5 + (yy or 0), 4.75, h, "", "bg_content", "")
if not data.bag_rename then if not data.bag_rename then
hypertext(1.3, yextra + 0.8, 4.3, 0.6, "content", hypertext(1.3, yextra + 0.8, 4.3, 0.6, "content",
fmt("<global size=16><center><b>%s</b></center>", desc)) fmt("<global size=16><center><b>%s</b></center>", desc))
image_button(5.22, yextra + 0.835, 0.25, 0.25, "", "bag_rename", "") image_button(5.22, yextra + 0.835, 0.25, 0.25, "", "bag_rename", "")
fs(fmt("tooltip[%s;%s]", "bag_rename", ES"Rename the bag")) fs("tooltip[bag_rename;%s]", ES"Rename the bag")
else else
box(1.7, yextra + 0.82, 2.6, 0.4, "#707070") box(1.7, yextra + 0.82, 2.6, 0.4, "#707070")
fs(fmt("field[1.8,%f;2.5,0.4;bag_newname;;%s]", yextra + 0.82, desc), fs("field[1.8,%f;2.5,0.4;bag_newname;;%s]", yextra + 0.82, desc)
"field_close_on_enter[bag_newname;false]") fs"field_close_on_enter[bag_newname;false]"
hypertext(4.4, yextra + 0.88, 0.8, 0.6, "confirm_rename", hypertext(4.4, yextra + 0.88, 0.8, 0.6, "confirm_rename",
fmt("<global size=16><tag name=action color=#fff hovercolor=%s>" .. fmt("<global size=16><tag name=action color=#fff hovercolor=%s>" ..
"<center><b><action name=ok>OK</action></b></center>", colors.yellow)) "<center><b><action name=ok>OK</action></b></center>", colors.yellow))
@ -412,8 +415,8 @@ local function get_bag_fs(fs, data, name, esc_name, bag_size, yextra)
x, size, spacing = 1.7, 0.8, 0.1 x, size, spacing = 1.7, 0.8, 0.1
end end
fs(fmt("style_type[list;size=%f;spacing=%f]", size, spacing)) fs("style_type[list;size=%f;spacing=%f]", size, spacing)
fs(fmt("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;]", esc_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
@ -432,7 +435,7 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
for i = 1, 10 do for i = 1, 10 do
image(heart_x + ((i - 1) * (heart_size + 0.1)), heart_h, image(heart_x + ((i - 1) * (heart_size + 0.1)), heart_h,
heart_size, heart_size, PNG.heart_grey) heart_size, heart_size, PNG.heart .. "^[colorize:#232428")
end end
for i = 1, hearts do for i = 1, hearts do
@ -444,21 +447,21 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
yoffset -= 0.5 yoffset -= 0.5
end end
fs(fmt("list[current_player;craft;%f,%f;3,3;]", 0, yoffset + 1.45)) fs("list[current_player;craft;%f,%f;3,3;]", 0, yoffset + 1.45)
image(3.47, yoffset + 2.69, 0.85, 0.85, PNG.arrow) image(3.47, yoffset + 2.69, 0.85, 0.85, PNG.arrow)
fs(fmt("list[current_player;craftpreview;%f,%f;1,1;]", 4.45, yoffset + 2.6), fs("list[current_player;craftpreview;%f,%f;1,1;]", 4.45, yoffset + 2.6)
fmt("list[detached:i3_trash;main;%f,%f;1,1;]", 4.45, yoffset + 3.75)) fs("list[detached:i3_trash;main;%f,%f;1,1;]", 4.45, yoffset + 3.75)
image(4.45, yoffset + 3.75, 1, 1, PNG.trash) image(4.45, yoffset + 3.75, 1, 1, PNG.trash)
local yextra = damage_enabled and 5.5 or 5 local yextra = damage_enabled and 5.5 or 5
for i, title in ipairs(i3.categories) do for i, title in ipairs(i3.categories) do
local btn_name = fmt("btn_%s", title) local btn_name = fmt("btn_%s", title)
fs(fmt("style[btn_%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", title, fs("style[btn_%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", title,
data.subcat == i and PNG[fmt("%s_hover", title)] or PNG[title], data.subcat == i and PNG[fmt("%s_hover", title)] or PNG[title],
PNG[fmt("%s_hover", title)])) PNG[fmt("%s_hover", title)])
image_button(0.25 + ((i - 1) * 1.18), yextra - 0.2, 0.5, 0.5, "", btn_name, "") image_button(0.25 + ((i - 1) * 1.18), yextra - 0.2, 0.5, 0.5, "", btn_name, "")
fs(fmt("tooltip[%s;%s]", btn_name, title:gsub("^%l", upper))) fs("tooltip[%s;%s]", btn_name, title:gsub("^%l", upper))
end end
box(0, yextra + 0.45, ctn_len, 0.045, "#bababa50") box(0, yextra + 0.45, ctn_len, 0.045, "#bababa50")
@ -479,10 +482,11 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
end end
local armor_def = armor.def[name] local armor_def = armor.def[name]
fs(fmt("list[detached:%s_armor;armor;0,%f;5,1;]", esc_name, yextra + 0.7)) 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)
for i = 1, 5 do for i = 1, 5 do
local _, armor_inv = armor:get_valid_player(player, "3d_armor")
local stack = armor_inv:get_stack("armor", i) local stack = armor_inv:get_stack("armor", i)
if stack:is_empty() then if stack:is_empty() then
@ -544,11 +548,10 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
if not skin then break end if not skin then break end
local btn_name = fmt("skin_btn_%u", i + 1) local btn_name = fmt("skin_btn_%u", i + 1)
fs(fmt([[ style[%s;padding=10; fs([[ style[%s;padding=10;fgimg=%s;bgimg=%s;bgimg_hovered=i3_btn9_hovered.png;
fgimg=%s;bgimg=%s;bgimg_hovered=i3_btn9_hovered.png; bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6;sound=] ]],
bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6] ]],
btn_name, skin:get_preview(), btn_name, skin:get_preview(),
skin.name == skin_name and "i3_btn9_hovered.png" or "i3_btn9.png")) skin.name == skin_name and "i3_btn9_hovered.png" or "i3_btn9.png")
local X = (i % 3) * 1.93 local X = (i % 3) * 1.93
@ -556,7 +559,7 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
Y += (Y * 2.45) + yextra - 2.75 + add_y Y += (Y * 2.45) + yextra - 2.75 + add_y
image_button(X, Y, 1.86, 3.4, "", btn_name, "") image_button(X, Y, 1.86, 3.4, "", btn_name, "")
fs(fmt("tooltip[%s;%s]", btn_name, ESC(skin.name))) fs("tooltip[%s;%s]", btn_name, ESC(skin.name))
end end
elseif data.subcat == 4 then elseif data.subcat == 4 then
@ -572,45 +575,41 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
end end
end end
local function show_popup(fs, data) local function show_settings(fs, data)
if data.confirm_trash then if data.confirm_trash then
fs"style_type[box;colors=#999,#999,#808080,#808080]" image(2.8, 10.65, 4.6, 0.7, PNG.bg_goto)
label(3.02, 11, "Confirm trash?")
for _ = 1, 3 do image_button(5.07, 10.75, 1, 0.5, "", "confirm_trash_yes", "Yes")
box(2.97, 10.75, 4.3, 0.5, "") image_button(6.17, 10.75, 1, 0.5, "", "confirm_trash_no", "No")
end
label(3.12, 11, "Confirm trash?")
image_button(5.17, 10.75, 1, 0.5, "", "confirm_trash_yes", "Yes")
image_button(6.27, 10.75, 1, 0.5, "", "confirm_trash_no", "No")
elseif data.show_settings then elseif data.show_settings then
fs"style_type[box;colors=#999,#999,#808080,#808080]" fs"container[-0.06,0]"
image(2.2, 9, 6.1, 2.35, PNG.bg_content)
for _ = 1, 3 do
box(2.1, 9.25, 6, 2, "")
end
for _ = 1, 3 do
box(2.1, 9.25, 6, 0.5, "#707070")
end
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_home = data.show_setting == "home"
local show_style = data.show_setting == "style"
local show_sorting = data.show_setting == "sorting" local show_sorting = data.show_setting == "sorting"
local show_misc = data.show_setting == "misc"
fs(fmt("style[setting_home;textcolor=%s;font=bold;font_size=16;sound=i3_click]", fs"style[setting_home,setting_style,setting_sorting;font=bold;font_size=16;sound=i3_click]"
show_home and colors.yellow or "#fff"), fs("style[setting_home:hovered;textcolor=%s]", show_home and colors.yellow or "#fff")
fmt("style[setting_sorting;textcolor=%s;font=bold;font_size=16;sound=i3_click]", fs("style[setting_style:hovered;textcolor=%s]", show_style and colors.yellow or "#fff")
show_sorting and colors.yellow or "#fff"), fs("style[setting_sorting:hovered;textcolor=%s]", show_sorting and colors.yellow or "#fff")
fmt("style[setting_misc;textcolor=%s;font=bold;font_size=16;sound=i3_click]",
show_misc and colors.yellow or "#fff"))
button(2.2, 9.25, 1.8, 0.55, "setting_home", "Home") fs("style[setting_home;bgimg=%s;bgimg_hovered=%s;bgimg_middle=9;padding=-9;textcolor=%s]",
button(4, 9.25, 1.8, 0.55, "setting_sorting", "Sorting") show_home and PNG.pagenum_hover or "", PNG.pagenum_hover,
button(5.8, 9.25, 1.8, 0.55, "setting_misc", "Misc.") show_home and colors.yellow or "#ddd")
fs("style[setting_style;bgimg=%s;bgimg_hovered=%s;bgimg_middle=9;padding=-9;textcolor=%s]",
show_style and PNG.pagenum_hover or "", PNG.pagenum_hover,
show_style and colors.yellow or "#ddd")
fs("style[setting_sorting;bgimg=%s;bgimg_hovered=%s;bgimg_middle=9;padding=-9;textcolor=%s]",
show_sorting and PNG.pagenum_hover or "", PNG.pagenum_hover,
show_sorting and colors.yellow or "#ddd")
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")
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
local coords, c, str = {"X", "Y", "Z"}, 0, ES"No home set" local coords, c, str = {"X", "Y", "Z"}, 0, ES"No home set"
@ -620,61 +619,83 @@ local function show_popup(fs, data)
"(%-?%d+)", function(a) "(%-?%d+)", function(a)
c++ c++
return fmt("<b>%s: <style color=%s font=mono>%s</style></b>", return fmt("<b>%s: <style color=%s font=mono>%s</style></b>",
coords[c], colors.black, a) coords[c], colors.blue, a)
end) end)
end end
hypertext(2.1, 9.9, 6, 0.6, "home_pos", fmt("<global size=16><center>%s</center>", str)) hypertext(2.2, 9.9, 6, 0.6, "home_pos", fmt("<global size=16><center>%s</center>", str))
image_button(4.2, 10.4, 1.8, 0.7, "", "set_home", "Set home") image_button(4.3, 10.4, 1.8, 0.7, "", "set_home", "Set home")
elseif show_sorting then elseif show_style then
button(2.1, 9.7, 6, 0.8, "select_sorting", ES"Select the inventory sorting method:") checkbox(2.6, 9.95, "cb_hide_tabs", "Hide tabs", tostring(data.hide_tabs))
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))
image_button(2.2, 10.6, 0.35, 0.35, "", "prev_sort", "") if not next(i3.recipe_filters) then
image_button(7.65, 10.6, 0.35, 0.35, "", "next_sort", "") checkbox(5.3, 10.85, "cb_collapse", "Collapse inventory", tostring(data.collapse))
fs"style[sort_method;font=bold;font_size=20]"
button(2.55, 10.36, 5.1, 0.8, "sort_method", toupper(data.sort))
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 end
elseif show_misc then
checkbox(2.4, 10.05, "cb_inv_compress", "Compression", tostring(data.inv_compress))
checkbox(2.4, 10.5, "cb_reverse_sorting", "Reverse mode", tostring(data.reverse_sorting))
checkbox(2.4, 10.95, "cb_ignore_hotbar", "Ignore hotbar", tostring(data.ignore_hotbar))
checkbox(5.4, 10.05, "cb_auto_sorting", "Automation", tostring(data.auto_sorting))
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 ""
label(5.4, 10.55, ES"Font size" .. fmt(": %s", sign .. data.font_size)) label(5.3, 9.95, ES"Font size" .. fmt(": %s", sign .. data.font_size))
local range = 5 local range = 5
fs(fmt("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(fmt("scrollbar[5.4,10.8;2.5,0.25;horizontal;sb_font_size;%d]", data.font_size)) fs("scrollbar[5.3,10.2;2.45,0.3;horizontal;sb_font_size;%d]", data.font_size)
fs(fmt("tooltip[cb_inv_compress;%s;#707070;#fff]", fs("tooltip[cb_hide_tabs;%s;#707070;#fff]",
ES"Enable this option to compress your inventory"), ES"Enable this option to change the style of the right panel")
fmt("tooltip[cb_reverse_sorting;%s;#707070;#fff]", fs("tooltip[cb_legacy_inventory;%s;#707070;#fff]",
ES"Enable this option to sort your inventory in reverse order"), ES"Enable this option to set the classic inventory size in Minetest")
fmt("tooltip[cb_ignore_hotbar;%s;#707070;#fff]", fs("tooltip[cb_wielditem_hud;%s;#707070;#fff]",
ES"Enable this option to sort your inventory except the hotbar slots"), ES"Enable this option to show the wielded item description in your HUD")
fmt("tooltip[cb_auto_sorting;%s;#707070;#fff]", fs("tooltip[cb_collapse;%s;#707070;#fff]",
ES"Enable this option to sort your inventory automatically")) ES"Enable this option to collapse certain items in your inventory")
elseif show_sorting then
checkbox(2.6, 9.95, "cb_inv_compress", "Compression", tostring(data.inv_compress))
checkbox(2.6, 10.4, "cb_reverse_sorting", "Reverse mode", tostring(data.reverse_sorting))
checkbox(2.6, 10.85, "cb_ignore_hotbar", "Ignore hotbar", tostring(data.ignore_hotbar))
checkbox(5.3, 9.95, "cb_auto_sorting", "Automation", tostring(data.auto_sorting))
local methods = {}
for _, v in ipairs(i3.sorting_methods) do
local name = toupper(v.name)
insert(methods, name)
end end
label(5.3, 10.4, ES"Sorting method:")
fs("dropdown[%f,%f;2.6,0.5;dd_sorting_method;%s;%u;true]",
5.3, 10.6, concat(methods, ","), data.sort)
local desc = i3.sorting_methods[data.sort].description
if desc then
tooltip(5.3, 10.6, 2.4, 0.5, ESC(desc))
end
fs("tooltip[cb_inv_compress;%s;#707070;#fff]",
ES"Enable this option to compress your inventory")
fs("tooltip[cb_reverse_sorting;%s;#707070;#fff]",
ES"Enable this option to sort your inventory in reverse order")
fs("tooltip[cb_ignore_hotbar;%s;#707070;#fff]",
ES"Enable this option to sort your inventory except the hotbar slots")
fs("tooltip[cb_auto_sorting;%s;#707070;#fff]",
ES"Enable this option to sort your inventory automatically")
end
fs"container_end[]"
end end
end end
local function get_inventory_fs(player, data, fs) local function get_inventory_fs(player, data, fs)
fs"listcolors[#bababa50;#bababa99]" fs"listcolors[#bababa50;#bababa99]"
get_inv_slots(fs) get_inv_slots(data, fs)
local props = player:get_properties() local props = player:get_properties()
local ctn_len, ctn_hgt, yoffset = 5.7, 6.3, 0 local ctn_len = 5.7
local ctn_hgt = data.legacy_inventory and 6.1 or 6.3
local yoffset = 0
if props.mesh ~= "" then if props.mesh ~= "" then
local anim = player:get_local_animation() local anim = player:get_local_animation()
@ -687,7 +708,7 @@ local function get_inventory_fs(player, data, fs)
local textures = concat(t, ","):gsub("!", ",") local textures = concat(t, ","):gsub("!", ",")
--fs("style[player_model;bgcolor=black]") -- fs"style[player_model;bgcolor=black]"
model(0.2, 0.2, armor_skin and 4 or 3.4, ctn_hgt, model(0.2, 0.2, armor_skin and 4 or 3.4, ctn_hgt,
"player_model", props.mesh, textures, "0,-150", "false", "false", "player_model", props.mesh, textures, "0,-150", "false", "false",
fmt("%u,%u;30", anim.x, anim.y)) fmt("%u,%u;30", anim.x, anim.y))
@ -698,6 +719,7 @@ local function get_inventory_fs(player, data, fs)
local awards_unlocked, award_list, award_list_nb = 0 local awards_unlocked, award_list, award_list_nb = 0
local max_val = damage_enabled and 12 or 7 local max_val = damage_enabled and 12 or 7
max_val += (data.legacy_inventory and 2 or 0)
local bag_size = get_group(ItemStack(data.bag):get_name(), "bag") local bag_size = get_group(ItemStack(data.bag):get_name(), "bag")
if data.subcat == 1 and bag_size > 0 then if data.subcat == 1 and bag_size > 0 then
@ -741,14 +763,12 @@ local function get_inventory_fs(player, data, fs)
end end
end end
fs(fmt([[ fs([[ scrollbaroptions[arrows=hide;thumbsize=%d;max=%d]
scrollbaroptions[arrows=hide;thumbsize=%d;max=%d]
scrollbar[%f,0.2;0.2,%f;vertical;scrbar_inv;%u] scrollbar[%f,0.2;0.2,%f;vertical;scrbar_inv;%u]
scrollbaroptions[arrows=default;thumbsize=0;max=1000] scrollbaroptions[arrows=default;thumbsize=0;max=1000] ]],
]], (max_val * 4) / 12, max_val, 9.8, ctn_hgt, data.scrbar_inv)
(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)) fs("scroll_container[3.9,0.2;%f,%f;scrbar_inv;vertical]", ctn_len, ctn_hgt)
get_container(fs, data, player, yoffset, ctn_len, award_list, awards_unlocked, award_list_nb, bag_size) get_container(fs, data, player, yoffset, ctn_len, award_list, awards_unlocked, award_list_nb, bag_size)
fs"scroll_container_end[]" fs"scroll_container_end[]"
@ -761,13 +781,13 @@ local function get_inventory_fs(player, data, fs)
for i, v in ipairs(btn) do for i, v in ipairs(btn) do
local btn_name, tooltip = unpack(v) local btn_name, tooltip = unpack(v)
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", fs("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]",
btn_name, PNG[btn_name], PNG[fmt("%s_hover", btn_name)])) btn_name, PNG[btn_name], PNG[fmt("%s_hover", btn_name)])
image_button(i + 3.43 - (i * 0.4), 11.43, 0.35, 0.35, "", btn_name, "") image_button(i + 3.43 - (i * 0.4), 11.43, 0.35, 0.35, "", btn_name, "")
fs(fmt("tooltip[%s;%s]", btn_name, tooltip)) fs("tooltip[%s;%s]", btn_name, tooltip)
end end
show_popup(fs, data) show_settings(fs, data)
end end
local function get_tooltip(item, info, pos, lang_code) local function get_tooltip(item, info, pos, lang_code)
@ -851,7 +871,23 @@ local function get_tooltip(item, info, pos, lang_code)
return fmt("tooltip[%s;%s]", item, ESC(tooltip)) return fmt("tooltip[%s;%s]", item, ESC(tooltip))
end end
local function get_output_fs(fs, data, rcp, is_recipe, shapeless, right, btn_size, btn_size2) local function get_true_count(data, count, is_recipe, is_usage)
local count_mul = 1
if is_recipe then
count_mul = data.scrbar_rcp
elseif is_usage then
count_mul = data.scrbar_usg
end
if count_mul then
count *= count_mul
end
return count
end
local function get_output_fs(fs, data, rcp, is_recipe, is_usage, shapeless, right, btn_size, btn_size2)
local custom_recipe = i3.craft_types[rcp.type] local custom_recipe = i3.craft_types[rcp.type]
local cooking = rcp.type == "cooking" local cooking = rcp.type == "cooking"
local fuel = rcp.type == "fuel" local fuel = rcp.type == "fuel"
@ -910,9 +946,9 @@ local function get_output_fs(fs, data, rcp, is_recipe, shapeless, right, btn_siz
if meta:get_string"color" ~= "" or meta:get_string"palette_index" ~= "" then if meta:get_string"color" ~= "" or meta:get_string"palette_index" ~= "" then
local rcp_usg = is_recipe and "rcp" or "usg" local rcp_usg = is_recipe and "rcp" or "usg"
fs(fmt("style_type[list;size=%f]", BTN_SIZE)) fs("style_type[list;size=%f]", BTN_SIZE)
fs"listcolors[#bababa50;#bababa99]" fs"listcolors[#bababa50;#bababa99]"
fs(fmt("list[detached:i3_output_%s_%s;main;%f,%f;1,1;]", rcp_usg, data.player_name, X + 0.11, Y)) 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, "") button(X + 0.11, Y, BTN_SIZE, BTN_SIZE, _name, "")
local inv = get_detached_inv(fmt("output_%s", rcp_usg), data.player_name) local inv = get_detached_inv(fmt("output_%s", rcp_usg), data.player_name)
@ -922,7 +958,7 @@ local function get_output_fs(fs, data, rcp, is_recipe, shapeless, right, btn_siz
local size = BTN_SIZE * 1.2 local size = BTN_SIZE * 1.2
slot(X, Y - 0.11, size, size) slot(X, Y - 0.11, size, size)
count *= (is_recipe and data.scrbar_rcp or data.scrbar_usg or 1) 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, "") item_image_button(X + 0.11, Y, BTN_SIZE, BTN_SIZE, fmt("%s %u %u", name, count, wear), _name, "")
end end
@ -951,7 +987,7 @@ local function get_output_fs(fs, data, rcp, is_recipe, shapeless, right, btn_siz
end end
end end
local function get_grid_fs(fs, data, rcp, is_recipe) local function get_grid_fs(fs, data, rcp, is_recipe, is_usage)
local width = rcp.width or 1 local width = rcp.width or 1
local right = 0 local right = 0
local btn_size, _btn_size = i3.settings.item_btn_size local btn_size, _btn_size = i3.settings.item_btn_size
@ -1050,7 +1086,7 @@ local function get_grid_fs(fs, data, rcp, is_recipe)
end end
local btn_name = groups and fmt("group!%s!%s", groups[1], name) or name local btn_name = groups and fmt("group!%s!%s", groups[1], name) or name
count *= (is_recipe and data.scrbar_rcp or data.scrbar_usg or 1) count = get_true_count(data, count, is_recipe, is_usage)
if group_cache and group_cache.sprite and not large_recipe then if group_cache and group_cache.sprite and not large_recipe then
local sprite = ESC(group_cache.sprite) local sprite = ESC(group_cache.sprite)
@ -1094,13 +1130,13 @@ local function get_grid_fs(fs, data, rcp, is_recipe)
end end
if large_recipe then if large_recipe then
fs("style_type[item_image_button;border=false]") fs"style_type[item_image_button;border=false]"
end end
get_output_fs(fs, data, rcp, is_recipe, shapeless, right, btn_size, _btn_size) get_output_fs(fs, data, rcp, is_recipe, is_usage, shapeless, right, btn_size, _btn_size)
end end
local function get_rcp_lbl(fs, data, panel, rn, is_recipe) 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
@ -1131,7 +1167,7 @@ local function get_rcp_lbl(fs, data, panel, rn, is_recipe)
image_button(data.inv_width + 7.5, y, size, size, "", next_name, "") image_button(data.inv_width + 7.5, y, size, size, "", next_name, "")
end end
get_grid_fs(fs, data, rcp, is_recipe) get_grid_fs(fs, data, rcp, is_recipe, is_usage)
end end
local function get_model_fs(fs, data, def, model_alias) local function get_model_fs(fs, data, def, model_alias)
@ -1188,19 +1224,19 @@ local function get_header(fs, data)
if nfavs < max_favs or (nfavs == max_favs and fav) then if nfavs < max_favs or (nfavs == max_favs and fav) then
local fav_marked = fmt("i3_fav%s.png", fav and "_off" or "") local fav_marked = fmt("i3_fav%s.png", fav and "_off" or "")
fs(fmt("style[fav;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]", fs("style[fav;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]",
fmt("i3_fav%s.png", fav and "" or "_off"), fav_marked, fav_marked)) fmt("i3_fav%s.png", fav and "" or "_off"), fav_marked, fav_marked)
image_button(star_x, star_y, size, size, "", "fav", "") image_button(star_x, star_y, size, size, "", "fav", "")
fs(fmt("tooltip[fav;%s]", fav and ES"Unmark this item" or ES"Mark this item")) fs("tooltip[fav;%s]", fav and ES"Unmark this item" or ES"Mark this item")
else else
fs(fmt("style[nofav;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]", fs("style[nofav;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]",
"i3_fav_off.png", PNG.cancel, PNG.cancel)) "i3_fav_off.png", PNG.cancel, PNG.cancel)
image_button(star_x, star_y, size, size, "", "nofav", "") image_button(star_x, star_y, size, size, "", "nofav", "")
fs(fmt("tooltip[nofav;%s]", ES"Cannot mark this item. Bookmark limit reached.")) fs("tooltip[nofav;%s]", ES"Cannot mark this item. Bookmark limit reached.")
end end
image_button(star_x + 0.05, star_y + 0.6, size, size, "", "exit", "") image_button(star_x + 0.05, star_y + 0.6, size, size, "", "exit", "")
fs(fmt("tooltip[exit;%s]", ES"Back to item list")) fs("tooltip[exit;%s]", ES"Back to item list")
local desc_lim, name_lim = 34, 35 local desc_lim, name_lim = 34, 35
local desc = get_desc(data.query_item, data.lang_code) local desc = get_desc(data.query_item, data.lang_code)
@ -1240,10 +1276,10 @@ local function get_crafting_fs(fs, data, is_recipe, is_usage, max_stacks_rcp, ma
local name = is_recipe and "rcp" or "usg" local name = is_recipe and "rcp" or "usg"
local show_crafting = (is_recipe and data.crafting_rcp) or (is_usage and data.crafting_usg) local show_crafting = (is_recipe and data.crafting_rcp) or (is_usage and data.crafting_usg)
fs(fmt("style[crafting_%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", fs("style[crafting_%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]",
name, fmt("%s", show_crafting and PNG.crafting_hover or PNG.crafting), PNG.crafting_hover)) name, fmt("%s", show_crafting and PNG.crafting_hover or PNG.crafting), PNG.crafting_hover)
image_button(data.inv_width + 7.35, data.yoffset + 0.2, 0.45, 0.45, "", fmt("crafting_%s", name), "") image_button(data.inv_width + 7.35, data.yoffset + 0.2, 0.45, 0.45, "", fmt("crafting_%s", name), "")
fs(fmt("tooltip[crafting_%s;%s]", name, ES"Quick crafting")) fs("tooltip[crafting_%s;%s]", name, ES"Quick crafting")
if not show_crafting then return end if not show_crafting then return end
@ -1267,14 +1303,13 @@ local function get_crafting_fs(fs, data, is_recipe, is_usage, max_stacks_rcp, ma
fs"style[quick_crafting;font_size=16;textcolor=#ddd]" fs"style[quick_crafting;font_size=16;textcolor=#ddd]"
button(x, data.yoffset + 0.85, 3.05, 0.55, "quick_crafting", ES"Quick Crafting") button(x, data.yoffset + 0.85, 3.05, 0.55, "quick_crafting", ES"Quick Crafting")
fs(fmt("style[scrbar_%s;noclip=true]", name), fs("style[scrbar_%s;noclip=true]", name)
fmt("scrollbaroptions[min=1;max=%u;smallstep=1]", craft_max)) fs("scrollbaroptions[min=1;max=%u;smallstep=1]", craft_max)
scrollbar(x + 0.2, data.yoffset + 1.45, 2.5, 0.35, "horizontal", fmt("scrbar_%s", name), stack_fs) scrollbar(x + 0.2, data.yoffset + 1.45, 2.5, 0.35, "horizontal", fmt("scrbar_%s", name), stack_fs)
button(x + 0.2, data.yoffset + 1.85, 2.5, 0.7, fmt("craft_%s", name), ES("Craft (×@1)", stack_fs)) button(x + 0.2, data.yoffset + 1.85, 2.5, 0.7, fmt("craft_%s", name), ES("Craft (×@1)", stack_fs))
fs"style_type[label;font_size=16;textcolor=#fff]" fs"style_type[label;font_size=16;textcolor=#fff]"
fs"style_type[image,button,image_button;noclip=false]"
end end
local function get_rcp_extra(fs, data, player, panel, is_recipe, is_usage) local function get_rcp_extra(fs, data, player, panel, is_recipe, is_usage)
@ -1307,7 +1342,7 @@ local function get_rcp_extra(fs, data, player, panel, is_recipe, is_usage)
get_crafting_fs(fs, data, is_recipe, is_usage, max_stacks_rcp, max_stacks_usg) get_crafting_fs(fs, data, is_recipe, is_usage, max_stacks_rcp, max_stacks_usg)
end end
get_rcp_lbl(fs, data, panel, rn, is_recipe) get_rcp_lbl(fs, data, panel, rn, is_recipe, is_usage)
else else
local lbl = is_recipe and ES"No recipes" or ES"No usages" local lbl = is_recipe and ES"No recipes" or ES"No usages"
button(data.inv_width + 0.1, data.yoffset + (panel.height / 2) - 0.5, 7.8, 1, "no_rcp", lbl) button(data.inv_width + 0.1, data.yoffset + (panel.height / 2) - 0.5, 7.8, 1, "no_rcp", lbl)
@ -1330,7 +1365,7 @@ local function hide_items(player, data)
data.items = new data.items = new
end end
if not core.is_creative_enabled(data.player_name) then if not core.is_creative_enabled(data.player_name) and not next(i3.recipe_filters) then
local new = {} local new = {}
for i = 1, #data.items do for i = 1, #data.items do
@ -1346,49 +1381,119 @@ local function hide_items(player, data)
end end
end end
local function get_header_items_fs(fs, data)
local X = data.inv_width
fs"set_focus[filter;true]"
if data.hide_tabs then
fs("style[enable_search;bgimg=%s;bgimg_hovered=%s;bgimg_pressed=%s]",
data.enable_search and PNG.search_hover or PNG.search, PNG.search_hover, PNG.search_hover)
image_button(X + 0.3, 0.2, 0.5, 0.5, "", "enable_search", "")
fs("tooltip[enable_search;%s]", ES"Search")
if data.enable_search then
image(X + 0.4, 0.75, 3.4, 0.8, PNG.bg_goto)
fs"style[filter;font_size=16]"
fs("field[%f,%f;3,0.45;filter;;%s]", X + 0.6, 0.95, data.filter)
fs"field_close_on_enter[filter;false]"
end
box(X + 1, 0.2, 0.01, 0.5, "#bababa50")
local cat = {{"all", "all items"}, {"node", "nodes only"}, {"item", "items only"}}
for i in ipairs(cat) do
local name, desc = unpack(cat[i])
local active = PNG[name .. "_hover"]
fs("style[itab_%u;bgimg=%s;bgimg_hovered=%s;bgimg_pressed=%s;sound=i3_tab]",
i, data.itab == i and active or PNG[name], active, active)
image_button(X + 1.25 + ((i - 1) * 0.7), 0.2, 0.5, 0.5, "", fmt("itab_%s", i), "")
fs("tooltip[itab_%u;Show %s]", i, desc)
end
else
fs("style[search;bgimg=%s]", PNG.search_hover)
image_button(X + 0.35, 0.32, 0.35, 0.35, "", "search", "")
fs("tooltip[search;%s]", ES"Search")
if data.enable_search then
fs"style[filter;font_size=18]"
fs("field[%f,0.2;3.35,0.6;filter;;%s]", X + 0.85, ESC(data.filter))
fs"field_close_on_enter[filter;false]"
if not true_str(data.filter) then
image(X + 0.85, 0.75, 4, 0.01, PNG.search_outline_trim .. "^[opacity:100")
end
else
fs"style_type[label;font=italic;font_size=18]"
label(X + 0.9, 0.49, clr("#aaa", ES"Search..."))
button(X + 0.8, 0.12, 4, 0.8, "enable_search", "")
fs"style_type[label;font=normal;font_size=16]"
end
if true_str(data.filter) then
image_button(X + 4.3, 0.4, 0.2, 0.2, "", "cancel", "")
fs("tooltip[cancel;%s]", ES"Clear")
box(X + 0.85, 0.75, 3.74, 0.01, "#f9826c")
end
end
image_button(X + 5.27, 0.3, 0.35, 0.35, "", "prev_page", "")
image_button(X + 7.45, 0.3, 0.35, 0.35, "", "next_page", "")
fs("style[pagenum;bgimg=%s;bgimg_hovered=%s;bgimg_middle=9;padding=-9;sound=i3_click]",
data.goto_page and PNG.pagenum_hover or "", PNG.pagenum_hover)
button(X + 5.8, 0.14, 1.48, 0.7, "pagenum",
fmt("%s / %u", clr(colors.yellow, data.pagenum), data.pagemax))
if data.goto_page then
image(X + 4.8, 0.85, 2.9, 0.8, PNG.bg_goto)
fs"style_type[label;font_size=16;textcolor=#ddd]"
label(X + 5, 1.25, ES"Go to page" .. ":")
box(X + 6.5, 1, 1, 0.45, "#bababa10")
fs("style[goto_page;font=mono,bold;font_size=16;textcolor=%s]", colors.yellow)
fs("field[%f,%f;1,0.45;goto_page;;%s]", X + 6.55, 1.05, data.pagenum)
fs"field_close_on_enter[goto_page;false]"
fs"style_type[label;font_size=16;textcolor=#fff]"
end
end
local function get_minitabs(fs, data, full_height)
local _tabs = {"All", "Nodes", "Items"}
local tab_len, tab_hgh = 1.8, 0.5
for i, title in ipairs(_tabs) do
local selected = i == data.itab
local hover_texture = selected and PNG.tab_small_hover or PNG.tab_small
fs([[ style_type[image_button;bgimg=%s;bgimg_hovered=%s;
bgimg_middle=14,0,-14,-14;padding=-14,0,14,14] ]], hover_texture, PNG.tab_small_hover)
fs([[ style_type[image_button;noclip=true;font=bold;font_size=16;
textcolor=%s;content_offset=0;sound=i3_tab] ]], selected and "#fff" or "#bbb")
fs"style_type[image_button:hovered;textcolor=#fff]"
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
local function get_items_fs(fs, data, player, full_height) local function get_items_fs(fs, data, player, full_height)
hide_items(player, data) hide_items(player, data)
bg9(data.inv_width + 0.1, 0, 7.9, full_height, PNG.bg_full)
local items = data.alt_items or data.items or {} local items = data.alt_items or data.items or {}
local rows, lines = 8, 12 local rows, lines = 8, 12
local ipp = rows * lines local ipp = rows * lines
local size = 0.85 local size = 0.85
bg9(data.inv_width + 0.1, 0, 7.9, full_height, PNG.bg_full)
if data.enable_search then
fs("set_focus[filter]",
"style[filter;font_size=18;textcolor=#ccc]",
fmt("field[%f,0.2;3.35,0.6;filter;;%s]", data.inv_width + 0.85, ESC(data.filter)),
"field_close_on_enter[filter;false]")
image(data.inv_width + 0.85, 0.75, 4, 0.01, PNG.search_outline_trim .. "^[opacity:100")
else
fs"style_type[label;font=italic;font_size=18]"
label(data.inv_width + 0.9, 0.49, clr("#aaa", ES"Search..."))
button(data.inv_width + 0.8, 0.12, 4, 0.8, "enable_search", "")
end
image_button(data.inv_width + 0.35, 0.32, 0.35, 0.35, "", "search", "")
image_button(data.inv_width + 5.27, 0.3, 0.35, 0.35, "", "prev_page", "")
image_button(data.inv_width + 7.45, 0.3, 0.35, 0.35, "", "next_page", "")
fs(fmt("tooltip[search;%s]", ES"Search"))
if true_str(data.filter) then
image_button(data.inv_width + 4.3, 0.4, 0.2, 0.2, "", "cancel", "")
fs(fmt("tooltip[cancel;%s]", ES"Clear"))
box(data.inv_width + 0.85, 0.75, 3.74, 0.01, "#f9826c")
end
data.pagemax = max(1, ceil(#items / ipp)) data.pagemax = max(1, ceil(#items / ipp))
if data.pagenum > data.pagemax then
fs(fmt("style[pagenum;bgimg=%s;bgimg_hovered=%s;bgimg_middle=9;padding=-9]", data.pagenum = data.pagemax
data.goto_page and PNG.pagenum_hover or "", PNG.pagenum_hover)) end
button(data.inv_width + 5.8, 0.14, 1.48, 0.7, "pagenum",
fmt("%s / %u", clr(colors.yellow, data.pagenum), data.pagemax))
if #items == 0 then if #items == 0 then
local lbl = ES"No item to show" local lbl = ES"No item to show"
@ -1417,12 +1522,29 @@ local function get_items_fs(fs, data, player, full_height)
local Y = round((i % ipp - X) / rows + 1, 0) local Y = round((i % ipp - X) / rows + 1, 0)
Y -= (Y * 0.085) + 0.92 Y -= (Y * 0.085) + 0.92
insert(fs, 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 data.items_progress[item] then
insert(fs, item_btn)
else
local col = "^\\[colorize:#232428^\\[opacity:245"
local img = reg_items[item].inventory_image .. col
if reg_nodes[item] then
img = PNG.cube .. col
end
insert(fs, fmt("image", X, Y, size, size, img))
end
else
insert(fs, item_btn)
end
if compressible(item, data) then if compressible(item, data) then
local expand = data.expand == name local expand = data.expand == name
fs(fmt("tooltip[%s;%s]", item, expand and ES"Click to hide" or ES"Click to expand")) fs("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"style_type[label;font=bold;font_size=20]"
label(X + 0.65, Y + 0.7, expand and "-" or "+") label(X + 0.65, Y + 0.7, expand and "-" or "+")
fs"style_type[label;font=normal;font_size=16]" fs"style_type[label;font=normal;font_size=16]"
@ -1430,35 +1552,7 @@ local function get_items_fs(fs, data, player, full_height)
end end
end end
if data.goto_page then get_header_items_fs(fs, data)
image(data.inv_width + 4.8, 0.85, 2.9, 0.8, PNG.bg_goto)
fs"style_type[label;font_size=16;textcolor=#ddd]"
label(data.inv_width + 5, 1.25, ES"Go to page" .. ":")
box(data.inv_width + 6.5, 1, 1, 0.45, "#bababa10")
fs(fmt("style[goto_page;font=mono,bold;font_size=16;textcolor=%s]", colors.yellow),
fmt("field[%f,%f;1,0.45;goto_page;;%s]", data.inv_width + 6.55, 1.05, data.pagenum),
"field_close_on_enter[goto_page;false]")
fs"style_type[label;font_size=16;textcolor=#fff]"
end
local _tabs = {"All", "Nodes", "Items"}
local tab_len, tab_hgh = 1.8, 0.5
for i, title in ipairs(_tabs) do
local selected = i == data.itab
local hover_texture = selected and PNG.tab_small_hover or PNG.tab_small
fs(fmt([[style_type[image_button;bgimg=%s;bgimg_hovered=%s;
bgimg_middle=14,0,-14,-14;padding=-14,0,14,14] ]], hover_texture, PNG.tab_small_hover))
fs(fmt("style_type[image_button;noclip=true;font_size=16;textcolor=%s;content_offset=0;sound=i3_tab]",
selected and "#fff" or "#bbb"))
fs"style_type[image_button:hovered;textcolor=#fff]"
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 end
local function get_favs(fs, data) local function get_favs(fs, data)
@ -1527,14 +1621,14 @@ local function get_tabs_fs(fs, player, data, full_height)
(btm and PNG.tab or PNG.tab_top) (btm and PNG.tab or PNG.tab_top)
local bgimg_hover = btm and PNG.tab_hover or PNG.tab_hover_top local bgimg_hover = btm and PNG.tab_hover or PNG.tab_hover_top
local middle = btm and "16,0,-16,-16" or "16,0,-16,0" local middle = btm and "16,0,-16,-16" or "16,16,-16,-16"
local padding = btm and "-16,0,16,16" or "-16,-16,16,16" local padding = btm and "-16,0,16,16" or "-16,-16,16,16"
fs(fmt([[style_type[image_button;bgimg=%s;bgimg_hovered=%s;bgimg_middle=%s;padding=%s] ]], fs([[ style_type[image_button;bgimg=%s;bgimg_hovered=%s;bgimg_middle=%s;padding=%s] ]],
bgimg, bgimg_hover, middle, padding)) bgimg, bgimg_hover, middle, padding)
fs(fmt("style_type[image_button;noclip=true;font_size=16;textcolor=%s;content_offset=0;sound=i3_tab]", fs("style_type[image_button;noclip=true;font_size=16;textcolor=%s;content_offset=0;sound=i3_tab]",
selected and "#fff" or "#ddd")) selected and "#fff" or "#ddd")
local X = (data.inv_width / 2) + (c * (tab_len + 0.1)) - ((tab_len + 0.05) * (shift / 2)) local X = (data.inv_width / 2) + (c * (tab_len + 0.1)) - ((tab_len + 0.05) * (shift / 2))
local Y = btm and full_height or -tab_hgh local Y = btm and full_height or -tab_hgh
@ -1546,7 +1640,7 @@ local function get_tabs_fs(fs, player, data, full_height)
local desc = translate(data.lang_code, def.description) local desc = translate(data.lang_code, def.description)
local desc_len = utf8_len(desc) + data.font_size local desc_len = utf8_len(desc) + data.font_size
fs("style_type[image;noclip=true]") fs"style_type[image;noclip=true]"
image(X + (tab_len / 2) - ((desc_len * 0.1) / 2) - 0.55, Y + 0.05, 0.35, 0.35, def.image) image(X + (tab_len / 2) - ((desc_len * 0.1) / 2) - 0.55, Y + 0.05, 0.35, 0.35, def.image)
end end
@ -1559,7 +1653,7 @@ local function get_debug_grid(data, fs, full_height)
button(-2, full_height - 1, 2, 1, "hide_debug_grid", "Toggle grid") button(-2, full_height - 1, 2, 1, "hide_debug_grid", "Toggle grid")
if data.hide_debug_grid then return end if data.hide_debug_grid then return end
fs("style_type[label;font_size=8;noclip=true]") fs"style_type[label;font_size=8;noclip=true]"
local spacing, i = 0.2, 1 local spacing, i = 0.2, 1
for x = 0, data.inv_width + 8, spacing do for x = 0, data.inv_width + 8, spacing do
@ -1587,10 +1681,11 @@ local function make_fs(player, data)
local fs = setmetatable({}, { local fs = setmetatable({}, {
__call = function(t, ...) __call = function(t, ...)
local args = {...} local args = {...}
local elem = fs_elements[args[1]]
if elem then if #args > 1 then
insert(t, fmt(elem, select(2, ...))) local arg1 = args[1]
local elem = fs_elements[arg1]
insert(t, fmt(elem or arg1, select(2, ...)))
else else
insert(t, concat(args)) insert(t, concat(args))
end end
@ -1600,8 +1695,10 @@ local function make_fs(player, data)
data.inv_width = 10.23 data.inv_width = 10.23
local full_height = 12 local full_height = 12
fs(fmt("formspec_version[%u]size[%f,%f]no_prepend[]bgcolor[#0000]", fs("formspec_version[%u]size[%f,%f]no_prepend[]bgcolor[#0000]",
i3.settings.min_fs_version, data.inv_width + 8, full_height), styles) i3.settings.min_fs_version, data.inv_width + 8, full_height)
fs(styles)
bg9(0, 0, data.inv_width, full_height, PNG.bg_full) bg9(0, 0, data.inv_width, full_height, PNG.bg_full)
@ -1615,6 +1712,10 @@ local function make_fs(player, data)
get_panels(fs, data, player) get_panels(fs, data, player)
else else
get_items_fs(fs, data, player, full_height) get_items_fs(fs, data, player, full_height)
if not data.hide_tabs then
get_minitabs(fs, data, full_height)
end
end end
local visible_tabs = #i3.tabs local visible_tabs = #i3.tabs

View File

@ -1,9 +1,17 @@
IMPORT("get_connected_players", "str_to_pos", "add_hud_waypoint") IMPORT("ceil", "get_connected_players", "str_to_pos", "add_hud_waypoint")
local function init_hud(player) local function init_hud(player)
local name = player:get_player_name() local name = player:get_player_name()
local data = i3.data[name] local data = i3.data[name]
local wdesc_y = -90
if core.global_exists"hb" then
wdesc_y -= ceil(hb.hudbars_count / 2) * 5
elseif not i3.settings.damage_enabled then
wdesc_y += 15
end
data.hud = { data.hud = {
bg = player:hud_add { bg = player:hud_add {
hud_elem_type = "image", hud_elem_type = "image",
@ -18,7 +26,7 @@ local function init_hud(player)
hud_elem_type = "image", hud_elem_type = "image",
position = {x = 0.79, y = 1.02}, position = {x = 0.79, y = 1.02},
alignment = {x = 1, y = 1}, alignment = {x = 1, y = 1},
scale = {x = 4, y = 4}, scale = {x = 1, y = 1},
text = "", text = "",
z_index = 0xDEAD, z_index = 0xDEAD,
}, },
@ -32,14 +40,18 @@ local function init_hud(player)
z_index = 0xDEAD, z_index = 0xDEAD,
style = 1, style = 1,
}, },
}
if not i3.settings.legacy_inventory then wielditem = player:hud_add {
core.after(0, function() hud_elem_type = "text",
player:hud_set_hotbar_itemcount(i3.settings.hotbar_len) position = {x = 0.5, y = 1},
player:hud_set_hotbar_image"i3_hotbar.png" offset = {x = 0, y = wdesc_y},
end) alignment = {x = 0, y = -1},
end number = 0xffffff,
text = "",
z_index = 0xDEAD,
style = 1,
},
}
end end
local function show_hud(player, data) local function show_hud(player, data)
@ -47,7 +59,7 @@ local function show_hud(player, data)
-- 2 calls for the notification's back and forth. -- 2 calls for the notification's back and forth.
local hud_info_bg = player:hud_get(data.hud.bg) local hud_info_bg = player:hud_get(data.hud.bg)
local dt = 0.016 local dt = 0.025
if hud_info_bg.position.y <= 0.9 then if hud_info_bg.position.y <= 0.9 then
data.show_hud = false data.show_hud = false
@ -91,6 +103,46 @@ local function show_hud(player, data)
end end
end end
core.register_globalstep(function(dt)
local players = get_connected_players()
players[0] = #players
for i = 1, players[0] do
local player = players[i]
local name = player:get_player_name()
local data = i3.data[name]
if not data then return end
if not data.wielditem_hud then
player:hud_change(data.hud.wielditem, "text", "")
return
end
data.timer = (data.timer or 0) + dt
local wieldidx = player:get_wield_index()
if wieldidx == data.old_wieldidx then
if data.timer >= i3.settings.wielditem_fade_after then
player:hud_change(data.hud.wielditem, "text", "")
end
return
end
data.timer = 0
data.old_wieldidx = wieldidx
local wielditem = player:get_wielded_item()
local meta = wielditem:get_meta()
local meta_desc = meta:get_string"short_description"
meta_desc = meta_desc:gsub("\27", "")
meta_desc = core.strip_colors(meta_desc)
local desc = meta_desc ~= "" and meta_desc or wielditem:get_short_description()
player:hud_change(data.hud.wielditem, "text", desc:trim())
end
end)
core.register_globalstep(function() core.register_globalstep(function()
local players = get_connected_players() local players = get_connected_players()
players[0] = #players players[0] = #players

View File

@ -81,6 +81,10 @@ local function _load(path, line, data, t)
if not l then if not l then
local err_line = tonumber(err:match(":(%d+):")) local err_line = tonumber(err:match(":(%d+):"))
if t then
print("err_line", err_line, t[err_line])
end
if line ~= err_line then if line ~= err_line then
return _load(path, err_line, data, t) return _load(path, err_line, data, t)
end end

View File

@ -2,11 +2,12 @@ local set_fs = i3.set_fs
local hud_notif = i3.hud_notif local hud_notif = i3.hud_notif
local POLL_FREQ = 0.25 local POLL_FREQ = 0.25
IMPORT("reg_items", "reg_nodes")
IMPORT("fmt", "search", "table_merge", "array_diff") IMPORT("fmt", "search", "table_merge", "array_diff")
IMPORT("is_group", "extract_groups", "item_has_groups", "apply_recipe_filters") IMPORT("is_group", "extract_groups", "item_has_groups", "apply_recipe_filters")
local function get_filtered_items(player, data) local function get_filtered_items(player, data)
local items, known, c = {}, 0, 0 local items, known = {}, 0
for i = 1, #i3.init_items do for i = 1, #i3.init_items do
local item = i3.init_items[i] local item = i3.init_items[i]
@ -17,8 +18,7 @@ local function get_filtered_items(player, data)
usages = #apply_recipe_filters(usages or {}, player) usages = #apply_recipe_filters(usages or {}, player)
if recipes > 0 or usages > 0 then if recipes > 0 or usages > 0 then
c++ items[item] = true
items[c] = item
known += recipes + usages known += recipes + usages
end end
end end
@ -133,10 +133,18 @@ local function poll_new_items(player, data, join)
if data.discovered > 0 then if data.discovered > 0 then
local msg = fmt("%u new recipe%s unlocked!", data.discovered, data.discovered > 1 and "s" or "") local msg = fmt("%u new recipe%s unlocked!", data.discovered, data.discovered > 1 and "s" or "")
hud_notif(data.player_name, msg, "i3_book.png") local last_discovered = diff[1]
local img = reg_items[last_discovered].inventory_image
if reg_nodes[last_discovered] then
local id = core.get_content_id(last_discovered)
img = i3.cubes[id] or img
end end
data.items_raw = items hud_notif(data.player_name, msg, img)
end
data.items_progress = items
data.itab = 1 data.itab = 1
search(data) search(data)

View File

@ -12,7 +12,6 @@ local PNG = {
search = "i3_search.png", search = "i3_search.png",
heart = "i3_heart.png", heart = "i3_heart.png",
heart_half = "i3_heart_half.png", heart_half = "i3_heart_half.png",
heart_grey = "i3_heart_grey.png",
prev = "i3_next.png^\\[transformFX", prev = "i3_next.png^\\[transformFX",
next = "i3_next.png", next = "i3_next.png",
arrow = "i3_arrow.png", arrow = "i3_arrow.png",
@ -51,6 +50,10 @@ local PNG = {
find_more = "i3_find_more.png", find_more = "i3_find_more.png",
search_outline = "i3_search_outline.png", search_outline = "i3_search_outline.png",
search_outline_trim = "i3_search_outline_trim.png", search_outline_trim = "i3_search_outline_trim.png",
all = "i3_all.png",
node = "i3_node.png",
item = "i3_item.png",
cube = "i3_cube.png",
cancel_hover = "i3_cancel.png^\\[brighten", cancel_hover = "i3_cancel.png^\\[brighten",
search_hover = "i3_search.png^\\[brighten", search_hover = "i3_search.png^\\[brighten",
@ -74,6 +77,9 @@ local PNG = {
exit_hover = "i3_exit.png^\\[brighten", exit_hover = "i3_exit.png^\\[brighten",
home_hover = "i3_home.png^\\[brighten", home_hover = "i3_home.png^\\[brighten",
edit_hover = "i3_edit.png^\\[brighten", edit_hover = "i3_edit.png^\\[brighten",
all_hover = "i3_all_on.png^\\[brighten",
node_hover = "i3_node_on.png^\\[brighten",
item_hover = "i3_item_on.png^\\[brighten",
} }
local styles = string.format([[ local styles = string.format([[
@ -86,10 +92,9 @@ local styles = string.format([[
style[;sound=] style[;sound=]
style[nofav;sound=i3_cannot] style[nofav;sound=i3_cannot]
style[search;content_offset=0]
style[pagenum,no_item,no_rcp;font=bold;font_size=18] style[pagenum,no_item,no_rcp;font=bold;font_size=18]
style[search;fgimg=%s;content_offset=0]
style[enable_search:hovered;bgimg=%s] style[enable_search:hovered;bgimg=%s]
style[enable_search:pressed;bgimg=%s^[opacity:178]
style[exit;fgimg=%s;fgimg_hovered=%s;content_offset=0] style[exit;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[cancel;fgimg=%s;fgimg_hovered=%s;content_offset=0] style[cancel;fgimg=%s;fgimg_hovered=%s;content_offset=0]
style[prev_page,prev_recipe,prev_usage,prev_sort,prev_skin;fgimg=%s;fgimg_hovered=%s] style[prev_page,prev_recipe,prev_usage,prev_sort,prev_skin;fgimg=%s;fgimg_hovered=%s]
@ -106,8 +111,7 @@ local styles = string.format([[
style[confirm_trash_yes;sound=i3_trash] style[confirm_trash_yes;sound=i3_trash]
]], ]],
PNG.slot, PNG.slot,
PNG.search_hover, PNG.search_outline,
PNG.search_outline, PNG.search_outline,
PNG.exit, PNG.exit_hover, PNG.exit, PNG.exit_hover,
PNG.cancel, PNG.cancel_hover, PNG.cancel, PNG.cancel_hover,
PNG.prev, PNG.prev_hover, PNG.prev, PNG.prev_hover,

View File

@ -11,32 +11,39 @@ mt3:get_meta():set_string("description", "Worn Pick")
mt3:get_meta():set_string("color", "yellow") mt3:get_meta():set_string("color", "yellow")
mt3:set_wear(10000) mt3:set_wear(10000)
minetest.register_craft({ minetest.register_craft {
output = mt:to_string(), output = mt:to_string(),
type = "shapeless", type = "shapeless",
recipe = { recipe = {
"default:wood", "default:wood",
mt2:to_string(), mt2:to_string(),
}, },
}) }
minetest.register_craft({ minetest.register_craft {
output = mt3:to_string(), output = mt3:to_string(),
type = "shapeless", type = "shapeless",
recipe = { recipe = {
"default:pick_mese", "default:pick_mese",
"default:diamond", "default:diamond",
}, },
}) }
minetest.clear_craft {
recipe = {
{"default:sand", "default:sand"},
{"default:sand", "default:sand"},
},
}
i3.register_craft { i3.register_craft {
url = "https://raw.githubusercontent.com/minetest-mods/i3/main/tests/test_online_recipe.json" url = "https://raw.githubusercontent.com/minetest-mods/i3/main/tests/test_online_recipe.json"
} }
i3.register_craft({ i3.register_craft {
result = "default:ladder_wood 2", result = "default:ladder_wood 2",
items = {"default:copper_ingot 7, default:tin_ingot, default:steel_ingot 2"}, items = {"default:copper_ingot 7, default:tin_ingot, default:steel_ingot 2"},
}) }
i3.register_craft { i3.register_craft {
result = "default:tree", result = "default:tree",
@ -56,7 +63,7 @@ i3.register_craft {
} }
} }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X", "X",
"#", "#",
@ -68,9 +75,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X", "X",
"#X", "#X",
@ -82,9 +89,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X", "X",
}, },
@ -93,10 +100,10 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X#", "X#",
}, },
@ -105,9 +112,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X#X", "X#X",
}, },
@ -116,9 +123,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X#XX", "X#XX",
}, },
@ -127,9 +134,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X#XX", "X#XX",
"X#X", "X#X",
@ -139,9 +146,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X#XX", "X#XX",
"X#X", "X#X",
@ -152,9 +159,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X##XX", "X##XX",
}, },
@ -163,9 +170,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X##X#X", "X##X#X",
}, },
@ -174,9 +181,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X##X#X", "X##X#X",
"", "",
@ -187,9 +194,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -201,9 +208,9 @@ i3.register_craft({
['X'] = "default:glass 2", ['X'] = "default:glass 2",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -215,9 +222,9 @@ i3.register_craft({
['X'] = "default:glass", ['X'] = "default:glass",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -230,9 +237,9 @@ i3.register_craft({
['X'] = "default:glass", ['X'] = "default:glass",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -245,10 +252,10 @@ i3.register_craft({
['X'] = "default:glass", ['X'] = "default:glass",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -262,9 +269,9 @@ i3.register_craft({
['X'] = "default:glass", ['X'] = "default:glass",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -278,9 +285,9 @@ i3.register_craft({
['X'] = "default:glass", ['X'] = "default:glass",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -294,9 +301,9 @@ i3.register_craft({
['X'] = "default:glass", ['X'] = "default:glass",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -310,9 +317,9 @@ i3.register_craft({
['X'] = "default:glass", ['X'] = "default:glass",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }
i3.register_craft({ i3.register_craft {
grid = { grid = {
"X #", "X #",
" ## ", " ## ",
@ -328,4 +335,4 @@ i3.register_craft({
['X'] = "default:glass", ['X'] = "default:glass",
}, },
result = "default:mese 3", result = "default:mese 3",
}) }

BIN
textures/i3_all.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
textures/i3_all_on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

BIN
textures/i3_cube.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

BIN
textures/i3_item.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
textures/i3_item_on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
textures/i3_node.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
textures/i3_node_on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB