From c8420db6751cdf9dec27b94882383c2c906da053 Mon Sep 17 00:00:00 2001 From: Kacper Kostka Date: Sun, 8 Jan 2023 15:29:39 +0100 Subject: [PATCH] hm --- mods/amogus_blocks/init.lua | 73 +- mods/amogus_general/init.lua | 0 mods/amogus_generator/init.lua | 0 mods/amogus_items/init.lua | 43 +- mods/i3/.editorconfig | 9 + mods/i3/.github/ISSUE_TEMPLATE/bug_report.md | 24 + mods/i3/.github/workflows/luacheck.yml | 21 + mods/i3/.gitignore | 41 + mods/i3/.luacheckrc | 37 + mods/i3/API.md | 338 ++++ mods/i3/LICENSE | 60 + mods/i3/README.md | 58 + mods/i3/init.lua | 127 ++ mods/i3/locale/i3.fr.tr | 85 + mods/i3/locale/template | 84 + mods/i3/mod.conf | 4 + mods/i3/settingtypes.txt | 2 + mods/i3/sounds/i3_achievement.ogg | Bin 0 -> 23557 bytes mods/i3/sounds/i3_cannot.ogg | Bin 0 -> 28026 bytes mods/i3/sounds/i3_click.ogg | Bin 0 -> 6220 bytes mods/i3/sounds/i3_craft.ogg | Bin 0 -> 12926 bytes mods/i3/sounds/i3_heavy_armor.ogg | Bin 0 -> 7439 bytes mods/i3/sounds/i3_heavy_boots.ogg | Bin 0 -> 6911 bytes mods/i3/sounds/i3_heavy_helmet.ogg | Bin 0 -> 6934 bytes mods/i3/sounds/i3_heavy_leggings.ogg | Bin 0 -> 6456 bytes mods/i3/sounds/i3_heavy_shield.ogg | Bin 0 -> 6877 bytes mods/i3/sounds/i3_light_armor.ogg | Bin 0 -> 6503 bytes mods/i3/sounds/i3_light_boots.ogg | Bin 0 -> 6053 bytes mods/i3/sounds/i3_light_helmet.ogg | Bin 0 -> 5731 bytes mods/i3/sounds/i3_light_leggings.ogg | Bin 0 -> 6228 bytes mods/i3/sounds/i3_light_shield.ogg | Bin 0 -> 6479 bytes mods/i3/sounds/i3_skin_change.ogg | Bin 0 -> 11481 bytes mods/i3/sounds/i3_tab.ogg | Bin 0 -> 6421 bytes mods/i3/sounds/i3_teleport.ogg | Bin 0 -> 14918 bytes mods/i3/sounds/i3_trash.ogg | Bin 0 -> 7685 bytes mods/i3/src/api.lua | 360 ++++ mods/i3/src/bags.lua | 173 ++ mods/i3/src/caches.lua | 349 ++++ mods/i3/src/callbacks.lua | 279 +++ mods/i3/src/common.lua | 800 ++++++++ mods/i3/src/compression.lua | 313 ++++ mods/i3/src/detached_inv.lua | 24 + mods/i3/src/fields.lua | 475 +++++ mods/i3/src/groups.lua | 62 + mods/i3/src/gui.lua | 1742 ++++++++++++++++++ mods/i3/src/hud.lua | 177 ++ mods/i3/src/model_aliases.lua | 11 + mods/i3/src/preprocessor.lua | 98 + mods/i3/src/progressive.lua | 169 ++ mods/i3/src/styles.lua | 146 ++ mods/i3/tests/test_compression.lua | 4 + mods/i3/tests/test_custom_recipes.lua | 338 ++++ mods/i3/tests/test_online_recipe.json | 8 + mods/i3/tests/test_operators.lua | 26 + mods/i3/tests/test_tabs.lua | 34 + mods/i3/textures/i3_add.png | Bin 0 -> 2134 bytes mods/i3/textures/i3_all.png | Bin 0 -> 2346 bytes mods/i3/textures/i3_all_on.png | Bin 0 -> 1615 bytes mods/i3/textures/i3_armor.png | Bin 0 -> 2473 bytes mods/i3/textures/i3_armor_1.png | Bin 0 -> 186 bytes mods/i3/textures/i3_armor_2.png | Bin 0 -> 191 bytes mods/i3/textures/i3_armor_3.png | Bin 0 -> 175 bytes mods/i3/textures/i3_armor_4.png | Bin 0 -> 167 bytes mods/i3/textures/i3_armor_5.png | Bin 0 -> 141 bytes mods/i3/textures/i3_armor_hover.png | Bin 0 -> 2656 bytes mods/i3/textures/i3_arrow.png | Bin 0 -> 382 bytes mods/i3/textures/i3_arrow_content.png | Bin 0 -> 1306 bytes mods/i3/textures/i3_award.png | Bin 0 -> 1259 bytes mods/i3/textures/i3_award_hover.png | Bin 0 -> 1263 bytes mods/i3/textures/i3_bag.png | Bin 0 -> 2338 bytes mods/i3/textures/i3_bag_hover.png | Bin 0 -> 2357 bytes mods/i3/textures/i3_bag_large.png | Bin 0 -> 378 bytes mods/i3/textures/i3_bag_medium.png | Bin 0 -> 372 bytes mods/i3/textures/i3_bag_small.png | Bin 0 -> 459 bytes mods/i3/textures/i3_bar.png | Bin 0 -> 209 bytes mods/i3/textures/i3_bg.png | Bin 0 -> 70 bytes mods/i3/textures/i3_bg_content.png | Bin 0 -> 17123 bytes mods/i3/textures/i3_bg_full.png | Bin 0 -> 2031 bytes mods/i3/textures/i3_bg_goto.png | Bin 0 -> 1858 bytes mods/i3/textures/i3_blank.png | Bin 0 -> 67 bytes mods/i3/textures/i3_btn9.png | Bin 0 -> 146 bytes mods/i3/textures/i3_btn9_hovered.png | Bin 0 -> 146 bytes mods/i3/textures/i3_btn9_pressed.png | Bin 0 -> 146 bytes mods/i3/textures/i3_cancel.png | Bin 0 -> 927 bytes mods/i3/textures/i3_compress.png | Bin 0 -> 1627 bytes mods/i3/textures/i3_crafting.png | Bin 0 -> 1842 bytes mods/i3/textures/i3_cube.png | Bin 0 -> 404 bytes mods/i3/textures/i3_edit.png | Bin 0 -> 749 bytes mods/i3/textures/i3_exit.png | Bin 0 -> 528 bytes mods/i3/textures/i3_fav.png | Bin 0 -> 3341 bytes mods/i3/textures/i3_fav_off.png | Bin 0 -> 2326 bytes mods/i3/textures/i3_find_more.png | Bin 0 -> 20154 bytes mods/i3/textures/i3_fire_anim.png | Bin 0 -> 1413 bytes mods/i3/textures/i3_flag_anim.png | Bin 0 -> 227 bytes mods/i3/textures/i3_furnace_anim.png | Bin 0 -> 867 bytes mods/i3/textures/i3_heart.png | Bin 0 -> 198 bytes mods/i3/textures/i3_heart_half.png | Bin 0 -> 150 bytes mods/i3/textures/i3_highlight.png | Bin 0 -> 70 bytes mods/i3/textures/i3_home.png | Bin 0 -> 802 bytes mods/i3/textures/i3_hotbar.png | Bin 0 -> 435 bytes mods/i3/textures/i3_item.png | Bin 0 -> 1809 bytes mods/i3/textures/i3_item_on.png | Bin 0 -> 1458 bytes mods/i3/textures/i3_mesepick.png | Bin 0 -> 309 bytes mods/i3/textures/i3_next.png | Bin 0 -> 1364 bytes mods/i3/textures/i3_next_hover.png | Bin 0 -> 570 bytes mods/i3/textures/i3_no_result.png | Bin 0 -> 22365 bytes mods/i3/textures/i3_node.png | Bin 0 -> 1487 bytes mods/i3/textures/i3_node_on.png | Bin 0 -> 1411 bytes mods/i3/textures/i3_non_visible.png | Bin 0 -> 1614 bytes mods/i3/textures/i3_refresh.png | Bin 0 -> 2329 bytes mods/i3/textures/i3_search.png | Bin 0 -> 3986 bytes mods/i3/textures/i3_search_outline.png | Bin 0 -> 507 bytes mods/i3/textures/i3_search_outline_trim.png | Bin 0 -> 304 bytes mods/i3/textures/i3_settings.png | Bin 0 -> 1481 bytes mods/i3/textures/i3_shapeless.png | Bin 0 -> 180 bytes mods/i3/textures/i3_skin.png | Bin 0 -> 1888 bytes mods/i3/textures/i3_skin_hover.png | Bin 0 -> 1899 bytes mods/i3/textures/i3_slot.png | Bin 0 -> 2424 bytes mods/i3/textures/i3_sort.png | Bin 0 -> 845 bytes mods/i3/textures/i3_steelpick.png | Bin 0 -> 298 bytes mods/i3/textures/i3_tab.png | Bin 0 -> 442 bytes mods/i3/textures/i3_tab_hover.png | Bin 0 -> 11962 bytes mods/i3/textures/i3_tab_small.png | Bin 0 -> 412 bytes mods/i3/textures/i3_tab_small_hover.png | Bin 0 -> 9260 bytes mods/i3/textures/i3_trash.png | Bin 0 -> 521 bytes mods/i3/textures/i3_visible.png | Bin 0 -> 1317 bytes mods/i3/textures/i3_waypoint.png | Bin 0 -> 2779 bytes mods/i3/textures/i3_waypoint_hover.png | Bin 0 -> 2769 bytes mods/i3/util/luacheck.lua | 141 ++ mods/i3/util/optipng.sh | 7 + mods/i3/util/servers.lua | 23 + 131 files changed, 6702 insertions(+), 63 deletions(-) create mode 100644 mods/amogus_general/init.lua create mode 100644 mods/amogus_generator/init.lua create mode 100644 mods/i3/.editorconfig create mode 100644 mods/i3/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 mods/i3/.github/workflows/luacheck.yml create mode 100644 mods/i3/.gitignore create mode 100644 mods/i3/.luacheckrc create mode 100644 mods/i3/API.md create mode 100644 mods/i3/LICENSE create mode 100644 mods/i3/README.md create mode 100644 mods/i3/init.lua create mode 100644 mods/i3/locale/i3.fr.tr create mode 100644 mods/i3/locale/template create mode 100644 mods/i3/mod.conf create mode 100644 mods/i3/settingtypes.txt create mode 100644 mods/i3/sounds/i3_achievement.ogg create mode 100644 mods/i3/sounds/i3_cannot.ogg create mode 100644 mods/i3/sounds/i3_click.ogg create mode 100644 mods/i3/sounds/i3_craft.ogg create mode 100644 mods/i3/sounds/i3_heavy_armor.ogg create mode 100644 mods/i3/sounds/i3_heavy_boots.ogg create mode 100644 mods/i3/sounds/i3_heavy_helmet.ogg create mode 100644 mods/i3/sounds/i3_heavy_leggings.ogg create mode 100644 mods/i3/sounds/i3_heavy_shield.ogg create mode 100644 mods/i3/sounds/i3_light_armor.ogg create mode 100644 mods/i3/sounds/i3_light_boots.ogg create mode 100644 mods/i3/sounds/i3_light_helmet.ogg create mode 100644 mods/i3/sounds/i3_light_leggings.ogg create mode 100644 mods/i3/sounds/i3_light_shield.ogg create mode 100644 mods/i3/sounds/i3_skin_change.ogg create mode 100644 mods/i3/sounds/i3_tab.ogg create mode 100644 mods/i3/sounds/i3_teleport.ogg create mode 100644 mods/i3/sounds/i3_trash.ogg create mode 100644 mods/i3/src/api.lua create mode 100644 mods/i3/src/bags.lua create mode 100644 mods/i3/src/caches.lua create mode 100644 mods/i3/src/callbacks.lua create mode 100644 mods/i3/src/common.lua create mode 100644 mods/i3/src/compression.lua create mode 100644 mods/i3/src/detached_inv.lua create mode 100644 mods/i3/src/fields.lua create mode 100644 mods/i3/src/groups.lua create mode 100644 mods/i3/src/gui.lua create mode 100644 mods/i3/src/hud.lua create mode 100644 mods/i3/src/model_aliases.lua create mode 100644 mods/i3/src/preprocessor.lua create mode 100644 mods/i3/src/progressive.lua create mode 100644 mods/i3/src/styles.lua create mode 100644 mods/i3/tests/test_compression.lua create mode 100644 mods/i3/tests/test_custom_recipes.lua create mode 100644 mods/i3/tests/test_online_recipe.json create mode 100644 mods/i3/tests/test_operators.lua create mode 100644 mods/i3/tests/test_tabs.lua create mode 100644 mods/i3/textures/i3_add.png create mode 100644 mods/i3/textures/i3_all.png create mode 100644 mods/i3/textures/i3_all_on.png create mode 100644 mods/i3/textures/i3_armor.png create mode 100644 mods/i3/textures/i3_armor_1.png create mode 100644 mods/i3/textures/i3_armor_2.png create mode 100644 mods/i3/textures/i3_armor_3.png create mode 100644 mods/i3/textures/i3_armor_4.png create mode 100644 mods/i3/textures/i3_armor_5.png create mode 100644 mods/i3/textures/i3_armor_hover.png create mode 100644 mods/i3/textures/i3_arrow.png create mode 100644 mods/i3/textures/i3_arrow_content.png create mode 100644 mods/i3/textures/i3_award.png create mode 100644 mods/i3/textures/i3_award_hover.png create mode 100644 mods/i3/textures/i3_bag.png create mode 100644 mods/i3/textures/i3_bag_hover.png create mode 100644 mods/i3/textures/i3_bag_large.png create mode 100644 mods/i3/textures/i3_bag_medium.png create mode 100644 mods/i3/textures/i3_bag_small.png create mode 100644 mods/i3/textures/i3_bar.png create mode 100644 mods/i3/textures/i3_bg.png create mode 100644 mods/i3/textures/i3_bg_content.png create mode 100644 mods/i3/textures/i3_bg_full.png create mode 100644 mods/i3/textures/i3_bg_goto.png create mode 100644 mods/i3/textures/i3_blank.png create mode 100644 mods/i3/textures/i3_btn9.png create mode 100644 mods/i3/textures/i3_btn9_hovered.png create mode 100644 mods/i3/textures/i3_btn9_pressed.png create mode 100644 mods/i3/textures/i3_cancel.png create mode 100644 mods/i3/textures/i3_compress.png create mode 100644 mods/i3/textures/i3_crafting.png create mode 100644 mods/i3/textures/i3_cube.png create mode 100644 mods/i3/textures/i3_edit.png create mode 100644 mods/i3/textures/i3_exit.png create mode 100644 mods/i3/textures/i3_fav.png create mode 100644 mods/i3/textures/i3_fav_off.png create mode 100644 mods/i3/textures/i3_find_more.png create mode 100644 mods/i3/textures/i3_fire_anim.png create mode 100644 mods/i3/textures/i3_flag_anim.png create mode 100644 mods/i3/textures/i3_furnace_anim.png create mode 100644 mods/i3/textures/i3_heart.png create mode 100644 mods/i3/textures/i3_heart_half.png create mode 100644 mods/i3/textures/i3_highlight.png create mode 100644 mods/i3/textures/i3_home.png create mode 100644 mods/i3/textures/i3_hotbar.png create mode 100644 mods/i3/textures/i3_item.png create mode 100644 mods/i3/textures/i3_item_on.png create mode 100644 mods/i3/textures/i3_mesepick.png create mode 100644 mods/i3/textures/i3_next.png create mode 100644 mods/i3/textures/i3_next_hover.png create mode 100644 mods/i3/textures/i3_no_result.png create mode 100644 mods/i3/textures/i3_node.png create mode 100644 mods/i3/textures/i3_node_on.png create mode 100644 mods/i3/textures/i3_non_visible.png create mode 100644 mods/i3/textures/i3_refresh.png create mode 100644 mods/i3/textures/i3_search.png create mode 100644 mods/i3/textures/i3_search_outline.png create mode 100644 mods/i3/textures/i3_search_outline_trim.png create mode 100644 mods/i3/textures/i3_settings.png create mode 100644 mods/i3/textures/i3_shapeless.png create mode 100644 mods/i3/textures/i3_skin.png create mode 100644 mods/i3/textures/i3_skin_hover.png create mode 100644 mods/i3/textures/i3_slot.png create mode 100644 mods/i3/textures/i3_sort.png create mode 100644 mods/i3/textures/i3_steelpick.png create mode 100644 mods/i3/textures/i3_tab.png create mode 100644 mods/i3/textures/i3_tab_hover.png create mode 100644 mods/i3/textures/i3_tab_small.png create mode 100644 mods/i3/textures/i3_tab_small_hover.png create mode 100644 mods/i3/textures/i3_trash.png create mode 100644 mods/i3/textures/i3_visible.png create mode 100644 mods/i3/textures/i3_waypoint.png create mode 100644 mods/i3/textures/i3_waypoint_hover.png create mode 100644 mods/i3/util/luacheck.lua create mode 100644 mods/i3/util/optipng.sh create mode 100644 mods/i3/util/servers.lua diff --git a/mods/amogus_blocks/init.lua b/mods/amogus_blocks/init.lua index df399af..62d4bb1 100644 --- a/mods/amogus_blocks/init.lua +++ b/mods/amogus_blocks/init.lua @@ -1,3 +1,7 @@ +minetest.register_on_joinplayer(function(player) + player:set_sky({r=0, g=0, b=0}, "plain", {}) +end) + minetest.register_node("amogus_blocks:ladder_steel", { description = "Ladder", drawtype = "signlike", @@ -25,12 +29,12 @@ minetest.register_node("amogus_blocks:floor", { minetest.register_node("amogus_blocks:tv", { description = "CRT TV", tiles = { - "PC2.png", - "PC2.png", - "PC2.png", - "PC2.png", - "PC2.png", - "PC.png" + "crt2.png", + "crt2.png", + "crt2.png", + "crt2.png", + "crt2.png", + "crt.png" }, paramtype2 = "facedir", drop = 'amogus_blocks:amogus_blocks', groups = {cracky=3, stone=1}, @@ -118,58 +122,5 @@ minetest.register_node("amogus_blocks:wood", { drop = 'amogus:wood', groups = {cracky=3, stone=1}, }) --- add water with blue color without texture -minetest.register_node("amogus_blocks:water", { - description = "Water", - drawtype = "liquid", - tiles = { - { - name = "water.png", - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 2.0, - }, - }, - }, - special_tiles = { - -- New-style water source material (mostly unused) - { - name = "water.png", - backface_culling = false, - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 2.0, - }, - }, - -- New-style flowing water material (mostly unused) - { - name = "water.png", - backface_culling = true, - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 0.8, - }, - }, - }, - alpha = 160, - paramtype = "light", - walkable = false, - pointable = false, - diggable = false, - buildable_to = true, - drowning = 1, - liquidtype = "source", - liquid_alternative_flowing = "amogus_blocks:water", - liquid_alternative_source = "amogus_blocks:water", - liquid_viscosity = 1, - post_effect_color = {a = 103, r = 30, g = 60, b = 90}, - groups = {water = 3, liquid = 3, puts_out_fire = 1}, -}) -minetest.register_alias("mapgen_dirt", "amogus_blocks:grass") -minetest.register_alias("mapgen_stone", "amogus_blocks:floor") \ No newline at end of file +minetest.register_alias("mapgen_dirt", "amogus_blocks:floor") +minetest.register_alias("mapgen_stone", "amogus_blocks:grass") \ No newline at end of file diff --git a/mods/amogus_general/init.lua b/mods/amogus_general/init.lua new file mode 100644 index 0000000..e69de29 diff --git a/mods/amogus_generator/init.lua b/mods/amogus_generator/init.lua new file mode 100644 index 0000000..e69de29 diff --git a/mods/amogus_items/init.lua b/mods/amogus_items/init.lua index 1b2029c..621c313 100644 --- a/mods/amogus_items/init.lua +++ b/mods/amogus_items/init.lua @@ -56,9 +56,48 @@ minetest.register_craftitem("amogus_items:tomato", { on_use = minetest.item_eat(1), }) minetest.register_craftitem("amogus_items:water", { - description = "Water", inventory_image = "water.png", on_use = minetest.item_eat(1), }) --- add sprite, coke, fanta, tomato, and water crafting recipes +-- add lightsaber_blue and lightsaber_red and lightsaber_green and let it destroy nodes and mobs +minetest.register_tool("amogus_items:lightsaber_blue", { + description = "Blue Lightsaber", + inventory_image = "lightsaber_blue.png", + tool_capabilities = { + full_punch_interval = 0.1, + max_drop_level=3, + groupcaps={ + snappy={times={[1]=0.1, [2]=0.1, [3]=0.1}, uses=0, maxlevel=3}, + }, + damage_groups = {fleshy=10}, + }, + sound = {breaks = "amogus_sound"}, +}) +minetest.register_tool("amogus_items:lightsaber_red", { + description = "Red Lightsaber", + inventory_image = "lightsaber_red.png", + tool_capabilities = { + full_punch_interval = 0.1, + max_drop_level=3, + groupcaps={ + snappy={times={[1]=0.1, [2]=0.1, [3]=0.1}, uses=0, maxlevel=3}, + }, + damage_groups = {fleshy=10}, + }, + sound = {breaks = "amogus_sound"}, +}) + +minetest.register_tool("amogus_items:lightsaber_green", { + description = "Green Lightsaber", + inventory_image = "lightsaber_green.png", + tool_capabilities = { + full_punch_interval = 0.1, + max_drop_level=3, + groupcaps={ + snappy={times={[1]=0.1, [2]=0.1, [3]=0.1}, uses=0, maxlevel=3}, + }, + damage_groups = {fleshy=10}, + }, + sound = {breaks = "amogus_sound"}, +}) \ No newline at end of file diff --git a/mods/i3/.editorconfig b/mods/i3/.editorconfig new file mode 100644 index 0000000..89dddff --- /dev/null +++ b/mods/i3/.editorconfig @@ -0,0 +1,9 @@ +[*] +end_of_line = lf + +[*.{lua,txt,md,json}] +charset = utf8 +indent_size = 8 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/mods/i3/.github/ISSUE_TEMPLATE/bug_report.md b/mods/i3/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..96ac07f --- /dev/null +++ b/mods/i3/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,24 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +- Mod version? Release or git? +- Engine version? +- LuaJIT enabled? +- Operating system? +- Did you try to disable other mods except i3? diff --git a/mods/i3/.github/workflows/luacheck.yml b/mods/i3/.github/workflows/luacheck.yml new file mode 100644 index 0000000..d9d6abf --- /dev/null +++ b/mods/i3/.github/workflows/luacheck.yml @@ -0,0 +1,21 @@ +name: Luacheck + +on: [push, pull_request] + +jobs: + + luacheck: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup ‘lua’ + uses: leafo/gh-actions-lua@v8 + with: + luaVersion: 5.1 + - name: Setup ‘luarocks’ + uses: leafo/gh-actions-luarocks@v4 + - name: Setup ‘luacheck’ + run: luarocks install luacheck + - name: Run ‘luacheck’ linter + run: cd util; lua luacheck.lua diff --git a/mods/i3/.gitignore b/mods/i3/.gitignore new file mode 100644 index 0000000..6fd0a37 --- /dev/null +++ b/mods/i3/.gitignore @@ -0,0 +1,41 @@ +# Compiled Lua sources +luac.out + +# luarocks build files +*.src.rock +*.zip +*.tar.gz + +# Object files +*.o +*.os +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo +*.def +*.exp + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + diff --git a/mods/i3/.luacheckrc b/mods/i3/.luacheckrc new file mode 100644 index 0000000..79da584 --- /dev/null +++ b/mods/i3/.luacheckrc @@ -0,0 +1,37 @@ +allow_defined_top = true + +ignore = { + "631", -- Line is too long. + "get_debug_grid", +} + +read_globals = { + "minetest", + "armor", + "skins", + "awards", + "hb", + "vector", + "string", + "table", + "ItemStack", + "VoxelArea", + "VoxelManip", +} + +globals = { + "i3", + "core", + "sfinv", + "unified_inventory", +} + +exclude_files = { + "tests/test_compression.lua", + "tests/test_custom_recipes.lua", + "tests/test_operators.lua", + "tests/test_tabs.lua", + + ".install", + ".luarocks", +} diff --git a/mods/i3/API.md b/mods/i3/API.md new file mode 100644 index 0000000..6d22301 --- /dev/null +++ b/mods/i3/API.md @@ -0,0 +1,338 @@ +## API + +### Custom tabs + +#### `i3.new_tab(name, def)` + +- `name` is the tab name. +- `def` is the tab definition. + +Custom tabs can be added to the `i3` inventory as follow (example): + +```Lua +i3.new_tab("stuff", { + description = "Stuff", + image = "image.png", -- Optional, add an image next to the tab description + + -- + -- The functions below are all optional + -- + + -- Determine if the tab is visible by a player, return false to hide the tab + access = function(player, data) + local name = player:get_player_name() + return name == "singleplayer" + end, + + formspec = function(player, data, fs) + fs("label", 3, 1, "Just a test") + fs"label[3,2;Lorem Ipsum]" + -- No need to return anything + end, + + -- Events handling happens here + fields = function(player, data, fields) + if fields.mybutton then + -- Do things + end + + i3.set_fs(player) -- Update the formspec, mandatory + end, +}) +``` + +- `player` is an `ObjectRef` to the user. +- `data` are the user data. +- `fs` is the formspec table which is callable with a metamethod. Every call adds a new entry. + +#### `i3.set_fs(player)` + +Update the current formspec. + +#### `i3.remove_tab(tabname)` + +Delete a tab by name. + +#### `i3.get_current_tab(player)` + +Return the current player tab. `player` is an `ObjectRef` to the user. + +#### `i3.set_tab(player[, tabname])` + +Sets the current tab by name. `player` is an `ObjectRef` to the user. +`tabname` can be omitted to get an empty tab. + +#### `i3.override_tab(tabname, def)` + +Override a tab by name. `def` is the tab definition like seen in `i3.set_tab` + +#### `i3.tabs` + +A list of registered tabs. + +--- + +### Custom recipes + +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. + +Examples: + +#### Registering a custom crafting type + +```Lua +i3.register_craft_type("digging", { + description = "Digging", + icon = "default_tool_steelpick.png", +}) +``` + +#### Registering a custom crafting recipe + +```Lua +i3.register_craft { + type = "digging", + result = "default:cobble 2", + items = {"default:stone"}, +} +``` + +```Lua +i3.register_craft { + result = "default:cobble 16", + items = { + "default:stone, default:stone, default:stone", + "default:stone, , default:stone", + "default:stone, default:stone, default:stone", + } +} +``` + +Recipes can be registered in a Minecraft-like way: + +```Lua +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "X X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} +``` + +Multiples recipes can also be registered: + +```Lua +i3.register_craft { + { + result = "default:mese", + items = { + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + } + }, + + big = { + result = "default:mese 4", + items = { + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + "default:mese_crystal, default:mese_crystal", + } + }, +} +``` + +Recipes can be registered from a given URL containing a JSON file (HTTP support is required¹): + +```Lua +i3.register_craft { + url = "https://raw.githubusercontent.com/minetest-mods/i3/main/tests/test_online_recipe.json" +} +``` + +--- + +### Recipe filters + +Recipe filters can be used to filter the recipes shown to players. Progressive +mode is implemented as a recipe filter. + +#### `i3.add_recipe_filter(name, function(recipes, player))` + +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`. + +Example function to hide recipes for items from a mod called "secretstuff": + +```lua +i3.add_recipe_filter("Hide secretstuff", function(recipes) + local filtered = {} + for _, recipe in ipairs(recipes) do + if recipe.output:sub(1,12) ~= "secretstuff:" then + filtered[#filtered + 1] = recipe + end + end + + return filtered +end) +``` + +#### `i3.set_recipe_filter(name, function(recipe, player))` + +Remove all recipe filters and add a new one. + +#### `i3.recipe_filters` + +A map of recipe filters, indexed by name. + +--- + +### Search filters + +Search filters are used to perform specific searches from the search field. +The filters can be cumulated to perform a specific search. +They are used like so: ` +=,,<...>` + +Example usages: + +- `+groups=cracky,crumbly` -> search for groups `cracky` and `crumbly` in all items. +- `wood +groups=flammable` -> search for group `flammable` amongst items which contain + `wood` in their names. + +Notes: +- If `optional_name` is omitted, the search filter will apply to all items, without pre-filtering. +- The `+groups` filter is currently implemented by default. + +#### `i3.add_search_filter(name, function(item, values))` + +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. +- `values` is a table of all possible values. + +Example function sorting items by drawtype: + +```lua +i3.add_search_filter("types", function(item, drawtypes) + local t = {} + + for i, dt in ipairs(drawtypes) do + t[i] = (dt == "node" and reg_nodes[item] and 1) or + (dt == "item" and reg_craftitems[item] and 1) or + (dt == "tool" and reg_tools[item] and 1) or nil + end + + return #t > 0 +end) +``` + +#### `i3.search_filters` + +A map of search filters, indexed by name. + +--- + +### Sorting methods + +Sorting methods are used to filter the player's main inventory. + +#### `i3.add_sorting_method(name, def)` + +Add a player inventory sorting method. + +- `name` is the method name. +- `def` is the method definition. + +Example: + +```Lua +i3.add_sorting_method("test", { + description = "Cool sorting method", + func = function(list, data) + -- `list`: inventory list + -- `data`: player data + + table.sort(list) + + -- A list must be returned + return list + end, +}) + +``` + +#### `i3.sorting_methods` + +A table containing all sorting methods. + +--- + +### Item list compression + +`i3` can reduce the item list size by compressing a group of items. + +#### `i3.compress(item, def)` + +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. + +Example: + +```Lua +i3.compress("default:diamondblock", { + replace = "diamond", + by = {"bronze", "copper", "gold", "steel", "tin"} +}) + +``` + +#### `i3.compress_groups` + +A map of all compressed item groups, indexed by stereotypes. + +--- + +### Miscellaneous + +#### `i3.hud_notif(name, msg[, img])` + +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. +- `img` (optional) is the HUD image to show (preferably 16x16 px). + +#### `i3.get_recipes(item)` + +Return a table of recipes and usages of `item`. + +#### `i3.export_url` + +If set, the mod will export all the cached recipes and usages in a JSON format +to the given URL (HTTP support is required¹). + +#### `groups = {bag = <1-4>}` + +The `bag` group in the item definition allows to extend the player inventory size +given a number between 1 and 4. + +--- + +**¹** Add `i3` to the `secure.http_mods` or `secure.trusted_mods` setting in `minetest.conf`. diff --git a/mods/i3/LICENSE b/mods/i3/LICENSE new file mode 100644 index 0000000..1abebab --- /dev/null +++ b/mods/i3/LICENSE @@ -0,0 +1,60 @@ +License of source code +---------------------- + +The MIT License (MIT) + +Copyright (c) 2020-2021 Jean-Patrick Guerrero and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +Licenses of media (textures) +---------------------------- + +paramat (CC BY-SA 3.0): + i3_arrow.png - derived from a texture by BlockMen (CC BY-SA 3.0) + i3_hotbar.png + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/i3/README.md b/mods/i3/README.md new file mode 100644 index 0000000..6d4f702 --- /dev/null +++ b/mods/i3/README.md @@ -0,0 +1,58 @@ +![logo](https://user-images.githubusercontent.com/7883281/145490041-d91d6bd6-a654-438d-b208-4d5736845ab7.png) + +[![MIT License](https://img.shields.io/apm/l/atomic-design-ui.svg?)](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs) [![GitHub Release](https://img.shields.io/github/release/minetest-mods/i3.svg?style=flat)]() ![workflow](https://github.com/minetest-mods/i3/actions/workflows/luacheck.yml/badge.svg) [![ContentDB](https://content.minetest.net/packages/jp/i3/shields/downloads/)](https://content.minetest.net/packages/jp/i3/) [![PayPal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/jpg84240) + +#### **`i3`** is a next-generation inventory for Minetest. + +This mod features a modern, powerful inventory menu with a good user experience. +**`i3`** provides a rich [**API**](https://github.com/minetest-mods/i3/blob/master/API.md) for mod developers who want to extend it. + +This mod requires **Minetest 5.6+** + +#### List of features: + - Crafting Guide (survival mode only) + - Progressive Mode¹ + - Quick Crafting + - 3D Player Model Real-Time Preview + - Isometric Map Preview + - Inventory Sorting (+ options: compression, reverse mode, automation, etc.) + - Item List Compression (**`moreblocks`** is supported) + - Item Bookmarks + - Waypoints + - Bags + - Home + +**¹** *This mode is a Terraria-like system that shows recipes you can craft from items you ever had in your inventory. +To enable it: `i3_progressive_mode = true` in `minetest.conf`.* + +#### This mod officially supports the following mods: + - [**`3d_armor`**](https://content.minetest.net/packages/stu/3d_armor/) + - [**`skinsdb`**](https://content.minetest.net/packages/bell07/skinsdb/) + - [**`awards`**](https://content.minetest.net/packages/rubenwardy/awards/) + +#### Recommendations + +To use this mod in the best conditions: + + - Use LuaJIT + - Use a HiDPI widescreen display + - Use the default Freetype font style + +#### Troubleshooting + +If the inventory's font size is too big on certain setups (namely Windows 10/11 or 144 DPI display), you should lower the +value of the setting `display_density_factor` in your `minetest.conf`. Note that the change is applied after restart. + +You can also use the font size slider in the inventory, settings window. + +#### Notes + +`i3` uses a larger inventory than the usual inventories in Minetest games. +Thus, most chests will be unadapted to this inventory size. +The `i3` inventory is 9 slots wide by default, such as Minecraft. + +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://user-images.githubusercontent.com/7883281/185755315-23c2fffa-203d-4115-9dc3-576c92615733.png) diff --git a/mods/i3/init.lua b/mods/i3/init.lua new file mode 100644 index 0000000..1ad3cbf --- /dev/null +++ b/mods/i3/init.lua @@ -0,0 +1,127 @@ +print[[ + + Powered by + + ██╗██████╗ + ██║╚════██╗ + ██║ █████╔╝ + ██║ ╚═══██╗ + ██║██████╔╝ + ╚═╝╚═════╝ +]] + +local modpath = core.get_modpath"i3" +local http = core.request_http_api() +local storage = core.get_mod_storage() +local _loadfile = dofile(modpath .. "/src/preprocessor.lua") + +local function lf(path) + return assert(_loadfile(modpath .. path)) +end + +i3 = { + version = 1123, + data = core.deserialize(storage:get_string"data") or {}, + + settings = { + debug_mode = false, + max_favs = 6, + max_waypoints = 30, + 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, + hud_timer_max = 1.5, + + damage_enabled = core.settings:get_bool"enable_damage", + progressive_mode = core.settings:get_bool"i3_progressive_mode", + }, + + categories = { + "bag", + "armor", + "skins", + "awards", + "waypoints", + }, + + saves = { -- Metadata to save + bag = true, + home = true, + sort = true, + collapse = true, + font_size = true, + hide_tabs = true, + waypoints = true, + inv_items = true, + auto_sorting = true, + inv_compress = 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 = { + api = lf"/src/api.lua", + bags = lf"/src/bags.lua", + caches = lf"/src/caches.lua", + callbacks = lf"/src/callbacks.lua", + common = lf"/src/common.lua", + compress = lf"/src/compression.lua", + detached = lf"/src/detached_inv.lua", + fields = lf"/src/fields.lua", + groups = lf"/src/groups.lua", + gui = lf"/src/gui.lua", + hud = lf"/src/hud.lua", + model_alias = lf"/src/model_aliases.lua", + progressive = lf"/src/progressive.lua", + styles = lf"/src/styles.lua", + }, + + -- Caches + init_items = {}, + fuel_cache = {}, + usages_cache = {}, + recipes_cache = {}, + + tabs = {}, + cubes = {}, + groups = {}, + plants = {}, + modules = {}, + craft_types = {}, + + recipe_filters = {}, + search_filters = {}, + sorting_methods = {}, +} + +i3.files.common() +i3.files.api(http) +i3.files.compress() +i3.files.detached() +i3.files.groups() +i3.files.callbacks(http, storage) + +if i3.settings.progressive_mode then + i3.files.progressive() +end + +if i3.settings.debug_mode then + lf("/tests/test_tabs.lua")() +-- lf("/tests/test_operators.lua")() + lf("/tests/test_compression.lua")() + lf("/tests/test_custom_recipes.lua")() +end diff --git a/mods/i3/locale/i3.fr.tr b/mods/i3/locale/i3.fr.tr new file mode 100644 index 0000000..2c57546 --- /dev/null +++ b/mods/i3/locale/i3.fr.tr @@ -0,0 +1,85 @@ +# textdomain: i3 + +### init.lua ### + +@1 added in your inventory=@1 ajouté à votre inventaire +@1 new recipe(s) discovered!=@1 nouvelle(s) recette(s) découverte(s)! +@1 of chance to drop=@1 de chance de tomber +@1 spawned=@1 spawné +Achievements: @1 of @2 (@3)=Succès : @1 sur @2 (@3) +Any black dye=N'importe quel colorant noir +Any black flower=N'importe quelle fleur noire +Any blue dye=N'importe quel colorant bleu +Any blue flower=N'importe quelle fleur bleue +Any brown dye=N'importe quel colorant marron +Any carpet=N'importe quel tapis +Any coal=N'importe quel charbon +Any cyan dye=N'importe quel colorant bleu turquoise +Any dark green dye=N'importe quel colorant vert foncé +Any dark grey dye=N'importe quel colorant gris foncé +Any dye=N'importe quel colorant +Any flower=N'importe quelle fleur +Any glass=N'importe quel verre +Any green dye=N'importe quel colorant vert +Any green flower=N'importe quelle fleur verte +Any grey dye=N'importe quel colorant gris +Any item belonging to the groups: @1=Tout item appartenant aux groupes : @1 +Any leaves=N'importe quelles feuilles d'arbre +Any magenta dye=N'importe quel colorant mauve +Any mushroom=N'importe quel champignon +Any orange dye=N'importe quel colorant orange +Any orange flower=N'importe quelle fleur orange +Any pink dye=N'importe quel colorant rose +Any red dye=N'importe quel colorant rouge +Any red flower=N'importe quelle fleur rouge +Any sand=N'importe quel sable +Any stick=N'importe quel bâton +Any stone=N'importe quelle roche +Any tree=N'importe quel tronc d'arbre +Any vessel=N'importe quel couvert +Any violet dye=N'importe quel colorant violet +Any violet flower=N'importe quelle fleur violette +Any white dye=N'importe quel colorant blanc +Any white flower=N'importe quelle fleur blanche +Any wood planks=N'importe quelles planches de bois +Any wool=N'importe quelle laine +Any yellow dye=N'importe quel colorant jaune +Any yellow flower=N'importe quelle fleur jaune +Armor=Armure +Bag=Sac +Bookmarks=Favoris +Burning time: @1=Temps de combustion : @1 +Cannot mark this item. Bookmark limit reached.= +Collect items to reveal more recipes=Collecter des items pour révéler des recettes +Compress items=Compresser les items +Cooking=Cuisson +Cooking time: @1=Temps de cuisson : @1 +Craft (x@1)=Fabriquer (x@1) +Digging=Minage +Digging (by chance)=Minage (par chance) +Heal=Guérison +Inventory=Inventaire +Items=Items +Level=Niveau +Mark this item=Ajouter aux favoris +No item to show=Aucun item à montrer +No recipes=Aucune recette +No usages=Aucun usage +Only drop if using one of these tools: @1=Tombe seulement en utilisant un de ces outils : @1 +Only drop if using this tool: @1=Tombe seulement en utilisant cet outil : @1 +Quick crafting=Fabrication rapide +Recipe @1 of @2=Recette @1 sur @2 +Repairable by step of @1=Réparable par étape de @1 +Replaced by @1 on burning=Remplacé par @1 à la combustion +Replaced by @1 on crafting=Remplacé par @1 à la fabrication +Replaced by @1 on smelting=Remplacé par @1 à la cuisson +Shapeless=Sans forme particulière +Skins=Skins +Sort items (A-Z)=Trier les items (A-Z) +Sort items (Z-A)=Trier les items (Z-A) +The inventory is extended by @1 slots=L'inventaire est étendu de @1 slots +Trash all items=Détruire tous les items +Unknown Item (@1)=Item inconnu (@1) +Unmark this item=Enlever des favoris +Usage @1 of @2=Usage @1 sur @2 + \ No newline at end of file diff --git a/mods/i3/locale/template b/mods/i3/locale/template new file mode 100644 index 0000000..1046d60 --- /dev/null +++ b/mods/i3/locale/template @@ -0,0 +1,84 @@ +# textdomain: i3 + +### init.lua ### + +@1 added in your inventory= +@1 new recipe(s) discovered!= +@1 of chance to drop= +@1 spawned= +Achievements: @1 of @2 (@3)= +Any black dye= +Any black flower= +Any blue dye= +Any blue flower= +Any brown dye= +Any carpet= +Any coal= +Any cyan dye= +Any dark green dye= +Any dark grey dye= +Any dye= +Any flower= +Any glass= +Any green dye= +Any green flower= +Any grey dye= +Any item belonging to the groups: @1= +Any leaves= +Any magenta dye= +Any mushroom= +Any orange dye= +Any orange flower= +Any pink dye= +Any red dye= +Any red flower= +Any sand= +Any stick= +Any stone= +Any tree= +Any vessel= +Any violet dye= +Any violet flower= +Any white dye= +Any white flower= +Any wood planks= +Any wool= +Any yellow dye= +Any yellow flower= +Armor= +Bag= +Bookmarks= +Burning time: @1= +Cannot mark this item. Bookmark limit reached.= +Collect items to reveal more recipes= +Compress items= +Cooking= +Cooking time: @1= +Craft (x@1)= +Digging= +Digging (by chance)= +Heal= +Inventory= +Items= +Level= +Mark this item= +No item to show= +No recipes= +No usages= +Only drop if using one of these tools: @1= +Only drop if using this tool: @1= +Quick crafting= +Recipe @1 of @2= +Repairable by step of @1= +Replaced by @1 on burning= +Replaced by @1 on crafting= +Replaced by @1 on smelting= +Shapeless= +Skins= +Sort items (A-Z)= +Sort items (Z-A)= +The inventory is extended by @1 slots= +Trash all items= +Unknown Item (@1)= +Unmark this item= +Usage @1 of @2= diff --git a/mods/i3/mod.conf b/mods/i3/mod.conf new file mode 100644 index 0000000..04452f7 --- /dev/null +++ b/mods/i3/mod.conf @@ -0,0 +1,4 @@ +name = i3 +description = Next-generation inventory +optional_depends = 3d_armor, skinsdb, awards +min_minetest_version = 5.6 diff --git a/mods/i3/settingtypes.txt b/mods/i3/settingtypes.txt new file mode 100644 index 0000000..a97f54a --- /dev/null +++ b/mods/i3/settingtypes.txt @@ -0,0 +1,2 @@ +# 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 diff --git a/mods/i3/sounds/i3_achievement.ogg b/mods/i3/sounds/i3_achievement.ogg new file mode 100644 index 0000000000000000000000000000000000000000..df38d5bc3dbb153373ec29e6f061fc05e1994071 GIT binary patch literal 23557 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 Wgm&c1-=c>=@%qJVe;ogt=YIh@sSFqZ literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_cannot.ogg b/mods/i3/sounds/i3_cannot.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8f97186a995d94b02dbb3e4dc7ddd44239417ae5 GIT binary patch literal 28026 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 Ct2wR! literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_heavy_armor.ogg b/mods/i3/sounds/i3_heavy_armor.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fe89ff2e9a854aa9c5320726b1b19808b03b804d GIT binary patch literal 7439 zcmb_0Tsl+5PWEuNXn31)zOj6N; zu}fkorIhTXv^{#N@0syD&*%C4{`kGVe|+!PnR~8tuH~HTeO>1|=ick<>jLpYe?9l1 z&p{mW?8h)Tk0MXh@i3BqIA?%I*^ToDLHpX)|0{X+ay0*WIGQ}5caV1=K=Sd z*6kPow!8lcKb^f{zNjF7k{j1L${wYstEa2GL)QSMPVn)LB>RW>qIQQw`G*}33HAwz zz;ITl0)8&Xk42pH3iB~{IUX6}jj}l&=IdknFB)Z_qbmvItSw!4n`4cQw`=PfYGZYI z1lFfl!CATSKo$^$#KANKYRRc4T^p6CvZdE>J(x}f+@MmKidCWs%ditkwr%!K!gXI5 zOxq7}6zK8?_J!GN&lHB2ArJJ0&Y}SI9_8B?DvSnHs_{%lSSog%D-nj_$X!6#CWT%{ z0*WpVs0t1hjBUyY8!!gcH0lx|?1mwSi}aNU6XjT8aqKN{EK?1ehS%k|!rT{?W1dTe zU}t2)Z*Z)DuKfBK%D{UglmP4U~2!dIJB5czU4t4UqPgTT)#19I9 zI6^`|&Mtv&m&9;SJ?3Am8eOWMU#d}E@846e)my)CSBI-^2O{l^=s1B8mh(akQc%z@j|DHkP?N2 zP_qs#M*-@+ihIxLSrwsI@i5$-!ZW?iK!Xbf@bMvv0>c3r@WRk(1UpQ5E-4AqDIea4 z?L@_k>CIlt++)&B&)8$qqf(Yi2*fZEE{=8YWyrNmc47EUOAMKcWg-9b+RB9iI1Jk$ z>zxJ`NI`Ioh5>u>>uv!iCsXBj6I5)&RBSU;x-+!wGtGJ%IL&F;+G*qdk^RA=UxSZ) z4Sqf1^ZKjL_=wM;Y@b)m;6v;~hejj+yK!BQ<%eQZrvU1p*`?C$M7Y68~3e z|Nk3riBdHL2}6)VXQ;ewsC;KA$15(vC_V@UK~~Q4yTi0PGYlMnkI$^1eD-wS9_ex* z`0pS95zf;YZU$O6fC3PiX7=TGz7jIMS9w1*lhcaOPkjJ*dpvV*!iwMj66ouv}7d z9h*(8EukSDxRX<{?3bh(W5BRSvoZ+D+P6Ky!zB< z0&1CG4~H)@L2B~|f)XU%V^N}{$rGy%L64CPWc(nCP9wwQC^V7;j)5Q#*jLg>0ERp= zNFFqKz*q=<5r(%%GeC6F3|CO!FYrMYvEupgWIlvkJsc7ehEOm<5_Sef%OK#TaE`_s zlqdv3fHnyAv^-@W9$&lP5eq0_rILxqvI;@@!C;u#pd53?FbuZd^!gZMm?#KJ5FSj# zCN6L)5{5w^CI)iH7<3vj8M{7~K?uZV6F9mwLZCK_fX8qshuV%@KmuJbhI9cG(5>r0 zk^uy4pvyuAI{i(NYe8|BHv$D2X{jc=U&gCUc#~o*H)WjxQrJXnJ2EWQvg?}l09H7U z(q(MR$jq=8F3Do+VM?+xh*KcXoO>#0**O0^`Vi5t1cGky34)(!$zWO*WT6N_7t#n+ z;3I&BRTwUTVITpR*OBBta2B~xvD4r{;xNFe#9{n>TuI=#lwb*mfuam@7%&`&RmDRd z2=&k=y3i(CTVeD#;3g0YX$6F3$W&$mC!aw0w7Fd7G?CMl3+x9;P1(Rf zeY2ab5k^i_%fK5Ar3pe7sCIA`8DFB2I2QpckaW2mw2|v*gT;Yc!}<+@!}#Z3kor#; z{u7V^P|r0^fJ%7F**iQg{TkQD$#ow)0lb8O+&F+Xnm&jt%jJX$K&dxNr@Ml@@8CE} zClCMyY7{3OsQ_|rijt^Ij`P|b?&Mmox3x@Upg1QCL0EP^*xMkBsdemp2cQc?nx{R1 z%eUPFYYjn}0HMhb9B8@DCUHc=V~1G`cPLO+1Qsug{oUh%O=&-vE^f=Y>>`)2W?jVnf?|enS#f#h-U_x zXFRD=I~g+M8_nMoV{{&We+$lzZ*SuzcM5q?)3DQH;VUhh$W+P4U7q1OkCE?^bsv96 z1=ThS9-#tz;p)J{H7iShY!lFk=JA92kT`sXz}Q%SU36u8{@O7&a?} zI^o9$iCK3!9^EG-E}_TshDRBv0ogh3qv=Fg3Q5tEQOSZjg?B!-i>pQW#dEKJu~4ie z6ieYvOgwh%#^blVTdm0PWo_^HRII&KxB?c?8*rUe;!!Tm%d5V1=V902*qhmv?~t&R zEGSlgJ-ob}%Qfc%23*E?x!<1rD%-e25a-*I!##m3ValC3pOKN4ot%}Gl$oENoJvil zCZ$j_F2=@$1liwasIJl>>;BuCf96&VKNV#jev(!Fc_!%*<#$G_k!fCcg>m$t;bfN3 z)xDlUhGsVBc1NM7~gR2 zxNxLprro=6*EZj|o|x#jecwM#3k$bw!OmqaVW9|n8|QGD$8su}s;#a|hxrdHn!DX4 zH0L8titGP)QaxFJ=~sF+vAkdMtE8&K=B1O7ysA$Mjl*L`T#w&8b!1Dlc3$)0-c7;y zwy=9mM@r@bBKt;r`8I2H%07AFDL?k6dD}+0UjJ=X2h5A|{o1b{k2x83@0Z!Z3~KqQ zMYTY89-@b#?445(@}`6bNh^2Gwfq_K_o>q1ypOHF(&vLB^YJZrJ#r2t-8-qdXuP{= z_`b)mvqH2krCjlL!T08DTZVm1_Sc=&{$}G_X7!lF_cLC|ID-RWgegYNc35X zO)6Nk{OHx4-Db`5S~Ktod#mLcvHJR!(r74grp8jBz96%I?a9FepPC`Bh;2DaUva7S z51bUF+lF-|-?!KK9+52{H)WG2_x5^bL^f(=%>BGl5AB03OvA22J4HL-5bw2J0kL9> z21x=g=NHw_npKwF?4O_O%PD4!gFWBVB4xXL8)-n)OHZRYF4aV79Cf;be%l_;r z5z=d2nq8dpLyy@V*1nsj<-gQ_r{Kp?#~Y9I)9k9+y1wprXIG~$E<}kwo_*iaSQYz) z-|4BWza85qy&yif=66%jA1eq~@0)kjzQC|?>3SlfjZ;}v?5l&xuF0_hfh`lk4+y`` zPA}h@dKqCDNP_SGqA^x19ulz?id(zK11W-4<>o=9KacWINGxhp|9HEH>1c7YNM%K@ zqWN)lwmQpdcK&mv-XJ02?hE0R&3=_egvl}Xh@Ut0h1JtX!gVa)vb=r)_@v5hx{A+Z~p$hBhCn3E74*f?sU7(YE*yz>+KdB85H$v|JV5h)q4X_x|n(R- zKL44g8sA=Cb}6o&t9z+HzuUNJq|DAaV87Xc7gt_-zYFRkSelWl^=HyouPAJ;dMJmM zk!B0*TyV{xSMWcK{`u*Yru4on{kZMNq-T8ttwjCDHqFpnE5hZ=9Vhh<%(EEV$7`n0 ziFTKr=~+w>)OhjE?h_*_Wead7J*M)f#D>qZecsKJgI5DAUS8gfiKAmAwTzSmZ=k0G@&Qd z=g2=ca(-|Uo&APUAe?f?>2mjSd*z;xux}XeD?x23c_LLUl1r*5f5(UwM$!(DOltp> zJQy37V`F)BUgxz?hqO)PMz@KuGLQIYAI;cal^2sJ(Q>UsZ<$0<>BNb(bHb3_ZduW_ zyQg(?R@j^6M)NmjwnYbacI*!mt?bD${&*50?eeFcJ{x;^q zu(j5qt{}9>ME+2G$feiQ>Z@A4ChwBm@Fu_T28vGcB99NOy)uFf%ut1Shl;8vl2!YA z>_%v=1;lT!8EsF$n%5j9@1Cma&G4^vZSVW&m81-R;az>6utwbb*k$}~R9hKN|BUqs zl7Ot2kfQX7-oefFFp-oPTkAI)-7<bpP3d_yGbC8A6E&>{g8#LCrY37zUjs*{Ph z_vc$bZSS9va?@6SQbxnOKPPWGQ5e$hD%=`?$TNto-@VdvA|?ouYm`FjZ{PCdvr=^V z7sXwjatxoZ)|9~d&SC#E!^keR#pF{t1T0?V*xs< zDxIyAR+E7muX%Q~{$Z)T@bGT;$x0n`sNm?Y@;%#cicMS-J*zkH3UxJV6TJV%pE7#+ zv@e4a8*N&iM@6deq|yhhp~C?xdBzre3!1B`*lRp5bjdcyP5Niv7c`za;*{DER}lav zGaqX*Us~3%YudYb;kmF!N~X13rlC#umlea8YRSDYx@KZ$#ruivjFnN9AFmb1wAA~I z+(O6sUWn9fGk$} z$WfGRRhbJT|0ZutnA(5XG(o*CLd9N5^-#jMEM?7c#nT@>Lz+$|=QPzh+#tPM3CcRE ze5dtDPu*`dAz>x!=kU%#s{Y07VpFqwy=uF#dk@M6F@EriRHwsRcz4e03s~j}p-%aH z50rpl39=1FsoLjWU&%zoKdLnA(%*kp(&;d3Sk}~f*VwtZUI9VWq5H~lu(hQSi^|(4 zCme6ONx&o{WL>b^k1&4me9>LF_>wq0{UgB7%x9;pXtUCw8n&ZIks&4q9dI2|`T60l z#Bt|xk;n6*Pv(;kNb5APUy8h`xcv52N0mCHDCe4OYy#bI{cU6oY0*(sS*G=zD#OCM zIiI)+OKn~7G;O%vKAV-mO+OFK|EsA=gUh2{=2TW!wvw2s}KJ-=>_>uTWKF2<6|6p};=Y@zY zj|ZN|ldixL6Ti;H-r0N&I{MVZPV4H#;&;|9z4tA9%J*L8-;--NBTC+1?s+QbRC@bZ z26Qfu>}(&)>)CDl9OIpJ z^cdapd(%q@s?PR($hfyR+?v8IVI>tOr8^H!i7ETe=g>5cdIbyomXF!B^qbMEw9}3x zb)8rKqd=CjQTedA(U7L$t~K~O!@x5b^1HP?w7W}X`+DVW@=W+`Ek-alh~F7{HroNk zik9U*ojf!|Ht+HzilmH37~1Ou_z$I-?T9obwVOBA7;I^zSA;32z@5MCIy>1nzvYMy zS@L46pO34h^T@F&je0jJVU>>S3iir6J+j~WsH!_pIlhi`fz4yL_XKSiDOUFi@)jSy z6YVm_hp#+8ISBmy4yCPngeQIM{j59)IDr@k!@MUbFp~% zbnbSVi{Pu}J0;>)W-XE79zQ184JXBXDinfd;G4d?;pST9)^636=-Yg!Wq1?Z43#Xm zS@r&rm~-6CK>Qa{f5H!{fwhjDw})Z{Ddm0q`Q|T!jBn0=@$vPsdKI#PYF2JFkpJ@apcy_%wb| z{I)mz?N;ZZA7q81!cXkg_`c@d9WR1(LiOpm*L9I+^=4;H^X4YX*{arRUgze1Bwgu) z@BcA-!74emEaFNt+O5P_F*^E4e=EIE_FBz&Q)%J051(43;0F3%ZKfjnDXH{VzZy?e zzu%F(pgYl|p{ZSsCw6$ZRQ}v0dcqD?qpqyp8=)rlzVlas7P=@cp!d?a-~OA@Jynt> zw_Z#`Mzw_rJJV`R1A;Fm^o3d+eSX1;`svha0kxKgD!tX<%J{0H;)h^6o4C7?cbcPS zZ%+Fo>vtd$L?wPsebOuCQ*XEh<1=1GTxk_3&N1Hf%j$CIio04VLW$BhzxP{2nf1a4 zeDA!q5u;sd)ZFZIW_!>;^pk;^(&)FnmsgFUx}3S|UT$;e=i0;z*3KwESDtrT6$L$P okJ|UFe6^rnfc7qDtBwyzuq$fMeaWKZP0Lz$8?GRatSLbM1G%BIO#lD@ literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_heavy_boots.ogg b/mods/i3/sounds/i3_heavy_boots.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f9b0965d66e2657f898c6d86afcdc50c7e252098 GIT binary patch literal 6911 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 literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_heavy_helmet.ogg b/mods/i3/sounds/i3_heavy_helmet.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9755b15887cc7d3c6bbdccb28493086376906860 GIT binary patch literal 6934 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 literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_heavy_leggings.ogg b/mods/i3/sounds/i3_heavy_leggings.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f0ad665f5f8356afdd9f17ed1569b5aa96a4eacf GIT binary patch literal 6456 zcmb_=c|4Te`~R_IhAd;LrfI4nVr-A`A(4u)4~h{nk(wd9vX)eKS%$R43GhA{BDO(8?EW0uyX9~yCJU#P#`0;NpD>Fm%<(h@2iN<{SH6s*!h zDzQ*vRBCSqP7 z1(T*%hSecfU=zR8N6_}h;+OYWZ@1ya(Pyg?`G%W!D5U=Ki75OU!Xhqy= zvvX8AcZro`ysX(;a-Uf>C*cV(Nrf@sRBMV>JobL;!esROr4V2M*sriTC9YE$t(Ztx zP&E&!AVBG*vTJwLD`oUV0)~9GD7vQ^ju21*eQYBnV#rVjeh}F#sx`49pPokS#E0D_ zbrKRJbzha_>@d2+&fa0vtz4c-4IuIqoa`E2u4Hg|!$n~iO^FO9iI4r~V}pPO=rBfX zwO1BgV4{M+XehLYUvdkA$Y#J>P?fDhm94Us?__J*ru^vm;!%BzejtV&%cP=SGgtidO?Ob|9@x4a6!;z}ggH8p7!)ipK#g%y7P z|5vzF@d5zi0Icl{!CQskJ3|n!1Pl{I0096qN4!O-W@omZE%fn$`Mo)J$4wDVyMz7; z0#res&M;&6-hos=A;;L}fu8;U@X9r@8zN_C&9HA&TH3m<up zlUE9MBe!#aNX{xRq;zGG()@`WCp58|!|EsT*%iYybQpS zeTsa7Inxxa!d4(#6X}xVsUp^0Ln4PYOeR)aFipFPaUn;NKk@Ss(BO=zX+BeB9WH|%Q4bN)g}Z8ZI-8d z#Vz9{q};>-8}76&9cTt}&4POh4XIM=zzQf0lNK~-d~CQJ!n!nB4Iz@bHc`;TZh^{> zIZ`AN6V5PQQ$RCmn1(11!)*eYgE>nJpj7j)j9T8XFldvuVgTJ$w)rI@M#H9-V_aK;sSbMQYVTbtgmsg+DybP z*VOY;0a++uLbwgjBEyp`I&u*(gGrZh`dTZ8>4-|$yH)^lP$*C(y2i)V#z+G%r7hrL4TvS&hW;U^FLJmGHmN{jQ7LS= z)&Bw#AsHobSE6B5D8$u&0u(h)qMVTc5ElTPa99nN_9E1KEx0i(0jvSU6pXE)se;V$ zCqSkAGXkRj28e%~LWcco1d)T(fWHlhmm;hBvnltt1p8F}1yJE~|JD3!ErPy(8=y)6 zV1&d|r)+>ctM|Nn!y$9UTcW#syC{GF4=xi?qb0gzVK4RCqOnaAmn07n%dAd&f7eXMn8Rf}@_87whVUCbgqCFyY5U*nNvHaK~C=JrjjMv#c~oS#Bvu^;zwL3wbV%Rmy^UPY94;&4zao zb`~TX*7pCpb`}XLDFAJv$VsO$lIup}IX)V+**j8ErNUMhDeD>1U-2jVNUNGUemYZ(%X%c>*$Nl6Oj zII2VeRl>ih&XR`^`5c3L6IOHn=B+a|*_Bo)X zq;-X!2q}@(fwi3jOFP^YEz3?Pq@%Qpu70>Jr5f&=Ah`a;f>;?4n<$);a^OH+`!nGU zW{iaLThB$5&ApTb3MSwQyiO_#DU}rzT&Ta=*401q(vN6vn^D&Tq|TdYpS$6_ z5Zr9hYtZ>{@x;%U;-10xK9O=o=Geqbtp+PLiF&Du%m#m|bN8s?KYtTOkSDej?9IDc zKbz-^nmVTw4BW`IiFKGFO2Wkl`vV>Zsc3#DiLs*Yc1h});W zE9B^Rm-k-I@8)~Y1?4h08He19Yd@$tpJE36aVDrlJN>}>r&b?H6Ez`MAD-vM@g>u* zKU?mpH<_RO8_RvUCk(xvtz?_y;!`W(ZU=oYj*e%$q)GZur5T!x-!nb4w;ml2JA0jW z#!M?zZeCr-!FAiTTsiK}R4a8lv8R9QZ>d{;TzK-XJ<_nR!1>eYrHRB&(dN}Jo;pvg zy69ICP!qWRnue#l_~lQP(=?fv--h0_bfhU|&PRMkb$@uHT8vt+dh_6Vaj)L4xLaQp zO4MV;nOTY>rZ}K_PfC}3Y*Rh;n``jK+V9+sAS-vA?0t(A$?<6^r+^;Z1gAFAaZ2^4 zTj_)>zN13ZgM$8em^0w8yUz!ev5dzs;jCVFY3BleqWNs<7TbcWb=vW629wW>_a61! z(s<}u#EF;)<8u*iE)}mEMZ6qSHjXSlE|=c*QgNB6qkfZz#xyUxF||+Y^@F!*7cYD4 zcDXor)@p7CrDrT*D$Uurp^$O0yS%J%GTP+WPoGJ(C>MTgXG(eMM(7lAJ zW}d|TQZQ=Hm4*LkDT-k_rzf*b*$Qo=%om~a3$Ft|MyR$P&3!PfS0sG;n3|!-iroea zwuYhh+*7B1FP+hQzHVz&%+L+hlSKWu=*r& zSGp*pU)evie?`VS{^vm?J&LOy^N>l=9-|*>wKfN(wbG3a*BgnPV#Dxv9G*% zO;t)M%U{D+$L%1?rYIKX@%3 zyWY5#T{gR|k^SD6@-m}%v|>%9(;W*Ao_<{0@A|eMi~4UDt3#sBc`JVR zY46Efeza=;Bi7h~3qISHwR8~)K6?t(?gT4+ZaRR{X}WH7a-YkX8E?CW{%wY##O|M~ zI=``pLib%V@RLvw69Ewy!HF+-^JHR$^Nz2vHc=nD$w;lPJGyv1h}d|3-4B(W4`<>^ z_l@fYsvZy6wME$QNJmQGc;|zaVMEJ5tT|b_jM;Ks*dFCuHy&C@WDJJ8?$MB4-OFXMJ(x#7nS` z9dheU&7pfMYAY>@c0d1w-5dnaaBrtfOITM12~X{+UD89 z*9`{S7gjI5EB6{_%1Xf&VicX#J zWIdam`#e^dWzjTs(^ur!=-a;b!zpWb)iiIjq#Jb9nfxbKiM%?_LiL88SWS}H;!#Wt zKJ}fZ=NFg!2%nbJ_ust|B}mEYO^;=GC1=j{VKMc(VoCt~Xjle*b#5qJWg=ADQDlsB zv&m>I7_|v|&wm?vB*ehQf4FsFSB)W6<;P>m!mv-{(c4ExQOSl}kAa&bnrmsj>!T=s zLf8~JhQSfuAC8*Sb`6c<=&OVhi4wP-24&G}n>#)}XxtZPc`bP;`{C!8CZwU0#p7ZO zO?m4F8!~>(48>=2pN2PGU@sR=92>I=v|sK3z?c)b?jv$XzN9U&>Bl7o$&4;pR~66K zE^y|MHgGz(&5X;?s?%snOm~8C16`x_+wlu&%f@^T*Yt$l$k#WocB>;ei{7_9Wy!t2 z>AFY!Vb4_EXtw;RXoZsazO<Bx-oOeYQEkE59GENzv*|97sn10c_u$x?;A^%B;&f9yE*DM|mz!A4yLMN=k zXd3dMKJx38e6dm5a?8_RL)m4nvNtE~z4u8tE%H(`X1(p{E32Y`VRuQA z>A*(WOU9C^j~n%J<;=g2p2dU9#wScfOH5k934^c!?25MdUq-;(w7TRq)2TJ5_ko11 zX~TD)-J2pah*9kMd0mHs?{1hN={goqaho=2Pi4@#>GPNgox`s>PY|e2yw%9Rlb@bL zYZ^B;%XiPU%GiB=_#$EZFAtG_0$k(3Taz46zY`ovFaQyCqI|xof%t{<&NbR zNsJ{S%cQiBvScY;OWn5bd5?SV=YD>F{2t#wzVF9-W?tt!U*~ns>-l<}*E#d6udf}% z5B>Et8SK-7#o|WCH+%|wr$Z^8{^4*3pOORo13^b0Z2VU6{R)r#=YdD^ftIo?F>+h@ zkAFWCn>Os=0PN%+=C}7(iZ3e2-_wC-9c78q(bmz{{z)5$(jaybDu)sbIJ#X(vU#&tBEBbf zFxei02QcLvk5Vi#Gr8dxl7!tr#VBZ4FILJt@njhi zNK82(mBUgnwvkTh*9X!x>I#u^OBY6wzG9TEuoVt$ZyvTx(`_8t(BmodzG$#{o)m(e z*%5vVwgQ@R8+|C8mo$_NL4`#ciLW)p#AWM*p>7BgH$Ew4o+4#cEBElRiYP+Vc{7L| zgaCRLmzfrcET<$N|9rKmVvX!#&6{=py>)vY*3JLEmp9x3MAufTGfYa5H_i)!5GOPe zOZ1Z7IMG?o`GVBTRs2v41PK5=5%XFp>t&UJkA?$({J-zUv?vIIE@^lnH~k#~grcm> zp**6btMCrIoWvn{eE*>eR@?+SUX?s#S7m}wJonyc{bls~jSz@KkcX6BLTr}`LXqkz zrEYq%6a}QWDo(wTvnq%eapL%<+~|kRU<8i};A0z#Dvk#_;0w)U5G~N9nVyO0F1heN zY!@m{L}#`z)yANQNw+cRRVhg#2BO(gc1LR8?jTpQxw+xDP0(Z-mV^AymokqA;IQ}> z8LwopK&lkaC=#Z`4ValE^I?f9CIBYtw;%a-~l$~Sn z-$4K>@Y5A;2;Lq*1rSmVEr)T||H~I9mLCGiC)b%7O(azGn^<7geGhWve#^`elg1w* zVGejDAl0h7hS2!rl59eEGBz;)&9XzFD_D#{EQeXjC26vLQvkt}fJ{M2LMU>?$qCpk zigDst4k|)ii6ci9!EaGyND+EaR7t#L3Rwg%2vDL>k(W3gt(XQv$}a~#d#GS70?3%3=z>R_EAD04*-c3 zU|roQOYp}qhDZPyAziO#%PMnFUj3Fmxv4~ge>DK6<`VXvQ-X>tIx$FNuLSr|K1uQUs+d;evmg{+~ zmdhno7cr1lyvb=;?sLy7eE?Xha_Gcsm7b$A-#b`iKJCcQr8$>Y~WN}$4!&3~;k|Ot8RxmsP4OwK6 zJgVe=eS~VfIKfht1){6UItJ={>?X)KMl@UU+9oO4I!Op21fj%YKX*udq0-@Ue2o^}dN(GyM<>Z3$gGRH{K{(*p$=X`(J;zr&+MXs1F9FJ)~3Q`iJ-2a=Lx(p_lUj}^+I zcI%t7Qt6gLMQL0ebWs|e^akXaZErav9q*sT93uG@K~T*mLGamHG?<(Q87n|gY%-As zd<4{Ra>K>YEF>Va3`y<-XOSHZI}Hvb7yzdd4E%juiQ##YU=a+UsDm&djt8+SZ{ved zZDuKtgv>4pi#iKIOt90swSgJHH3RG^1fWWz6Un1AT#VNwagY&`FzaG?4VXxpJeAi( z9t6sOIqYdTCM>S!9v;nDE(uoVf^7nr1360yBvi1G2qZOi3(Wd1 z2Xj5N?AARvFI6a65Hdz}fU`*d3d0k=2pj@QmkG0t++Z6l4%`|xZU`{&&%Ge&pD_F< zApM}8YleYJSYzuIekrAp=i}stk6nOXVnF64z_u!L5MPoBhYC=sGs|Qi19{&GJIW*y zfdpz4oQ^a=IWI*$X>8beOs5mMn&)jb8yP4Hham{d%?5iLWHGIln{5Tg0+r@zSKxAk zQ((0&C=(zw*@68nWn52KC48v`f>H$qp>ly;zD||~T5_U$c|7cbVo)8xKlt>84|m=s zXs_OB6W7F+}VF(6a~uj;R+-liBO{P%pppV*{hd>wsfZi{GFn z*!!gLB_lz1Lr@+-`WXrCrfC;5(mktcxpLr0D+U8CROb z&#WEfTg~eV=k~ULdJWEw_1AIRenxoElCjfc;U8Ldl4;x8yIsTgwj-ymX}5nu1ywf- zy3>F?^11iAp9-U~?FeNW_<9lk`0yvNW6hB6R6eL#LJUgSY9>kam2r?gIVFTtN(Ot6 z55j_)4elb$WI#5k?f-S{%;i;52x=36Pdcr!G-ndq_W6jV+ltA=b_37-I&X-YJ`|JR$LBh!5drkax6S`4vRXSCa$jO(6E|n!?6D)h>$-;`8 zD^3q$ThAD&FFuPvh52oQ zL`=JnoH&XQ71QCH;8VhDLKa7kGWJH8AS9UAP}cfSG zr-Cql*1r#BE;kL`W32`l%D#N9mD*OD=-o3u;wox*3)hgWBCFl-EDJSFt!VN?DQ*GN-fSJ{}Cb|AuDoq9tjcF})f#G?O=D=W%g* zfm1K?kovB_{J{9B9}mMRA*s*aqf;##uit#&-`g-RVE@(T;`bJ`XZuU$pS^z(%&UjUR(Y|5ztHFK-Q?@f>iZOPJFUY#V z>kkXYg|Z)STMF#r-QB7RQcHDbgm(5t*`Hn=y>U7aSK6BxB_0yp_fw1W=h$SIPKPj! z`CQ_T?q74klJb` zF6r%g)au&h^@XGHW?{}lqo0eJN0pY^id_5Tf2@=aj~!IBwh>_S-8?z^x$&`0QD7V8 z+kJ%_10yU|@)4VrErPFX9;7|I_&Iq~e(xKFq^k(xeAKr^^4TN@wavi`gJbbTb)$PAU*}EX?*9ueilICa6!m~PWm;8^}BG&U{h+W%^ zl)SfxdlksfZ8kw&`5 zXFFCtn0b)y&Xf&EtnZ*0R^x_`pQ~It;=lV&_laPORPmg%L7sVo2Y(6N+N9V}GZgvR z@JL^iwNiV2xjE@a<7xAfp6oZinJ9+EDC5;o|JuQ`v2g<1usO{+4KtsmIH%SQ+_9Kg z4LCG)SUI?EUFHD)h3t-eid+=`V=eFF*-+bpaLP(iMA;-UA%u9KRDLA^eIsK<^L3e7 zPqa2^$b&7PVHEsi_mirM7kYiq?FY4n)q`UFD$;(oKcO2o_c+$p{N^}ob$N#csgs|* zil25ey;A!5vEJSF$u;#xohjkr+6$?zjUh{plLud`I$YnKSo4Q=#=76A_l+L>HnV+a zLWR}HYchPT&s0(v!b*sc=ug9?A|lh0D0HdQ;J~ahGu>fj@yDJ5OZ1f#W|S$%WB1sH zmF%?a6p@AGz#4(}e8UJzV>@IX6Y= zrx(&rXxSVsQ=hp*%O;{i&Eu|W4OL%Uhm=pz3es3 z*Nx$SeCoNo!^E6$W@UYzM688WPCX^SpLzV<;iVUTmxm9C+GeZ!zc>2)`ddJ2Sb}>- z6e_pWwegoH`-E|b1BRx*OuR@ZaRKM9WEQZ^qu6Fu1# zVkjToVqj#oJ0S4Y=dke(pR%OIV>x~o&T#hKEw=7|6Vkj};e}#H(6FQYg#Z=lhr*iO z&k0HAX9WbFYbetdqF*xX?#`iqDOws`RBL}B{KUY?Ui!RxagD8^K)buMS9<%QOlx-N zlH}yds8jaM>o1zu20+b<=l3L>iHQ7RAm! zi^M=}qPA*}JD1x}9n*SZYj5C~VU&tF6?Dw{DK1>a-+uid(lo8K^q!Wfcb3wl?>9`g zar`t&HCQ(G#KgvT%!SWWc^PC8Z}#mXxgSCbD&e6|k~{Y0sqHk05$JY(D-kn4_Cr(J zI?I_leS6uV^g#ZjEtJOno!^UtaE(})3Ltt6Zq+NAK(Y})cW;dlYu7}`Ph zHcrHE-+^KuO+uIKF|}p&i|_dd<5&6&lSEeZmlWb(uB74Q)Y5S>#)Y|s z5l!#%{6{Ta{C(=B4-siqU0>&tt&tdGYh%9FcXsgyAPL&*-W6wlC|8JJSy__!YUf$9 z9k*6fwOKK<@9r8`si-%A+L?QCr1g$C&TLX{ zG4dj7snpZ^bV8TlgsJVQu~^lSY@2280-}z*V~#?L^!sC4Dd*0tl&p<&PDT~P+8m8i zhofmA@I|xZI$-6io8jyh#2DlkGZucRqgj(L@u& zObPkqIgX@kX{kp3v!mpk^sURt`)#c+F+*8g2Hi~n5lM=xeYh4k{xr(x!+@gn`fQZG ze$6`$`G={1Moa&+@A0l%d6+A;EPB(Qi&RR%SX_qXCH(C)!K+^H=a%$eo>k6b&9N_i zNL&6RMYK?&PfBPd*Y)eW56^9(C)=D>J}FnSVsqtR!$ z@#0+0?>KvHmsG#tK~3%ryTEg_tVS^n-~LUldi!l~_8;2VFo|ZQaExff_$KK~T1^8Na-%*hQ)FEZa99G4A6+7LyCn z0aNtz=qc*Fk{i{g*-r0qNAkTY*Jj3RcLSGKKQRHFUn^ivpL{u$vk z9nHa*@2&DNU6Q#cgs-=r4mo~4a;4fYL_empV$ zdvigstGBmH@S}Lc)n3t~#p7h5-%XFc{uCd*%I9}IC{Cll#4AGM>V)l=Gxp`xbtq{5 z0-ddmcbfioRXwj@ooOvO8Y9)T&aY$I6-nRn0J^Y_t}jDxuPMB^lP_DCidWzO}Nw=A7@Z5bxjTtGc=AnwyGja_h2%@AAO>!W)kxU8n1toT>~f zJxP}SP>^zhaDu@%b>9SsD4~}6LSzAj@0^UHM9E3Y^4X6A3kRCUBe7_{x{z5FZ#ljT zj?I|55uXW~c5JQ^t(;5w_5N-LTccKiaq~RO14n<<&83&GYV$+)ZdY_!EG|BD?96!n zdE%IWU+}$TWQoHjsPN~#0>%?(y+WXgd8`ZK?d3B|@-b&7ruk!{9E|1*YEx@IDe?Ue DMAOhA literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_light_armor.ogg b/mods/i3/sounds/i3_light_armor.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c9b49fa63546abea09dcf9c832a5fc7e4427d2d4 GIT binary patch literal 6503 zcmb_fc|4Tg_kS$eLTJ*^&`b6 zV+dgP;QjmbcF=;*VZna81=i8_Xaju%ef>@PhG;Evfd2t%a6}N=CL%VN78wy95D|le zSBC^2m&m}FxV^LhbC<{i5&me~NLo+;+E7n_1;DH=ciEWZO-)U8^-Xm3HwrCVno^x$ zwOa_X0OJXA+RHf9Y_slF7=}_s8KD=~r9v3QRH|F0oAHdgkW^x`el$Y72u1P@@L z+;-CJb*GA>E0J#fQLoWJdW8<^kCMa!Dcf`^mzIrRLS<<E@t1QH7cq-t0S z$2aBD226o8i9SZAT`+=CWRNUvIc$Xo+j|RJW*9Y%Ea?f91z!xQR07)MX@OJeGmjK@vdEE{$cE z$#%~U3@+6;T%lE1pFmRS8+aOG=S| zlDASJ3|Q5$Q=j3EVyQzeb(RvCgjw@1PvU2nLLdi0dl4q-N4nG{FmykJrghXgG>~4Y zyZ0V?tu8U1Do40l9N*UrMhK_?KDMLjas;3QzHlri*$#Iu-!Bu_g^KRSccD|I4PKY! zZ8z&-O`74F;~4OSI0hYOJ4*0I*nL6t#Tc84Zr_6-1l?%)6syZp93C^ z26&$i80Ut2^S!9^~lu- zJ{@%Ebk(84>I_wZ3J45f4Lr#eg0QK3oIV#^S_KFD{Q1mtHRsQV6rKzI-(TT!Of3XS zLXb*V6p9#y>WYHB5-^MwfzS|S<&3hS>2&29IshMst?w>)IU65vaSQ(|2tWmXx}vv$ zw+B!GguE^G!-h`(#}_767y`+M>dcQPlWGPm?eLmGn|Y|l{36*^1V@Ulv41*JgVQyH zBji*TlDc#7nISl~iv+HQ%^bw@Sm*c@ZFZw72%bD-4N8&(h9^f&$BSW7?hGlngUaqMomN`VmvAH`*p#lITR)`a)Q<)U3%N(Kr zV1#mR zj6}kpX8MKc@*eut8G#W?fbJD#PlgeZVF^ru$=UE6HC(VNV9HD!dy46&gXQJ}0GJZT zuye^_SoRnJ$5{f#{Q9}vu@J4APIwMB(v!ixG8XcV)u>3$0L%5us^{}5oN^}8K`=Q3 z&wuP!X9@s&EH9UwrF+E-OkTyOh3f*K--zcG&*4suP&hSQ3IMv4qwBbnPb`7w3Z7sN zU`m%qvBK30ChrtX?jEfLoBDHd9x{46XA}TN+})wT6f*SPlBuS#5DxdVPxL!3NNpi; zP=Z$WT9jkf3ngno&@ChznL3DOF{yIObf%vyfsLRJ*w--q01X9HkUUuGfT;xbs2s^2 z%LdWKvUh>{enbSaNR}y7$Pz&)Usix5Bq6jMITJsHX6BMf@&rdyF$|qd4$%dno#l^QMy&npJy2Z!UH2IUy;!?F1WlS_T<5sEk{K_oB{pYj&2NH{iYgc2&~ zW3!l)Ec{YmE;$r`nhcL+l0$WQWD*XR95|i%Km=n!AJPR#U~GLSk_sr`gRwkhsMB8( zl>>@9$^;Z-q@|{ktK!~D$M? z39-OV>(&Qm0M|^grz8MXTAfG%rO~p2CWVKLQGi*OC1}A!GF0e-CUP@S2F&4O;h3=b zemVl0@q7xb%m>>9Fb8s$5=yG!BB^y;zA)6j5(Onog}JLdXYJFuB=AuTYL|n+vLF#z za8PP6j|i$y4NM>GIGwD_7R0s2kYoztN+$Of=j{Zc0-*={4J@0J3bF&oRiuiSGnpV` zc(Md-xOrSfkU%`76;M{BGPr4QK7sJ*3Q+DO1#T*b-T_HX7lT<}vzuswQ(mrP=#PbR z#32jxZEzNu9%K5!7Xd4fbonsb$R)PH;=rw8>4pFUf8PtT{|>`H0T}@GTzfyLgqNKC zqf<_n34DCMNxt zAA<`!uiNQPk*&RibCwASh2<9I6&w6Xb4hwjL#;C*WZXl#IR&{DV(l_;43&Qh~%IlUQJ@{{_$i z8D(HsN`R=4a7upyBrP^w!At;13IKKts0K@W5$L@U+!&Ss<`8TO#8%M6!gKrykV*fH z0O-E~+~20)VgDL|W5YGzZv&F$@T&f7D*P>hKJ32$GFa}vnt!cD(D!cxWGM(TgX5`R zF+_N0IMJ)N-x|{)x@%uI2||N|%Rp9<0&*Uf4G_b(Z$96`Kv>;sOszyzgq4TiZLT7*>JwiwCx+T2Ya6qJ!3BJy9Ja7 zkbdUkYZ>|#%+r2#^?X!z0mwcH9_yz z*B9XI`0^rk#a4;Ej2!&rSoB=mYAR#Jt!}Sqy<5nMEd5(w(P5lsabE_oM@^VD`dSu` zza^o@0AJ(L_iVm`9czp9r3*pL^0H9+a$5y*kkW4Ds0m5rx*V|ggdjYq+2Ah1$^m49 z+WueH&SF6&g`jp(_@rAucFKdob$&cz@3Ua}Y^9msMuV4R?LgYP*C&-j>J{D%N=3{G z3rZQJ1VJxZOeRHFnb2z)Y?R)Oex=^2zK)ucGL%x4gHN~bRiR2@mes@#;*TOKmB~^C zWT}wzrfJ#uYP{xivLss!WR4t!Myo^ZkmXHjNZ-T)X)5cjwr9t)yib8<< zf%ZKNhWV!Zopm8G_kMKipBS)59y|LW(I-(h?9BJsl{fP5^6!1`XPpUqc&c%bSyEbE zYPBMzamUxtwmZMiik|3d)bd3ymNZmf2PDJ(nSN~GLd+*xh{U+XNRV+ zwP7Kx@tzG4TMTPUk;L~Gn}=N#i$i2NRlvy*A9D2H*}W-6>;A~4TT`Q&^S5pO z_z`bDLhN08ucqhn5cgWGd8XUvzAbl0_O)$taPrJMriJlHFZ#TpZFQKD=$x}GWRadW zuK3(7zwsn zoT=y?_DknvdvKr6-yqtCO?FSckv#FTq}wg6tF@k!^!<76uIsA@r}vc^>xD^R;x49X z9-i(vDXkVrsSQZu;M4X3o2ePg} zN6tZ|eBDeJSG?V*ZqM)6v&N&ww_8s3b0T~F z$+ze4*rc+8kQH8jhsvJT%J`WrY+KxX==6}{!b6YE7vl=;na!?a%NlefKg_8gAeaSu zjVntp&)3qT-SivbV?MTsUO!wZii9pL=CwM}45zRQ47{Ra#+imzp9^Xw7i#Y;63=|` z=V%0X-=?=jDi3V(R3bkq``CF|#=g9SoA}X0MuKZCe*0eNwxrmND~(a1<#RO;Wfw2` zPd%Rrs;)bt;4tfBt81>9_?B@jZvLZp*o}5#x%MOM$DFIw;o+*aBi{>1tBxVM={w8I zgsx&+M4p7eY`B$fkb%nbPdX5%ni z<-Xd`gf&$O8bv~(Lc6zW%efowd$nDfTHJExcw)zq+f;)xYqRkSlpBb{duegMAFMfS zS-)o5>-DOWGf}jwD^6?vQ9UuGg zG%~62nsY&Qmz$Kv@G*P;Ek)Ou?TIeWPuR~C7#t@SJ<5Jvg|&D{^_YoJU6=Ls3+?i^ zA7{wJX46^cZxY#>JKA^deLONYCa<95*ihqLp>5u~m|DLtz;(>~uLdL>^1)W zzE3vi*PpZ0^e{ji*v1uWz%+VW&E{1P?`T#w{`B_K`E85kw!<#l47ZjBH>uWq9KF}x zO?o6rXgQu$JRP5C=0+(9Oq57d7FDP$b*Xj=44+d~RbB~+Lsx0DYzR`Li*|;pMh`fj ztM@(Iw7&LLcfym1wY6KDyslwt#6Khs$;aQels)Kapu=l6i`6i82-@V^_U?~k)zrw@ z(F~Js{l~XoSYIsbLb&!yd5tg6cG}^1sDBToKXNws?uU8Z;&rMzb2}M*xkJkjcux6- zoJw<&ACollhZ1`XL?Nhd?KT8aKcE+)S{GE9ed=$f9I_tfbs1}qJD%y?S7M#x9%tme z>!hK=miZV=pTW85r1Zx}?XnT0ek(3pRO}%g{QP6KCu8>EY#{YzPt|l)RKr|7+e(35 z(qrUS^6A4ploS5Sy`i=*3FmaWhN#25HCGwWcT z9RF19`|II9@5I*SOEwI|U!5>F3%2#kTh`DTNsP3cmS6A@4nVQZ-Cqe44U^T~@<~$q z#~A?)T0V`c5y~deA@& z65SurKfSC3>O|C6zD#Xpy7qC*C_8Ict$*+?@D8zyQ*h=*-0b;~{;vH5KSB)6cOay3 zlS<;IF6|>WGHYw|Ux+Qw<}74t(%V#BrMq?*jlRitjn!-!|JeA&{OCgNh{5vyUFeLq zy)_E%h)=om{3p7*G7gH&nHguNJlHcL1NoRtGesf0y2&8f<+?&7c^f2q#c% zds6=S+KsJ^es&WJJ=DVsGivJZhXU8hE1PM)i*iw#3Q=^m|0Dg`xMOt3bMMx7njS5+ zoi!Clo4D7brjW?Hg!g+F#>H;vRF9BGR)-jglxixc3qu+UYU;vl2}~yAS2yXgbG+_Q zN?c?;Q%*Z#n;GIzbk{bG5Ob7qV&ZK5qPs`$+78+z%VhNxm*KV|AKJ{u<76}6Ti>|6 zb-eh7nA?%X2b+U>e&7da*Pm`E@=;i3?-zG%^@ipMyZMMoQnk6fNaFp10wGA&R;C?+ zaXk4-drQ=z24v6n){{4Dv@OGXW!~Jch+LzTwF<=xR-&i2n14M??B)J(kaop)`Wx@V z&hwGPGdf3iRmJy3m6Gl6+clW3%=^-yr6Tph$Eemwdw4n4>FS3B}LKGS{OFwV>1 z7rI*!TR$dsWMnLQ@$n9y#byT{xy42Gt7^t}7H+%9Pt=Q-RnKxSigMY literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_light_boots.ogg b/mods/i3/sounds/i3_light_boots.ogg new file mode 100644 index 0000000000000000000000000000000000000000..04e2c5fab184c0336c969d729d6d67e4c53cdc68 GIT binary patch literal 6053 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 A$N&HU literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_light_helmet.ogg b/mods/i3/sounds/i3_light_helmet.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ca09535a62425e79da34dd900a08a9b54cee38c6 GIT binary patch literal 5731 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 kmU`bCDcZUSNa{3#_B4LcX17w3R9B>qcnmcV!Z literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_light_leggings.ogg b/mods/i3/sounds/i3_light_leggings.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b4371ee3f54077c20417c47bae67806cb8943b8e GIT binary patch literal 6228 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 O`Z0&;xwl5nJ0uSM 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 M?*Ep%ccmZnA848x4FCWD literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_skin_change.ogg b/mods/i3/sounds/i3_skin_change.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5ef190dec5d58140277018f45a96313c2b04d807 GIT binary patch literal 11481 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 IA&m(}cR;q*iA zI&st3T%S$VM_)L_8XO4YlnAcoe%IPvAmAYFf_{`Q4AFUilY%Ez8bMZMtP*HtfwPUk z&yvKu9IzF$Ac7Ry9pruOQ#{GbP?m2XPn3O3h#o>rbX=YXwbYdO)so9Afl;~CR5F5Q zC>*upI(n5EP`>$bmY;C}iXC-m>ZB>-p-0ITZvmN~4S}2b6r^+T`SPcu{>B`_ABEWV zyb{7G4>FsBjMT(q7vf_4#-`SZp5oh2fVIrTNIe)G3?rbvjW44o%)q^H44PiFT+JFm ziks?77Yt5Iuk&^h(`RvGr<1@yqdH3dRj;}zt+ld0Y_DvqYz33sCZAEwfhTPP&#hr&ahb)b9Ty^mM4y8 z8eiO-dLvFu)6Mv~Owof3y&*cnVOPELkR1pr^GKLTu@0e=5-b`EB*6S+9d#ihSzc@uYgEfG?mpJJG0*Z9_j$#e*oq)o!|ff literal 0 HcmV?d00001 diff --git a/mods/i3/sounds/i3_trash.ogg b/mods/i3/sounds/i3_trash.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cc6aaafa3a898e3df5ba4a7bad26d3de1d0e0176 GIT binary patch literal 7685 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 Yc^r6<7iYWch9on}LR~Kg{M+Ea0N{ftZ~y=R literal 0 HcmV?d00001 diff --git a/mods/i3/src/api.lua b/mods/i3/src/api.lua new file mode 100644 index 0000000..fb8ba00 --- /dev/null +++ b/mods/i3/src/api.lua @@ -0,0 +1,360 @@ +local http = ... +local make_fs, get_inventory_fs = i3.files.gui() + +IMPORT("gmatch", "split") +IMPORT("S", "err", "fmt", "reg_items") +IMPORT("sorter", "sort_inventory", "play_sound") +IMPORT("sort", "concat", "copy", "insert", "remove") +IMPORT("true_str", "true_table", "is_str", "is_func", "is_table", "clean_name") + +function i3.register_craft_type(name, def) + if not true_str(name) then + return err "i3.register_craft_type: name missing" + elseif not true_table(def) then + return err "i3.register_craft_type: definition missing" + elseif not is_str(def.description) then + def.description = "" + end + + i3.craft_types[name] = def +end + +function i3.register_craft(def) + local width, c = 0, 0 + + if http and true_str(def.url) then + http.fetch({url = def.url}, function(result) + if result.succeeded then + local t = core.parse_json(result.data) + if is_table(t) then + return i3.register_craft(t) + end + end + end) + + return + end + + if not true_table(def) then + return err "i3.register_craft: craft definition missing" + end + + if #def > 1 then + for _, v in pairs(def) do + i3.register_craft(v) + end + return + end + + if def.result then + def.output = def.result -- Backward compatibility + def.result = nil + end + + if not true_str(def.output) and not def.url then + return err "i3.register_craft: output missing" + end + + if not is_table(def.items) then + def.items = {} + end + + if def.grid then + if not is_table(def.grid) then + def.grid = {} + end + + if not is_table(def.key) then + def.key = {} + end + + local cp = copy(def.grid) + sort(cp, function(a, b) return #a > #b end) + + width = #cp[1] + + for i = 1, #def.grid do + while #def.grid[i] < width do + def.grid[i] = def.grid[i] .. " " + end + end + + for symbol in gmatch(concat(def.grid), ".") do + c++ + def.items[c] = def.key[symbol] + end + else + local items = copy(def.items) + local lines = {} + def.items = {} + + for i = 1, #items do + lines[i] = split(items[i], ",", true) + + if #lines[i] > width then + width = #lines[i] + end + end + + for i = 1, #items do + while #lines[i] < width do + insert(lines[i], items[i]) + end + end + + for _, line in ipairs(lines) do + for _, v in ipairs(line) do + c++ + def.items[c] = clean_name(v) + end + end + end + + local item = ItemStack(def.output):get_name() + i3.recipes_cache[item] = i3.recipes_cache[item] or {} + + def.custom = true + def.width = width + + insert(i3.recipes_cache[item], def) +end + +function i3.add_recipe_filter(name, f) + if not true_str(name) then + return err "i3.add_recipe_filter: name missing" + elseif not is_func(f) then + return err "i3.add_recipe_filter: function missing" + end + + i3.recipe_filters[name] = f +end + +function i3.set_recipe_filter(name, f) + if not is_str(name) then + return err "i3.set_recipe_filter: name missing" + elseif not is_func(f) then + return err "i3.set_recipe_filter: function missing" + end + + i3.recipe_filters = {[name] = f} +end + +function i3.add_search_filter(name, f) + if not true_str(name) then + return err "i3.add_search_filter: name missing" + elseif not is_func(f) then + return err "i3.add_search_filter: function missing" + end + + i3.search_filters[name] = f +end + +function i3.get_recipes(item) + item = core.registered_aliases[item] or item + local recipes = i3.recipes_cache[item] + local usages = i3.usages_cache[item] + + return {recipes = recipes, usages = usages} +end + +function i3.set_fs(player) + if not player or player.is_fake_player then return end + local name = player:get_player_name() + local data = i3.data[name] + if not data then return end + + if data.auto_sorting then + sort_inventory(player, data) + end + + for i, tab in ipairs(i3.tabs) do + if data.tab == i and tab.access and not tab.access(player, data) then + data.tab = 1 + break + end + end + + local fs = make_fs(player, data) + player:set_inventory_formspec(fs) +end + +function i3.new_tab(name, def) + if not true_str(name) then + return err "i3.new_tab: tab name missing" + elseif not true_table(def) then + return err "i3.new_tab: tab definition missing" + elseif not true_str(def.description) then + return err "i3.new_tab: description missing" + elseif #i3.tabs == 6 then + return err(fmt("i3.new_tab: cannot add '%s' tab. Limit reached (6).", def.name)) + end + + def.name = name + insert(i3.tabs, def) +end + +i3.new_tab("inventory", { + description = S"Inventory", + formspec = get_inventory_fs, + fields = i3.files.fields(), +}) + +function i3.remove_tab(name) + if not true_str(name) then + return err "i3.remove_tab: tab name missing" + end + + for i, def in ipairs(i3.tabs) do + if name == def.name then + remove(i3.tabs, i) + break + end + end +end + +function i3.get_current_tab(player) + local name = player:get_player_name() + local data = i3.data[name] + + return data.tab +end + +function i3.set_tab(player, tabname) + local name = player:get_player_name() + local data = i3.data[name] + + if not tabname or tabname == "" then + data.tab = 0 + return + end + + for i, tab in ipairs(i3.tabs) do + if tab.name == tabname then + data.tab = i + return + end + end + + err(fmt("i3.set_tab: tab name '%s' does not exist", tabname)) +end + +function i3.override_tab(name, newdef) + if not true_str(name) then + return err "i3.override_tab: tab name missing" + elseif not true_table(newdef) then + return err "i3.override_tab: tab definition missing" + elseif not true_str(newdef.description) then + return err "i3.override_tab: description missing" + end + + newdef.name = name + + for i, def in ipairs(i3.tabs) do + if def.name == name then + i3.tabs[i] = newdef + break + end + end +end + +i3.register_craft_type("digging", { + description = S"Digging", + icon = "i3_steelpick.png", +}) + +i3.register_craft_type("digging_chance", { + description = S"Digging (by chance)", + icon = "i3_mesepick.png", +}) + +i3.add_search_filter("groups", function(item, groups) + local def = reg_items[item] + local has_groups = true + + for _, group in ipairs(groups) do + if not def.groups[group] then + has_groups = nil + break + end + end + + return has_groups +end) + +function i3.compress(item, def) + if not true_str(item) then + return err "i3.compress: item name missing" + elseif not true_table(def) then + return err "i3.compress: replace definition missing" + elseif not true_str(def.replace) then + return err "i3.compress: replace string missing" + elseif not is_table(def.by) then + return err "i3.compress: replace substrings missing" + elseif i3.compressed[item] then + return err(fmt("i3.compress: item '%s' is already compressed", item)) + end + + local t = {} + i3.compress_groups[item] = i3.compress_groups[item] or {} + + for _, str in ipairs(def.by) do + local it = item:gsub(def.replace, str) + + insert(t, it) + insert(i3.compress_groups[item], it) + + i3.compressed[it] = true + end +end + +function i3.hud_notif(name, msg, img) + if not true_str(name) then + return err "i3.hud_notif: player name missing" + elseif not true_str(msg) then + return err "i3.hud_notif: message missing" + end + + local data = i3.data[name] + + if not data then + return err "i3.hud_notif: no player data initialized" + end + + data.show_hud = true + data.hud_msg = msg + + play_sound(name, "i3_achievement", 1.0) + + if img then + data.hud_img = fmt("%s^[resize:64x64", img) + end +end + +function i3.add_sorting_method(name, def) + if not true_str(name) then + return err "i3.add_sorting_method: name missing" + elseif not true_table(def) then + return err "i3.add_sorting_method: definition missing" + elseif not is_func(def.func) then + return err "i3.add_sorting_method: function missing" + end + + def.name = name + insert(i3.sorting_methods, def) +end + +i3.add_sorting_method("alphabetical", { + description = S"Sort items by name (A-Z)", + func = function(list, data) + sorter(list, data, 1) + return list + end +}) + +i3.add_sorting_method("numerical", { + description = S"Sort items by number of items per stack", + func = function(list, data) + sorter(list, data, 2) + return list + end, +}) diff --git a/mods/i3/src/bags.lua b/mods/i3/src/bags.lua new file mode 100644 index 0000000..5b3deca --- /dev/null +++ b/mods/i3/src/bags.lua @@ -0,0 +1,173 @@ +local set_fs = i3.set_fs + +IMPORT("get_bag_description", "ItemStack") +IMPORT("S", "ES", "fmt", "msg", "slz", "dslz") +IMPORT("get_group", "play_sound", "get_detached_inv", "create_inventory") + +local function get_content(content) + local t = {} + + for i, v in pairs(content) do + t[i] = ItemStack(v) + end + + return t +end + +local function init_bags(player) + local name = player:get_player_name() + local data = i3.data[name] + + local bag = create_inventory(fmt("i3_bag_%s", name), { + allow_put = function(inv, _, _, stack) + local empty = inv:is_empty"main" + local item_group = get_group(stack:get_name(), "bag") + + if empty and item_group > 0 and item_group <= 4 then + return 1 + end + + if not empty then + msg(name, S"There is already a bag") + else + msg(name, S"This is not a bag") + end + + return 0, play_sound(name, "i3_cannot", 0.8) + end, + + on_put = function(_, _, _, stack) + data.bag = stack:to_string() + + local meta = stack:get_meta() + local content = dslz(meta:get_string"content") + + if content then + local inv = get_detached_inv("bag_content", name) + inv:set_list("main", get_content(content)) + end + + set_fs(player) + end, + + on_take = function() + data.bag = nil + data.bag_rename = nil + + local content = get_detached_inv("bag_content", name) + content:set_list("main", {}) + + set_fs(player) + end, + }, name) + + bag:set_size("main", 1) + + if data.bag then + bag:set_list("main", get_content{data.bag}) + end + + local function save_content(inv) + local bagstack = bag:get_stack("main", 1) + local meta = bagstack:get_meta() + local desc = get_bag_description(data, bagstack) + + if inv:is_empty"main" then + meta:set_string("description", desc) + meta:set_string("content", "") + else + local list = inv:get_list"main" + local t, c = {}, 0 + + for i = 1, #list do + local stack = list[i] + + if not stack:is_empty() then + c++ + t[i] = stack:to_string() + end + end + + local bag_size = get_group(bagstack:get_name(), "bag") + local percent = fmt("%d", (c * 100) / (bag_size * 4)) + + meta:set_string("description", ES("@1 (@2% full)", desc, percent)) + meta:set_string("content", slz(t)) + end + + bag:set_stack("main", 1, bagstack) + data.bag = bagstack:to_string() + + set_fs(player) + end + + local bag_content = create_inventory(fmt("i3_bag_content_%s", name), { + on_move = save_content, + on_put = save_content, + on_take = save_content, + + allow_put = function(_, _, _, stack) + local meta = stack:get_meta() + local content = dslz(meta:get_string"content") + + if content then + msg(name, "You cannot put a bag in another bag") + return 0, play_sound(name, "i3_cannot", 0.8) + end + + return stack:get_count() + end, + }, name) + + bag_content:set_size("main", 4*4) + + if data.bag then + local meta = bag:get_stack("main", 1):get_meta() + local content = dslz(meta:get_string"content") + + if content then + bag_content:set_list("main", get_content(content)) + end + end +end + +local bag_recipes = { + small = { + rcp = { + {"", "farming:string", ""}, + {"group:wool", "group:wool", "group:wool"}, + {"group:wool", "group:wool", "group:wool"}, + }, + size = 2, + }, + medium = { + rcp = { + {"farming:string", "i3:bag_small", "farming:string"}, + {"farming:string", "i3:bag_small", "farming:string"}, + }, + size = 3, + }, + large = { + rcp = { + {"farming:string", "i3:bag_medium", "farming:string"}, + {"farming:string", "i3:bag_medium", "farming:string"}, + }, + size = 4, + }, +} + +for size, item in pairs(bag_recipes) do + local bagname = fmt("i3:bag_%s", size) + + core.register_craftitem(bagname, { + description = fmt("%s Backpack", size:gsub("^%l", string.upper)), + inventory_image = fmt("i3_bag_%s.png", size), + groups = {bag = item.size}, + stack_max = 1, + }) + + core.register_craft{output = bagname, recipe = item.rcp} + core.register_craft{type = "fuel", recipe = bagname, burntime = 3} +end + +return init_bags diff --git a/mods/i3/src/caches.lua b/mods/i3/src/caches.lua new file mode 100644 index 0000000..5fb9a90 --- /dev/null +++ b/mods/i3/src/caches.lua @@ -0,0 +1,349 @@ +local replacements = {fuel = {}} +local http = ... + +IMPORT("maxn", "copy", "insert", "sort", "match", "sub") +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") + +local function get_burntime(item) + return core.get_craft_result{method = "fuel", items = {item}}.time +end + +local function cache_fuel(item) + local burntime = get_burntime(item) + if burntime > 0 then + i3.fuel_cache[item] = { + type = "fuel", + items = {item}, + burntime = burntime, + replacements = replacements.fuel[item], + } + end +end + +local function cache_groups(group, groups) + i3.groups[group] = {} + i3.groups[group].groups = groups + i3.groups[group].items = groups_to_items(groups) + + if #groups == 1 then + i3.groups[group].stereotype = get_group_stereotype(groups[1]) + end + + local items = i3.groups[group].items + if #items <= 1 then return end + + local px, lim, c = 64, 10, 0 + local sprite = "[combine:WxH" + + for _, item in ipairs(items) do + local def = reg_items[item] + local tiles = def.tiles or def.tile_images + local texture = true_str(def.inventory_image) and def.inventory_image --or tiles[1] + + if def.drawtype and is_cube(def.drawtype) then + texture = get_cube(tiles) + end + + if texture then + texture = texture:gsub("%^", "\\^"):gsub(":", "\\:") .. fmt("\\^[resize\\:%ux%u", px, px) + sprite = sprite .. fmt(":0,%u=%s", c * px, texture) + c++ + if c == lim then break end + end + end + + if c > 1 then + sprite = sprite:gsub("WxH", px .. "x" .. px * c) + i3.groups[group].sprite = sprite + i3.groups[group].count = c + end +end + +local function get_item_usages(item, recipe, added) + if is_group(item) then + local group = item:sub(7) + local group_cache = i3.groups[group] + local groups = group_cache and group_cache.groups or extract_groups(item) + + if not group_cache then + cache_groups(group, groups) + end + + for name, def in pairs(reg_items) do + if not added[name] and valid_item(def) and item_has_groups(def.groups, groups) then + local usage = copy(recipe) + table_replace(usage.items, item, name) + + i3.usages_cache[name] = i3.usages_cache[name] or {} + insert(i3.usages_cache[name], 1, usage) + + added[name] = true + end + end + elseif valid_item(reg_items[item]) then + i3.usages_cache[item] = i3.usages_cache[item] or {} + insert(i3.usages_cache[item], 1, recipe) + end +end + +local function get_usages(recipe) + local added = {} + + for _, item in pairs(recipe.items) do + item = reg_aliases[item] or item + + if not added[item] then + get_item_usages(item, recipe, added) + added[item] = true + end + end +end + +local function cache_usages(item) + local recipes = i3.recipes_cache[item] or {} + + for i = 1, #recipes do + get_usages(recipes[i]) + end + + if i3.fuel_cache[item] then + i3.usages_cache[item] = table_merge(i3.usages_cache[item] or {}, {i3.fuel_cache[item]}) + end +end + +local function drop_table(name, drop) + local count_sure = 0 + local drop_items = drop.items or {} + local max_items = drop.max_items + + for i = 1, #drop_items do + local di = drop_items[i] + local valid_rarity = di.rarity and di.rarity > 1 + + if di.rarity or not max_items or + (max_items and not di.rarity and count_sure < max_items) then + for j = 1, #di.items do + local dstack = ItemStack(di.items[j]) + local dname = dstack:get_name() + local dcount = dstack:get_count() + local empty = dstack:is_empty() + + if not empty and (dname ~= name or (dname == name and dcount > 1)) then + local rarity = valid_rarity and di.rarity + + i3.register_craft { + type = rarity and "digging_chance" or "digging", + items = {name}, + output = fmt("%s %u", dname, dcount), + rarity = rarity, + tools = di.tools, + } + end + end + end + + if not di.rarity then + count_sure++ + end + end +end + +local function cache_drops(name, drop) + if true_str(drop) then + local dstack = ItemStack(drop) + local dname = dstack:get_name() + local empty = dstack:is_empty() + + if not empty and dname ~= name then + i3.register_craft { + type = "digging", + items = {name}, + output = drop, + } + end + elseif is_table(drop) then + drop_table(name, drop) + end +end + +local function cache_recipes(item) + local recipes = core.get_all_craft_recipes(item) + + if replacements[item] then + local _recipes = {} + + for k, v in ipairs(recipes or {}) do + _recipes[#recipes + 1 - k] = v + end + + local shift = 0 + local size_rpl = maxn(replacements[item]) + local size_rcp = #_recipes + + if size_rpl > size_rcp then + shift = size_rcp - size_rpl + end + + for k, v in pairs(replacements[item]) do + k += shift + + if _recipes[k] then + _recipes[k].replacements = v + end + end + + recipes = _recipes + end + + if recipes then + i3.recipes_cache[item] = table_merge(recipes, i3.recipes_cache[item] or {}) + end +end + +--[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not + return the fuel, replacements and toolrepair recipes, we have to + override `core.register_craft` and do some reverse engineering. + See engine's issues #4901, #5745 and #8920. ]] + +local old_register_craft = core.register_craft +local rcp_num = {} + +core.register_craft = function(def) + old_register_craft(def) + + if def.type == "toolrepair" then + i3.toolrepair = def.additional_wear * -100 + end + + local output = def.output or (true_str(def.recipe) and def.recipe) or nil + if not output then return end + output = {match(output, "%S+")} + + local groups + + if is_group(output[1]) then + groups = extract_groups(output[1]) + output = groups_to_items(groups) + end + + for i = 1, #output do + local item = output[i] + rcp_num[item] = (rcp_num[item] or 0) + 1 + + if def.replacements then + if def.type == "fuel" then + replacements.fuel[item] = def.replacements + else + replacements[item] = replacements[item] or {} + replacements[item][rcp_num[item]] = def.replacements + end + end + end +end + +local old_clear_craft = core.clear_craft + +core.clear_craft = function(def) + old_clear_craft(def) + + -- TODO: hide in crafting guide +end + +local function resolve_aliases(hash) + for oldname, newname in pairs(reg_aliases) do + cache_recipes(oldname) + local recipes = i3.recipes_cache[oldname] + + if recipes then + if not i3.recipes_cache[newname] then + i3.recipes_cache[newname] = {} + end + + local similar + + for i = 1, #i3.recipes_cache[oldname] do + local rcp_old = i3.recipes_cache[oldname][i] + + for j = 1, #i3.recipes_cache[newname] do + local rcp_new = copy(i3.recipes_cache[newname][j]) + rcp_new.output = oldname + + if table_eq(rcp_old, rcp_new) then + similar = true + break + end + end + + if not similar then + insert(i3.recipes_cache[newname], rcp_old) + end + end + end + + if newname ~= "" and i3.recipes_cache[oldname] and reg_items[newname] and not hash[newname] then + insert(i3.init_items, newname) + end + end +end + +local function init_recipes() + local _select, _preselect = {}, {} + + for name, def in pairs(reg_items) do + if name ~= "" and valid_item(def) then + cache_drops(name, def.drop) + cache_fuel(name) + cache_recipes(name) + + _preselect[name] = true + end + end + + for name in pairs(_preselect) do + cache_usages(name) + + insert(i3.init_items, name) + _select[name] = true + end + + resolve_aliases(_select) + sort(i3.init_items) + + if http and true_str(i3.export_url) then + local post_data = { + recipes = i3.recipes_cache, + usages = i3.usages_cache, + } + + http.fetch_async { + url = i3.export_url, + post_data = core.write_json(post_data), + } + end +end + +local function init_cubes() + for name, def in pairs(reg_nodes) do + if def then + local id = core.get_content_id(name) + local tiles = def.tiles or def.tile_images + + if is_cube(def.drawtype) then + i3.cubes[id] = get_cube(tiles) + elseif sub(def.drawtype, 1, 9) == "plantlike" or sub(def.drawtype, 1, 8) == "firelike" then + local texture = true_str(def.inventory_image) and def.inventory_image or tiles[1] + + if texture then + i3.plants[id] = texture + end + end + end + end +end + +return function() + init_recipes() + init_cubes() +end diff --git a/mods/i3/src/callbacks.lua b/mods/i3/src/callbacks.lua new file mode 100644 index 0000000..f72bae4 --- /dev/null +++ b/mods/i3/src/callbacks.lua @@ -0,0 +1,279 @@ +local http, storage = ... +local init_bags = i3.files.bags() +local fill_caches = i3.files.caches(http) +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", "update_inv_size") + +core.register_on_player_hpchange(function(player, hpchange) + local name = player:get_player_name() + local data = i3.data[name] + if not data then return end + + local hp_max = player:get_properties().hp_max + data.hp = min(hp_max, player:get_hp() + hpchange) + + set_fs(player) +end) + +core.register_on_dieplayer(function(player) + local name = player:get_player_name() + local data = i3.data[name] + if not data then return end + + if i3.settings.drop_bag_on_die then + local bagstack = ItemStack(data.bag) + spawn_item(player, bagstack) + end + + data.bag = nil + local bag = get_detached_inv("bag", name) + local content = get_detached_inv("bag_content", name) + + bag:set_list("main", {}) + content:set_list("main", {}) + + set_fs(player) +end) + +core.register_on_chatcommand(function(name) + local player = core.get_player_by_name(name) + core.after(0, set_fs, player) +end) + +core.register_on_priv_grant(function(name, _, priv) + if priv == "creative" or priv == "all" then + local data = i3.data[name] + reset_data(data) + data.favs = {} + + local player = core.get_player_by_name(name) + core.after(0, set_fs, player) + end +end) + +core.register_on_player_inventory_action(function(player, _, _, info) + local name = player:get_player_name() + + if not core.is_creative_enabled(name) and + ((info.from_list == "main" and info.to_list == "craft") or + (info.from_list == "craft" and info.to_list == "main") or + (info.from_list == "craftresult" and info.to_list == "main")) then + set_fs(player) + end +end) + +if core.global_exists"armor" then + i3.modules.armor = true + + local group_indexes = { + {"armor_head", "i3_heavy_helmet"}, + {"armor_torso", "i3_heavy_armor"}, + {"armor_legs", "i3_heavy_leggings"}, + {"armor_feet", "i3_heavy_boots"}, + {"armor_shield", "i3_heavy_shield"}, + } + + local function check_group(def, group) + return def.groups[group] and def.groups[group] > 0 + end + + armor:register_on_equip(function(player, idx, stack) + local _, armor_inv = armor:get_valid_player(player, "3d_armor") + local def = stack:get_definition() + local name = player:get_player_name() + local data = i3.data[name] + + for i, v in ipairs(group_indexes) do + local group, sound = unpack(v) + local stackname = stack:get_name() + + if stackname:find"wood" or stackname:find"stone" or stackname:find"cactus" then + sound = sound:gsub("heavy", "light") + end + + if i == idx and check_group(def, group) then + data.armor_allow = sound + return armor:register_on_update(set_fs) + end + end + + data.armor_disallow = true + armor_inv:remove_item("armor", stack) + end) + + armor:register_on_update(function(player) + local _, armor_inv = armor:get_valid_player(player, "3d_armor") + if not armor_inv then return end + + for i = 1, 5 do + local stack = armor_inv:get_stack("armor", i) + local def = stack:get_definition() + + for j, v in ipairs(group_indexes) do + local group = v[1] + + if check_group(def, group) and i ~= j then + armor_inv:set_stack("armor", i, armor_inv:get_stack("armor", j)) + armor_inv:set_stack("armor", j, stack) + + return play_sound(player:get_player_name(), "i3_cannot", 0.8) + end + end + end + end) + + core.register_on_player_inventory_action(function(player, action, _, info) + if action ~= "take" then return end + local name = player:get_player_name() + local data = i3.data[name] + + if data.armor_disallow then + local inv = player:get_inventory() + inv:set_stack("main", info.index, info.stack) + data.armor_disallow = nil + play_sound(name, "i3_cannot", 0.8) + + elseif data.armor_allow then + play_sound(name, data.armor_allow, 0.8) + data.armor_allow = nil + end + end) +end + +if core.global_exists"skins" then + i3.modules.skins = true +end + +if core.global_exists"awards" then + i3.modules.awards = true + + core.register_on_craft(function(_, player) + set_fs(player) + end) + + core.register_on_dignode(function(_, _, player) + set_fs(player) + end) + + core.register_on_placenode(function(_, _, player) + set_fs(player) + end) + + core.register_on_chat_message(function(name) + local player = core.get_player_by_name(name) + set_fs(player) + end) +end + +local function disable_inventories() + if rawget(_G, "sfinv") then + function sfinv.set_player_inventory_formspec() return end + sfinv.enabled = false + end + + if rawget(_G, "unified_inventory") then + function unified_inventory.set_inventory_formspec() return end + end +end + +core.register_on_mods_loaded(function() + fill_caches() + disable_inventories() +end) + +local function get_lang_code(info) + return info and info.lang_code +end + +local function get_formspec_version(info) + return info and info.formspec_version or 1 +end + +local function outdated(name) + core.show_formspec(name, "i3_outdated", + ("size[6.5,1.3]image[0,0;1,1;i3_book.png]label[1,0;%s]button_exit[2.6,0.8;1,1;;OK]"):format( + "Your Minetest client is outdated.\nGet the latest version on minetest.net to play the game.")) +end + +local function init_data(player, info) + local name = player:get_player_name() + i3.data[name] = i3.data[name] or {} + local data = i3.data[name] + + for k, v in pairs(i3.default_data) do + local val = data[k] + if val == nil then + val = v + end + + data[k] = val + end + + data.player_name = name + data.filter = "" + data.pagenum = 1 + data.skin_pagenum = 1 + data.items = i3.init_items + data.items_raw = i3.init_items + data.favs = {} + data.show_setting = "home" + data.crafting_counts = {} + data.tab = 1 + data.itab = 1 + data.subcat = 1 + data.scrbar_inv = 0 + data.lang_code = get_lang_code(info) + data.fs_version = info.formspec_version + + update_inv_size(player, data) + + core.after(0, set_fs, player) +end + +local function save_data(player_name) + local _data = copy(i3.data) + + for name, v in pairs(_data) do + for dat in pairs(v) do + if not i3.saves[dat] then + _data[name][dat] = nil + + if player_name and i3.data[player_name] then + i3.data[player_name][dat] = nil -- To free up some memory + end + end + end + end + + storage:set_string("data", slz(_data)) +end + +insert(core.registered_on_joinplayers, 1, function(player) + local name = player:get_player_name() + local info = core.get_player_information and core.get_player_information(name) + + if not info or get_formspec_version(info) < i3.settings.min_fs_version then + return outdated(name) + end + + init_data(player, info) + init_bags(player) + init_hud(player) +end) + +core.register_on_leaveplayer(function(player) + local name = player:get_player_name() + save_data(name) +end) + +core.register_on_shutdown(save_data) + +local function routine() + save_data() + core.after(i3.settings.save_interval, routine) +end + +core.after(i3.settings.save_interval, routine) diff --git a/mods/i3/src/common.lua b/mods/i3/src/common.lua new file mode 100644 index 0000000..6161a34 --- /dev/null +++ b/mods/i3/src/common.lua @@ -0,0 +1,800 @@ +local vec = vector.new +local ItemStack = ItemStack +local loadstring = loadstring +local reg_items = core.registered_items +local translate = core.get_translated_string +local sort, concat, insert = table.sort, table.concat, table.insert +local min, floor, ceil = math.min, math.floor, math.ceil +local fmt, find, match, gmatch, sub, split, lower, upper = + string.format, string.find, string.match, string.gmatch, + string.sub, string.split, string.lower, string.upper + +if not core.registered_privileges.creative then + core.register_privilege("creative", { + description = "Allow player to use creative inventory", + give_to_singleplayer = false, + give_to_admin = false, + }) +end + +local old_is_creative_enabled = core.is_creative_enabled + +function core.is_creative_enabled(name) + if name == "" then + return old_is_creative_enabled(name) + end + + return core.check_player_privs(name, {creative = true}) or old_is_creative_enabled(name) +end + +local S = core.get_translator"i3" +local ES = function(...) return core.formspec_escape(S(...)) end + +local function is_num(x) + return type(x) == "number" +end + +local function is_str(x) + return type(x) == "string" +end + +local function is_table(x) + return type(x) == "table" +end + +local function is_func(x) + return type(x) == "function" +end + +local function true_str(str) + return is_str(str) and str ~= "" +end + +local function true_table(x) + return is_table(x) and next(x) +end + +local function reset_compression(data) + data.alt_items = nil + data.expand = "" +end + +local function msg(name, str) + local prefix = "[i3]" + return core.chat_send_player(name, fmt("%s %s", core.colorize("#ff0", prefix), str)) +end + +local function err(str) + return core.log("error", str) +end + +local function round(num, decimal) + local mul = 10 ^ decimal + return floor(num * mul + 0.5) / mul +end + +local function toupper(str) + return str:gsub("%f[%w]%l", upper):gsub("_", " ") +end + +local function utf8_len(str) + local c = 0 + + for _ in str:gmatch"[%z\1-\127\194-\244][\128-\191]*" do -- Arguably working duct-tape code + c++ + end + + return c +end + +local function get_bag_description(data, stack) + local desc = translate(data.lang_code, stack:get_description()) + desc = split(desc, "(")[1] or desc + desc = toupper(desc:trim()) + + return desc +end + +local function search(data) + reset_compression(data) + + local filter = data.filter + local opt = "^(.-)%+([%w_]+)=([%w_,]+)" + local search_filter = next(i3.search_filters) and match(filter, opt) + local filters = {} + + if search_filter then + search_filter = search_filter:trim() + + for filter_name, values in gmatch(filter, sub(opt, 6)) do + if i3.search_filters[filter_name] then + values = split(values, ",") + filters[filter_name] = values + end + end + end + + local filtered_list, c = {}, 0 + + for i = 1, #data.items_raw do + local item = data.items_raw[i] + local def = reg_items[item] + local desc = lower(translate(data.lang_code, def.description)) or "" + local search_in = fmt("%s %s", item, desc) + local temp, j, to_add = {}, 1 + + if search_filter then + for filter_name, values in pairs(filters) do + if values then + local func = i3.search_filters[filter_name] + to_add = (j > 1 and temp[item] or j == 1) and + func(item, values) and (search_filter == "" or + find(search_in, search_filter, 1, true)) + + if to_add then + temp[item] = true + end + + j++ + end + end + else + local ok = true + + for keyword in gmatch(filter, "%S+") do + if not find(search_in, keyword, 1, true) then + ok = nil + break + end + end + + if ok then + to_add = true + end + end + + if to_add then + c++ + filtered_list[c] = item + end + end + + data.items = filtered_list +end + +local function table_replace(t, val, new) + for k, v in pairs(t) do + if v == val then + t[k] = new + end + end +end + +local function table_merge(t1, t2, hash) + t1 = t1 or {} + t2 = t2 or {} + + if hash then + for k, v in pairs(t2) do + t1[k] = v + end + else + local c = #t1 + + for i = 1, #t2 do + c++ + t1[c] = t2[i] + end + end + + return t1 +end + +local function array_diff(t1, t2) + local hash = {} + + for i = 1, #t1 do + local v = t1[i] + hash[v] = true + end + + for i = 1, #t2 do + local v = t2[i] + hash[v] = nil + end + + local diff, c = {}, 0 + + for i = 1, #t1 do + local v = t1[i] + if hash[v] then + c++ + diff[c] = v + end + end + + return diff +end + +local function table_eq(t1, t2) + local ty1, ty2 = type(t1), type(t2) + if ty1 ~= ty2 then return end + + if ty1 ~= "table" and ty2 ~= "table" then + return t1 == t2 + 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 +end + +local function clean_name(item) + if sub(item, 1, 1) == ":" or sub(item, 1, 1) == " " or sub(item, 1, 1) == "_" then + item = sub(item, 2) + end + + return item +end + +local function is_group(item) + return sub(item, 1, 6) == "group:" +end + +local function extract_groups(str) + return split(sub(str, 7), ",") +end + +local function item_has_groups(item_groups, groups) + for i = 1, #groups do + local group = groups[i] + if (item_groups[group] or 0) == 0 then return end + end + + return true +end + +local function valid_item(def) + return def and def.groups.not_in_creative_inventory ~= 1 and + def.description and def.description ~= "" +end + +local function get_group_stereotype(group) + local stereotype = i3.group_stereotypes[group] + local def = reg_items[stereotype] + + if valid_item(def) then + return stereotype + end +end + +local function groups_to_items(groups) + local names = {} + + for name, def in pairs(reg_items) do + if valid_item(def) and item_has_groups(def.groups, groups) then + insert(names, name) + end + end + + sort(names) + + return names +end + +local function is_cube(drawtype) + return drawtype == "normal" or drawtype == "liquid" or + sub(drawtype, 1, 9) == "glasslike" or + sub(drawtype, 1, 8) == "allfaces" +end + +local function get_cube(tiles) + if not true_table(tiles) then + return "i3_blank.png" + end + + local top = tiles[1] or "i3_blank.png" + if is_table(top) then + top = top.name or top.image + end + + local left = tiles[3] or top or "i3_blank.png" + if is_table(left) then + left = left.name or left.image + end + + local right = tiles[5] or left or "i3_blank.png" + if is_table(right) then + right = right.name or right.image + end + + return core.inventorycube(top, left, right) +end + +local function apply_recipe_filters(recipes, player) + for _, filter in pairs(i3.recipe_filters) do + recipes = filter(recipes, player) + end + + return recipes +end + +local function recipe_filter_set() + return next(i3.recipe_filters) +end + +local function compression_active(data) + return data.collapse and not recipe_filter_set() and data.filter == "" +end + +local function compressible(item, data) + return compression_active(data) and i3.compress_groups[item] +end + +local function is_fav(data) + for i = 1, #data.favs do + if data.favs[i] == data.query_item then + return i + end + end +end + +local function sort_by_category(data) + reset_compression(data) + local items = data.items_raw + + if data.filter ~= "" then + search(data) + items = data.items + end + + local new = {} + + for i = 1, #items do + local item = items[i] + local to_add = true + + if data.itab == 2 then + to_add = core.registered_nodes[item] + elseif data.itab == 3 then + to_add = core.registered_craftitems[item] or core.registered_tools[item] + end + + if to_add then + insert(new, item) + end + end + + data.items = new +end + +local function spawn_item(player, stack) + local dir = player:get_look_dir() + local ppos = player:get_pos() + ppos.y = ppos.y + player:get_properties().eye_height + local look_at = ppos + dir + + core.add_item(look_at, stack) +end + +local function get_recipes(player, item) + item = core.registered_aliases[item] or item + local recipes = i3.recipes_cache[item] + local usages = i3.usages_cache[item] + + if recipes then + recipes = apply_recipe_filters(recipes, player) + end + + local no_recipes = not recipes or #recipes == 0 + if no_recipes and not usages then return end + usages = apply_recipe_filters(usages, player) + local no_usages = not usages or #usages == 0 + + return not no_recipes and recipes or nil, + not no_usages and usages or nil +end + +local function get_stack(player, stack) + local inv = player:get_inventory() + + if inv:room_for_item("main", stack) then + inv:add_item("main", stack) + else + spawn_item(player, stack) + end +end + +local function craft_stack(player, data, craft_rcp) + local inv = player:get_inventory() + local rcp_usg = craft_rcp and "recipe" or "usage" + local rcp_def = rcp_usg == "recipe" and data.recipes[data.rnum] or data.usages[data.unum] + local output = craft_rcp and data.recipes[data.rnum].output or data.usages[data.unum].output + output = ItemStack(output) + local stackname, stackcount, stackmax = output:get_name(), output:get_count(), output:get_stack_max() + local scrbar_val = data[fmt("scrbar_%s", craft_rcp and "rcp" or "usg")] or 1 + + for name, count in pairs(data.crafting_counts[rcp_usg].rcp) do + local items = {[name] = count} + + if is_group(name) then + items = {} + local groups = extract_groups(name) + local groupname = name:sub(7) + local item_groups = i3.groups[groupname].items or groups_to_items(groups) + local remaining = count + + for _, item in ipairs(item_groups) do + for _name, _count in pairs(data.crafting_counts[rcp_usg].inv) do + if item == _name and remaining > 0 then + local c = min(remaining, _count) + items[item] = c + remaining -= c + end + + if remaining == 0 then break end + end + end + end + + for k, v in pairs(items) do + inv:remove_item("main", fmt("%s %s", k, v * scrbar_val)) + end + end + + if rcp_def.replacements then + for _, pair in ipairs(rcp_def.replacements) do + get_stack(player, ItemStack(pair[2])) + end + end + + local count = stackcount * scrbar_val + local iter = ceil(count / stackmax) + local leftover = count + + for _ = 1, iter do + local c = min(stackmax, leftover) + local stack = ItemStack(fmt("%s %s", stackname, c)) + get_stack(player, stack) + leftover -= stackmax + end +end + +local function play_sound(name, sound, volume) + core.sound_play(sound, {to_player = name, gain = volume}, true) +end + +local function safe_teleport(player, pos) + local name = player:get_player_name() + play_sound(name, "i3_teleport", 0.8) + + local vel = player:get_velocity() + player:add_velocity(-vel) + + local p = vec(pos) + p.y += 0.25 + + player:set_pos(p) +end + +local function sorter(inv, data, mode) + sort(inv, function(a, b) + if mode == 1 then + a = translate(data.lang_code, a:get_short_description()) + b = translate(data.lang_code, b:get_short_description()) + else + a, b = a:get_count(), b:get_count() + end + + if data.reverse_sorting then + return a > b + end + + return a < b + end) +end + +local function pre_sorting(list, start_i) + local new_inv, special = {}, {} + + for i = start_i, #list do + local stack = list[i] + local empty = stack:is_empty() + local meta = stack:get_meta():to_table() + local wear = stack:get_wear() > 0 + + if not empty then + if next(meta.fields) or wear then + insert(special, stack) + else + insert(new_inv, stack) + end + end + end + + new_inv = table_merge(new_inv, special) + return new_inv +end + +local function compress_items(list, start_i) + local hash, new_inv, special = {}, {}, {} + + for i = start_i, #list do + local stack = list[i] + local name = stack:get_name() + local count = stack:get_count() + local stackmax = stack:get_stack_max() + local empty = stack:is_empty() + local meta = stack:get_meta():to_table() + local wear = stack:get_wear() > 0 + + if not empty then + if next(meta.fields) or wear or count >= stackmax then + insert(special, stack) + else + hash[name] = hash[name] or 0 + hash[name] += count + end + end + end + + for name, count in pairs(hash) do + local stackmax = ItemStack(name):get_stack_max() + local iter = ceil(count / stackmax) + local leftover = count + + for _ = 1, iter do + insert(new_inv, ItemStack(fmt("%s %u", name, min(stackmax, leftover)))) + leftover -= stackmax + end + end + + new_inv = table_merge(new_inv, special) + return new_inv +end + +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 (data.hotbar_len + 1) or 1 + + if data.inv_compress then + list = compress_items(list, start_i) + else + list = pre_sorting(list, start_i) + end + + local new_inv = i3.sorting_methods[data.sort].func(list, data) + if not new_inv then return end + + if not data.ignore_hotbar then + inv:set_list("main", new_inv) + return + end + + for i = start_i, size do + local index = i - start_i + 1 + inv:set_stack("main", i, new_inv[index] or "") + end +end + +local function reset_data(data) + data.filter = "" + data.expand = "" + data.pagenum = 1 + data.rnum = 1 + data.unum = 1 + data.scrbar_rcp = 1 + data.scrbar_usg = 1 + data.query_item = nil + data.enable_search = nil + data.goto_page = nil + data.recipes = nil + data.usages = nil + data.crafting_rcp = nil + data.crafting_usg = nil + data.alt_items = nil + data.confirm_trash = nil + data.show_settings = nil + data.show_setting = "home" + data.items = data.items_raw + + if data.itab > 1 then + sort_by_category(data) + end +end + +local function add_hud_waypoint(player, name, pos, color) + return player:hud_add { + hud_elem_type = "waypoint", + name = name, + text = "m", + world_pos = pos, + number = color, + z_index = -300, + } +end + +local function get_detached_inv(name, player_name) + return core.get_inventory { + type = "detached", + name = fmt("i3_%s_%s", 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 "} + + for k = 2, n do + ret[2 + (k - 2) * 4] = "t[" + ret[3 + (k - 2) * 4] = k - 1 + ret[4 + (k - 2) * 4] = "]" + + if k ~= n then + ret[5 + (k - 2) * 4] = "," + end + end + + return loadstring(concat(ret)) +end + +local newunpack = createunpack(33) + +------------------------------------------------------------------------------- + +local _ = { + -- Groups + is_group = is_group, + extract_groups = extract_groups, + item_has_groups = item_has_groups, + groups_to_items = groups_to_items, + get_group_stereotype = get_group_stereotype, + + -- Compression + compressible = compressible, + compression_active = compression_active, + + -- Sorting + search = search, + sorter = sorter, + get_recipes = get_recipes, + sort_inventory = sort_inventory, + sort_by_category = sort_by_category, + recipe_filter_set = recipe_filter_set, + apply_recipe_filters = apply_recipe_filters, + + -- Type checks + is_fav = is_fav, + is_str = is_str, + is_num = is_num, + is_func = is_func, + true_str = true_str, + true_table = true_table, + + -- Console + err = err, + msg = msg, + + -- Misc. functions + is_cube = is_cube, + get_cube = get_cube, + ItemStack = ItemStack, + valid_item = valid_item, + spawn_item = spawn_item, + clean_name = clean_name, + play_sound = play_sound, + reset_data = reset_data, + safe_teleport = safe_teleport, + add_hud_waypoint = add_hud_waypoint, + + -- Core functions + clr = core.colorize, + slz = core.serialize, + dslz = core.deserialize, + ESC = core.formspec_escape, + draw_cube = core.inventorycube, + get_group = core.get_item_group, + pos_to_str = core.pos_to_string, + str_to_pos = core.string_to_pos, + check_privs = core.check_player_privs, + get_player_by_name = core.get_player_by_name, + get_connected_players = core.get_connected_players, + + -- 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, + + -- Registered items + reg_items = core.registered_items, + reg_nodes = core.registered_nodes, + reg_tools = core.registered_tools, + reg_aliases = core.registered_aliases, + reg_entities = core.registered_entities, + reg_craftitems = core.registered_craftitems, + + -- i18n + S = S, + ES = ES, + translate = core.get_translated_string, + + -- String + sub = string.sub, + find = string.find, + fmt = string.format, + upper = string.upper, + lower = string.lower, + split = string.split, + match = string.match, + gmatch = string.gmatch, + toupper = toupper, + utf8_len = utf8_len, + + -- Table + maxn = table.maxn, + sort = table.sort, + copy = table.copy, + concat = table.concat, + insert = table.insert, + remove = table.remove, + indexof = table.indexof, + unpack = newunpack, + is_table = is_table, + table_merge = table_merge, + table_replace = table_replace, + table_eq = table_eq, + array_diff = array_diff, + + -- Math + round = round, + min = math.min, + max = math.max, + ceil = math.ceil, + floor = math.floor, + random = math.random, + + -- Vectors + vec = vector.new, + vec_round = vector.round, +} + +function i3.get(...) + local t = {} + + for i, var in ipairs{...} do + t[i] = _[var] + end + + return newunpack(t) +end diff --git a/mods/i3/src/compression.lua b/mods/i3/src/compression.lua new file mode 100644 index 0000000..fd06624 --- /dev/null +++ b/mods/i3/src/compression.lua @@ -0,0 +1,313 @@ +IMPORT("fmt", "copy", "insert") + +local wood_types = { + "acacia_wood", "aspen_wood", "junglewood", "pine_wood", +} + +local material_tools = { + "bronze", "diamond", "mese", "stone", "wood", +} + +local material_stairs = { + "acacia_wood", "aspen_wood", "brick", "bronzeblock", "cobble", "copperblock", + "desert_cobble", "desert_sandstone", "desert_sandstone_block", "desert_sandstone_brick", + "desert_stone", "desert_stone_block", "desert_stonebrick", + "glass", "goldblock", "ice", "junglewood", "mossycobble", "obsidian", + "obsidian_block", "obsidian_glass", "obsidianbrick", "pine_wood", + "sandstone", "sandstone_block", "sandstonebrick", + "silver_sandstone", "silver_sandstone_block", "silver_sandstone_brick", + "snowblock", "steelblock", "stone", "stone_block", "stonebrick", + "straw", "tinblock", +} + +local colors = { + "black", "blue", "brown", "cyan", "dark_green", "dark_grey", "green", + "grey", "magenta", "orange", "pink", "red", "violet", "yellow", +} + +local to_compress = { + ["default:wood"] = { + replace = "wood", + by = wood_types, + }, + + ["default:fence_wood"] = { + replace = "wood", + by = wood_types, + }, + + ["default:fence_rail_wood"] = { + replace = "wood", + by = wood_types, + }, + + ["default:mese_post_light"] = { + replace = "mese_post_light", + by = { + "mese_post_light_acacia_wood", + "mese_post_light_aspen_wood", + "mese_post_light_junglewood", + "mese_post_light_pine_wood", + } + }, + + ["doors:gate_wood_closed"] = { + replace = "wood", + by = wood_types, + }, + + ["wool:white"] = { + replace = "white", + by = colors + }, + + ["dye:white"] = { + replace = "white", + by = colors + }, + + ["default:axe_steel"] = { + replace = "steel", + by = material_tools + }, + + ["default:pick_steel"] = { + replace = "steel", + by = material_tools + }, + + ["default:shovel_steel"] = { + replace = "steel", + by = material_tools + }, + + ["default:sword_steel"] = { + replace = "steel", + by = material_tools + }, + + ["farming:hoe_steel"] = { + replace = "steel", + by = {"wood", "stone"} + }, + + ["stairs:slab_wood"] = { + replace = "wood", + by = material_stairs + }, + + ["stairs:stair_wood"] = { + replace = "wood", + by = material_stairs + }, + + ["stairs:stair_inner_wood"] = { + replace = "wood", + by = material_stairs + }, + + ["stairs:stair_outer_wood"] = { + replace = "wood", + by = material_stairs + }, + + ["walls:cobble"] = { + replace = "cobble", + by = {"desertcobble", "mossycobble"} + }, +} + +local circular_saw_names = { + {"micro", "_1"}, + {"panel", "_1"}, + {"micro", "_2"}, + {"panel", "_2"}, + {"micro", "_4"}, + {"panel", "_4"}, + {"micro", ""}, + {"panel", ""}, + + {"micro", "_12"}, + {"panel", "_12"}, + {"micro", "_14"}, + {"panel", "_14"}, + {"micro", "_15"}, + {"panel", "_15"}, + {"stair", "_outer"}, + {"stair", ""}, + + {"stair", "_inner"}, + {"slab", "_1"}, + {"slab", "_2"}, + {"slab", "_quarter"}, + {"slab", ""}, + {"slab", "_three_quarter"}, + {"slab", "_14"}, + {"slab", "_15"}, + + {"slab", "_two_sides"}, + {"slab", "_three_sides"}, + {"slab", "_three_sides_u"}, + {"stair", "_half"}, + {"stair", "_alt_1"}, + {"stair", "_alt_2"}, + {"stair", "_alt_4"}, + {"stair", "_alt"}, + {"stair", "_right_half"}, + + {"slope", ""}, + {"slope", "_half"}, + {"slope", "_half_raised"}, + {"slope", "_inner"}, + {"slope", "_inner_half"}, + {"slope", "_inner_half_raised"}, + {"slope", "_inner_cut"}, + {"slope", "_inner_cut_half"}, + + {"slope", "_inner_cut_half_raised"}, + {"slope", "_outer"}, + {"slope", "_outer_half"}, + {"slope", "_outer_half_raised"}, + {"slope", "_outer_cut"}, + {"slope", "_outer_cut_half"}, + {"slope", "_outer_cut_half_raised"}, + {"slope", "_cut"}, +} + +local moreblocks_nodes = { + "coal_stone", + "wood_tile", + "iron_checker", + "circle_stone_bricks", + "cobble_compressed", + "plankstone", + "clean_glass", + "split_stone_tile", + "all_faces_tree", + "dirt_compressed", + "coal_checker", + "clean_glow_glass", + "tar", + "clean_super_glow_glass", + "stone_tile", + "cactus_brick", + "super_glow_glass", + "desert_cobble_compressed", + "copperpatina", + "coal_stone_bricks", + "glow_glass", + "cactus_checker", + "all_faces_pine_tree", + "all_faces_aspen_tree", + "all_faces_acacia_tree", + "all_faces_jungle_tree", + "iron_stone", + "grey_bricks", + "wood_tile_left", + "wood_tile_down", + "wood_tile_center", + "wood_tile_right", + "wood_tile_full", + "checker_stone_tile", + "iron_glass", + "iron_stone_bricks", + "wood_tile_flipped", + "wood_tile_offset", + "coal_glass", + + "straw", + + "stone", + "stone_block", + "cobble", + "mossycobble", + "brick", + "sandstone", + "steelblock", + "goldblock", + "copperblock", + "bronzeblock", + "diamondblock", + "tinblock", + "desert_stone", + "desert_stone_block", + "desert_cobble", + "meselamp", + "glass", + "tree", + "wood", + "jungletree", + "junglewood", + "pine_tree", + "pine_wood", + "acacia_tree", + "acacia_wood", + "aspen_tree", + "aspen_wood", + "obsidian", + "obsidian_block", + "obsidianbrick", + "obsidian_glass", + "stonebrick", + "desert_stonebrick", + "sandstonebrick", + "silver_sandstone", + "silver_sandstone_brick", + "silver_sandstone_block", + "desert_sandstone", + "desert_sandstone_brick", + "desert_sandstone_block", + "sandstone_block", + "coral_skeleton", + "ice", +} + +local colors_moreblocks = copy(colors) +insert(colors_moreblocks, "white") + +local moreblocks_mods = { + wool = colors_moreblocks, + moreblocks = moreblocks_nodes, +} + +local t = {} + +for mod, v in pairs(moreblocks_mods) do +for _, nodename in ipairs(v) do + t[nodename] = {} + + for _, shape in ipairs(circular_saw_names) do + if shape[1] ~= "slope" or shape[2] ~= "" then + insert(t[nodename], fmt("%s_%s%s", shape[1], nodename, shape[2])) + end + end + + local slope_name = fmt("slope_%s", nodename) + + to_compress[fmt("%s:%s", mod, slope_name)] = { + replace = slope_name, + by = t[nodename], + } +end +end + +local compressed = {} + +for k, v in pairs(to_compress) do + compressed[k] = compressed[k] or {} + + for _, str in ipairs(v.by) do + local it = k:gsub(v.replace, str) + insert(compressed[k], it) + end +end + +local _compressed = {} + +for _, v in pairs(compressed) do +for _, v2 in ipairs(v) do + _compressed[v2] = true +end +end + +i3.compress_groups, i3.compressed = compressed, _compressed diff --git a/mods/i3/src/detached_inv.lua b/mods/i3/src/detached_inv.lua new file mode 100644 index 0000000..9fd750d --- /dev/null +++ b/mods/i3/src/detached_inv.lua @@ -0,0 +1,24 @@ +local set_fs = i3.set_fs +IMPORT("play_sound", "create_inventory") + +local trash = create_inventory("i3_trash", { + allow_put = function(_, _, _, stack) + return stack:get_count() + end, + + on_put = function(inv, listname, _, _, player) + 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 + set_fs(player) + end + end, +}) + +trash:set_size("main", 1) diff --git a/mods/i3/src/fields.lua b/mods/i3/src/fields.lua new file mode 100644 index 0000000..e21441d --- /dev/null +++ b/mods/i3/src/fields.lua @@ -0,0 +1,475 @@ +local set_fs = i3.set_fs + +IMPORT("min", "max", "vec_round") +IMPORT("reg_items", "reg_aliases") +IMPORT("sort", "copy", "insert", "remove", "indexof") +IMPORT("S", "random", "translate", "compressible", "ItemStack") +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("search", "sort_inventory", "sort_by_category", "get_recipes", "get_detached_inv", "update_inv_size") + +local function inv_fields(player, data, fields) + local name = data.player_name + local inv = player:get_inventory() + local sb_inv = fields.scrbar_inv + + if sb_inv and sub(sb_inv, 1, 3) == "CHG" then + data.scrbar_inv = tonumber(match(sb_inv, "%d+")) + return + 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 + if sub(field, 1, 4) == "btn_" then + data.subcat = indexof(i3.categories, sub(field, 5)) + break + + elseif sub(field, 1, 3) == "cb_" then + local str = sub(field, 4) + data[str] = false + + if fields[field] == "true" then + data[str] = true + 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 + data.show_setting = match(field, "_(%w+)$") + + elseif sub(field, 1, 9) == "skin_btn_" then + local id = tonumber(field:match("%d+")) + local _skins = skins.get_skinlist_for_player(name) + + play_sound(name, "i3_skin_change", 0.6) + skins.set_player_skin(player, _skins[id]) + + elseif find(field, "waypoint_%d+") then + local id, action = match(field, "_(%d+)_(%w+)$") + id = tonumber(id) + local waypoint = data.waypoints[id] + if not waypoint then return end + + if action == "see" then + if data.waypoint_see and data.waypoint_see == id then + data.waypoint_see = nil + else + data.waypoint_see = id + end + + elseif action == "delete" then + player:hud_remove(waypoint.id) + remove(data.waypoints, id) + + elseif action == "teleport" then + local pos = str_to_pos(waypoint.pos) + safe_teleport(player, pos) + msg(name, S("Teleported to: @1", waypoint.name)) + + elseif action == "refresh" then + local color = random(0xffffff) + waypoint.color = color + player:hud_change(waypoint.id, "number", color) + + elseif action == "hide" then + if waypoint.hide then + local new_id = add_hud_waypoint( + player, waypoint.name, str_to_pos(waypoint.pos), waypoint.color) + + waypoint.id = new_id + waypoint.hide = nil + else + player:hud_remove(waypoint.id) + waypoint.hide = true + end + end + + break + end + end + + if fields.quit then + data.confirm_trash = nil + data.show_settings = nil + data.waypoint_see = nil + data.bag_rename = nil + data.goto_page = nil + + if data.filter == "" then + data.enable_search = nil + end + + elseif fields.trash then + data.show_settings = nil + data.confirm_trash = true + + elseif fields.settings then + if not data.show_settings then + data.confirm_trash = nil + data.show_settings = true + else + data.show_settings = nil + end + + elseif fields.confirm_trash_yes or fields.confirm_trash_no then + if fields.confirm_trash_yes then + inv:set_list("main", {}) + inv:set_list("craft", {}) + end + + data.confirm_trash = nil + + elseif fields.close_settings then + data.show_settings = nil + + elseif fields.close_preview then + data.waypoint_see = nil + + elseif fields.sort then + sort_inventory(player, data) + + elseif fields.home then + if not data.home then + return msg(name, "No home set") + elseif not check_privs(name, {home = true}) then + return msg(name, "'home' privilege missing") + end + + safe_teleport(player, str_to_pos(data.home)) + msg(name, S"Welcome back home!") + + elseif fields.set_home then + data.home = pos_to_str(player:get_pos(), 1) + + elseif fields.bag_rename then + data.bag_rename = true + + elseif fields.confirm_rename then + local bag = get_detached_inv("bag", name) + local bagstack = bag:get_stack("main", 1) + local meta = bagstack:get_meta() + local desc = translate(data.lang_code, bagstack:get_description()) + local fill = split(desc, "(")[2] + local newname = fields.bag_newname:gsub("([%(%)])", "") + newname = toupper(newname:trim()) + + if fill then + newname = fmt("%s (%s", newname, fill) + end + + meta:set_string("description", newname) + bag:set_stack("main", 1, bagstack) + + data.bag = bagstack:to_string() + data.bag_rename = nil + + elseif fields.waypoint_add then + local max_waypoints = i3.settings.max_waypoints + + if #data.waypoints >= max_waypoints then + play_sound(name, "i3_cannot", 0.8) + return msg(name, fmt("Waypoints limit reached (%u)", max_waypoints)) + end + + local pos = player:get_pos() + + for _, v in ipairs(data.waypoints) do + if vec_round(pos) == vec_round(str_to_pos(v.pos)) then + play_sound(name, "i3_cannot", 0.8) + return msg(name, S"You already have set a waypoint at this position") + end + end + + local waypoint = fields.waypoint_name + + if fields.waypoint_name == "" then + waypoint = "Waypoint" + end + + local color = random(0xffffff) + local id = add_hud_waypoint(player, waypoint, pos, color) + + insert(data.waypoints, { + name = waypoint, + pos = pos_to_str(pos, 1), + color = color, + id = id, + }) + + data.scrbar_inv += 1000 + + elseif fields.hide_debug_grid then + data.hide_debug_grid = not data.hide_debug_grid + end + + return set_fs(player) +end + +local function select_item(player, data, fields) + local item + + for field in pairs(fields) do + if find(field, ":") then + item = field + break + end + end + + if not item then return end + + if compressible(item, data) then + local idx + + for i = 1, #data.items do + local it = data.items[i] + if it == item then + idx = i + break + end + end + + if data.expand ~= "" then + data.alt_items = nil + + if item == data.expand then + data.expand = nil + return + end + end + + if idx and item ~= data.expand then + data.alt_items = copy(data.items) + data.expand = item + + if i3.compress_groups[item] then + local items = copy(i3.compress_groups[item]) + insert(items, fmt("_%s", item)) + + sort(items, function(a, b) + if a:sub(1, 1) == "_" then + a = a:sub(2) + end + + return a < b + end) + + local i = 1 + + for _, v in ipairs(items) do + if valid_item(reg_items[clean_name(v)]) then + insert(data.alt_items, idx + i, v) + i++ + end + end + end + end + else + if sub(item, 1, 1) == "_" then + item = sub(item, 2) + elseif sub(item, 1, 6) == "group!" then + item = match(item, "([%w:_]+)$") + end + + item = reg_aliases[item] or item + if not reg_items[item] then return end + + if core.is_creative_enabled(data.player_name) then + local stack = ItemStack(item) + local stackmax = stack:get_stack_max() + stack = fmt("%s %s", item, stackmax) + + return get_stack(player, stack) + end + + if item == data.query_item then return end + local recipes, usages = get_recipes(player, item) + + data.query_item = item + data.recipes = recipes + data.usages = usages + data.rnum = 1 + data.unum = 1 + data.scrbar_rcp = 1 + data.scrbar_usg = 1 + data.crafting_rcp = nil + data.crafting_usg = nil + end +end + +local function rcp_fields(player, data, fields) + local sb_rcp, sb_usg = fields.scrbar_rcp, fields.scrbar_usg + + if not data.hide_tabs and fields.filter and fields.filter == "" then + data.enable_search = nil + end + + if fields.cancel then + reset_data(data) + + elseif fields.exit then + 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 + reset_data(data) + return set_fs(player) + end + + local str = lower(fields.filter) + if data.filter == str then return end + + data.filter = str + data.pagenum = 1 + + search(data) + + if data.itab > 1 then + sort_by_category(data) + end + + elseif fields.pagenum then + data.goto_page = not data.goto_page + + elseif fields.goto_page then + local pagenum = tonumber(fields.goto_page) + data.pagenum = max(1, min(data.pagemax, pagenum or data.pagenum)) + data.goto_page = nil + + elseif fields.prev_page or fields.next_page then + if data.pagemax == 1 then return end + data.pagenum -= (fields.prev_page and 1 or -1) + + if data.pagenum > data.pagemax then + data.pagenum = 1 + elseif data.pagenum == 0 then + data.pagenum = data.pagemax + end + + elseif fields.prev_skin or fields.next_skin then + if data.skin_pagemax == 1 then return end + data.skin_pagenum -= (fields.prev_skin and 1 or -1) + + if data.skin_pagenum > data.skin_pagemax then + data.skin_pagenum = 1 + elseif data.skin_pagenum == 0 then + data.skin_pagenum = data.skin_pagemax + end + + elseif fields.prev_recipe or fields.next_recipe then + local num = data.rnum + (fields.prev_recipe and -1 or 1) + data.rnum = data.recipes[num] and num or (fields.prev_recipe and #data.recipes or 1) + data.crafting_rcp = nil + data.scrbar_rcp = 1 + + elseif fields.prev_usage or fields.next_usage then + local num = data.unum + (fields.prev_usage and -1 or 1) + data.unum = data.usages[num] and num or (fields.prev_usage and #data.usages or 1) + data.crafting_usg = nil + data.scrbar_usg = 1 + + elseif fields.fav then + local fav = is_fav(data) + + if #data.favs < i3.settings.max_favs and not fav then + insert(data.favs, data.query_item) + elseif fav then + remove(data.favs, fav) + end + + elseif fields.crafting_rcp or fields.crafting_usg then + if fields.crafting_rcp then + data.crafting_rcp = not data.crafting_rcp + + if not data.crafting_rcp then + data.scrbar_rcp = 1 + end + else + data.crafting_usg = not data.crafting_usg + + if not data.crafting_usg then + data.scrbar_usg = 1 + end + end + + elseif (sb_rcp and sub(sb_rcp, 1, 3) == "CHG") or (sb_usg and sub(sb_usg, 1, 3) == "CHG") then + data.scrbar_rcp = sb_rcp and tonumber(match(sb_rcp, "%d+")) + data.scrbar_usg = sb_usg and tonumber(match(sb_usg, "%d+")) + + elseif fields.craft_rcp or fields.craft_usg then + craft_stack(player, data, fields.craft_rcp) + + if fields.craft_rcp then + data.crafting_rcp = nil + data.scrbar_rcp = 1 + else + data.crafting_usg = nil + data.scrbar_usg = 1 + end + else + select_item(player, data, fields) + end +end + +core.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + + if formname == "i3_outdated" then + return false, core.kick_player(name, + S"Your Minetest client needs updating (www.minetest.net)") + elseif formname ~= "" then + return false + end + +-- No-op buttons + 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 or + fields.quick_crafting then + return false + end + +-- print(dump(fields)) + local data = i3.data[name] + if not data then return end + + for f in pairs(fields) do + if sub(f, 1, 4) == "tab_" then + local tabname = sub(f, 5) + i3.set_tab(player, tabname) + break + elseif sub(f, 1, 5) == "itab_" then + data.pagenum = 1 + data.itab = tonumber(f:sub(-1)) + sort_by_category(data) + break + end + end + + rcp_fields(player, data, fields) + + local tab = i3.tabs[data.tab] + + if tab and tab.fields then + return true, tab.fields(player, data, fields) + end + + return true, set_fs(player) +end) + +return inv_fields diff --git a/mods/i3/src/groups.lua b/mods/i3/src/groups.lua new file mode 100644 index 0000000..6db4cd0 --- /dev/null +++ b/mods/i3/src/groups.lua @@ -0,0 +1,62 @@ +IMPORT("S") + +i3.group_stereotypes = { + dye = "dye:white", + wool = "wool:white", + wood = "default:wood", + tree = "default:tree", + sand = "default:sand", + glass = "default:glass", + stick = "default:stick", + stone = "default:stone", + leaves = "default:leaves", + coal = "default:coal_lump", + fence = "default:fence_wood", + vessel = "vessels:glass_bottle", + flower = "flowers:dandelion_yellow", + water_bucket = "bucket:bucket_water", + mesecon_conductor_craftable = "mesecons:wire_00000000_off", +} + +i3.group_names = { + dye = S"Any dye", + coal = S"Any coal", + sand = S"Any sand", + tree = S"Any tree", + wool = S"Any wool", + glass = S"Any glass", + stick = S"Any stick", + stone = S"Any stone", + fence = S"Any fence", + carpet = S"Any carpet", + flower = S"Any flower", + leaves = S"Any leaves", + vessel = S"Any vessel", + wood = S"Any wood planks", + mushroom = S"Any mushroom", + + ["color_red,flower"] = S"Any red flower", + ["color_blue,flower"] = S"Any blue flower", + ["color_black,flower"] = S"Any black flower", + ["color_white,flower"] = S"Any white flower", + ["color_green,flower"] = S"Any green flower", + ["color_orange,flower"] = S"Any orange flower", + ["color_yellow,flower"] = S"Any yellow flower", + ["color_violet,flower"] = S"Any violet flower", + + ["color_red,dye"] = S"Any red dye", + ["color_blue,dye"] = S"Any blue dye", + ["color_grey,dye"] = S"Any grey dye", + ["color_pink,dye"] = S"Any pink dye", + ["color_cyan,dye"] = S"Any cyan dye", + ["color_black,dye"] = S"Any black dye", + ["color_white,dye"] = S"Any white dye", + ["color_brown,dye"] = S"Any brown dye", + ["color_green,dye"] = S"Any green dye", + ["color_orange,dye"] = S"Any orange dye", + ["color_yellow,dye"] = S"Any yellow dye", + ["color_violet,dye"] = S"Any violet dye", + ["color_magenta,dye"] = S"Any magenta dye", + ["color_dark_grey,dye"] = S"Any dark grey dye", + ["color_dark_green,dye"] = S"Any dark green dye", +} diff --git a/mods/i3/src/gui.lua b/mods/i3/src/gui.lua new file mode 100644 index 0000000..365e6c6 --- /dev/null +++ b/mods/i3/src/gui.lua @@ -0,0 +1,1742 @@ +local damage_enabled = i3.settings.damage_enabled +local debug_mode = i3.settings.debug_mode + +local model_aliases = i3.files.model_alias() +local PNG, styles, fs_elements, colors = i3.files.styles() + +local sprintf = string.format +local VoxelArea, VoxelManip = VoxelArea, VoxelManip + +IMPORT("vec", "vec_round") +IMPORT("find", "match", "sub", "upper") +IMPORT("clr", "ESC", "msg", "check_privs") +IMPORT("min", "max", "floor", "ceil", "round") +IMPORT("true_str", "is_fav", "is_num", "str_to_pos") +IMPORT("reg_items", "reg_nodes", "reg_tools", "reg_entities") +IMPORT("get_bag_description", "get_detached_inv", "get_recipes") +IMPORT("compression_active", "compressible", "recipe_filter_set") +IMPORT("S", "ES", "translate", "ItemStack", "toupper", "utf8_len") +IMPORT("maxn", "sort", "concat", "copy", "insert", "remove", "unpack") +IMPORT("extract_groups", "groups_to_items", "is_group", "item_has_groups", "get_group") + +local function fmt(elem, ...) + if not fs_elements[elem] then + return sprintf(elem, ...) + end + + return sprintf(fs_elements[elem], ...) +end + +local function repairable(tool) + local def = reg_tools[tool] + return i3.toolrepair and def and def.groups and def.groups.disable_repair ~= 1 +end + +local function weird_desc(str) + return not true_str(str) or find(str, "\n") or not find(str, "%u") +end + +local function snip(str, limit, font_size) + limit -= (font_size > 3 and font_size + 1 or font_size) + + if utf8_len(str) > limit then + return fmt("%s...", sub(str, 1, limit - 3)) + end +end + +local function get_desc(item, lang_code) + if sub(item, 1, 1) == "_" then + item = sub(item, 2) + end + + local def = reg_items[item] + if not def then + return S("Unknown Item (@1)", item) + end + + local desc = ItemStack(item):get_short_description() + desc = translate(lang_code, desc) + + if true_str(desc) then + desc = desc:trim():gsub("_", " ") + + if not find(desc, "%u") then + desc = toupper(desc) + end + + return desc + + elseif true_str(item) then + return toupper(match(item, ":(.*)")) + end +end + +local function get_stack_max(inv, data, is_recipe, rcp) + local list = inv:get_list"main" + local size = inv:get_size"main" + local counts_inv, counts_rcp, counts = {}, {}, {} + local rcp_usg = is_recipe and "recipe" or "usage" + + for _, it in pairs(rcp.items) do + counts_rcp[it] = (counts_rcp[it] or 0) + 1 + end + + data.crafting_counts[rcp_usg] = {} + data.crafting_counts[rcp_usg].rcp = counts_rcp + + for i = 1, size do + local stack = list[i] + + if not stack:is_empty() then + local item = stack:get_name() + local count = stack:get_count() + + for name in pairs(counts_rcp) do + if is_group(name) then + local def = reg_items[item] + + if def then + local group_cache = i3.groups[name:sub(7)] + local groups = group_cache and group_cache.groups or extract_groups(name) + + if item_has_groups(def.groups, groups) then + counts_inv[name] = (counts_inv[name] or 0) + count + end + end + end + end + + counts_inv[item] = (counts_inv[item] or 0) + count + end + end + + data.crafting_counts[rcp_usg].inv = counts_inv + + for name in pairs(counts_rcp) do + counts[name] = floor((counts_inv[name] or 0) / (counts_rcp[name] or 0)) + end + + local max_stacks = math.huge + + for _, count in pairs(counts) do + if count < max_stacks then + max_stacks = count + end + end + + return max_stacks +end + +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]" + + for i = 0, hotbar_len - 1 do + box(i * size + inv_x + (i * spacing), inv_y, size, size, "") + end + + fs("style_type[list;size=%f;spacing=%f]", size, spacing) + fs("list[current_player;main;%f,%f;%u,1;]", inv_x, inv_y, hotbar_len) + + fs("style_type[list;size=%f;spacing=%f,%f]", size, spacing, legacy_inventory and 0.15 or spacing) + + 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]" +end + +local function add_subtitle(fs, name, y, ctn_len, font_size, sep, label) + fs("style[%s;font=bold;font_size=%u]", name, font_size) + button(0, y, ctn_len, 0.5, name, ESC(label)) + + if sep then + image(0, y + 0.55, ctn_len, 0.035, PNG.bar) + end +end + +local function get_award_list(data, fs, ctn_len, yextra, award_list, awards_unlocked, award_list_nb) + local percent = fmt("%.1f%%", (awards_unlocked * 100) / award_list_nb):gsub("%.0", "") + + add_subtitle(fs, "awards", yextra, ctn_len, 18, false, + ES("Achievements: @1 of @2 (@3)", awards_unlocked, award_list_nb, percent)) + + for i = 1, award_list_nb do + local award = award_list[i] + local y = yextra - 0.6 + i + (i * 0.3) + + local def, progress = award.def, award.progress + local title, desc = def.title, def.description + + title = translate(data.lang_code, title) + desc = translate(data.lang_code, desc):gsub("%.$", "") + + local title_lim, desc_lim = 27, 39 + local icon_size = 1.1 + + local _title = snip(title, title_lim, data.font_size) or title + local _desc = snip(desc, desc_lim, data.font_size) or desc + + if not award.unlocked and def.secret then + title = ES"Secret award" + desc = ES"Unlock this award to find out what it is" + end + + local icon = def.icon or "awards_unknown.png" + + if not award.unlocked then + icon = fmt("%s^\\[colorize:#000:220", icon) + end + + insert(fs, fmt("image", 0, y, icon_size, icon_size, icon)) + insert(fs, "style_type[box;colors=#bababa30,#bababa30,#bababa05,#bababa05]") + insert(fs, fmt("box", 0, y, ctn_len, icon_size, "")) + + if progress then + local box_len = ctn_len - icon_size - 0.15 + local current, target = progress.current, progress.target + local curr_bar = (current * box_len) / target + + insert(fs, fmt("box", icon_size + 0.15, y + 0.8, box_len, 0.3, "#101010")) + insert(fs, "style_type[box;colors=#9dc34c80,#9dc34c,#9dc34c,#9dc34c80]") + insert(fs, fmt("box", icon_size + 0.15, y + 0.8, curr_bar, 0.3, "")) + insert(fs, "style_type[label;font_size=14]") + insert(fs, fmt("label", icon_size + 0.55, y + 0.97, fmt("%u / %u", current, target))) + + y -= 0.14 + end + + local end_title = ESC(_title or title) + local end_desc = ESC(_desc or desc) + + insert(fs, "style_type[label;font=bold;font_size=17]") + insert(fs, fmt("label", icon_size + 0.2, y + 0.4, end_title)) + insert(fs, "style_type[label;font=normal;font_size=15]") + insert(fs, fmt("label", icon_size + 0.2, y + 0.75, clr("#bbb", end_desc))) + insert(fs, "style_type[label;font_size=16]") + insert(fs, fmt("tooltip", 0, y, icon_size, icon_size, ESC(desc))) + end +end + +local function get_isometric_view(fs, pos, X, Y, t, cubes, depth, high) + pos = vec_round(pos) + cubes = cubes or 0 + depth = depth or -1 + high = high or math.huge + + t = t or {} + t[depth] = {} + + local width = 8 + local base_height = 4 + local base_depth = depth == -1 + local max_depth = -7 + local height = base_depth and (base_height - 1) or depth + + local pos1 = vec(pos.x - width, pos.y + depth, pos.z - width) + local pos2 = vec(pos.x + width, pos.y + height, pos.z + width) + + local vm = VoxelManip(pos1, pos2) + local emin, emax = vm:get_emerged_area() + local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax} + local data = vm:get_data() + + for idx in area:iterp(pos1, pos2) do + local cube = i3.cubes[data[idx]] + local plant = i3.plants[data[idx]] + local img = cube or plant + + if img then + local p = area:position(idx) + p -= pos + + local size = 0.25 + local x = 2 + (size / 2 * (p.z - p.x)) + local y = 1 + (size / 4 * (p.x + p.z - 2 * p.y)) + + if y < high then + high = y + end + + if plant then + size -= 0.05 + end + + cubes++ + insert(t[depth], {x + X, y + Y, size, size, img}) + end + end + + local maxc = ((width * 2) ^ 2) * base_height + + if cubes < maxc and depth > max_depth then + -- if there's not enough map to preview, go deeper + depth -= 1 + return get_isometric_view(fs, pos, X, Y, t, cubes, depth, high) + end + + local shift = -0.3 - high + + for i = max_depth, 0 do + local dth = t[i] + if dth then + dth[0] = #dth + for j = 1, dth[0] do + local params = dth[j] + params[2] += shift + insert(fs, fmt("image[%f,%f;%.1f,%.1f;%s]", unpack(params))) + end + end + end + + shift += (base_depth and 0.45 or 0.95) + animated_image(2.75, Y + shift, 3/14, 0.3, "i3_flag_anim.png", 4, 150) +end + +local function get_waypoint_fs(fs, data, player, yextra, ctn_len) + fs("box[0,%f;4.9,0.6;#bababa25]", yextra + 1.1) + label(0, yextra + 0.85, ES"New waypoint" .. ":") + 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", "") + fs("tooltip[waypoint_add;%s]", ES"Add waypoint") + + if #data.waypoints == 0 then return end + 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)) + local icon_size, yi = 0.35, y + 0.12 + + fs"style_type[box;colors=#bababa30,#bababa30,#bababa05,#bababa05]" + box(0, y, ctn_len, 0.6, "") + + local waypoint_name, lim = v.name, 22 + waypoint_name = snip(waypoint_name, lim, data.font_size) or waypoint_name + + local hex = fmt("%02x", v.color) + + while #hex < 6 do + hex = "0" .. hex + end + + local teleport_priv = check_privs(player, {teleport = true}) + local waypoint_preview = data.waypoint_see and data.waypoint_see == i + + label(0.15, y + 0.33, clr(fmt("#%s", hex), waypoint_name)) + + local tooltip = fmt("Name: %s\nPosition:%s", clr("#dbeeff", v.name), + v.pos:sub(2,-2):gsub("(%-*%d*%.?%d+)", clr("#dbeeff", " %1"))) + + if teleport_priv then + tooltip = fmt("%s\n%s", tooltip, clr("#ff0", ES"[Click to teleport]")) + end + + tooltip(0, y, ctn_len - 2.1, 0.65, tooltip) + + local del = fmt("waypoint_%u_delete", i) + 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, "") + fs("tooltip[%s;%s]", del, ES"Remove waypoint") + + local rfs = fmt("waypoint_%u_refresh", i) + 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, "") + fs("tooltip[%s;%s]", rfs, ES"Change color") + + local see = fmt("waypoint_%u_see", i) + 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) + image_button(ctn_len - 1.5, yi, icon_size, icon_size, "", see, "") + fs("tooltip[%s;%s]", see, ES"Preview the waypoint area") + + local vsb = fmt("waypoint_%u_hide", i) + 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, "") + fs("tooltip[%s;%s]", vsb, v.hide and ES"Show waypoint" or ES"Hide waypoint") + + if teleport_priv then + local tp = fmt("waypoint_%u_teleport", i) + button(0, y, ctn_len - 2.1, 0.6, tp, "") + end + + if waypoint_preview then + image(0.25, y - 3.5, 5, 4, PNG.bg_content) + fs"style[area_preview;font_size=16;textcolor=#ddd]" + button(0.25, y - 3.35, 5, 0.55, "area_preview", v.name) + image_button(4.65, y - 3.25, 0.25, 0.25, PNG.cancel_hover .. "^\\[brighten", "close_preview", "") + + local pos = str_to_pos(data.waypoints[i].pos) + get_isometric_view(fs, pos, 0.6, y - 2.5) + end + end + + fs"style_type[label;font=normal;font_size=16;textcolor=#fff]" +end + +local function get_bag_fs(fs, data, bag_size, yextra) + fs("list[detached:i3_bag_%s;main;0,%f;1,1;]", data.player_name, yextra + 0.7) + local bag = get_detached_inv("bag", data.player_name) + if bag:is_empty"main" then return end + + local v = {{1.9, 2, 0.12}, {3.05, 5, 0.06}, {4.2, 10}, {4.75, 10}} + local h, m, yy = unpack(v[bag_size]) + + local bagstack = bag:get_stack("main", 1) + local desc = ESC(get_bag_description(data, bagstack)) + + image(0.5, yextra + 1.85, 0.6, 0.6, PNG.arrow_content) + 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", "") + + if not data.bag_rename then + hypertext(1.3, yextra + 0.8, 4.3, 0.6, "content", + fmt("
%s
", desc)) + image_button(5.22, yextra + 0.835, 0.25, 0.25, "", "bag_rename", "") + fs("tooltip[bag_rename;%s]", ES"Rename the bag") + else + box(1.7, yextra + 0.82, 2.6, 0.4, "#707070") + fs("field[1.8,%f;2.5,0.4;bag_newname;;%s]", yextra + 0.82, desc) + fs"field_close_on_enter[bag_newname;false]" + hypertext(4.4, yextra + 0.88, 0.8, 0.6, "confirm_rename", + fmt("" .. + "
OK
", colors.yellow)) + end + + local x, size, spacing = 1.45, 0.9, 0.12 + + if bag_size == 4 then + x, size, spacing = 1.7, 0.8, 0.1 + end + + fs("style_type[list;size=%f;spacing=%f]", size, spacing) + fs("list[detached:i3_bag_content_%s;main;%f,%f;4,%u;]", data.player_name, x, yextra + 1.3, bag_size) + fs"style_type[list;size=1;spacing=0.15]" +end + +local function get_container(fs, data, player, yoffset, ctn_len, award_list, awards_unlocked, award_list_nb, bag_size) + local nametag = player:get_nametag_attributes() + local name = true_str(nametag.text) and nametag.text or data.player_name + local esc_name = ESC(name) + + add_subtitle(fs, "player_name", 0, ctn_len, 22, true, esc_name) + + if damage_enabled then + local hp = data.hp or player:get_hp() or 20 + local half = ceil((hp / 2) % 1) + local hearts = (hp / 2) + half + local heart_size = 0.35 + local heart_x, heart_h = 0.65, yoffset + 0.75 + + for i = 1, 10 do + image(heart_x + ((i - 1) * (heart_size + 0.1)), heart_h, + heart_size, heart_size, PNG.heart .. "^[colorize:#232428") + end + + for i = 1, hearts do + image(heart_x + ((i - 1) * (heart_size + 0.1)), heart_h, + heart_size, heart_size, + (half == 1 and i == floor(hearts)) and PNG.heart_half or PNG.heart) + end + else + yoffset -= 0.5 + end + + 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) + fs("list[current_player;craftpreview;%f,%f;1,1;]", 4.45, yoffset + 2.6) + 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) + + local yextra = damage_enabled and 5.5 or 5 + + for i, title in ipairs(i3.categories) do + local btn_name = fmt("btn_%s", 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], + PNG[fmt("%s_hover", title)]) + image_button(0.25 + ((i - 1) * 1.18), yextra - 0.2, 0.5, 0.5, "", btn_name, "") + fs("tooltip[%s;%s]", btn_name, title:gsub("^%l", upper)) + end + + box(0, yextra + 0.45, ctn_len, 0.045, "#bababa50") + image((data.subcat - 1) * 1.18, yextra + 0.45, 1, 0.045, PNG.highlight) + + local function not_installed(modname) + hypertext(0, yextra + 0.9, ctn_len, 0.6, "not_installed", + fmt("
not installed
", + colors.blue, modname)) + end + + if data.subcat == 1 then + get_bag_fs(fs, data, bag_size, yextra) + + elseif data.subcat == 2 then + if not i3.modules.armor then + return not_installed "3d_armor" + end + + local armor_def = armor.def[data.player_name] + local _, armor_inv = armor:get_valid_player(player, "3d_armor") + + fs("list[detached:%s_armor;armor;0,%f;5,1;]", esc_name, yextra + 0.7) + + for i = 1, 5 do + local stack = armor_inv:get_stack("armor", i) + + if stack:is_empty() then + local tips = {ES"Helmet", ES"Chest", ES"Leggings", ES"Boots", ES"Shield"} + local x = (i - 1) + ((i - 1) * 0.15) + local y = yextra + 0.7 + + image(x, y, 1, 1, fmt("i3_armor_%u.png", i)) + tooltip(x, y, 1, 1, tips[i]) + end + end + + local box_len, max_level, max_heal = 4, 85, 60 + local bar_lvl = (armor_def.level * box_len) / max_level + local bar_heal = (armor_def.heal * box_len) / max_heal + + fs"style_type[label;font_size=15]" + + box(0.8, yextra + 1.95, box_len, 0.4, "#101010") + fs"style_type[box;colors=#9dc34c80,#9dc34c,#9dc34c,#9dc34c80]" + box(0.8, yextra + 1.95, bar_lvl, 0.4, "") + label(1.1, yextra + 2.15, ES"Armor level") + + box(0.8, yextra + 2.55, box_len, 0.4, "#101010") + fs"style_type[box;colors=#4466aa80,#4466aa,#4466aa,#4466aa80]" + box(0.8, yextra + 2.55, bar_heal, 0.4, "") + label(1.1, yextra + 2.75, ES"Armor healing") + + fs"style_type[label;font_size=16]" + + elseif data.subcat == 3 then + if not i3.modules.skins then + return not_installed "skinsdb" + end + + local _skins = skins.get_skinlist_for_player(data.player_name) + local skin_name = skins.get_player_skin(player).name + local spp, add_y = 24, 0 + + if #_skins > spp then + local btn_y = yextra + 0.75 + add_y += 0.6 + + data.skin_pagemax = max(1, ceil(#_skins / spp)) + + image_button(1.5, btn_y, 0.35, 0.35, "", "prev_skin", "") + image_button(3.85, btn_y, 0.35, 0.35, "", "next_skin", "") + + fs"style[skin_page;font=bold;font_size=18]" + button(1.85, btn_y - 0.23, 2, 0.8, "skin_page", + fmt("%s / %u", clr(colors.yellow, data.skin_pagenum), data.skin_pagemax)) + end + + local first = (data.skin_pagenum - 1) * spp + local last = first + spp - 1 + + for i = first, last do + local skin = _skins[i + 1] + if not skin then break end + local btn_name = fmt("skin_btn_%u", i + 1) + + fs([[ style[%s;padding=10;fgimg=%s;bgimg=%s;bgimg_hovered=i3_btn9_hovered.png; + bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6;sound=] ]], + btn_name, skin:get_preview(), + skin.name == skin_name and "i3_btn9_hovered.png" or "i3_btn9.png") + + local X = (i % 3) * 1.93 + + local Y = ceil((i % spp - X) / 3 + 1) + Y += (Y * 2.45) + yextra - 2.75 + add_y + + image_button(X, Y, 1.86, 3.4, "", btn_name, "") + fs("tooltip[%s;%s]", btn_name, ESC(skin.name)) + end + + elseif data.subcat == 4 then + if not i3.modules.awards then + return not_installed "awards" + end + + yextra = yextra + 0.7 + get_award_list(data, fs, ctn_len, yextra, award_list, awards_unlocked, award_list_nb) + + elseif data.subcat == 5 then + get_waypoint_fs(fs, data, player, yextra, ctn_len) + end +end + +local function show_settings(fs, data) + if data.confirm_trash then + 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"container[-0.06,0]" + image(2.2, 9, 6.1, 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" + + fs"style[setting_home,setting_style,setting_sorting;font=bold;font_size=16;sound=i3_click]" + fs("style[setting_home:hovered;textcolor=%s]", show_home and colors.yellow or "#fff") + fs("style[setting_style:hovered;textcolor=%s]", show_style and colors.yellow or "#fff") + fs("style[setting_sorting:hovered;textcolor=%s]", show_sorting and colors.yellow or "#fff") + + fs("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") + 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.4, 9.1, 1.6, 0.55, "setting_sorting", "Sorting") + image_button(X + 5.12, 9.2, 0.25, 0.25, PNG.cancel_hover .. "^\\[brighten", "close_settings", "") + + if show_home then + local coords, c, str = {"X", "Y", "Z"}, 0, ES"No home set" + + if data.home then + str = data.home:gsub(",", " "):sub(2,-2):gsub("%.%d", ""):gsub( + "(%-?%d+)", function(a) + c++ + return fmt("%s: ", + coords[c], colors.blue, a) + end) + end + + hypertext(2.2, 9.9, 6, 0.6, "home_pos", fmt("
%s
", str)) + image_button(4.3, 10.4, 1.8, 0.7, "", "set_home", "Set home") + + 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)) + + if not recipe_filter_set() then + checkbox(5.3, 10.85, "cb_collapse", "Collapse list", tostring(data.collapse)) + end + + local sign = (data.font_size > 0 and "+") or (data.font_size > 0 and "-") or "" + label(5.3, 9.95, ES"Font size" .. fmt(": %s", sign .. data.font_size)) + + local range = 5 + fs("scrollbaroptions[min=-%u;max=%u;smallstep=1;largestep=1;thumbsize=2]", range, range) + fs("scrollbar[5.3,10.2;2.55,0.3;horizontal;sb_font_size;%d]", data.font_size) + + fs("tooltip[cb_hide_tabs;%s;#707070;#fff]", + ES"Enable this option to change the style of the right panel") + fs("tooltip[cb_legacy_inventory;%s;#707070;#fff]", + ES"Enable this option to set the classic inventory size in Minetest") + fs("tooltip[cb_wielditem_hud;%s;#707070;#fff]", + ES"Enable this option to show the wielded item description in your HUD") + fs("tooltip[cb_collapse;%s;#707070;#fff]", + ES"Enable this option to collapse the inventory list by grouping some items") + + 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 + + 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 + +local function get_inventory_fs(player, data, fs) + fs"listcolors[#bababa50;#bababa99]" + + get_inv_slots(data, fs) + + local props = player:get_properties() + 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() + local armor_skin = i3.modules.armor or i3.modules.skins + local t = {} + + for _, v in ipairs(props.textures) do + insert(t, (ESC(v):gsub(",", "!"))) + end + + local textures = concat(t, ","):gsub("!", ",") + + -- 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)) + else + local size = 2.5 + image(0.7, 0.2, size, size * props.visual_size.y, props.textures[1]) + end + + 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 + max_val += min(32, 6 + ((bag_size - 1) * 10)) + + elseif i3.modules.armor and data.subcat == 2 then + if data.scrbar_inv >= max_val then + data.scrbar_inv += 10 + end + + max_val += 10 + + elseif i3.modules.skins and data.subcat == 3 then + local spp = 24 + local _skins = skins.get_skinlist_for_player(data.player_name) + local nb = #_skins + local num = max(1, min(spp, nb - ((data.skin_pagenum - 1) * spp))) + + max_val += ceil(num / 3) * (nb > spp and 34 or 31) + + elseif i3.modules.awards and data.subcat == 4 then + award_list = awards.get_award_states(data.player_name) + award_list_nb = #award_list + + for i = 1, award_list_nb do + local award = award_list[i] + + if award.unlocked then + awards_unlocked++ + end + end + + max_val += (award_list_nb * 13) + + elseif data.subcat == 5 then + local wp = #data.waypoints + + if wp > 0 then + local mul = (wp > 8 and 7) or (wp > 4 and 6) or 5 + max_val += 11 + (wp * mul) + end + end + + fs([[ scrollbaroptions[arrows=hide;thumbsize=%d;max=%d] + scrollbar[%f,0.2;0.2,%f;vertical;scrbar_inv;%u] + scrollbaroptions[arrows=default;thumbsize=0;max=1000] ]], + (max_val * 4) / 12, max_val, 9.8, ctn_hgt, data.scrbar_inv) + + 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) + fs"scroll_container_end[]" + + local btn = { + {"trash", ES"Clear inventory"}, + {"sort", ES"Sort inventory"}, + {"settings", ES"Settings"}, + {"home", ES"Go home"}, + } + + for i, v in ipairs(btn) do + local btn_name, tooltip = unpack(v) + fs("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", + 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, "") + fs("tooltip[%s;%s]", btn_name, tooltip) + end + + show_settings(fs, data) +end + +local function get_tooltip(item, info, lang_code) + local tooltip + + if info.groups then + sort(info.groups) + tooltip = i3.group_names[concat(info.groups, ",")] + + if not tooltip then + local groupstr = {} + + for i = 1, #info.groups do + insert(groupstr, clr("#ff0", info.groups[i])) + end + + groupstr = concat(groupstr, ", ") + tooltip = S("Any item belonging to the groups: @1", groupstr) + end + else + tooltip = info.meta_desc or get_desc(item, lang_code) + end + + local function add(str) + return fmt("%s\n%s", tooltip, str) + end + + if info.cooktime then + tooltip = add(S("Cooking time: @1", clr("#ff0", info.cooktime))) + end + + if info.burntime then + tooltip = add(S("Burning time: @1", clr("#ff0", info.burntime))) + end + + if info.replace then + for i = 1, #info.replace.items do + local rpl = ItemStack(info.replace.items[i]):get_name() + local desc = clr("#ff0", get_desc(rpl, lang_code)) + + if info.replace.type == "cooking" then + tooltip = add(S("Replaced by @1 on smelting", desc)) + elseif info.replace.type == "fuel" then + tooltip = add(S("Replaced by @1 on burning", desc)) + else + tooltip = add(S("Replaced by @1 on crafting", desc)) + end + end + end + + if info.repair then + tooltip = add(S("Repairable by step of @1", clr("#ff0", i3.toolrepair .. "%"))) + end + + if info.rarity then + local chance = (1 / max(1, info.rarity)) * 100 + tooltip = add(S("@1 of chance to drop", clr("#ff0", chance .. "%"))) + end + + if info.tools then + local several = #info.tools > 1 + local names = several and "\n" or "" + + if several then + for i = 1, #info.tools do + names = fmt("%s\t\t- %s\n", names, clr("#ff0", get_desc(info.tools[i], lang_code))) + end + + tooltip = add(S("Only drop if using one of these tools: @1", sub(names, 1, -2))) + else + tooltip = add(S("Only drop if using this tool: @1", + clr("#ff0", get_desc(info.tools[1], lang_code)))) + end + end + + return fmt("tooltip[%s;%s]", item, ESC(tooltip)) +end + +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 cooking = rcp.type == "cooking" + local fuel = rcp.type == "fuel" + + if custom_recipe or shapeless or cooking then + local icon, tooltip = PNG.blank + + if custom_recipe and true_str(custom_recipe.icon) then + icon = custom_recipe.icon + elseif shapeless then + icon = PNG.shapeless + end + + local pos_x = right + btn_size + 0.42 + local pos_y = data.yoffset + 0.9 + + if cooking then + animated_image(pos_x, pos_y, 0.5, 0.5, PNG.furnace_anim, 8, 180) + else + image(pos_x, pos_y, 0.5, 0.5, icon) + end + + if custom_recipe and true_str(custom_recipe.description) then + tooltip = custom_recipe.description + elseif shapeless then + tooltip = S"Shapeless" + elseif cooking then + tooltip = S"Cooking" + end + + if tooltip then + tooltip(pos_x, pos_y, 0.5, 0.5, ESC(tooltip)) + end + end + + local BTN_SIZE = i3.settings.item_btn_size + local arrow_X = right + 0.2 + (btn_size2 or BTN_SIZE) + local X = arrow_X + 1.2 + local Y = data.yoffset + 1.4 + + image(arrow_X, Y + 0.06, 1, 1, PNG.arrow) + + if fuel then + animated_image(X + 0.05, Y, BTN_SIZE, BTN_SIZE, PNG.fire_anim, 8, 180) + return + end + + local item = ItemStack(rcp.output) + local meta = item:get_meta() + local name = item:get_name() + local count = item:get_count() + local _name = fmt("_%s", name) + + local size = BTN_SIZE * 1.2 + slot(X, Y - 0.11, size, size) + + count = get_true_count(data, count, is_recipe, is_usage) + item:set_count(count) + + local itemstr = ESC(item:to_string()) + item_image_button(X + 0.11, Y, BTN_SIZE, BTN_SIZE, itemstr, _name, "") + + local def = reg_items[name] + local unknown = not def or nil + local desc = def and def.description + local weird = name ~= "" and desc and weird_desc(desc) or nil + local burntime = i3.fuel_cache[name] and i3.fuel_cache[name].burntime + + local short_desc = meta:get_string"short_description" + local long_desc = meta:get_string"description" + local meta_desc = (short_desc ~= "" and short_desc) or (long_desc ~= "" and long_desc) + + local infos = { + unknown = unknown, + weird = weird, + burntime = burntime, + repair = repairable(name), + rarity = rcp.rarity, + tools = rcp.tools, + meta_desc = meta_desc, + } + + if next(infos) then + fs(get_tooltip(_name, infos, data.lang_code)) + end +end + +local function get_grid_fs(fs, data, rcp, is_recipe, is_usage) + local width = rcp.width or 1 + local right = 0 + local btn_size, _btn_size = i3.settings.item_btn_size + local cooktime, shapeless + + if rcp.type == "cooking" then + cooktime, width = width, 1 + elseif width == 0 and not rcp.custom then + shapeless = true + local n = #rcp.items + width = (n < 5 and n > 1) and 2 or min(3, max(1, n)) + end + + local rows = ceil(maxn(rcp.items) / width) + local large_recipe = width > 3 or rows > 3 + + if large_recipe then + fs"style_type[item_image_button;border=true]" + end + + for i = 1, width * rows do + local item = rcp.items[i] or "" + item = ItemStack(item) + local meta = item:get_meta() + local name = item:get_name() + local count = item:get_count() + local X, Y + + if large_recipe then + local a, b = 3, 3 + local add_x, add_y = 0, 0 + + if width < 3 then + a, b = width * 2, 1 + add_x = 2 + elseif rows < 3 then + a, b = 1, rows * 2 + add_y = 1.4 + end + + btn_size = (a / width) * (b / rows) + 0.3 + _btn_size = btn_size + + local xi = (i - 1) % width + local yi = floor((i - 1) / width) + + X = btn_size * xi + data.inv_width + 0.3 + (xi * 0.05) + add_x + Y = btn_size * yi + data.yoffset + 0.2 + (yi * 0.05) + add_y + else + X = ceil((i - 1) % width - width) + X += (X * 0.2) + data.inv_width + 3.9 + + Y = ceil(i / width) - min(2, rows) + Y += (Y * 0.15) + data.yoffset + 1.4 + end + + if X > right then + right = X + end + + local groups + local group_cache = i3.groups[name:sub(7)] + + if is_group(name) then + groups = group_cache and group_cache.groups or extract_groups(name) + name = group_cache and (group_cache.stereotype or group_cache.items[1]) or + groups_to_items(groups)[1] or "" + end + + local label = groups and "\nG" or "" + local replace + + for j = 1, #(rcp.replacements or {}) do + local replacement = rcp.replacements[j] + if replacement[1] == name then + replace = replace or {type = rcp.type, items = {}} + + local added + + for _, v in ipairs(replace.items) do + if replacement[2] == v then + added = true + break + end + end + + if not added then + label = fmt("%s%s\nR", label ~= "" and "\n" or "", label) + insert(replace.items, replacement[2]) + end + end + end + + if not large_recipe then + slot(X, Y, btn_size, btn_size) + end + + local btn_name = groups and fmt("group!%s!%s", groups[1], name) or name + count = get_true_count(data, count, is_recipe, is_usage) + + if group_cache and group_cache.sprite and not large_recipe then + local sprite = ESC(group_cache.sprite) + local size = btn_size - 0.02 + + item_image_button(X, Y, btn_size, btn_size, "", btn_name, "") + animated_image(X + 0.01, Y + 0.025, size, size, sprite, group_cache.count, 1500) + label(X + 0.45, Y + 0.18, label) + + if count > 1 then + label(X + 0.8, Y + 0.9, count) + end + else + item:set_name(name) + item:set_count(count) + local itemstr = ESC(item:to_string()) + item_image_button(X, Y, btn_size, btn_size, itemstr, btn_name, label) + end + + local def = reg_items[name] + local unknown = not def or nil + unknown = not groups and unknown or nil + local desc = def and def.description + local weird = name ~= "" and desc and weird_desc(desc) or nil + local burntime = i3.fuel_cache[name] and i3.fuel_cache[name].burntime + + local short_desc = meta:get_string"short_description" + local long_desc = meta:get_string"description" + local meta_desc = (short_desc ~= "" and short_desc) or (long_desc ~= "" and long_desc) or nil + + local infos = { + unknown = unknown, + weird = weird, + groups = groups, + burntime = burntime, + cooktime = cooktime, + replace = replace, + meta_desc = meta_desc, + } + + if next(infos) then + fs(get_tooltip(btn_name, infos, data.lang_code)) + end + end + + if large_recipe then + 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) +end + +local function get_rcp_lbl(fs, data, panel, rn, is_recipe, is_usage) + local rcp = is_recipe and panel.rcp[data.rnum] or panel.rcp[data.unum] + + if rcp.custom then + local craft_type = i3.craft_types[rcp.type] + if craft_type then + local desc = craft_type.description + hypertext(data.inv_width + 4.8, data.yoffset + 0.12, 3, 1, "custom_rcp", + fmt("%s\n%s", + ES"Custom recipe", ESC(desc))) + end + end + + local lbl = ES("Usage @1 of @2", data.unum, rn) + + if is_recipe then + lbl = ES("Recipe @1 of @2", data.rnum, rn) + end + + local one = rn == 1 + local y = data.yoffset + 3.3 + + hypertext(data.inv_width + (one and 4.7 or 3.95), y, 3, 0.6, "rcp_num", + fmt("%s", lbl)) + + if not one then + local btn_suffix = is_recipe and "recipe" or "usage" + local prev_name = fmt("prev_%s", btn_suffix) + local next_name = fmt("next_%s", btn_suffix) + local size = 0.3 + + image_button(data.inv_width + 7.05, y, size, size, "", prev_name, "") + image_button(data.inv_width + 7.5, y, size, size, "", next_name, "") + end + + get_grid_fs(fs, data, rcp, is_recipe, is_usage) +end + +local function get_model_fs(fs, data, def, model_alias) + if model_alias then + if model_alias.drawtype == "entity" then + def = reg_entities[model_alias.name] + local init_props = def.initial_properties + def.textures = init_props and init_props.textures or def.textures + def.mesh = init_props and init_props.mesh or def.mesh + else + def = reg_items[model_alias.name] + end + end + + local tiles = def.tiles or def.textures or {} + local t = {} + + for _, v in ipairs(tiles) do + local _name + + if v.color then + if is_num(v.color) then + local hex = fmt("%02x", v.color) + + while #hex < 8 do + hex = "0" .. hex + end + + _name = fmt("%s^[multiply:%s", v.name, fmt("#%s%s", sub(hex, 3), sub(hex, 1, 2))) + else + _name = fmt("%s^[multiply:%s", v.name, v.color) + end + elseif v.animation then + _name = fmt("%s^[verticalframe:%u:0", v.name, v.animation.frames_h or v.animation.aspect_h) + end + + insert(t, _name or v.name or v) + end + + while #t < 6 do + insert(t, t[#t]) + end + + model(data.inv_width + 6.6, data.yoffset + 0.05, 1.3, 1.3, "preview", + def.mesh, concat(t, ","), "0,0", "true", "true", + model_alias and model_alias.frames or "") +end + +local function get_header(fs, data) + local fav = is_fav(data) + local nfavs = #data.favs + local max_favs = i3.settings.max_favs + local star_x, star_y, size = data.inv_width + 0.3, data.yoffset + 0.2, 0.4 + + if nfavs < max_favs or (nfavs == max_favs and fav) then + local fav_marked = fmt("i3_fav%s.png", fav and "_off" or "") + fs("style[fav;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]", + fmt("i3_fav%s.png", fav and "" or "_off"), fav_marked, fav_marked) + image_button(star_x, star_y, size, size, "", "fav", "") + fs("tooltip[fav;%s]", fav and ES"Unmark this item" or ES"Mark this item") + else + fs("style[nofav;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]", + "i3_fav_off.png", PNG.cancel, PNG.cancel) + image_button(star_x, star_y, size, size, "", "nofav", "") + fs("tooltip[nofav;%s]", ES"Cannot mark this item. Bookmark limit reached.") + end + + image_button(star_x + 0.05, star_y + 0.6, size, size, "", "exit", "") + fs("tooltip[exit;%s]", ES"Back to item list") + + local desc_lim, name_lim = 34, 35 + local desc = get_desc(data.query_item, data.lang_code) + desc = ESC(desc) + local tech_name = data.query_item + local X = data.inv_width + 0.95 + local Y1 = data.yoffset + 0.47 + local Y2 = Y1 + 0.5 + + local _desc = snip(desc, desc_lim, data.font_size) + if _desc then + tooltip(X, Y1 - 0.1, 5.7, 0.24, desc) + end + + local _tech_name = snip(tech_name, name_lim, data.font_size) + if _tech_name then + tooltip(X, Y2 - 0.1, 5.7, 0.24, tech_name) + end + + fs"style_type[label;font=bold;font_size=20]" + label(X, Y1, _desc or desc) + fs"style_type[label;font=mono;font_size=16]" + label(X, Y2, clr(colors.blue, _tech_name or tech_name)) + fs"style_type[label;font=normal;font_size=16]" + + local def = reg_items[data.query_item] + local model_alias = model_aliases[data.query_item] + + if def.drawtype == "mesh" or model_alias then + get_model_fs(fs, data, def, model_alias) + else + item_image(data.inv_width + 6.8, data.yoffset + 0.17, 1.1, 1.1, data.query_item) + end +end + +local function get_crafting_fs(fs, data, is_recipe, is_usage, max_stacks_rcp, max_stacks_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) + + 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) + image_button(data.inv_width + 7.35, data.yoffset + 0.2, 0.45, 0.45, "", fmt("crafting_%s", name), "") + fs("tooltip[crafting_%s;%s]", name, ES"Quick crafting") + + if not show_crafting then return end + + local craft_max = is_recipe and max_stacks_rcp or max_stacks_usg + local stack_fs = (is_recipe and data.scrbar_rcp) or (is_usage and data.scrbar_usg) or 1 + + if stack_fs > craft_max then + stack_fs = craft_max + + if is_recipe then + data.scrbar_rcp = craft_max + elseif is_usage then + data.scrbar_usg = craft_max + end + end + + local x = data.inv_width + 6.8 + + fs"style_type[image,button,image_button;noclip=true]" + image(x, data.yoffset + 0.8, 3, 2, PNG.bg_content) + fs"style[quick_crafting;font_size=16;textcolor=#ddd]" + button(x, data.yoffset + 0.85, 3.05, 0.55, "quick_crafting", ES"Quick Crafting") + + fs("style[scrbar_%s;noclip=true]", name) + 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) + 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]" +end + +local function get_rcp_extra(fs, data, player, panel, is_recipe, is_usage) + fs"container[0,0.075]" + local rn = panel.rcp and #panel.rcp + + if rn then + local rcp_ok = is_recipe and panel.rcp[data.rnum].type == "normal" + local usg_ok = is_usage and panel.rcp[data.unum].type == "normal" + local max_stacks_rcp, max_stacks_usg = 0, 0 + local inv = player:get_inventory() + + if rcp_ok then + max_stacks_rcp = get_stack_max(inv, data, is_recipe, panel.rcp[data.rnum]) + end + + if usg_ok then + max_stacks_usg = get_stack_max(inv, data, is_recipe, panel.rcp[data.unum]) + end + + if is_recipe and max_stacks_rcp == 0 then + data.crafting_rcp = nil + data.scrbar_rcp = 1 + elseif is_usage and max_stacks_usg == 0 then + data.crafting_usg = nil + data.scrbar_usg = 1 + end + + if max_stacks_rcp > 0 or max_stacks_usg > 0 then + get_crafting_fs(fs, data, is_recipe, is_usage, max_stacks_rcp, max_stacks_usg) + end + + get_rcp_lbl(fs, data, panel, rn, is_recipe, is_usage) + else + 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) + end + + fs"container_end[]" +end + +local function hide_items(player, data) + if compression_active(data) then + local new = {} + + for i = 1, #data.items do + local item = data.items[i] + if not i3.compressed[item] then + insert(new, item) + end + end + + data.items = new + end + + if not core.is_creative_enabled(data.player_name) and not recipe_filter_set() then + local new = {} + + for i = 1, #data.items do + local item = data.items[i] + local recipes, usages = get_recipes(player, item) + + if recipes or usages then + insert(new, item) + end + end + + data.items = new + 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) + 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 + + data.pagemax = max(1, ceil(#items / ipp)) + + if data.pagenum > data.pagemax then + data.pagenum = data.pagemax + end + + if #items == 0 then + local lbl = ES"No item to show" + local icon, width, offset = PNG.no_result, 4, 2 + + if recipe_filter_set() and #i3.init_items > 0 and data.filter == "" then + lbl = ES"Collect items to reveal more recipes" -- Progressive mode, etc. + icon, width, offset = PNG.find_more, 2.5, 2.75 + end + + image(data.inv_width + offset, 3.5, width, width, icon) + button(data.inv_width + 0.1, 7, 8, 1, "no_item", lbl) + else + local first_item = (data.pagenum - 1) * ipp + + for i = first_item, first_item + ipp - 1 do + local item = items[i + 1] + if not item then break end + + local _compressed = item:sub(1, 1) == "_" + local name = _compressed and item:sub(2) or item + + local X = i % rows + X -= (X * 0.045) + data.inv_width + 0.28 + + local Y = round((i % ipp - X) / rows + 1, 0) + Y -= (Y * 0.085) + 0.92 + + local item_btn = fmt("item_image_button", X, Y, size, size, name, item, "") + + if recipe_filter_set() 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 + local nodedef = reg_nodes[item] + + if nodedef and not true_str(nodedef.inventory_image) 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 + local expand = data.expand == name + + 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]" + label(X + 0.65, Y + 0.7, expand and "-" or "+") + fs"style_type[label;font=normal;font_size=16]" + end + end + end + + get_header_items_fs(fs, data) +end + +local function get_favs(fs, data) + local btn_size = i3.settings.item_btn_size + label(data.inv_width + 0.4, data.yoffset + 0.4, ES"Bookmarks") + + for i, item in ipairs(data.favs) do + local name = fmt("_%s", item) + local X = data.inv_width - 0.7 + (i * 1.2) + local Y = data.yoffset + 0.8 + + if data.query_item == item then + slot(X, Y, btn_size, btn_size) + end + + item_image_button(X, Y, btn_size, btn_size, item, name, "") + end +end + +local function get_panels(fs, data, player) + local title = {name = "title", height = 1.4, func = get_header} + local favs = {name = "favs", height = 2.23, func = get_favs} + local recipes = {name = "recipes", rcp = data.recipes, height = 4.045, func = get_rcp_extra} + local usages = {name = "usages", rcp = data.usages, height = 4.045, func = get_rcp_extra} + local panels = {title, recipes, usages, favs} + data.yoffset = 0 + + for i, panel in ipairs(panels) do + if i > 1 then + data.yoffset += panels[i - 1].height + 0.1 + end + + bg9(data.inv_width + 0.1, data.yoffset, 7.9, panel.height, PNG.bg_full) + + local is_recipe, is_usage = panel.name == "recipes", panel.name == "usages" + panel.func(fs, data, player, panel, is_recipe, is_usage) + end +end + +local function get_tabs_fs(fs, player, data, full_height) + local tab_len, tab_hgh, c, over = 3, 0.5, 0 + local _tabs = copy(i3.tabs) + + for i, def in ipairs(i3.tabs) do + if def.access and not def.access(player, data) then + remove(_tabs, i) + end + end + + local shift = min(3, #_tabs) + + for i, def in ipairs(_tabs) do + if not over and c > 2 then + over = true + c = 0 + end + + local btm = i <= 3 + + if not btm then + shift = #_tabs - 3 + end + + local selected = i == data.tab + local bgimg = selected and (btm and PNG.tab_hover or PNG.tab_hover_top) or + (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,16,-16,-16" + local padding = btm and "-16,0,16,16" or "-16,-16,16,16" + + fs([[ style_type[image_button;bgimg=%s;bgimg_hovered=%s;bgimg_middle=%s;padding=%s] ]], + bgimg, bgimg_hover, middle, padding) + + fs("style_type[image_button;noclip=true;font_size=16;textcolor=%s;content_offset=0;sound=i3_tab]", + selected and "#fff" or "#ddd") + + 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 + + fs"style_type[image_button:hovered;textcolor=#fff]" + image_button(X, Y, tab_len, tab_hgh, "", fmt("tab_%s", def.name), ESC(def.description)) + + if true_str(def.image) then + local desc = translate(data.lang_code, def.description) + local desc_len = utf8_len(desc) + data.font_size + + 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 + + c++ + end +end + +local function get_debug_grid(data, fs, full_height) + fs"style[hide_debug_grid;noclip=true]" + 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]" + local spacing, i = 0.2, 1 + + for x = 0, data.inv_width + 8, spacing do + box(x, 0, 0.01, full_height, "#ff0") + label(x, full_height + 0.1, tostring(i)) + i++ + end + + i = 61 + + for y = 0, full_height, spacing do + box(0, y, data.inv_width + 8, 0.01, "#ff0") + label(-0.15, y, tostring(i)) + i -= 1 + end + + box(data.inv_width / 2, 0, 0.01, full_height, "#f00") + box(0, full_height / 2, data.inv_width, 0.01, "#f00") + fs"style_type[label;font_size=16]" +end + +local function make_fs(player, data) + local start = debug_mode and core.get_us_time() or nil + + local fs = setmetatable({}, { + __call = function(t, ...) + local args = {...} + + if #args > 1 then + local arg1 = args[1] + local elem = fs_elements[arg1] + insert(t, fmt(elem or arg1, select(2, ...))) + else + insert(t, concat(args)) + end + end + }) + + data.inv_width = 10.23 + local full_height = 12 + + fs("formspec_version[%u]size[%f,%f]no_prepend[]bgcolor[#0000]", + i3.settings.min_fs_version, data.inv_width + 8, full_height) + + fs(styles) + + bg9(0, 0, data.inv_width, full_height, PNG.bg_full) + + local tab = i3.tabs[data.tab] + + if tab and tab.formspec then + tab.formspec(player, data, fs) + end + + if data.query_item then + 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 + + for _, def in ipairs(i3.tabs) do + if def.access and not def.access(player, data) then + visible_tabs -= 1 + end + end + + if visible_tabs > 1 then + get_tabs_fs(fs, player, data, full_height) + end + + if debug_mode then + get_debug_grid(data, fs, full_height) + msg(data.player_name, fmt("make_fs(): %.2f ms", (core.get_us_time() - start) / 1000)) + msg(data.player_name, fmt("#fs elements: %u", #fs)) + end + + fs = concat(fs) + + if data.font_size ~= 0 then + fs = fs:gsub("([font][global]*)([%s_])size=(%d+)", function(a, b, c) + return fmt("%s%ssize=%s", a, b, tostring(tonumber(c) + data.font_size)) + end) + end + + return fs +end + +return make_fs, get_inventory_fs diff --git a/mods/i3/src/hud.lua b/mods/i3/src/hud.lua new file mode 100644 index 0000000..e790851 --- /dev/null +++ b/mods/i3/src/hud.lua @@ -0,0 +1,177 @@ +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", + position = {x = 0.78, y = 1}, + alignment = {x = 1, y = 1}, + scale = {x = 370, y = 112}, + text = "i3_bg.png", + z_index = 0xDEAD, + }, + + img = player:hud_add { + hud_elem_type = "image", + position = {x = 0.79, y = 1.02}, + alignment = {x = 1, y = 1}, + scale = {x = 1, y = 1}, + text = "", + z_index = 0xDEAD, + }, + + text = player:hud_add { + hud_elem_type = "text", + position = {x = 0.84, y = 1.04}, + alignment = {x = 1, y = 1}, + number = 0xffffff, + text = "", + z_index = 0xDEAD, + style = 1, + }, + + 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) + -- It would better to have an engine function `hud_move` to only need + -- 2 calls for the notification's back and forth. + + local hud_info_bg = player:hud_get(data.hud.bg) + local dt = 0.025 + + if hud_info_bg.position.y <= 0.9 then + data.show_hud = false + data.hud_timer = (data.hud_timer or 0) + dt + end + + player:hud_change(data.hud.text, "text", data.hud_msg) + + if data.hud_img then + player:hud_change(data.hud.img, "text", data.hud_img) + end + + if data.show_hud then + for _, def in pairs(data.hud) do + local hud_info = player:hud_get(def) + + player:hud_change(def, "position", { + x = hud_info.position.x, + y = hud_info.position.y - ((dt / 5) * i3.settings.hud_speed) + }) + end + + elseif data.show_hud == false then + if data.hud_timer >= i3.settings.hud_timer_max then + for _, def in pairs(data.hud) do + local hud_info = player:hud_get(def) + + player:hud_change(def, "position", { + x = hud_info.position.x, + y = hud_info.position.y + ((dt / 5) * i3.settings.hud_speed) + }) + end + + if hud_info_bg.position.y >= 1 then + data.show_hud = nil + data.hud_timer = nil + data.hud_msg = nil + data.hud_img = nil + 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() + 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 data and data.show_hud ~= nil then + show_hud(player, data) + end + end +end) + +local function init_waypoints(player) + local name = player:get_player_name() + local data = i3.data[name] + data.waypoints = data.waypoints or {} + + for _, v in ipairs(data.waypoints) do + if not v.hide then + local id = add_hud_waypoint(player, v.name, str_to_pos(v.pos), v.color) + v.id = id + end + end +end + +return function(player) + init_hud(player) + init_waypoints(player) +end diff --git a/mods/i3/src/model_aliases.lua b/mods/i3/src/model_aliases.lua new file mode 100644 index 0000000..f1d6699 --- /dev/null +++ b/mods/i3/src/model_aliases.lua @@ -0,0 +1,11 @@ +return { + ["boats:boat"] = {name = "boats:boat", drawtype = "entity"}, + ["carts:cart"] = {name = "carts:cart", drawtype = "entity", frames = "0,0"}, + ["default:chest"] = {name = "default:chest_open"}, + ["default:chest_locked"] = {name = "default:chest_locked_open"}, + ["doors:door_wood"] = {name = "doors:door_wood_a"}, + ["doors:door_glass"] = {name = "doors:door_glass_a"}, + ["doors:door_obsidian_glass"] = {name = "doors:door_obsidian_glass_a"}, + ["doors:door_steel"] = {name = "doors:door_steel_a"}, + ["xpanes:door_steel_bar"] = {name = "xpanes:door_steel_bar_a"}, +} diff --git a/mods/i3/src/preprocessor.lua b/mods/i3/src/preprocessor.lua new file mode 100644 index 0000000..138842e --- /dev/null +++ b/mods/i3/src/preprocessor.lua @@ -0,0 +1,98 @@ +--[[ All source files have to be preprocessed before loading. + This allows implementing custom operators like bitwise ones. ]] + +local fmt, split = string.format, string.split +local var = "[%w%.%[%]\"\'_]" +local modpath = core.get_modpath"i3" +local _,_, fs_elements = dofile(modpath .. "/src/styles.lua") + +local operators = { + ["([%+%-%*%^/&|])="] = function(a, b, c) + return fmt("%s = %s %s %s", a, a, b, c) + end, + + ["+%+"] = function(a, b) + return fmt("%s = %s + 1\n%s", a, a, b) + end, + + ["&"] = function(a, b) + return fmt("bit.band(%s, %s)", a, b) + end, + + ["|"] = function(a, b) + return fmt("bit.bor(%s, %s)", a, b) + end, + + ["<<"] = function(a, b) + return fmt("bit.lshift(%s, %s)", a, b) + end, + + [">>"] = function(a, b) + return fmt("bit.rshift(%s, %s)", a, b) + end, + + ["<<="] = function(a, b) + return fmt("%s = bit.lshift(%s, %s)", a, a, b) + end, + + [">>="] = function(a, b) + return fmt("%s = bit.rshift(%s, %s)", a, a, b) + end, +} + +local function compile(data) + data = data:gsub("IMPORT%((.-)%)", function(a) + return "local " .. a:gsub("\"", "") .. " = i3.get(" .. a .. ")" + end) + + data = data:gsub("([%w_]+)%(", function(a) + if fs_elements[a] then + return fmt("fs('%s',", a) + end + end) + + data = data:gsub("([%w_]+)-%-\n", function(a) + return fmt("%s = %s - 1", a, a) + end) + + for op, func in pairs(operators) do + data = data:gsub("(" .. var .. "+)%s?" .. op .. "%s?(" .. var .. "*)", func) + end + + return data +end + +local function _load(path, line, data, t) + if line then + if not t then + t = split(data, "\n") + end + t[line] = t[line]:gsub("(" .. var .. "+)%s?=%s?(" .. var .. "*)", "%2") + data = table.concat(t, "\n") + else + local file = assert(io.open(path, "r")) + data = file:read"*a" + file:close() + data = compile(data) + end + + local l, err = loadstring(data) + + if not l then + local err_line = tonumber(err:match(":(%d+):")) + + if t then + print("err_line", err_line, t[err_line]) + end + + if line ~= err_line then + return _load(path, err_line, data, t) + end + end + + return l, err +end + +return function(path) + return _load(path) or loadfile(path) +end diff --git a/mods/i3/src/progressive.lua b/mods/i3/src/progressive.lua new file mode 100644 index 0000000..1797aa1 --- /dev/null +++ b/mods/i3/src/progressive.lua @@ -0,0 +1,169 @@ +local set_fs = i3.set_fs +local hud_notif = i3.hud_notif +local POLL_FREQ = 0.25 + +IMPORT("reg_items", "reg_nodes") +IMPORT("fmt", "search", "table_merge", "array_diff") +IMPORT("is_group", "extract_groups", "item_has_groups", "apply_recipe_filters") + +local function get_filtered_items(player, data) + local items, known = {}, 0 + + for i = 1, #i3.init_items do + local item = i3.init_items[i] + local recipes = i3.recipes_cache[item] + local usages = i3.usages_cache[item] + + recipes = #apply_recipe_filters(recipes or {}, player) + usages = #apply_recipe_filters(usages or {}, player) + + if recipes > 0 or usages > 0 then + items[item] = true + known += recipes + usages + end + end + + data.known_recipes = known + + return items +end + +local function item_in_inv(item, inv_items) + local inv_items_size = #inv_items + + if is_group(item) then + local groupname = item:sub(7) + local group_cache = i3.groups[groupname] + local groups = group_cache and group_cache.groups or extract_groups(item) + + for i = 1, inv_items_size do + local def = core.registered_items[inv_items[i]] + + if def then + if item_has_groups(def.groups, groups) then + return true + end + end + end + else + for i = 1, inv_items_size do + if inv_items[i] == item then + return true + end + end + end +end + +local function recipe_in_inv(rcp, inv_items) + for _, item in pairs(rcp.items) do + if not item_in_inv(item, inv_items) then return end + end + + return true +end + +local function progressive_filter(recipes, player) + if not recipes then + return {} + end + + local name = player:get_player_name() + local data = i3.data[name] + + if #data.inv_items == 0 then + return {} + end + + local filtered, c = {}, 0 + + for i = 1, #recipes do + local recipe = recipes[i] + if recipe_in_inv(recipe, data.inv_items) then + c++ + filtered[c] = recipe + end + end + + return filtered +end + +local item_lists = {"main", "craft", "craftpreview"} + +local function get_inv_items(player) + local inv = player:get_inventory() + if not inv then + return {} + end + + local stacks = {} + + for i = 1, #item_lists do + local list = inv:get_list(item_lists[i]) + table_merge(stacks, list) + end + + local inv_items, c = {}, 0 + + for i = 1, #stacks do + local stack = stacks[i] + + if not stack:is_empty() then + local name = stack:get_name() + if core.registered_items[name] then + c++ + inv_items[c] = name + end + end + end + + return inv_items +end + +-- Workaround. Need an engine call to detect when the contents of +-- the player inventory changed, instead. +local function poll_new_items(player, data, join) + local inv_items = get_inv_items(player) + local diff = array_diff(inv_items, data.inv_items) + + if join or #diff > 0 then + data.inv_items = table_merge(diff, data.inv_items) + local oldknown = data.known_recipes or 0 + local items = get_filtered_items(player, data) + data.discovered = data.known_recipes - oldknown + + if data.discovered > 0 then + local msg = fmt("%u new recipe%s unlocked!", data.discovered, data.discovered > 1 and "s" or "") + 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 + + hud_notif(data.player_name, msg, img) + end + + data.items_progress = items + data.itab = 1 + + search(data) + set_fs(player) + end + + core.after(POLL_FREQ, poll_new_items, player, data) +end + +i3.add_recipe_filter("Default progressive filter", progressive_filter) + +core.register_on_joinplayer(function(player) + local name = player:get_player_name() + local data = i3.data[name] + if not data then return end + + data.inv_items = data.inv_items or {} + data.known_recipes = data.known_recipes or 0 + data.discovered = data.discovered or 0 + + poll_new_items(player, data, true) +end) diff --git a/mods/i3/src/styles.lua b/mods/i3/src/styles.lua new file mode 100644 index 0000000..9b36930 --- /dev/null +++ b/mods/i3/src/styles.lua @@ -0,0 +1,146 @@ +local fmt = string.format + +local PNG = { + blank = "i3_blank.png", + bg = "i3_bg.png", + bg_full = "i3_bg_full.png", + bg_goto = "i3_bg_goto.png", + bg_content = "i3_bg_content.png", + bar = "i3_bar.png", + hotbar = "i3_hotbar.png", + highlight = "i3_highlight.png", + search = "i3_search.png", + heart = "i3_heart.png", + heart_half = "i3_heart_half.png", + prev = "i3_next.png^\\[transformFX", + next = "i3_next.png", + arrow = "i3_arrow.png", + arrow_content = "i3_arrow_content.png", + trash = "i3_trash.png", + sort = "i3_sort.png", + settings = "i3_settings.png", + compress = "i3_compress.png", + fire = "i3_fire.png", + fire_anim = "i3_fire_anim.png", + book = "i3_book.png", + sign = "i3_sign.png", + cancel = "i3_cancel.png", + crafting = "i3_crafting.png", + slot = "i3_slot.png^\\[resize:128x128", + pagenum_hover = "i3_slot.png^\\[resize:128x128^\\[opacity:130", + tab = "i3_tab.png", + tab_small = "i3_tab_small.png", + tab_top = "i3_tab.png^\\[transformFY", + furnace_anim = "i3_furnace_anim.png", + shapeless = "i3_shapeless.png", + bag = "i3_bag.png", + armor = "i3_armor.png", + awards = "i3_award.png", + skins = "i3_skin.png", + waypoints = "i3_waypoint.png", + add = "i3_add.png", + refresh = "i3_refresh.png", + visible = "i3_visible.png^\\[brighten", + nonvisible = "i3_non_visible.png", + exit = "i3_exit.png", + home = "i3_home.png", + flag = "i3_flag_anim.png", + edit = "i3_edit.png", + no_result = "i3_no_result.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", + cube = "i3_cube.png", + + cancel_hover = "i3_cancel.png^\\[brighten", + search_hover = "i3_search.png^\\[brighten", + crafting_hover = "i3_crafting.png^\\[brighten", + trash_hover = "i3_trash.png^\\[brighten^\\[colorize:#f00:100", + compress_hover = "i3_compress.png^\\[brighten", + sort_hover = "i3_sort.png^\\[brighten", + settings_hover = "i3_settings.png^\\[brighten", + prev_hover = "i3_next_hover.png^\\[transformFX", + next_hover = "i3_next_hover.png", + tab_hover = "i3_tab_hover.png", + tab_small_hover = "i3_tab_small_hover.png", + tab_hover_top = "i3_tab_hover.png^\\[transformFY", + bag_hover = "i3_bag_hover.png", + armor_hover = "i3_armor_hover.png", + awards_hover = "i3_award_hover.png", + skins_hover = "i3_skin_hover.png", + waypoints_hover = "i3_waypoint_hover.png", + add_hover = "i3_add.png^\\[brighten", + refresh_hover = "i3_refresh.png^\\[brighten", + exit_hover = "i3_exit.png^\\[brighten", + home_hover = "i3_home.png^\\[brighten", + 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([[ + style_type[field;border=false;bgcolor=transparent] + style_type[label,field;font_size=16] + style_type[button;border=false;content_offset=0] + style_type[image_button,item_image_button,checkbox,dropdown;border=false;sound=i3_click] + style_type[item_image_button;bgimg_middle=9;padding=-9] + style_type[item_image_button:hovered;bgimg=%s] + + style[;sound=] + style[nofav;sound=i3_cannot] + style[search;content_offset=0] + style[pagenum,no_item,no_rcp;font=bold;font_size=18] + style[enable_search:hovered;bgimg=%s] + style[exit;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[next_page,next_recipe,next_usage,next_sort,next_skin;fgimg=%s;fgimg_hovered=%s] + style[waypoint_add;fgimg=%s;fgimg_hovered=%s;content_offset=0] + style[bag_rename;fgimg=%s;fgimg_hovered=%s;content_offset=0] + style[btn_bag,btn_armor,btn_skins;font=bold;font_size=18;content_offset=0;sound=i3_click] + style[craft_rcp,craft_usg;noclip=true;font_size=16;sound=i3_craft; + bgimg=i3_btn9.png;bgimg_hovered=i3_btn9_hovered.png; + bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6] + style[confirm_trash_yes,confirm_trash_no,set_home;noclip=true;font_size=16; + bgimg=i3_btn9.png;bgimg_hovered=i3_btn9_hovered.png; + bgimg_pressed=i3_btn9_pressed.png;bgimg_middle=4,6] + style[confirm_trash_yes;sound=i3_trash] +]], +PNG.slot, +PNG.search_outline, +PNG.exit, PNG.exit_hover, +PNG.cancel, PNG.cancel_hover, +PNG.prev, PNG.prev_hover, +PNG.next, PNG.next_hover, +PNG.add, PNG.add_hover, +PNG.edit, PNG.edit_hover) + +local fs_elements = { + label = "label[%f,%f;%s]", + box = "box[%f,%f;%f,%f;%s]", + image = "image[%f,%f;%f,%f;%s]", + tooltip = "tooltip[%f,%f;%f,%f;%s]", + button = "button[%f,%f;%f,%f;%s;%s]", + checkbox = "checkbox[%f,%f;%s;%s;%s]", + slot = "image[%f,%f;%f,%f;" .. fmt("%s;9]", PNG.slot), + item_image = "item_image[%f,%f;%f,%f;%s]", + hypertext = "hypertext[%f,%f;%f,%f;%s;%s]", + bg9 = "background9[%f,%f;%f,%f;%s;false;12]", + scrollbar = "scrollbar[%f,%f;%f,%f;%s;%s;%u]", + model = "model[%f,%f;%f,%f;%s;%s;%s;%s;%s;%s;%s]", + image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", + animated_image = "animated_image[%f,%f;%f,%f;;%s;%u;%u]", + item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]", +} + +local colors = { + yellow = "#ffd866", + black = "#2d2a2e", + blue = "#7bf", +} + +return PNG, styles, fs_elements, colors diff --git a/mods/i3/tests/test_compression.lua b/mods/i3/tests/test_compression.lua new file mode 100644 index 0000000..7e5bb73 --- /dev/null +++ b/mods/i3/tests/test_compression.lua @@ -0,0 +1,4 @@ +i3.compress("default:diamondblock", { + replace = "diamond", + by = {"bronze", "copper", "gold", "steel", "tin"} +}) diff --git a/mods/i3/tests/test_custom_recipes.lua b/mods/i3/tests/test_custom_recipes.lua new file mode 100644 index 0000000..acac746 --- /dev/null +++ b/mods/i3/tests/test_custom_recipes.lua @@ -0,0 +1,338 @@ +local mt = ItemStack("default:wood") +mt:get_meta():set_string("description", "test wood") +mt:get_meta():set_string("color", "green") + +local mt2 = ItemStack("dye:red") +mt2:get_meta():set_string("description", "test red") +mt2:get_meta():set_string("color", "#ff0") + +local mt3 = ItemStack("default:pick_diamond") +mt3:get_meta():set_string("description", "Worn Pick") +mt3:get_meta():set_string("color", "yellow") +mt3:set_wear(10000) + +minetest.register_craft { + output = mt:to_string(), + type = "shapeless", + recipe = { + "default:wood", + mt2:to_string(), + }, +} + +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 { + result = "default:ladder_wood 2", + items = {"default:copper_ingot 7, default:tin_ingot, default:steel_ingot 2"}, +} + +i3.register_craft { + result = "default:tree", + items = { + "default:wood", + "", + "default:wood" + }, +} + +i3.register_craft { + result = "default:cobble 16", + items = { + "default:stone, default:stone", + "default:stone, , default:stone", + ", default:stone, default:stone", + } +} + +i3.register_craft { + grid = { + "X", + "#", + "X", + "X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X", + "#X", + "X", + "X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + + +i3.register_craft { + grid = { + "X#", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X#X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X#XX", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X#XX", + "X#X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X#XX", + "X#X", + "#", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X##XX", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X##X#X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X##X#X", + "", + "X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "X X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass 2", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#X", + "X X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "#X#X#", + "X X", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "#X#X#", + "X X##", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} + + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "#X#X#", + "X X##", + " ## ", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "#X#X#", + "X X##X", + " ## ", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "#X#X#", + "X X##X#", + " ## ", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "#X#X#", + "X X##X#X", + " ## ", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} + +i3.register_craft { + grid = { + "X #", + " ## ", + "X#X#", + "#X#X#", + "X X##X#X", + " ## ", + "#X#X#", + "#X#X#", + }, + key = { + ['#'] = "default:wood", + ['X'] = "default:glass", + }, + result = "default:mese 3", +} diff --git a/mods/i3/tests/test_online_recipe.json b/mods/i3/tests/test_online_recipe.json new file mode 100644 index 0000000..aa08e59 --- /dev/null +++ b/mods/i3/tests/test_online_recipe.json @@ -0,0 +1,8 @@ +{ + "items": [ + "default:stone, default:stone, default:stone", + "default:stone, , default:stone", + "default:stone, default:stone, default:stone" + ], + "result": "default:cobble 16" +} diff --git a/mods/i3/tests/test_operators.lua b/mods/i3/tests/test_operators.lua new file mode 100644 index 0000000..aeffc55 --- /dev/null +++ b/mods/i3/tests/test_operators.lua @@ -0,0 +1,26 @@ +local a, b, c = 0, 0, 0 +b+=1 +c++; local foo = "bar"; +local t = { + a = a++, + b = 2, + c = c+=2, + d = a&3, + e = 1, +} +t["b"] <<= 4 +t.b >>= 2 +assert(t.b == 8) +--print(dump(t)) +--c += 1 +c*=2 +local i = 16 +i += i<<4 +assert(i == 272) +assert((a+=2) == 2) +assert(c++ == 3) +assert((a-=1) == -1) +assert((c^=4) == 16) +assert((a&b) == 0) +assert((c|=a) == 2) +assert((1<<8) == 256) diff --git a/mods/i3/tests/test_tabs.lua b/mods/i3/tests/test_tabs.lua new file mode 100644 index 0000000..376bfd9 --- /dev/null +++ b/mods/i3/tests/test_tabs.lua @@ -0,0 +1,34 @@ +i3.new_tab("test1", { + description = "Test 1 Test 1", + image = "i3_heart.png", + + formspec = function(player, data, fs) + fs("label", 3, 1, "Just a test") + fs"label[3,2;Lorem Ipsum]" + end, +}) + +i3.new_tab("test2", { + description = "Test 2", + image = "i3_mesepick.png", + + formspec = function(player, data, fs) + fs("label[3,1;Test 2]") + end, +}) + +i3.new_tab("test_creative", { + description = "Test creative", + + access = function(player, data) + local name = player:get_player_name() + return core.is_creative_enabled(name) + end, + + formspec = function(player, data, fs) + fs("label[3,1;Creative enabled]") + end, + + fields = i3.set_fs, +}) + diff --git a/mods/i3/textures/i3_add.png b/mods/i3/textures/i3_add.png new file mode 100644 index 0000000000000000000000000000000000000000..68cd3ea1deaa7e1fb7d9e8af3ff4d1352ae63c3f GIT binary patch literal 2134 zcmV-c2&wmpP)7la6vwCX(H1Ds7D&VU=aip5Q2$9-AIM7Ko}Kp zg?0gm3YcoGl4wa-04+2@%4bST=?87;Ym4Wa-^JTurgUCso-J?jPhQ^Kx%Zqi=kwlk zE!(!OD3Jh$2}TH#1>*(J3tke;5#$S23O*7X68tQGFK7ez`R@W_zUG~k%%SF* z#@ypsYXoa+I-=rZAk04p5u*fYf=ofKV4+}@V29wK;Dq3;;F93Fph3_ocqoW~hy2&T zm`l8)-aWuvE17#1Yo)RF2xv)&g#a|;!}$t|h$(`(f~A5F1p5Ui1%C;y2yVexGhbUX z-Yw_>-G(6A7~8R+L8_55QqR0P_NN~$vC7Hg584C zf@(pXVb@(AUpZPhg`xe062xU_D1oLq&^Q{J69y`P1e{C?j^}kjk>DFaC7!$4U_20L{Fzt!&h6yWlvssGL;0!=XKj5lqL~4lUKtwjElt zp}kKb^oRKu1&alrpl(+MO?-h^GwvmbhtQ;GJ0sXBcnjM56hdD%pMn$>^PdXJ1huGL zWDqd#rVTCR5x+q5Vt7dL@(Etvel&Kp2x+PbZ{U0)gM@K6K}4YO1~l)4hfH{SB09Lm z`D8rlJnZQVQVp8<9-raSuMn<7`*xi7WWso_Ji!!zPI4v?PS)d8t{Q6J6R_HLIl^X; zLTG{Z<3z66@TQZcUINf|KbC}I1!1Kc=Mo8lK%MgH6giAFnuu5`b6hT%?(_#v)z83Y zN{FouhPMxjuucfOM)h}r-%UIVN(eeSG{DPlD$5Mh6wHv9Mqa&yz}lwGtQ}rX2{s7w1gW};wD63hsH~Qe+gAr{_nH``>VFH43RY9zF68%7 zp0$M_^k#VaisCH`o`+k;*Ply;RY9H|wCZb{JTKTql*tD31;soI+UICfQ1!}hg01kH zE=aVn{Y+}?BUDOYtSpm=*=IKu*q?dB69tADft z2+Is^lk9D_IDj}i0Ll0C1KJDMK&UcPeU}CsLbG;V6R2ycZqDtulk#t z5fLVLgWm7I!^X-QiY_gH9R4d~j6Of`nlBRNri>X4l*yM`97SD^A_X<8x+W5s1`pK3 zn6ka^1%-l_sXoW@yO3u!jIHluzI&|cw~93D17-5RTU29yt3Itt_sQSSV@4I&u@mKd zUB%!&BOf0FviNTwW6F5PZLSK|I?vjEt4PxfE?ZPees+7zy#69Z%r4T~BAl5MYf!-8IVC)f6_lq_i_}YEI;! z>RAT!!+;h-7GrWe=9tMExfD=p?NVrI^U1@%JIR($JJQl?#&k+Zqq8Y$QjP3xoD0UH z@`;Y4Z7qZ`jB$Hc&zs6x+2k-K(Bj95KlWeGf&e}rr~ra6f%!w(1cGpa#W8zQaF4H3O1_Gi3qiA{^cP0^D? zo!ofc7T<4fi#rcS>H$K%TOzcjx7K|)uNrAC89 zX%tnR-v)`F1n;>uNH|+$@@Xfjbfl$2wMC|$W53Ucb}u+vWSq^Bs*$JwXHgXbVgFZ? zRDoBMl(S7PotCn91;?I&Ho0R)n_RkAo1AG1Ni-Fz=E7|h4YfnCQL+}=xAnJC(ydiC zpPacYq;Anzw94l9w^g>UX6a(Pce8Y-J$Rd?YoRr&W@)c>`8Ne0+e4#W{xn*<*p9MY z-c1NoQKfA-l`6u^V7f4&XgUs!`St)WOg!z%%n@Si4ZHW1nXm=nygSrPl2Zvy>!C5z z4&cg+*QKf1#8j17{D|cLk4sZ^r0l1lWjVA3dTGk-+FUx@*bC4Gn@AJ|V`oOBb08`EAFCx2zFEv%hK3ZG(! zcyZG0>TD84MHZ#>5^DPW^x;+VrEbGO3l7Uo7$(#0jBVuI8r%Kq>>Sokg_h8-&h~YA zIvry2*lH>y6dfikowNVDN31o&d3pMQ@ujcuj_+oo0dH;a9J9zMR(9D0A8KcJTq3h&r=E`O6iL8|v?N>MP59Z+(%vagBkN^Mx M07*qoM6N<$g0ThzBme*a literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_all.png b/mods/i3/textures/i3_all.png new file mode 100644 index 0000000000000000000000000000000000000000..c404271e091af3182a2af9f16ed5666fff8358d4 GIT binary patch literal 2346 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 N002ovPDHLkV1h-N>P-Lu literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_armor.png b/mods/i3/textures/i3_armor.png new file mode 100644 index 0000000000000000000000000000000000000000..f838673c648883b56b59dd6dab6fc2c319e901e7 GIT binary patch literal 2473 zcmV;a30C%rP)i7yghT={!6;g@7#H-PGBqiS;5I=-T_&(q z*j%~id`B~rMVWtT7LD;oGIc6O1Dj66)C@Nmu3D^gg_hp=Jm2>mINY6k+upWUisvM6 z?rrb6-}}7J_kQp9-Sa)4=hf-TWHMeyM~7!j-~}eg!WO|E4~+i}yk4jOc}tco@h-WG z!QXY)$Gk8!Bp`=CuZ2Abdlhy9wga}%7?b5aot+=C-?=0LU%7H6f;I@g=$X)O00B$T z>%9uTBqIquu$y>K81BctfwyACikV47TU(pAZTmJaKoG9i4ST)C82=6s@B_U6w*r4% z#`pcO@8h0#frPmxG&z`UC)*BZt>#9-rjwC&jn_K0|2IH zV9pzR3dVp7u-QoQD^=LuuhjmNdi`ud;N`}9PQsptJp@|^YqxEpZ4gkfgfKfUz~HdO zu@XCDsOe%g4#O}CtN}KQ0N~_uIGY2fO|ZGJ`LL^DH{$a<@cK!B4eyxx$0sIy014!i-1fHScJ!{5?UR!%S=R-j9`XUqwo@xV=x+x&_u4@A1{ES4TxQ54#TkYcOuX1XJ&m0!}Q~Har z4}yTpH3Tjx0xGR1qG@(enerS+S!9RE{{aC>_A&@q%ymRcKuSPLKuSPLKuSPLKuSPL zKuSPLKuSPLKuSPLKuSPLKphC!e320F)))bs>qtPb)opVH|0@Fc;PgchaD#g$Xt7M& zzQBPp0#0equBE1ir-lIT3;x{hAGn>T7GXM7M!x84NM|347?CxXzQ zZTAj=MVR87qXWX;R2uq)>F^!5*7?Z)W}W?3vr z7>$+6@belpLT+O+C(**o2_Sw1yB;92EQS*mG}cH!Nm``!+#0jKi2+!&n^Zna+!pB# zCw#44x7Lartw_oQzbz9z5lEk#4udA%w_(GE36W3(0ZRSgE4HvXy+MOka#dv>>j;Q|#Nl*LXH0SxY+8267zXPl)^`j$wdT#+^)%*0;1 z-1fYR!w!Q(3640`d=H=B%=<_}$E_VxO+ZPyVpM&b?pa~FnZ6U`JH&X%roU65)UFg= zwQ7~q`npu>PDr(q*#5Q^I-9_bH)g_EtdEm`v-*4|?9DECt2Vz$J_i!;^tq+F8=8z^ zQaWI#>#167N?L(Y9l9vWgiV{es**4U0VVAMKWl}LPD+!Nh-#61olFo&O}aS0;o=l0 znaX8W-{(Y0qX~eypZ^4f(Qw>IdHiF&U-xpk+(Zc&kuKnIwDk@xa~VvdMAuKqS1Dl& z{RO8%$*Mc&vQAKQv&I}AzAbC{2 z9}pIM=!zJp^(qt!aS~bq`qL^tBUSW0eL5<`!w(ChnSzB9mJ98P5L@9{?bqqvzA8H5 z5$n_WZjFK`wz^#BNO0q=MYF@fF^aZd!QSpfk;Q`TdHde}uSfTs8RJ;Z!ANm# zG1N2o3x}KDmepcsXQw5>jYU4C z@!zZGaVN%kP^#Ken7;tOt2Q~@th}B+FRC+zJeWj1uR9=FY~c9-Et-BeMrv0ZD!)e? zoA?XR9jGi?9~bTMT9*wUCIQi+X^#6P=|8F!-|#q(*1SYXEWZ1;z^*8LJHOv~XXnf~ zNy>%D-hDmMSz%0X{#91n>kc}+T7ifWO?}h^Z@_o>pfk@ldiOu(H8(eVGwM2jZus0O zQvR5_UdQB~R~2y(DJc$Zqt z^nE{{_=S*5+Lxcr_doy0SWt4&m22tEiw+N%Pr}~|yp#Agc+Fui z(Ap?bB;eb{xdruI_c&6*Z<^xFjzeJYrb&Xl=n<) lc)9kta_0weipn)GT8EXaKR@fuE}&x=JYD@<);T3K0RUo;Mrr^6 literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_armor_2.png b/mods/i3/textures/i3_armor_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4aeb3ce1cb018879576980c4732f4d86d5e7b759 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJHcuDFkch)~uU_Olpuoct@Lj8f z>3jU~f8s};6df~ms*l=Zqhh-D?v{Dm`A-M)f8dW3UFLj=Va?*!;wKE(-d}rmg|%Wf zr>;fo35K-R8@}P<4Eyc*Hpo5Ya@o&*i815BwvRf@9fw{q?wRnL;YGlwch{L+);}re q<5BqayRx{HVNLJtG)F6iIRRoA?yA6-n*lQ`r7O){al%`l5yJ8Jxs|Rts7Kb$>o$mLlu$^@y1O9|OZY X^UnL1Rxf7+x`4sc)z4*}Q$iB}sz*EF literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_armor_4.png b/mods/i3/textures/i3_armor_4.png new file mode 100644 index 0000000000000000000000000000000000000000..f08dd7cfca83fbe765277ab0f7004761f6a3a478 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJJWm(Lkch)?uO#v@D6p^ve9wB# za`(SgY4Z<>pqqbst}88)PuODjOz%G962{AnG0Lx5Uol=#-ywgX@zAx4vI}BQS2M&s z+%UV|!NTD;<5kuO?yJlm?WcL?u{kWgv{2aj6ypxI4_0!_4#KwedJk?!v|s(&@WG5R Q0cbOWr>mdKI;Vst0A^i1-2eap literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_armor_5.png b/mods/i3/textures/i3_armor_5.png new file mode 100644 index 0000000000000000000000000000000000000000..413edb61aee12e00753edc413e62269775e68780 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`A)YRdAr_~T6Am!1d0X?Z*?@Uv zS3;6OVNI5S$pd4a)mAlrN0v+Gam4Z-co|z1+qftrf%iZgG_6Lpvitma4P oKQL_&2^W~U(__=jNpE-<8kb#?Eiu2<4>X^_)78&qol`;+0CspTxc~qF literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_armor_hover.png b/mods/i3/textures/i3_armor_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..4d94503747612a8deb3ccd94b1cf63f3f0d665f6 GIT binary patch literal 2656 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 O00008-&SBJAYmW7_JPS Lu6{1-oD!M<*erK& literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_arrow_content.png b/mods/i3/textures/i3_arrow_content.png new file mode 100644 index 0000000000000000000000000000000000000000..f7fccd5230b1e30491c797f38beb4a404cdf43a1 GIT binary patch literal 1306 zcmV+#1?BpQP)Zy zAdfw`IdfZL3cykS|IN%QfINP~WtrL%QveG12hU9vG_Cd|c?n1}K8 z2CyxJuu!ye*n#DkRAT@aU^~|1B222ABgLi&`9dG-IKIM?TKzHsU@>;16W`zloLCnK zSc@b504T&uZN!3F7^D<{Jt^qhaW_t`xh~*w92x*XJ`B=&oL}uo=mS9FNB#^`Hm9bZ z1UF*u007buHegXTA@l#GrOsZBZ(NpSy2CB5#u=5QL1du#)4_>aSX~HS^FiK;EGFFljKZRm1jEEXnBLK-W z58?eN=U1*pAug+MpiBViU#0`!;=!mePsfD8UTz2ginZu^Osxn4#$kR4P45sPBzbx; z?DZ?S8mC57G*=No+Nu7C`zkg~VLhKNQw;lCz4#Zq@DU!yrI-~e-inscpXLexq)pSB zicC}LP_nJUC@2oquE^QHumx|%u5(+|ALrxR63p0ODYy^qVVWjZ5(Q6GparF*NM}UZ ze*7I^c2xm-VwyJN$|0Gi(1Nq^dE{52PAgx<&q++v?L#t6v8}8ef-e|Js|P#rSm;hu zIRM6DCZ3PnZBz)kNU_&qTOMC-Dx8B)OFSct)Rhmt`Jimm6eeaFw)RmoY%~Z-rD=It zrYV&4*08$04GbY|n(i;zG=&~a!#&YA%r!WK-q>=V!I>qM_yR&3?v3MUqent6JjgmM zDraYCi$dj&e#+>L24Oc|Eq8mI8W#4uK3ZyxB#Qg-78aIklE#KGE{*!ZfdF)4X_JTuip@6sSVfR<2cQAk8mGQ-HubF#6---UHCH6qI(2=`GZkD zTT-*0V}O_(Y4J$(6Za0YP$o+MLY#1G-*t|(XpPFu3cQ0~LUlXq=pmA_{XzWwT>Nb4rzl{Ly&MEw!F)C?_f=#mmf!`rnEehNjKoZf+QU^2neR=v&5f1y0=tqSc> QnE(I)07*qoM6N<$g03Y}^#A|> literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_award.png b/mods/i3/textures/i3_award.png new file mode 100644 index 0000000000000000000000000000000000000000..680af5eb5c04656cfa4f245da0123c3523f501b7 GIT binary patch literal 1259 zcmVpajCSPS`rEiRk z2V22gFbIYnW{_iV;atXKhc5vE^1waNtH5|28T&4nqC$WI@Iuk*>kM!X1*!yirC5ML z&LJg0N`RCADFIRfs1Trmp-5#IY)~b@Bv1vufhg#6m?+1t;#?dTU>sNiE`Zyh)?sAK z^I$RO;RR0TPlgHM$JNspDC1;Ip+X)_Z!ma7B^fN7u%9JHA-jumi|06{vV zCeUp&O&lxeCIQ3|Edy;1#Qrvpm6j49C4jqpz)}YVSn4((ARf8cfdZ*s2%YD)C?I5k z{h$$af(RJ0z~~{vzQ2)UWVvx8b+&;k;LRAtFdE$qZh#$NKF9F8Q2^uXkiiU1 z7vm~;N24?o!!@>fZ!mfR_x%&BdhDId1#~ecgHlir{=~e~MxXJAZAy9WV2jZzk|9Y~ zSAox5WsSSK*QDEU{WIH+OSWXl3`t=2f*)Mz-{2x&5#bWA4O5H*Onf{eKsGoHe$mJd zupWfS242&}InP|*GXltJ9sxfMtGo})Ap3c3m~D=F?Fo=o-UwRxo=cc(0oN=4{cGVh zjcqpa9?uBiXAWP>J%JwUBQbjf`TGvr`n@E89tl>0XFS%{V&Z=H1W-{E4AH=s zG3N;bytdq_M_-iylEE$HPH!k?>nqn5Sy}IMqX6RB4;ehZk#7E$=~V$_OIu`eoTh*6 zQDpb_SCs%^uoHBdBtu3oc{nF<&4Ff$rQF+|$j;yshuN0@yE-6lYQlgnlPE{}N$SPOQ6j7(aUzpi_ry;%c@bMUL6k&k(_OP!G_T9*_ zE`!~iLr{ePQu4aScQ!%?W@}S`>8o>d?!E8DNMu>S`h^bS?+R51f%h@R7QbV5l-=u)EqGW9GGcE z&R}JtBO;u%(I;qp%FbG4ywy8Fnb34l&J$eC28VZoekb78t+4*BP&qR@%_8H!aYs1a z>QvdTynhb3KT75oFa7LmZZe$>%Eshr%sJp#kv^Uzve|K306)W1vxTpK^flX#8i5@G zq_O;M<>xYO>@zJH1jyhw0bLdf(8WG8l0g8e>K-)eIU=2f?7`2)w#V!B& zj>xu1U`Ii836HpqlkcP9HDDe8k54*{@$>I|*8OVOwl7AAR`wlqy8tCztpTp4gs?iW ziH3*%vxls<6We{sp>j V#x-ipHl_do002ovPDHLkV1fk&L`(nx literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_award_hover.png b/mods/i3/textures/i3_award_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..43e87253d0f06afcbb0d96a85ea754b5d40fcb55 GIT binary patch literal 1263 zcmV(cKdti(S0gAzML!<8;z3fA=DFI#@7NC!P z$Ow=TAR|CVfQ$ep1gPUwWO5p;GbO-ia0Pq^ouJEOI@$IW_Qi7nhJd-?G`I!sc#O1p z3d~_&JQqO70fk(OnxK$<$TB5B%A>NfAQ%DiH8X;3`AUFnPy#B!Zp~D(t!zID5Tr9| z0BxFSU|T^y2_TMWK4|t}?r&yWIT-;m0{F`Z%=1uyd4BT&;*qC&kRWvuq0{^}3kU^Z zC#VPCKm_zFFuLEh?yqMX1%6xz1=ukeoekhTcs)ol+(tKoYhV+Y!8QVZ6u|vD;B=Y9(yli0Y{7?uo%>Wo|t#q?K650t77?N;x z3HZcOwz#T$McQ2FKe6l(JH>*bct`-V9sJ}-{|0CHiU?r4(n$bkCRhZXa$DPqng64_w$Q5?z(h_kL<3*M z>?ic{+ybv2eNzHR1UHK-z5bY`ubi8$GT-M%0mQTKad~|A(Z*}}=_-IMY0Kkmr#WAH zly+mpx*?@X6HsRewW9*0xSnxz#(uIJOds78GZLt z(7}7IvW_jRvx04mWt(})I?QB8T0HhProSFCXZMAX-47ZPrH4<%c((|>ytjjOwX*Jd zwsj6{Wgmhj1dx>1MZU8UIxrPU&_wcu-E6akeK7KY#CWE!On)L%%f5InfMjP6B;eU~ z9n$7k_MyOp0NHd%$N7F*9vlCSpXZb%;|NvE0%c5hc_o6|_(>*bfmjia@{zPWF#aT% zs3K-i8R&=zM>P5bi%;1JRmQ7c2}*}1fP>t@wKO=q!}L4KqD37cZwW;RD-yxt9^oMh ztTa^C757g85B?MRC3&Ox4 z5Fm%?Z+ zME^P>taDT<2rv#*$C&|~&tN_><0E{akyf0Upqh32T7Y;nfMd91b#8!VoZ7^wrQ9k0 zJivEE+GYYB3DLRS;&ykwi-unZE9}4j@fk{E0{lIWdB5u{+Z7{36YCE8U4ROXRxd|W zrm(wU4Gj+sFp2?QD`wfdytk8eHL~uY-+h2Msw(iFtHF&7U_uE#zK#&3ytjsRRq1eo Ze*m7d$3rJO8HNA=002ovPDHLkV1jEqKlK0r literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_bag.png b/mods/i3/textures/i3_bag.png new file mode 100644 index 0000000000000000000000000000000000000000..7f0a9f1bd1cb54fb0beecf52184bdae476e20ab3 GIT binary patch literal 2338 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 Y1?=85%0znp3IG5A07*qoM6N<$f^ZL@od5s; literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_bag_medium.png b/mods/i3/textures/i3_bag_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..e752801b77887da0b8cb8415bcf8d75df443dc49 GIT binary patch literal 372 zcmV-)0gL{LP)3Sda4f?gT#;xFcyT+0<2gJ06DG3&;0+k z;vhIiw;g5x$aNU5fZ2u|aG)?j4@eLVQjcN)Of$&;Ak$$OBo?D5{y#v88^Zt?4L1Pf zcUTO7yaK{4VfNsV2g&=$v4b&I1CX5wO9wFTgsAbOL?tW$;Re7ofoy&_F%#?!5Djtx zvH>s}s{wLckdQ_80(uPKH2|a-WC+ZuFbwlENHYk7G=nfG20#{~_#YPc8CJ?*oMxej z)c}k%08&ustb>txU^vH41Dt?h&c~Vxk#if!R*>x=4AKbGjGP8=W+p-yn?3+R%ONqR SG+09b0000AKaOXx!q@=ju z#=mpyJnueQqebnhr}urI_xC&J{LXoVsKheV2;}y^ny+FWoCVxi9kAg~U@Uq)4&x=c zgvW!R1lkyGmq2_k3&Mhr^C%wn7qK(x!bNyWHZQxH(OF+cMUI`!NGISh2!whq*dFh} z`j8!MdI7CUV9@jn2mx3`fMB;7Zi|pg*ue89jRKG<#btCFCC#51>719vw+Uaqk(=Y# zbV6=bl>$-(KxE2)KV3m`ZY1C6cQ#@p(uDNGSSw)H7Zi}a2!O@~ zx=gs)@=E6TScjC)1i01Jiu+6^E4|c2x=yng9doCAp3T}c5`gRr9gXrn@c)l7l7UWh zZWeO(NWWFiuFFU^Ysz0|854`iXw@pSW}~aj`UXLa=>9SE=A8fl002ovPDHLkV1nl+ B*G2#U literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_bar.png b/mods/i3/textures/i3_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..164b256d234e4518f298aa8656aed19f8538eb2e GIT binary patch literal 209 zcmV;?051QDP)lXz1#0CW_R8xd{=yZCwtFk zWc;f-u-xL*gxNeTDtoXN>0F?lj_{;#K-9c>tKkp3h+XmD^8S=lOdtrN)a9 za8P=m@Q!L37l=3+2M_Bu7_2W2G|o6e)bR8#%;KIZeX~C7Z~k+?S6sa@mHz`t00000 LNkvXXu0mjf@mg9D literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_bg.png b/mods/i3/textures/i3_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..1cad26d493e106a4df776c0f5fed3279e0896fff GIT binary patch literal 70 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 QyaG;DQBwgZXBPf{08M3r4gdfE literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_bg_full.png b/mods/i3/textures/i3_bg_full.png new file mode 100644 index 0000000000000000000000000000000000000000..9f86d727590126684fe6b14093805239b684b7a1 GIT binary patch literal 2031 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4YzZe+Uw|TlahE&{od*@*8AqN46 zi@AqGf3!^v)++FPcc8T3+rg_ldO{{h9-SD#67jI5{Jxhz*MgX5M)C%FPankC*|i(A zn&v#@W~i{fy>E4KI{(wF!vAgBjyfYwK;FkI+UWKJ;R zV8}Q%g>i!v3xi4OS%!k@c!rGAVLXfsx0D$e9Kb$e5MW?v0J2yZ7!-gMBLf2mAt@4- zgMtof2{EQ4DMz>oVFW^qpgTb(u{0=>>OCX}41jxyj|L=n0t1Dp(7+bg0t{{7)QwHf z0hl822R(_=fv|)E_mUZ*3P8`06`>9c62P3#z(6=O5Z*&rhE0qplMqG_rM!UwmWfGJ zjtCTl5eP8?@elPKV*&?*0?+|uhA*L1h9e9qa4)$T27hkA;Z9H(j@*LCPm*D_BZEWm zHlBv73JeQ0v)K-$2ryijqRE_K0IHt?J{^(oPGoQpp7yEw(ZLL0)zz}`&b*2wGZBUr zw_^UytJuUHeweXA>uKNnQ+tK=zbG*O3*y-s z4p=_rlRv%s`KRLf4SOO3?ipUlZDxF6oBMm+xw*D7Z@=enx9C^<(rc{>Osx!_u6{1- HoD!M<{OsO2 literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_bg_goto.png b/mods/i3/textures/i3_bg_goto.png new file mode 100644 index 0000000000000000000000000000000000000000..6f69b91c7575bc6129c6b04c41c37b2539c6d47e GIT binary patch literal 1858 zcmZ{ldr*^C8pcn!NPt54N<$O~3E(Oy7bDklNhu}-Ef)m?$gOBZ%;Hjo6hmM!i$X$# z1SpM2mAHfzP%fsW0tJyFNIBo#SwmY-`yw7>hIdh)hJLf%f zat{Yl4D?L(000ID{YfDJXjs7GOyo8=CRT0#6aXFFgQU-oGJkzO_62{`?-QT?@S+n9 z;YC=jZkxnD8=v8#G~!rTywMYfZ+RyRi#*F;o3jg|YEj2g%$10W&@)cfM|IF_9f~FZ8->BA z(TZz`*&#W8k&qQ=&y-pRdtH%t$%F$o)p`OciNQqyW|?w3u8+#B;R(vVHYGqiID33m zcnAmXEGerr#ZP}WChRxEc_%tORN5$}4tt$1;R;-g(O_azKW}&~RC3PYUG%#o0#SI= zxK`=zd{;qYBMrbv0=FSc@dbpP^<&$0$>`5|>&q3Dq6@!U-;L4L1Pji7nVZk$I8K$j z;R+#1oYMc%?7y{>#i&)fl}V&N88tbm3o@K-tzvm2%**pmX0(iHE05BZbCKL!Rv_i8 zvq%Vx+$WgF=1edz_r{}NCWb2RVS=3c{~I|#z+g^jg0f!bnN4%3UK&=0sK$u=qU+Y0 zN?F%T+H7vAOJ2WywDH3QS1=Nj7;WD98S3#_JJyXK)z0BK1{zVxpHO-a6}2r=l6G-& zk-)32p0f1fdH3}k>8n|Fs&-=MORBwM$bsfq{7T(~EO0RvC<1&c2=3o^1Ge`e>c2?S z-E;Rvu~Vxr4yDESjv#55NPFFd9pa48`8M+zLt+1Mi7i-=4^eHT#*S1*D>+?4pC`s* z61{~cSA;9)N=6@_+1fESNVOGBjoN-IZ;DT42~{T3kQ+>X3=K)qZo;$ADCDPjNy57b%ih*SmpD{zgBP0Mb~4@!5znH2v6tc zd$>OvP7P2so6Rk7X5JwYU>%K*cYJg`Y>v2&OB!`_)6rz3ZshR;zv0_YN={)pbRDn| zl~_Cb#NKt$)FSGl78tp3sfJj)dapwhsF~2mQNAQ50N#@RwWnhp(z#E75st3d2;=C0 z_Q#iWz@4t)9?miV<1P_!wwwtEycYnIi2o5J3b1cd&lAuVpuGixL(x%hJrrDzE(-X- z2C&;-#Rz_M@Z<+!!!B_4CxN}TvJbN5{2t){alD6vakdyg$i$Hu)e)FO5DbUL2p8=w z#x2mlI=s)ePDv`thRgpO-gQ%C4}&t@?oAfHr6SrncfWp8*a-VCOT^;YW-`1MVP@G3 z;bJV4n+6O4=);-aKA;dTckj(~^aF95l72nGaHL>S@h;z3FfGysWxu73B(J!mEpJQ3 zR6^PTRtXEV6K8UlPm^W0oGdu#FR!^RCy3~A4ox?AA4|;;Mt(O%Cs8{xOG`ttO?fZy~^$zjz&>39tHV?LA_>3Gd~x5?%&q6T}!bfaGJEl!#ADvAGF1nyk&I@ zGEe^ZRY}9hi}{qwt5{okdhzE+a%2+L*cB^(m9mM#M4Eu6-#TfkSS&50l^QCzZ#Iyh zg2w-_!B8RjgC(ivyjnC?X60c>_-85EAGB}c_B4B}%Vlr(6CW<04)i{ydGc|mwE-?R zc;7?pcafu(ULX!PNoX7vkE^n8-rj8y&zQEdD~BxlZOUmb26QrK1h8e73#!RCUrsCR z>o7%k>(0`)^!d z;j8ar9qq2?@xzQNuF?-+(K8IO%Z&dn47k%WaXOoV#n*ZY9sFb=rvn~P>^gG}>Hx1` z?sPUXcU)Pbf3aCzrK#Ark`6Z!BBcHocekvHy&fkljaXCS%knD^ B9%ldm literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_blank.png b/mods/i3/textures/i3_blank.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae3f9a34036b575bf0c3b3857534ce32f93fca6 GIT binary patch literal 67 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k8}blE>9Q75DwX7kPIsWV^{7T1)wN{ Mr>mdKI;Vst06TUH?*IS* literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_btn9.png b/mods/i3/textures/i3_btn9.png new file mode 100644 index 0000000000000000000000000000000000000000..34433ac82a89114e0be99fd1f2a9bd1bfdfd0a2e GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4*Z=?j1DUzm@pGrQ1^S1s zuk85)zhDN3XE)M-979hR$B+ufWCbRUMGS0gZmG#C2`UE;WISnNnc~Rg<UFh8?dxNWAcRH9oX2}8U;&j$mLBWRgX;Ibw|j5k@gF5a&wCoWvv~rWoSo zWr!&uiOHO#q`L+NCZj}1u*MPFEHX(D3qxG_1$H>+k`vaMVS*7=gkR-Hm|%u=PPpWp z9Tu1*NI=|Qze|pL9=RdIhC0Fk`3*AM@W?$mc3C9KxG>2AyW}WRrB0bUPE`>G%Aaya znL1U9}#4cc^gQ$_GB|3-&4 z4XQkl2t&zt70TR_!4?v%llftQ zX9OjAXZ0D zh7gyyA9)jF*hzf|o062IY^uq-D=ANOE?aD0@?8KQ2>#?h0Q@2-&sKea`Vo|8?u+^} z{IQUahj>~1?P3$dO}3P_@w`lnY8dSW5-dNlG%S81`3w<)1c@+1N;Q=GJxroRnN^eT zou`TjdCo|)!U}25$g3acstC^%$a2UbSqeP+NoZ6M+BB$9;+ktp)ZC0xRbCOHNu3H6 z>NI`J4~5X~A+%`Hr1j|&A8GwygcPUbdG6hANAmOg2G8W(Evn|N{xFsf!Wji>G->nx zUo+7L^^5|?Cu zvSAS<$_j^EQ~7oe+BB(f%^@p99pn9xv?L`iVX-{gd))w<{{qbqq2_I(=Ii2cEcfcc`Mj|I^wfNO8(7Pdspe z-EG}Eu6Kz&vRsj2>nC$L@7dpX&F%cp=5~t=S7g~^i6|igf2g-cQT2?DyOI5HXV29CN@bQ;ZY9{0CaQR{J0zsD}Um002ovPDHLkV1l3! Bv26eV literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_compress.png b/mods/i3/textures/i3_compress.png new file mode 100644 index 0000000000000000000000000000000000000000..1584131f0750f06e9b258b756d6f6ae9179cb45d GIT binary patch literal 1627 zcmV-h2Bi6kP)feJW!&9Hlcz5 zHDC5_ANE{%vRQwd_%4!#SsQ!L+?g{o=gy68-@ZK!dV3a2;3#E&vk+2A=>i&;U+=LttOeV__;et^6AB z1MnHJ0MrD&Tww4`;0V|Oo&kRVn=%A`ah=@$mcTCpRlotIF@g60>`$*=Xu;Qke}G58 zUEn^jEsvN6W`Iejn7^)-ua42}t=l$@5uzR!BoF*U;Ah|-u%)=KX`!zGGfsrJs2AKA zV?NR990@=}*C%yvQyoIG8~DF;y{3@ADcm(DOL)Q?r`vnRehEBRtVYU2%fKbMZuTC# zf#1~is<3_yd<(1q6{jy4C*gUwKLd7w2f#0i*D|mK{Aj{+!rW&s;E(jbO9KBrunNor z&IOd`J!`)Lo+@U`GR`h=YIq^Zcuptq(;4ue10U;pR5{CcLy=^K1e3}6XwN2|VW%G-g#hi(9$5jN)tiHQ+meUl14cT-Jx|0kPDZ*TC<3zAsOx0hbN< zRW(afYL>DUV<9=flixw66t1d$|4OdEqK2+4kBJS~sGFV;Itj+6G>+7`T~OR#Q%8r4 zRL`t*B+wo8gb)o7wIRcj9u>93drFBfjF6L+&?bSoPI`h15PZqpWRx+&i88{52r+L} z{qwSPzvT{kLNErfv05>!T+ZnS>cHQs2}*4U&VSYgy=O0@Cj=P+Wv%E%#rB-8pJi@5 zGE5(L38Q94U=1=0ct8&LK)L-3y|zPZBcmHvWM3=m^A;5fF7zzmOw0mY1^zV#Nctqv zl00fbHA6MzEZ}cy68K2JKT*Zk=mUJ77fdUh@)YHuJRmY@uB_bM91wig2yIpG5Yr%S zGQcpOS1M8|Y;XF!imRRtki3tZ7}5I&X5Mc7_$b}*y#X7>0JaxD8zB)n^LtIM}pyQ5D{@@_Z!}PslTXm!F@L z?$SP0zunCX@?P@>m^bC^q{+=ehrprqw=L;%ohmXr-H~lvCQM^ zY~Gi20NzyH-Z0@3nSy3Vwf(W)8!QQWC1qC9Q!H<2<`}_lX}=*AFb{G(;Y`LkF`kr! zXaLXJHKU~1;e;e7RQyoG6H@i|l$JP|WV|E}1$ZX|_%`yATFC5hLf%-)safUNd`^6h zmF2mHfNvuwcz2)Pg0CyKpGc$I*XtD-;3P!Qy^x?^!HFEgYiPy2DtnJqq}Bu{t`4S2gtdzo~{=9)ZY zQz4Rs>IJ>D!~F~)u90q6%_}^n+K^!(4A2kwC0ZMmEBgNz6kyui4FNtof$4W?XH^V^ zGJ`mj9?50li(sOn9 zr2!5)gxF3`@O)FH&pEzx0)M7rZQGF^C*9}mA;cQ314jK$VCLxw_WHQbBU-Y5?9|oy zqooa6N6Q8tKW(EYz<7`3#RmK<;4!f7NH;)yw>B-Zx=DJpY;^$e;|ANw?LGKEfnS09 zPA>2D`x&|Z4Rv+%nV2o&Ibu(E2j1-k{vNR9XbmAoCU@5)X}QoVxgKKPZt^^qh~vqA Z_kX>Qkq&=KC*A-6002ovPDHLkV1itp{Hy=~ literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_crafting.png b/mods/i3/textures/i3_crafting.png new file mode 100644 index 0000000000000000000000000000000000000000..06d44e766cef687b419821a90db2c9dadfdd72e7 GIT binary patch literal 1842 zcmV-22hI42P)grJ~_O1z`;3r2$y z2pW%#Awf9=btQ_xa;Tt&Lk>aqrtNn9!)KCloVGL5cH5GjWU@)Soqo^ry~p#u-&>!r z`|7^BuS{NmAIJwPfGVI5P!5y=g+PxJ9efbD5O^K<1Xu>V2s{W}35)>-iku3dCr||B z0sdSE-y66a*bX!U?LZsQ1RMnp0egY1z~{hgz+=Gmz}diH5mRE20R(b|fD+&qU>6Vp zI^*0Oz;TiEH*gr(2kZbo1?~h+0V;vvK!3T9Kbr}t(&F0_fKNnBJ8%$K1-uP30AB)E z$X)!|N z$W~WKHwjI^8$gBE1qKwci_&FAX(piwcpfP8lBbJ+(}7!oYk@&PUXGD)5SRuOy9Hkg zTn>Dryt^Ox2p9|G=MV|)K%LfI;0F9u;0L7?Bh@qmp8?ffWC?94N|DV{lH=l%U;{oB z<6$eL&;1Sw?V+@n=kPN{z(tb4kuD*@0eJJn_9?#>nm%u?==w^I4wN*l1|~_rpQ`tJ z+39vufix4?qwniXD+w;Zn*+-XBd}=4&XuyO1J(gQN$2lT{PoH)3RMFK+uJ#4KNU}h3O2RQ;Ee_ClvwEt zydytN7x?|aY@nYHcuuXSs6+4;HJ6skuMz5OzHp>dDfRR#+(Rko3 zwSyfA&cMeYB$eR%N#520=ZN5$lFNrpUERsrgsUxeKuqv9B&-pcA;l3-;PX|yqze2E zGVf#jdkq)Rks{(IV3_GRY=|i^cO(LDAz`9|<67WRrPYAjn!Go#$bmp|0{%u|o6J2b z-(RGK<*9-^Nq&Ex$wJN$3BNi4Z`r&`J>Oe5Sgo(k9@Ll_e18jgb2YX~@0Y0fc>-7h z{3f@UE@Fo08SZy6$*xQ#@U9k{D)15Y5k3SimAMWCzL%-DiJ-9DWx6b(xXXL`K!Hwd z>rE}OWWaYQs?QMU3LS%213%kXnwf-PCJ6A$Jf}DyArbga1-}I{<&%NCfW><4s~CYc zCrGe@uhmg^*rL}rYPYL^m*fhqQk-pZ+Fn^rLL%@HiIC-Lub1kKVVld~nw2D2!OyUO z?*M*LemDDkO$?uRLc&(yDsv+?QzUHA9SgkS^Yi5MgMr)CFrBRw=tW$$0Ut|S_%lhu zcwj;d@P^OV1Eb~hFU#j!L`<86s{$FbnKL5L^I4a0w@C(KOZ}jpO zE8vatnC9a7{IE>>d{FXsdyEcj3-Fc*s8L1db;ldk4Q|x#&&#yW2i45j7N`9jQf?ol zyuZX_Prn^l3EZb(H&reb$Y$`y&h1xSU#4^YdJlomP>|V`T}6NQjz-q79#)<9eDa4Fr?}uXq??H2{5} z-hOEU652E#|1dCL6DNJh^t89Cw@n^qbE1;Mb4>#e@%jnILCC0#`@F^cM<+O!>x^?; zHQ(I5O+Z3euMN(cIbNL(ovA~Kq`=20rPu2qq)B?=DIl0_v%3SdGZ7bN|ExY2h?7@=o0=O~3Oub6HApW1Y|UjK&=`TO6!1J> g_tkxMUnj!#4+w|Hm^O~W?f?J)07*qoM6N<$g3ts|^#A|> literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_cube.png b/mods/i3/textures/i3_cube.png new file mode 100644 index 0000000000000000000000000000000000000000..3f3d27a73c13a20281b5d0cf53f28e2f73f87dbf GIT binary patch literal 404 zcmV;F0c-w=P)w@(glkm zOi+jO`!)&AJLh)yz3-=do=aEmUg;B_CqqW|N&0~@WjR2J3jkVdx(5{T`I&Q8-2w7= z^!XiwPa%E40>`}bS3YQxPY;lz!7KlzhsV5qz$|s188t67n6n3%qQ(Q`=8-xx$pKj^ zbcmaP8k6w>6YO$L(%exc8waq(6}Hl*G9KXj#@S4ZjnM!_d<^L%;$9BEE=Arrn=$w- zM+4Sq^NE|>Qwjr4ahcmNpy?FQQGfyzpa2CZKmiI+fC3bt00k&O0b#)K64v(b*QF{N z2-ub@sh-%AtLeJz%N3Px9LZI+J-lIkak^!7pA)8~>UzT&IjONR3tl yH_r8J2LU^B!)3&cb2r^~IglK$4`tW$#LpMPDgjszyWEKY0000Ds>AsP)?t)kdi#2YqVIvf1}V&OH~#Lu9ejfHqA)yneM_yGhjg_lM_R8Si= zf~X*PH-%9!_t?C`u&icxvxYgdGce6I!}FZ^zjMyn^LBM5e4!h?*oYIjgLn9V$2gB2 zsG_^8NLRr3V-N0O6u&TqX-wcdMsN(PQ7Iby0Xz%Xxxd^q@kX4(n&c(az(0=>pPT2N z#pmQD1bnqg_^gCaIGdz|%*YSnMU(Kg5>8=NQiTyc*omht!e=GC$8oGkNk9dIxPqSn z(yD|Ryu_~5V$g$axX}g)W4M(2+}HVS3AVRE!X!rWT=14*E&6IjWF%Z)fP`86$aA&d zk6ReV$~qEyuoYKZlrV#Dd7tEr;}wqnLqe-@7{~n-W_Z){NNBYtjN)V})7y4Sn800Z zN@;H2sD$|n<5WCnH+oZB*i1K26aEy&A9W;5#WZ>-p4*)gd@~ZZ)RB;duciv$s)WfR z!8a@63Z4`Vz8MMYV-?w7H26j(R6;}{;Tw{W@-|j05{A*2H~58YW6d==zrP);$nHGA z_bliw48JF;5u4iui06qX{_#T*gN{zy%zR fcJyM5@I2RVnluXRhozL+00000NkvXXu0mjf)<0`a literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_exit.png b/mods/i3/textures/i3_exit.png new file mode 100644 index 0000000000000000000000000000000000000000..e3fbd6d84b03266791ea133cc95eebaae2406715 GIT binary patch literal 528 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 literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_find_more.png b/mods/i3/textures/i3_find_more.png new file mode 100644 index 0000000000000000000000000000000000000000..e4ddbe928761991dfe5c3271abef4a41c12dca33 GIT binary patch literal 20154 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 TI1Lll00000NkvXXu0mjfN*Gu} literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_fire_anim.png b/mods/i3/textures/i3_fire_anim.png new file mode 100644 index 0000000000000000000000000000000000000000..1bc7fd33e20443eb2b29523738168c6ba8dd7ab5 GIT binary patch literal 1413 zcmV;01$z34P)ni~j>d_s}9?WZ{MiG2YFxN_hQ`-FtpakZ=4?ab`52M$(d z>~^&sxvIOJu&!(PmlnRid);s6VLcq*T6f^r`|Fbhz%yRwt?#B4ct%^_5kMXT0ROQ7 z4C2}e0C`H=$&XrBmg{-e`BR#joXi@ z8sxTYEt<(?OKHW)9{nMC%EqIaJR0C+H3y#2$LoF%&ix}y@Nei+b zyqKU^O83ZfC@9;cn-vKTl_yJ-BhRpH3?HKgl&y7yN09Iofb+06%49(jfb564PV@x} zL0|hG8c%F2rxfaRZY3@#dIAJ}07&N^eMW#|+m86_p_8I}*TUsPtaw z_gGi=P@bC3OIdcTx>&bysT)Ehv4V;rbIb;Xl%Y9%Yl! z)5AO1xb9@jAe-Hv4|gq{yB^N_#MJUizI<-L_mk)V@E#e+S0ow`ZvX(f3>dRFG`T^? zP;G}IdGivJu=1oPxq#Rdb~Y(aR%SA0k4mWuJA+ao@_5(~Tr-)b14E`Tv;c$?Hc~pn znTOJX^t@CJ$iNHq0BS>$r5IQ801=vnngBpVJfpJLz8=6+G?S3tSg|o$@t^B~C6^p& z&epG0EKICS>Cz``yv1|F#wOkG$e5kzRW>af*UC^UY05i-E606BCgMN$*_tYF+*h=P zck1&P8-#7#V1y7q>T%HsiO!=VAk4lv_@WX4Kvb6PP)#6&n)T$w3r!|AVDXU9f2z(T zxH8LFSZuh5CIDRM%-IMi9EX;^P@$;7gLvj7Le%J_0iA;6W$1isYVUL5pfcx{LOX}| ztJS;JgkB!ey{Y&y8ICZul_GWOfQPA`dzFxTdZ20s@S$*l&%XN-*^45~IOuR^(tW)J zTPN^Du=S$1q>3(YuX6TnC2v*}EDL27&GEjIie05RdBDpJcne@7rvgGIOVhCfz-_F_ zN8nhm%AbovXWvog$|{*CwYL(-)w&JyI@z{K1dKs>&fMibF%G(Oc3vu!$g0!!47LJM zH4!UNM;9ucxn}TQEXJDhADw*tiPdy!1O|GR7H|@-$>R{~8r>U)+2fi{93Lz{!8lN% zOq|Z$`hJjRf9YQNYgZwcaURRu)OK!lAvEXSOtJ;IwP7)%ubJ_}{A_@F@|@QU-X&vzzOMAmEgn^m!N85cz{xa zV21K6IzbUA4(j`X`w7u#M#!H6Q5!7#V5-=DUMiS4VcJWs%wkanzkMW6))xzIfST7WvZTd1-BUO|nyZfq@LGiu!b%XN*qZ5At5UwjY T`X@7y00000NkvXXu0mjfjuWSd literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_flag_anim.png b/mods/i3/textures/i3_flag_anim.png new file mode 100644 index 0000000000000000000000000000000000000000..4cc74a7a728f6c87e81d3530c735283ec4092e03 GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp^Ahrbu8<0HGkSPtMR(ZNOhIkx*JM}hig94B1%??3{ zRz-;hL78qriG%Ux4%wHMtaVxSQPjD<)(P0mk-L@fBHh$BZU(~yv;VmQXDS4lxat%| z_WSbRa&%tvFeH)J#oN63({ITYhKt#%tIjoh&SGjUF*wE4_CtC-%a`2*x|+e$)z4*}Q$iB}8Yxk0 z8}n|vn`}SC!^2D_@4T7a3A;5-isNtkcn>KIhie%OK4lI)o{eLJ*rj>l3ohjwH^V!I8CGV_P1z+b*G38ocNj`-#fiP%P7#(ad+FyZInN5RZ$_d0J!l03hj4GqU z1&nG@hX!||OdyE9ynk_Xe!(|@ZPWz zp65R`9`XFJIg8pV1B`>B#tJcv=(jyHMs5%WqNv)mzCdP7%1q)0-yn^fOmYlvK*bSA zDh4=EQshpy7WRup4nj(rWY}T{vl^`^*yq2W^WCfn1QbK^LHe2@p|`9^jm=N?T24>BWIAemr)V?D@&y4qaiilg>$j+1|*LJg>$j+1|*LJgFVdQ&MBb@0H;w7!2kdN literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_home.png b/mods/i3/textures/i3_home.png new file mode 100644 index 0000000000000000000000000000000000000000..bde85be7401e2c19202c9100a8b03046b4b199ae GIT binary patch literal 802 zcmV+-1Ks?IP)dxWJ|9@xBne#j+%lgC34Mewo`eCw7e~SX;Ri3F0Pus8 zP$2mJODG_G|0EO`zV{MJ0N*DYl>poy_E+Hiuup=AVo7*ABodmzdVPHv9K%QW0Wac1VFmSs zpzFc3h*^A(5C1=pgi-9r8C=6%{1TnY4!?qj!Sqcq?#F2BexQaAuosi~EZ&o{3z);H zU>Xm`+E&}*(bzD|CLmxoSVr??gen1*fZhpcZa5&>8qJgi)bR#?;t3wL#FO~#O_!J8 zLI_xmrRW@v#EiVJB_`vyFJcL2$-$}R01jim4He>C7=>8Fae(=BH-^}$t7S1j^TL% z0{+5L?8qaah6AxhZIoC*1CJvKTFdgZ*p*$4RB~AbEcmbOZReQWuE-4k(cx1tC;<)p zj+5Bgj(}REk-v(Gq+JOsxYLG!yB*Xe8Zm!ejwiX6wbLR&u@9H_}vCPT*_&ig(+TP>)pDY3$B1=5Bl*ee2tVe;4<5 g1;@9_KCQQZ0j^&On>1mfga7~l07*qoM6N<$g3ZNxO8@`> literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_hotbar.png b/mods/i3/textures/i3_hotbar.png new file mode 100644 index 0000000000000000000000000000000000000000..d7e502779382d0240144ff239517fa18d5d7d127 GIT binary patch literal 435 zcmeAS@N?(olHy`uVBq!ia0y~yV44SH`*E-V$~)y|IzE!9ak; zvFF97+Y5MZ?XdFYn>evY=1hxx+?HR{mgF-q7~ITbVqj=dXJ9xa%)sC#bKW_0Zd#>x z(an>7Wt%3?eUqa8=1Z-*ygvg&ouUmRg80cgEWHp$TY|xn1L|*At%HFB)Z`P z3j+g?k4!sMFoF3XS^;PsIt{WGB#ulYJBL_jAvpu=Z!~AXoQ3QhkTa2;vtie?C9@eB h8gAAg1&c%xbJiZM%0=bDO2Eiq@O1TaS?83{1OT$9YMKB5 literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_item.png b/mods/i3/textures/i3_item.png new file mode 100644 index 0000000000000000000000000000000000000000..d5b50da17e1fc443772a2c93a6387ecb6242bf53 GIT binary patch literal 1809 zcmV+s2k!WZP);rl0FPNoB;44pG|l4fq_^qlwoZtwT~ z|72wJ;{jv>V}QGW7l19mkH8V29_RvMdJX}{fW5$G;6>nGpaLiah5?xwet7@^U_9^% za299+T7eD$?h*LQdXDPzb|9kT>wv$2Pl2a^JAfh}7YL*}0ok(PSp)Q1{-Po!44eYC z0S^J?Kt2#mRRXer>A)dbv_oL71h!3JoAkQJd><1TA>b!qIZy@U^~ED@nD@v+i-2{& zHzK1BxM2UWghCUjqIC-T`I_@;vIT60Zt|EsB4*sY7T5sXsgTM8#sZ6F^?DN; zQJ@j{3YZH_QusA^fOnerog!g+Qp4dY5@rD~3)rN}(P^w3kvBX76w9(Xiu=caeX?fE zB+BE!E+tg=c?)n5*a@6A3AP1z8yJxam7^GVKsVWF!lGNmtN|thL*zxnfT_T{z&VdM zSQ5h$SX1OdOGH9UMEnkvq>6ybQF&XTgxG14WLU{;rb}M(h+=ujL3x0!FzvwSz|A@~ zpd7Tz{O{As9f4HQ5kZB;{VI*k#+sLa{j%as0u)e=m;-#LQtL?Q0CvdwSt4PIDuGj^ z$AQvRl+!uDWMHilV$_ts6Tma-H-bii-YR!*G^AYwJ`?as`aa_EkWs0sDqU0cq$)+1 ziSt_E4JE{&Ile-qg*+te0KV`f$1}i#KyIoxS0h!k_enK603nsTO4l(egi3+er6jFh zXgBX0fYlOeDc@iPl=x;!3|%tGv625ClUzL)31flRq!(hIz9I~)mskpB_~jwZKU;GJ zE2Eo%t%~y@9#2?na)J{;yF{3;<_tkuY`tRovd5||Qi8X8NT^WayJ+SQ$E6sv{RDoz z#888Y<2GgVs8NnJuI!n_I9W-s-DLmm(i}m*Siaf=J}kFiEhQK=p0L%4A5$XdsQ!1G z+_6HMBj88ynTHRu1)es& zLq71h(Fa``$q#%&ybj=<>^&l}LY&czCcr8?J%qisNuUoBte8H)#i5x^71)nn2D%ajZ&f!_>4 zr?d>0nTnR5(2M1(d+X{%!WcC~&1S}UK-1v843%D@Y3KaU%?Gs!x2UsBK8#Vf1nO30Oj4-NI=?dSveS(2XftsI2Q~LI+WNtAf zvkth&*KVKS`cw>539-$y?r=2OZoerR*}f0= zR-i@ENSxg&JwPa#mfx7HY~M#On4#flG|qsvEp5S@`z+KZjn+5>bo#Q?UBeo~0&Ulc z_1gndIpz~ogmK!l)aA(m=hM>dal-98SMkupN7*)%b4P=GfL(h}gX#$_J^W70C_6Xbz> zjm#G+tTX!?^GR!IlSo8XZ=0^K)Y2vb-xvpcIX>H#@;~^&48HU#!6$W+Gf)JK)~18d zRhGKVshsVvg@A|6uIj-BUf_0`L19E72M2foY*2&HqaQs@9W>wtvNhi3fk6RY1ROFy zajOR&6$#UT57QdF2v{YMZqrdc@UxnRNLqsz0k;9WO(JyR5cOQr#6aoEHt{(!v)rO*?bOrw}E);A500000NkvXXu0mjfrbRv- literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_item_on.png b/mods/i3/textures/i3_item_on.png new file mode 100644 index 0000000000000000000000000000000000000000..41dec85def795a3c5a1d3bb11259f4b47f65baa9 GIT binary patch literal 1458 zcmV;j1x@;iP)1q_NJ5;Q3@?pTeS3|=E4I# z*n(C;enIHz#;YEZi&m{YU{SD*Q7f&2n$xbXmZWAAcSmpj124nOW)9u#?6(~lhF#{H z_xb<7=lMT}_x)C^=;MW9Y{E7879PQqcmaoT0`+`O;-7d7598a|j&raMYcRZGsk~6b z7W^Eq<1HM;OaRXY{CoMF%m0tzNWOmv&*PW485dza#!wq{0!DHNUoU|6@}3JR(|85H z!VNeZ;~47U#;n5X*jQUA0#@RqcrJHzCScy{<6RFKllU{ff%6g`wGM!fV=F#}9k@Cn zHnAW?WWi74$M|)~IE4Qc@!u;M@8V7T2{**&l)cX+3Y3xayPh_1& z{C_+lbF9U+vv@k8R6ErfV`W_TGCYL+aqWJ*;UD-?LT_l-u3fdH&nxhI{I>y(5?aBe)TRupS@q*xlv z9wWwn0H44UZB)F|aCo30j770F@jtHw7l?$_xEPP-j`l*rWU|Bhf$u8Y5U~muq-L1v zfrPoF$SQLhWogf`=*xzQ_t2@L={L+X>+x zDhIx48}9OX1n~r3tR(otwsk3PF5Ct;RTnq@q#+usVw*=FSx&j7SwUP(%_5Y z=(?N@sQ2vwO9_0D5jMA|3ubY!(%=ibC-B{zUMsV}zRH7-?IYPHKh!iSexmZ=i!eAl zLz6}}I0}^qU*K4e-xZ^?X?$~8fDe|_V@Knd-fOseS%5EQhu3Egupd9erey)X(1CGW zicbaK@Uj5kqC9SS=(_UYmyO{4AAAqs&*~HW)RF`r0yg08KEdCYZLg&TJ_LL*$4HkS z_z_?oMmC{J@8RkFVYq&rdNi9>Eemc*^u%o?rJ`nQAH9y9H4u%lhSxv^M=NwX;sAjJ}~6zYevtDKmY&$ M07*qoM6N<$g6{0qSO5S3 literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_mesepick.png b/mods/i3/textures/i3_mesepick.png new file mode 100644 index 0000000000000000000000000000000000000000..ae52c7942dd03b3ff001c96d2257d9a100e188a3 GIT binary patch literal 309 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 literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_node.png b/mods/i3/textures/i3_node.png new file mode 100644 index 0000000000000000000000000000000000000000..b4b483a93d379e7688fd376bc7b1bac8090c96ef GIT binary patch literal 1487 zcmV;=1u*)FP)Y8xfqM!6-Py5fKM8Mp1D_O^n8kD_rOb7rHVU-RMR)xKKaD;DpgQ z5{%I}#(9i!7Elo<1f?6ap}XCjPF`N#D_&Q6E;f@;Bz@X@C|yf1>fUt9E(X9y|Zn60uID=cn_PQ3z$LVj0-v_WAf8ZrtiD?)+5;r~?lW__jz)$!$HrkJW zuog>Wti{&EzyFJM@!eB{GscV*bKe~^aSOf-KOa2dZD9q^;-avQsW>kP@fY+aETkv6 z;!YeH9MaLM8y}DTaV_4&#)O~uh2Ou8MK~Zn-w|UR_Qf@L9e;*941V`7yo>9DOUAbh z5ZEQIumyN3=M=xf?KmRu6a$Fea2RgJ=jcvZ&+l<;(nYQTr;}a=Dr(d;6{9g%^6I-5)12P^02JEaRHvrxIwz{ zMR3hw!95*SZ+;x6hp)bd4H>@rQQYMR#r@w=0=FCx8sgmyZrO;pf?M{BHFlJ}@iFMa znRpoMQ+~b$-vwJAg+0nN%Y=%Y6(|06#_jSeR^XhloL$QD^F44h?utz&g-dUM@mOg4 zt}5^ASkGRV7aCz*N?&XZO|b+g1ec7i7x4*U#y8-@Fz>#EpKrh`xH{Zo+|s2>JDS8p zg9`HsycoB`_Jl=l#;3RmhYU$pS2}q$F~*P%smSK%#1&JGc~#>UMcnk!kk#XAP1cF~ zLW%V!qP2g*8WxmBFxBK4x^On0k2Mb@EO%2JY-g=Wy6||M_CR9v;K8ttJzFtePguh2 z2(Wrmd)OL#>#7HU{)pE<8E)S%zy%+~TKmfYpg$pRlf?2et{U!mJveJxim$I37pM$?j7-q^1u{X07tQA-EbY(&nW0PaEUj_?8qEdf%r(^9;DjBlty%zf zkPYsxkqw@jl+z(&r_{&}Z%N!Xg|fp<1t6myFc2$f*gwpQ;INk4^ub^7CYk zux?E;>;M#~3iqdit*zk#rBsPq27naNb>a*x4>uS{#2hOkmM^7GpydEaMQ}62%(ut* zIP`sKdBv6mApW0e(I+qnzuCa)OXqxHV3`JAr*l257+bg{{SypP>m<~tOo!9002ovPDHLkV1hdFzhnRa literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_node_on.png b/mods/i3/textures/i3_node_on.png new file mode 100644 index 0000000000000000000000000000000000000000..b49c9dc8a16b9d6bf6cc0f4c6124a6338c173eb0 GIT binary patch literal 1411 zcmV-}1$_F6P)0R!s%LIKC( zD!hoLxE>==7;w10(1M|ugeUML_Fym8VLm2f7+McE!;iqpcmSVb2fA=DRu^{SE6l~I z7>t(wZhRY#$E{d~tvHY}Ji9uv4e#J?j7EEZG`tl@<03qRU+^!wdoVs(-SOVv@GLG1 z%_#Jj<30pu;chww$X zqOJxsJP(LnScOM$M%iI?eBegB8Lp?Z9~hn&R&U395sD8kXZJ^8UPNL08uZAQ>N3|w z_BpELQxKvz5;x%G5SRn~$oM2^dL6e!&{QZ@^x8T)I$CnV+vQaZZ)@om(_!-|p=B*$ zQ(I9{4CBW{WH%ylBUMgtYI)p?CQd0gJ}qo)%>$qvGooOz08`U$B$eV`94YRvWu&;Z zT>Fcq&N*)U6I_~`Lj(XbBbh1cMp8wN+rvw2?IV3iiYM>lp4i#;B5wTipvLB~u}1*5 z&9@!)6*57_@BdZVf=k#yuVbcRTY5rkKTjtBY!xj zNDy)@Ug)7_cp!H2HOvZE+m@+9O~9jAU12a*69CeD-4VgYoZ#l56ki7hhiBu%;C5#( zK3BWvdZLSLd<#2gYtUT?QT!wZu900}C ze0)aD3z?v*x89@S0O-k|7c%vS(YUKh@k7G_kd5dTh1exRH?~F*WWxcF&|*Vyybx=0 zJgaqT-4FmAjO1!+3V^Bc>|hgsCIC$UngBEbXadj#pb0<|fF=M<0Ga^Q8-O-k5GAT| zDy{tifTTjTCTwggc11oUYH+pe_^dYo=?>Fb7}8fgzx4*7@*d+lG)2@Bfa-Ob>s{Y} zy#c7*oI$E7;x@cdg{FvV15o=(lPWhwR11Lm&l)K{{ncGZ01}=j%@XyWHcK@{%nZ(L zDnlQ713*$*Uz}=|=(~BMOjE?$C0=S&0zhZ#a^=3HS)!w(qwhy&a;~*j9^zW78~~E$ z=hb=55{)=6S4vYvDFF0%!P@BKbLpmtCH_BPaVP+iEB04$lWGk>^Z_l>%?;@hn_>VY zBQPIln~MO>>YE5tr=$Rw63^;81l0%nFg%*6=0{&&0>H$0HlyA={}2BxYA;H- ROeO#T002ovPDHLkV1h^lhc*BJ literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_non_visible.png b/mods/i3/textures/i3_non_visible.png new file mode 100644 index 0000000000000000000000000000000000000000..273b8d9f3cca4ec46c5c9a813d874fae109cd9b2 GIT binary patch literal 1614 zcmV-U2C?~xP)rq7WmBiSFFlQCiW&xIhsfQ6t7jFbc%@ zQ(=d}s4R?bjL?FQm{?Ox)T(F@N@zQ6X)B%1;O2kL&E(F^oqJD5oZiI=q@6kE{Quwk z`%WW3WG1gjNI*zHNI*zHNI*zHMJ)@61I<7^5S>W`SU@9?1iFANB4I`lU;#})2k<*E z0qmD1R6GH;SZ4|WQDBxNl8|jS0B7m{^MG1l z4p3F>;vT@C?PZVYmdtE{Z3fzaTY(3GXMk6M9l+bbR^Ub8G2lMnI^aS{unwqp0TUSf zbP-S`&=&x!f#-nFb;;wvATR=q0%KYy^|KUk0yql%2z&r+1a1(hs7df939zKzO~5t4 zX5avDOu$Y7S>SXDDwgm6fJ^0$i!Ha={<* z3qB|TFIlsmFm|eM&tm33mYx0E^^2>y#DRnPDTa0GMCE z=1U>F4|o(fuTV)`EWEV=Z%VZ?KGppg@R~ezyhwd+IsA-Y@XoW3>gG z$-9N1L4~1R>J+sr!`rMle@Naw?NjAPfPG#YqJG-qmjkZ@zW^T>k-VR_cqTx6|4XB} zC0<+Neg-2k%>h>e7aQo_nyBhhGOzoAbMrMnO^?QA>7Y{k_9mxCW5CbA3&0ifC1o3q zx}~@FygyS0;D^=eU7?{(j559xbOZmV2Bq&vD#He=OWVeWHJsT2+@x`MHD!J%S*WmS z*6)_99Ns6#ocwTPC|QF z{D*Ia1HHp@AtWwo&Qr3|phPR7-_7zkOeqTiMjs^oA76{x%?LkjtcoC@S+(?pNa&~} z@LmY02VN2hNtr{%fcHW`R3tR}O*O;67zqgo2?z-Y2?z-Y2{>cdKOso*gFpOSpa1{> M07*qoM6N<$f_pCQV*mgE literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_refresh.png b/mods/i3/textures/i3_refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..94f6e26ce49fba7beddbb4d95f7b26d4f06b75a1 GIT binary patch literal 2329 zcmV+!3Fh{RP)+l3raZ;MScovnx`tFp`k%UL`3*q zYjkw9YMJqb1%!JDX@qH}cfG8vOr4O;ypYg}-Ri?`Uef?pwJFCl0vojn zmgDw0Uj0FZ&&bG7Cu2=NL--YE(>+PT`zm4px66arAe$omtA2#{emk!4+1c5u@bjR_ zlQ5%e*BORz9QnqWL&zX(g_Q=}sDQ%fzAzRiomC&sA|Ih{!ncH-gb#47 z{R~Ff3nFx7A{^|Pd%mTmMSA;0LNi#LJ46z52`2d&p_cG47+pG8T_UJ%G92tY+%V7L zmia?7w-~K}<;$1L-Jeb<2m5k`AovA1q}P~iz$wKNqE$}s2R3kwSSTk8?D9t_;;J?U zq^72-B&P^JIue2>X7hdl)OZGjR_|u9a^*@97Z*3i`pV18eH9Xc_~I7A^9Z6Wy?(t5 zXm4+qJCF|ZbDBKo{kV%Cf#BYquBfO8$khW;?%dp5UqvwOzLT&Ev4Pt%1!QJss;2)m zXr|kQ$@k*w$yV7|K|#SNZXQa+>7$4!gvgt$QiA7)6fI{GzCjdcRCo?7Y7lIAcD=5y z&eV>Z48rVir29>*Gq3^{E?g)lX2-K0Uf-zMGtp>-7x(OXVPRodyY6rJ1U8c1T4Mpq z#0wD18+CjG;0WpX-V-reJ^Tp2c^qyZvI3@?+^WlmuL-XzAO+c$A%o}s zFyR5tsK`Ww)kDcTX%k*5fSt-6AU#GV=j-kj!c0E*RaI4%pLrf_ZEf;eo*f{bw@d-- z{OZ88jO_jqq`_EmT7*|_CeHg+f=+9RLIphdCpg!^K5*i`XZ|jhEn6mZ4JaVd#M(j$ z(uM^b*---;=KnuVxF7UZ+wM=00@&Xj5a9iXvAdT8z=?dodvKVx)vH$vokKYSYY-Lo z2U(+0I58K`xn6){SHiRdjZUP#^Fc=~WqSSw7d@0D?7f7S2_0SGj}FYmb2{XY#2|o~ zISw3Bc&4SgM`UEAOvB3%*%4%YW*}v;iPqLuF;09w1}wbJv+tXoTD5AGsr8uw&pkD! z#?+V^Q{#UO?q$+@uGEl%QM6^aKTAcl==47zY*tXJxFk9OZ zP(JeWw23PTpV_T z1UFguyhF&wecx+Bc>cTJQ34!Y(X!A7Tm-$m4_fxN$dr_nm{J7qIJedKyhWIS_M82< z?%XE*Q$6AyQCeC$ssLf-Eij1dh=ZZq5Os~}3R|~s-IzxX+%UzBQ+_(eq9OPqG+uRw zK-;-h?|t|u+n9=$1|sBwHSqg^mk76mbi}DIH3A?KLdT-Dt^}=ihj7eXA^4{sum-zd zPNK03(*;xg8;z2@gT-iKo((Ua2&7<#a?wm#i*I_cgRT&N|1Z2fijharUkz@e`uZ=T z`|K#%V!uR0wiCBVH`-`V<60dGBS@3YTN`8_LsL_ee?MfR`PixkMK?M=hY^+zqA$s9 zq2(PzyREl*D`0BQz+z9~+SzXM>X{6|eenJcg^+nD9`5?~5;g!mD?443ZB!@OP7G z4I^-NTfr5)Pv{J1qWS5V!mQXi{o^ZqR8*A5i8MAg`aYZEjL%o-FC3X*!Ox?yvmDOO zL%8be>&?|7KsNS3lLzs*aE>ax%FUN9U8-8cbi603B7BEz?6BtR^em2GJz@{<3)1}j zeDkpfGAe0!PP#yOb~Z|Qb@0RGEnBvzad|Ahtp!)_0dpG+(@#jD`@s=-qn<)jcbwdH zzT-o#K>57X@a#H2G&bTu_;Ho;nlwV8uy^5A=`JKH&%#k%0-qT2^LTm)yugXSJ%ew# zgY`v1DZ=0w)i3eO^{_&34ovtdxtx%nn46t2D=W*F)7znpB*LwP3RG*}Ma1|M$cikY z9K-S3i$_$OakjH?zT;&ni|60AZJXzfgB9anWpXRm?vR=$00000NkvXXu0mjf?!jNA literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_search.png b/mods/i3/textures/i3_search.png new file mode 100644 index 0000000000000000000000000000000000000000..75ef7470c31505c35eb0db4b1cec9549bac59e96 GIT binary patch literal 3986 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 literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_search_outline.png b/mods/i3/textures/i3_search_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..a641e8969299be822dd57854ecf0b1afbc8b0497 GIT binary patch literal 507 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJC2XL?fNpl6|GeChuo-U3d6}R4Aedu}AK!D*v zTdi;Isa?(x15-(`{zHJ|2wTv?!M*r^y1?x_q4u8`rX{_p8U`DxbNw*9+*`y_?!EKllB z<6U>;zSP$}ru))OKCQbI{^(zs@9OvKiq_n_X;o>rfA9T&j~H%FKCCQf7E$`+NXnVV zpJ&K~Bwv~@n^pLcq2^4wPExPueUDqKzb9R)Keu#p@YL%+XPvd~iU>V-_0Q^$8-Ms8 zTf#T-iOHnW8)ElOCs~A^-Mn$NH`G7izI5o-$=HWWeuHAg)78&qol`;+ E07>o4>i_@% literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_search_outline_trim.png b/mods/i3/textures/i3_search_outline_trim.png new file mode 100644 index 0000000000000000000000000000000000000000..9dae2365d2966e39a820a80dbc8f34d47b84abfa GIT binary patch literal 304 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 literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_slot.png b/mods/i3/textures/i3_slot.png new file mode 100644 index 0000000000000000000000000000000000000000..ed144ec3a86430666479d5ce628871abc4ee9ebf GIT binary patch literal 2424 zcmdT_e@s(X6h5!NC=>>nI$E27wJ`D@-IJVlA7l51A|k zGq3~?&bjw| z?>pbk=CJqJ+0bnOz>f89$a??;JR|^>f-gql-5CJuKvqalr11V&Z`eWCeXFy6_agRU zx6k$|gGl6r^Ndr(BQmvF@L66DV>s=&uZi0`bnQ|`M8^2;)(Xv$vf}TgJPEIqSHLUg zNi}(z*CD!(Bj~BoUP)J|)q zWs09JZz7Yiak*+!^4rx@oaSje{u)SP*swg>yUX5}BHIcB$(;zpt}Lg-mH{rJ&jxSbP}s*Ht`1Ke; zqlc+>B0(fy%CyP^tit&dDsbF_0T2Kx0Q%R@2L}KQk4OLvd|7-8*UQVmEr%?rx&>}I zr#0rWfI3!PW|5 zHjcW4QCiU8b6Q@|;mc9Al9=@-Eq^>2I4#T40*WUtYsxS@@qgB=BmOAAXwYZ`u@6@j zryy9YwIe`nk`)LvF*S$ezQ!J7E zkOAnL@5>NxZwDy9#*ntRb3k@aFx}r~OM&S5H^?|2$j>!6=aMOyAbQXxArXbny-l-2 zKiXMCG{5Aqvy=cR-#ljypfwS&_dnE}=?YKv^@YUh{p#U_lI%tV{WdJMahMrJUk|=_ z6k0=0d(sY9NBHKz2ZE{G_L~euwr}^(chWb9LgJUTG5UJVz+5AR1|3P!f(dT8`$I=6 zbR3+>FE;(M3JI_VZ0K2s`9Q1LI0};_P>!D%GK>97&q}ETWw2<(PnC(6-$(^ra*^k3 zyO};o4(;znASLOB;;4W6`L5hr94OzI+L&`vm!8Gy-n1HGny+ZPuS?>^1vD#I8?_}_ zFABJNVuwWOMS(u^@re$V?$Et;nt^z-)7o`l_(;%St-a~Nu6@wv&GzwfId&*to9{du r1f8#brRb^Q|9Y!cH+n91DsP-t)sXEzIz#fnH3O_&?2wB)<4*kvT(0hJ literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_sort.png b/mods/i3/textures/i3_sort.png new file mode 100644 index 0000000000000000000000000000000000000000..29e6ed810abeb309da71ffc4e429e41726e5c8ae GIT binary patch literal 845 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 M07*qoM6N<$f|CA8j{pDw literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_tab_small.png b/mods/i3/textures/i3_tab_small.png new file mode 100644 index 0000000000000000000000000000000000000000..f8cbdcc499c70e7e8d65724bee35dd74e35fec5f GIT binary patch literal 412 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!-8k5QWLfIUzd(UxPZ!6Kid%1QpXNN|AmVUw zy9aCDTjzpQ&X-3(G2&K{hl!<2Dg zO7qodmJ1Db?5n-MO=AqvF<;ef^YVCxqQlW+7XDT<)UCZ4wWi!Q>3{86&m+bhlF?B; z*>8<5`-&4*a=uoU-e%KSLKL=Vh@D^Na(b%RhwIv_r*GUqq;=y(E8|^<*PF+5H zu{!Di|Gmvp`SaN7B-X9lBWOQ0pTE|Cx8|#2apuX8TbK4;UL<^*|3rS;y;eD3s55xF L`njxgN@xNAe>#ig literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_tab_small_hover.png b/mods/i3/textures/i3_tab_small_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..a8103291c420515c72489a2b3147817ca6624d6e GIT binary patch literal 9260 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 bFof%0TvD;kZT8%u00000NkvXXu0mjfHSKA! literal 0 HcmV?d00001 diff --git a/mods/i3/textures/i3_waypoint.png b/mods/i3/textures/i3_waypoint.png new file mode 100644 index 0000000000000000000000000000000000000000..14f1e126257cc536507c6142149b2bad15af7e68 GIT binary patch literal 2779 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 XQw8K;{l@hd00000NkvXXu0mjfhQ~ (len + 1)) + return items +end + +local files = { + "api", + "bags", + "caches", + "callbacks", + "common", + "compression", + "detached_inv", + "fields", + "groups", + "gui", + "hud", + "model_aliases", + "progressive", + "styles", +} + +local operators = { + ["([%+%-%*%^/&|])="] = function(a, b, c) + return fmt("%s = %s %s %s", a, a, b, c) + end, + + ["+%+"] = function(a, b) + return fmt("%s = %s + 1\n%s", a, a, b) + end, + + ["&"] = function(a, b) + return fmt("bit.band(%s, %s)", a, b) + end, + + ["|"] = function(a, b) + return fmt("bit.bor(%s, %s)", a, b) + end, + + ["<<"] = function(a, b) + return fmt("bit.lshift(%s, %s)", a, b) + end, + + [">>"] = function(a, b) + return fmt("bit.rshift(%s, %s)", a, b) + end, + + ["<<="] = function(a, b) + return fmt("%s = bit.lshift(%s, %s)", a, a, b) + end, + + [">>="] = function(a, b) + return fmt("%s = bit.rshift(%s, %s)", a, a, b) + end, +} + +local function compile(data) + data = data:gsub("IMPORT%((.-)%)", function(a) + return "local " .. a:gsub("\"", "") .. " = i3.get(" .. a .. ")" + end) + + data = data:gsub("([%w_]+)%(", function(a) + if fs_elements[a] then + return fmt("fs('%s',", a) + end + end) + + data = data:gsub("([%w_]+)-%-\n", function(a) + return fmt("%s = %s - 1", a, a) + end) + + for op, func in pairs(operators) do + data = data:gsub("(" .. var .. "+)%s?" .. op .. "%s?(" .. var .. "*)", func) + end + + return data +end + +for _, p in ipairs(files) do + local function _load(path, line, data, t) + if line then + if not t then + t = split(data, "\n") + end + t[line] = t[line]:gsub("(" .. var .. "+)%s?=%s?(" .. var .. "*)", "%2") + data = table.concat(t, "\n") + else + local file = assert(io.open(path, "r")) + data = file:read"*a" + file:close() + data = compile(data) + end + + local l, err = loadstring(data) + + if not l then + local err_line = tonumber(err:match(":(%d+):")) + + if line ~= err_line then + return _load(path, err_line, data, t) + end + end + + local _file = io.open(path:match("(.*)%.") .. ".lc", "w") + _file:write(data) + _file:close() + end + + _load("../src/" .. p .. ".lua") +end + +exec "luacheck ../init.lua" +exec "luacheck ../src/preprocessor.lua" +exec "luacheck ../src/*.lc" +exec "rm ../src/*.lc" diff --git a/mods/i3/util/optipng.sh b/mods/i3/util/optipng.sh new file mode 100644 index 0000000..4e59b44 --- /dev/null +++ b/mods/i3/util/optipng.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Colors with 0 alpha need to be preserved, because opaque leaves ignore alpha. +# For that purpose, the use of indexed colors is disabled (-nc). + +cd ../textures +find -name '*.png' -print0 | xargs -0 optipng -o7 -zm1-9 -nc -strip all -clobber diff --git a/mods/i3/util/servers.lua b/mods/i3/util/servers.lua new file mode 100644 index 0000000..abd06a7 --- /dev/null +++ b/mods/i3/util/servers.lua @@ -0,0 +1,23 @@ +local JSON = require"JSON" -- luarocks install json-lua +os.execute "clear" + +local list = io.popen("curl -s -H 'Accept: text/html' http://servers.minetest.net/list"):read("*a") + list = JSON:decode(list).list + +local servers = {} + +for _, server in ipairs(list) do + if server.mods then + for _, mod in ipairs(server.mods) do + if mod == "i3" then + table.insert(servers, server.name) + end + end + end +end + +if #servers > 0 then + print(("=> %u/%u servers using [i3]:\n\t• %s"):format(#servers, #list, table.concat(servers, "\n\t• "))) +else + print"No server using [i3]" +end