Compare commits

..

27 Commits

Author SHA1 Message Date
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
21 changed files with 412 additions and 289 deletions

View File

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

38
API.md
View File

@ -21,31 +21,33 @@ i3.new_tab("stuff", {
end,
formspec = function(player, data, fs)
fs("label[3,1;This is just a test]")
fs"label[3,1;This is just a test]"
end,
-- Events handling happens here
fields = function(player, data, fields)
if fields.mybutton then
do_things()
end
end,
})
```
- `player` is an `ObjectRef` to the user.
- `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)`
Updates the current formspec.
Update the current formspec.
#### `i3.remove_tab(tabname)`
Deletes a tab by name.
Delete a tab by name.
#### `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])`
@ -54,7 +56,7 @@ Sets the current tab by name. `player` is an `ObjectRef` to the user.
#### `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`
@ -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.
**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
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
i3.register_craft {
@ -159,7 +163,7 @@ mode is implemented as a recipe filter.
#### `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
user. Each recipe is a table of the form returned by
`minetest.get_craft_recipe`.
@ -181,7 +185,7 @@ end)
#### `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`
@ -207,7 +211,7 @@ Notes:
#### `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).
- `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)`
Adds a player inventory sorting method.
Add a player inventory sorting method.
- `name` is the method name.
- `def` is the method definition.
@ -276,7 +280,7 @@ A table containing all sorting methods.
#### `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.
- `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])`
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.
- `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)`
Returns a table of recipes and usages of `item`.
Return a table of recipes and usages of `item`.
#### `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
![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
i3 = {
version = 190,
version = 1115,
data = core.deserialize(storage:get_string"data") or {},
settings = {
@ -30,6 +30,7 @@ i3 = {
min_fs_version = 6,
item_btn_size = 1.1,
drop_bag_on_die = true,
wielditem_fade_after = 3,
save_interval = 600, -- Player data save interval (in seconds)
hud_speed = 1,
@ -37,7 +38,6 @@ i3 = {
damage_enabled = core.settings:get_bool"enable_damage",
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),
},
@ -53,9 +53,12 @@ i3 = {
bag = true,
home = true,
font_size = true,
hide_tabs = true,
waypoints = true,
inv_items = true,
known_recipes = true,
wielditem_hud = true,
legacy_inventory = true,
},
files = {
@ -93,9 +96,6 @@ i3 = {
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.api(http)
i3.files.compress()

View File

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

View File

@ -3,6 +3,3 @@ 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

View File

@ -2,7 +2,7 @@ local replacements = {fuel = {}}
local http = ...
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("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)
old_clear_craft(def)
if true_str(def) then
return -- TODO
elseif is_table(def) then
return -- TODO
end
-- TODO: hide in crafting guide
end
local function resolve_aliases(hash)
@ -274,7 +270,7 @@ local function resolve_aliases(hash)
local rcp_new = copy(i3.recipes_cache[newname][j])
rcp_new.output = oldname
if rcp_eq(rcp_old, rcp_new) then
if table_eq(rcp_old, rcp_new) then
similar = true
break
end

View File

@ -6,7 +6,7 @@ local init_hud = i3.files.hud()
local set_fs = i3.set_fs
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)
local name = player:get_player_name()
@ -211,13 +211,13 @@ local function init_data(player, info)
data.items = i3.init_items
data.items_raw = i3.init_items
data.favs = {}
data.sort = "alphabetical"
data.show_setting = "home"
data.ignore_hotbar = false
data.auto_sorting = false
data.reverse_sorting = false
data.inv_compress = true
data.crafting_counts = {}
data.sort = 1
data.tab = 1
data.itab = 1
data.subcat = 1
@ -226,8 +226,7 @@ local function init_data(player, info)
data.lang_code = get_lang_code(info)
data.fs_version = info.formspec_version
local inv = player:get_inventory()
inv:set_size("main", i3.settings.inv_size)
update_inv_size(player, data)
core.after(0, set_fs, player)
end

View File

@ -216,18 +216,22 @@ local function array_diff(t1, t2)
return diff
end
local function rcp_eq(rcp, rcp2)
if rcp.type ~= rcp2.type then return end
if rcp.width ~= rcp2.width then return end
if #rcp.items ~= #rcp2.items then return end
if rcp.output ~= rcp2.output then return end
local function table_eq(t1, t2)
local ty1, ty2 = type(t1), type(t2)
if ty1 ~= ty2 then return end
for i, item in pairs(rcp.items) do
if item ~= rcp2.items[i] then return end
if ty1 ~= "table" and ty2 ~= "table" then
return t1 == t2
end
for i, item in pairs(rcp2.items) do
if item ~= rcp.items[i] then return end
for k, v in pairs(t1) do
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
return true
@ -443,10 +447,8 @@ local function craft_stack(player, data, craft_rcp)
end
if rcp_def.replacements then
for _, v in ipairs(rcp_def.replacements) do
for _, item2 in ipairs(v) do
get_stack(player, ItemStack(item2))
end
for _, pair in ipairs(rcp_def.replacements) do
get_stack(player, ItemStack(pair[2]))
end
end
@ -479,18 +481,6 @@ local function safe_teleport(player, pos)
player:set_pos(p)
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)
sort(inv, function(a, b)
if mode == 1 then
@ -571,7 +561,7 @@ local function sort_inventory(player, data)
local inv = player:get_inventory()
local list = inv:get_list"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
list = compress_items(list, start_i)
@ -579,8 +569,7 @@ local function sort_inventory(player, data)
list = pre_sorting(list, start_i)
end
local idx = get_sorting_idx(data.sort)
local new_inv = i3.sorting_methods[idx].func(list, data)
local new_inv = i3.sorting_methods[data.sort].func(list, data)
if not new_inv then return end
if not data.ignore_hotbar then
@ -638,6 +627,24 @@ local function get_detached_inv(name, player_name)
}
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`
local function createunpack(n)
local ret = {"local t = ... return "}
@ -676,7 +683,6 @@ local _ = {
sorter = sorter,
get_recipes = get_recipes,
sort_inventory = sort_inventory,
get_sorting_idx = get_sorting_idx,
sort_by_category = sort_by_category,
apply_recipe_filters = apply_recipe_filters,
@ -720,6 +726,7 @@ local _ = {
-- Inventory
get_stack = get_stack,
craft_stack = craft_stack,
update_inv_size = update_inv_size,
get_detached_inv = get_detached_inv,
get_bag_description = get_bag_description,
create_inventory = core.create_detached_inventory,
@ -761,7 +768,7 @@ local _ = {
is_table = is_table,
table_merge = table_merge,
table_replace = table_replace,
rcp_eq = rcp_eq,
table_eq = table_eq,
array_diff = array_diff,
-- Math

View File

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

View File

@ -6,7 +6,7 @@ IMPORT("S", "random", "translate", "ItemStack")
IMPORT("sort", "copy", "insert", "remove", "indexof")
IMPORT("fmt", "find", "match", "sub", "lower", "split", "toupper")
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)
@ -32,6 +32,10 @@ local function inv_fields(player, data, fields)
data[str] = true
end
if str == "legacy_inventory" then
update_inv_size(player, data)
end
elseif sub(field, 1, 8) == "setting_" then
data.show_setting = match(field, "_(%w+)$")
@ -124,19 +128,8 @@ local function inv_fields(player, data, fields)
elseif fields.sort then
sort_inventory(player, data)
elseif fields.prev_sort or fields.next_sort then
local idx = get_sorting_idx(data.sort)
local tot = #i3.sorting_methods
idx -= (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.dd_sorting_method then
data.sort = tonumber(fields.dd_sorting_method)
elseif fields.home then
if not data.home then
@ -189,7 +182,7 @@ local function inv_fields(player, data, fields)
for _, v in ipairs(data.waypoints) do
if vec_eq(vec_round(pos), vec_round(str_to_pos(v.pos))) then
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
@ -312,7 +305,7 @@ end
local function rcp_fields(player, data, fields)
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
end
@ -323,7 +316,11 @@ local function rcp_fields(player, data, fields)
data.query_item = nil
elseif fields.enable_search then
if data.hide_tabs then
data.enable_search = not data.enable_search
else
data.enable_search = true
end
elseif fields.filter and (fields.key_enter_field == "filter" or fields.search) then
if fields.filter == "" then

View File

@ -1,5 +1,4 @@
local damage_enabled = i3.settings.damage_enabled
local hotbar_len = i3.settings.hotbar_len
local debug_mode = i3.settings.debug_mode
local model_aliases = i3.files.model_alias()
@ -11,10 +10,10 @@ local VoxelArea, VoxelManip = VoxelArea, VoxelManip
IMPORT("find", "match", "sub", "upper")
IMPORT("vec_new", "vec_sub", "vec_round")
IMPORT("clr", "ESC", "msg", "check_privs")
IMPORT("compression_active", "compressible")
IMPORT("min", "max", "floor", "ceil", "round")
IMPORT("reg_items", "reg_tools", "reg_entities")
IMPORT("true_str", "is_fav", "is_num", "str_to_pos")
IMPORT("get_sorting_idx", "compression_active", "compressible")
IMPORT("get_bag_description", "get_detached_inv", "get_recipes")
IMPORT("S", "ES", "translate", "ItemStack", "toupper", "utf8_len")
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
end
local function get_inv_slots(fs)
local inv_x = i3.settings.legacy_inventory and 0.75 or 0.22
local inv_y = 6.9
local size, spacing = 1, 0.1
local function get_inv_slots(data, fs)
local legacy_inventory = data.legacy_inventory
local hotbar_len = data.hotbar_len
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]"
@ -142,11 +144,12 @@ local function get_inv_slots(fs)
fs(fmt("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(fmt("style_type[list;size=%f;spacing=%f]", size, 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(fmt("style_type[list;size=%f;spacing=%f,%f]", size, spacing, legacy_inventory and 0.15 or spacing))
fs(fmt("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]"
end
@ -299,13 +302,13 @@ end
local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
fs(fmt("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))
image_button(5.1, yextra + 1.15, 0.5, 0.5, "", "waypoint_add", "")
fs(fmt("tooltip[waypoint_add;%s]", ES"Add waypoint"))
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
local y = yextra + 1.35 + (i - (i * 0.3))
@ -479,10 +482,11 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
end
local armor_def = armor.def[name]
local _, armor_inv = armor:get_valid_player(player, "3d_armor")
fs(fmt("list[detached:%s_armor;armor;0,%f;5,1;]", esc_name, yextra + 0.7))
for i = 1, 5 do
local _, armor_inv = armor:get_valid_player(player, "3d_armor")
local stack = armor_inv:get_stack("armor", i)
if stack:is_empty() then
@ -572,45 +576,40 @@ local function get_container(fs, data, player, yoffset, ctn_len, award_list, awa
end
end
local function show_popup(fs, data)
local function show_settings(fs, data)
if data.confirm_trash then
fs"style_type[box;colors=#999,#999,#808080,#808080]"
for _ = 1, 3 do
box(2.97, 10.75, 4.3, 0.5, "")
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")
image(2.8, 10.65, 4.6, 0.7, PNG.bg_goto)
label(3.02, 11, "Confirm trash?")
image_button(5.07, 10.75, 1, 0.5, "", "confirm_trash_yes", "Yes")
image_button(6.17, 10.75, 1, 0.5, "", "confirm_trash_no", "No")
elseif data.show_settings then
fs"style_type[box;colors=#999,#999,#808080,#808080]"
for _ = 1, 3 do
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", "")
image(2.2, 9, 6, 2.35, PNG.bg_content)
local show_home = data.show_setting == "home"
local show_style = data.show_setting == "style"
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]",
show_home and colors.yellow or "#fff"),
fmt("style[setting_sorting;textcolor=%s;font=bold;font_size=16;sound=i3_click]",
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"))
fs"style[setting_home,setting_style,setting_sorting;font=bold;font_size=16;sound=i3_click]"
fs(fmt("style[setting_home:hovered;textcolor=%s]", show_home and colors.yellow or "#fff"))
fs(fmt("style[setting_style:hovered;textcolor=%s]", show_style and colors.yellow or "#fff"))
fs(fmt("style[setting_sorting:hovered;textcolor=%s]", show_sorting and colors.yellow or "#fff"))
button(2.2, 9.25, 1.8, 0.55, "setting_home", "Home")
button(4, 9.25, 1.8, 0.55, "setting_sorting", "Sorting")
button(5.8, 9.25, 1.8, 0.55, "setting_misc", "Misc.")
fs(fmt("style[setting_home;bgimg=%s;bgimg_hovered=%s;bgimg_middle=9;padding=-9;textcolor=%s]",
show_home and PNG.pagenum_hover or "", PNG.pagenum_hover,
show_home and colors.yellow or "#ddd"),
fmt("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"),
fmt("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.6, 9.1, 1.6, 0.55, "setting_style", "Style")
button(X + 3.2, 9.1, 1.6, 0.55, "setting_sorting", "Sorting")
image_button(X + 5, 9.2, 0.25, 0.25, PNG.cancel_hover .. "^\\[brighten", "close_settings", "")
if show_home then
local coords, c, str = {"X", "Y", "Z"}, 0, ES"No home set"
@ -620,41 +619,53 @@ local function show_popup(fs, data)
"(%-?%d+)", function(a)
c++
return fmt("<b>%s: <style color=%s font=mono>%s</style></b>",
coords[c], colors.black, a)
coords[c], colors.blue, a)
end)
end
hypertext(2.1, 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")
elseif show_sorting then
button(2.1, 9.7, 6, 0.8, "select_sorting", ES"Select the inventory sorting method:")
image_button(2.2, 10.6, 0.35, 0.35, "", "prev_sort", "")
image_button(7.65, 10.6, 0.35, 0.35, "", "next_sort", "")
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
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))
elseif show_style then
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))
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
fs(fmt("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(fmt("scrollbar[5.3,10.25;2.45,0.3;horizontal;sb_font_size;%d]", data.font_size))
fs(fmt("tooltip[cb_hide_tabs;%s;#707070;#fff]",
ES"Enable this option to change the style of the right panel"),
fmt("tooltip[cb_legacy_inventory;%s;#707070;#fff]",
ES"Enable this option to set the classic inventory size in Minetest"),
fmt("tooltip[cb_wielditem_hud;%s;#707070;#fff]",
ES"Enable this option to show the wielded item description in your HUD"))
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.4, 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
label(5.4, 10.4, ES"Sorting method:")
fs(fmt("dropdown[%f,%f;2.4,0.5;dd_sorting_method;%s;%u;true]",
5.4, 10.6, concat(methods, ","), data.sort))
local desc = i3.sorting_methods[data.sort].description
if desc then
tooltip(5.4, 10.6, 2.4, 0.5, ESC(desc))
end
fs(fmt("tooltip[cb_inv_compress;%s;#707070;#fff]",
ES"Enable this option to compress your inventory"),
@ -671,10 +682,12 @@ end
local function get_inventory_fs(player, data, fs)
fs"listcolors[#bababa50;#bababa99]"
get_inv_slots(fs)
get_inv_slots(data, fs)
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
local anim = player:get_local_animation()
@ -687,7 +700,7 @@ local function get_inventory_fs(player, data, fs)
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,
"player_model", props.mesh, textures, "0,-150", "false", "false",
fmt("%u,%u;30", anim.x, anim.y))
@ -698,6 +711,7 @@ local function get_inventory_fs(player, data, fs)
local awards_unlocked, award_list, award_list_nb = 0
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")
if data.subcat == 1 and bag_size > 0 then
@ -767,7 +781,7 @@ local function get_inventory_fs(player, data, fs)
fs(fmt("tooltip[%s;%s]", btn_name, tooltip))
end
show_popup(fs, data)
show_settings(fs, data)
end
local function get_tooltip(item, info, pos, lang_code)
@ -1110,7 +1124,7 @@ local function get_grid_fs(fs, data, rcp, is_recipe, is_usage)
end
if large_recipe then
fs("style_type[item_image_button;border=false]")
fs"style_type[item_image_button;border=false]"
end
get_output_fs(fs, data, rcp, is_recipe, is_usage, shapeless, right, btn_size, _btn_size)
@ -1290,7 +1304,6 @@ local function get_crafting_fs(fs, data, is_recipe, is_usage, max_stacks_rcp, ma
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[image,button,image_button;noclip=false]"
end
local function get_rcp_extra(fs, data, player, panel, is_recipe, is_usage)
@ -1362,50 +1375,116 @@ local function hide_items(player, data)
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(fmt("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(fmt("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]",
fmt("field[%f,%f;3,0.45;filter;;%s]", X + 0.6, 0.95, data.filter),
"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(fmt("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(fmt("tooltip[itab_%u;Show %s]", i, desc))
end
else
fs(fmt("style[search;bgimg=%s]", PNG.search_hover))
image_button(X + 0.35, 0.32, 0.35, 0.35, "", "search", "")
fs(fmt("tooltip[search;%s]", ES"Search"))
if data.enable_search then
fs("style[filter;font_size=18]",
fmt("field[%f,0.2;3.35,0.6;filter;;%s]", X + 0.85, ESC(data.filter)),
"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(fmt("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(fmt("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(fmt("style[goto_page;font=mono,bold;font_size=16;textcolor=%s]", colors.yellow),
fmt("field[%f,%f;1,0.45;goto_page;;%s]", X + 6.55, 1.05, data.pagenum),
"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(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=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)
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 rows, lines = 8, 12
local ipp = rows * lines
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))
fs(fmt("style[pagenum;bgimg=%s;bgimg_hovered=%s;bgimg_middle=9;padding=-9]",
data.goto_page and PNG.pagenum_hover or "", PNG.pagenum_hover))
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
local lbl = ES"No item to show"
local icon, width, offset = PNG.no_result, 4, 2
@ -1446,35 +1525,7 @@ local function get_items_fs(fs, data, player, full_height)
end
end
if data.goto_page then
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
get_header_items_fs(fs, data)
end
local function get_favs(fs, data)
@ -1543,7 +1594,7 @@ local function get_tabs_fs(fs, player, data, full_height)
(btm and PNG.tab or PNG.tab_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"
fs(fmt([[style_type[image_button;bgimg=%s;bgimg_hovered=%s;bgimg_middle=%s;padding=%s] ]],
@ -1562,7 +1613,7 @@ local function get_tabs_fs(fs, player, data, full_height)
local desc = translate(data.lang_code, def.description)
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)
end
@ -1575,7 +1626,7 @@ local function get_debug_grid(data, fs, full_height)
button(-2, full_height - 1, 2, 1, "hide_debug_grid", "Toggle grid")
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
for x = 0, data.inv_width + 8, spacing do
@ -1631,6 +1682,10 @@ local function make_fs(player, data)
get_panels(fs, data, player)
else
get_items_fs(fs, data, player, full_height)
if not data.hide_tabs then
get_minitabs(fs, data, full_height)
end
end
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 name = player:get_player_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 = {
bg = player:hud_add {
hud_elem_type = "image",
@ -32,14 +40,18 @@ local function init_hud(player)
z_index = 0xDEAD,
style = 1,
},
}
if not i3.settings.legacy_inventory then
core.after(0, function()
player:hud_set_hotbar_itemcount(i3.settings.hotbar_len)
player:hud_set_hotbar_image"i3_hotbar.png"
end)
end
wielditem = player:hud_add {
hud_elem_type = "text",
position = {x = 0.5, y = 1},
offset = {x = 0, y = wdesc_y},
alignment = {x = 0, y = -1},
number = 0xffffff,
text = "",
z_index = 0xDEAD,
style = 1,
},
}
end
local function show_hud(player, data)
@ -91,6 +103,46 @@ local function show_hud(player, data)
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()
local players = get_connected_players()
players[0] = #players

View File

@ -51,6 +51,9 @@ local PNG = {
find_more = "i3_find_more.png",
search_outline = "i3_search_outline.png",
search_outline_trim = "i3_search_outline_trim.png",
all = "i3_all.png",
node = "i3_node.png",
item = "i3_item.png",
cancel_hover = "i3_cancel.png^\\[brighten",
search_hover = "i3_search.png^\\[brighten",
@ -74,6 +77,9 @@ local PNG = {
exit_hover = "i3_exit.png^\\[brighten",
home_hover = "i3_home.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([[
@ -86,8 +92,8 @@ local styles = string.format([[
style[;sound=]
style[nofav;sound=i3_cannot]
style[search;content_offset=0]
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:pressed;bgimg=%s^[opacity:178]
style[exit;fgimg=%s;fgimg_hovered=%s;content_offset=0]
@ -106,7 +112,6 @@ local styles = string.format([[
style[confirm_trash_yes;sound=i3_trash]
]],
PNG.slot,
PNG.search_hover,
PNG.search_outline, PNG.search_outline,
PNG.exit, PNG.exit_hover,
PNG.cancel, PNG.cancel_hover,

View File

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

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