# API :screwdriver: ### Table of Contents 1. [**Tabs**](#tabs) 2. [**Footer buttons**](#footer-buttons) 3. [**Recipes**](#recipes) 4. [**Minitabs**](#minitabs) 5. [**Recipe filters**](#recipe-filters) 6. [**Search filters**](#search-filters) 7. [**Sorting methods**](#sorting-methods) 8. [**Item list compression**](#item-list-compression) 9. [**Waypoints**](#waypoints) 10. [**Miscellaneous**](#miscellaneous) --- ### Tabs ![Screenshot of the inventory with the below example tab in focus.](res/api-tabs.png) #### `i4.new_tab(name, def)` - `name` is the tab name. - `def` is the tab definition. Custom tabs can be added to the `i4` inventory as follow (example): ```Lua i4.new_tab("stuff", { description = "Stuff", image = "speech_icon.png", -- Optional, add an image next to the tab description slots = true, -- Optional, whether the inventory slots are shown or not. Disabled by default. -- -- 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, -- Build the formspec 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 -- To prevent a formspec update, return false. -- Otherwise: no need to return anything, it's automatic. 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. #### `i4.set_fs(player)` Update the current formspec. #### `i4.remove_tab(tabname)` Delete a tab by name. #### `i4.get_current_tab(player)` Return the current player tab. `player` is an `ObjectRef` to the user. #### `i4.set_tab(player[, tabname])` Set the current tab by name. `player` is an `ObjectRef` to the user. `tabname` can be omitted to get an empty tab. #### `i4.override_tab(tabname, def)` Override a tab by name. `def` is the tab definition like seen in `i4.set_tab` #### `i4.tabs` A list of registered tabs. --- ### Footer buttons ![Screenshot of the inventory with the below example footer-button.](res/api-footer_button.png) `i4.new_footer_button(name, def)` * `name` is the footer button’s name. * `def` is the button defintion. Custom footer buttons can be added beside the trash, sort, and settings buttons. For example: ```Lua i4.new_footer_button("broadcast_msg", { description = "Broadcast message", image = "speech_icon.png", -- Required, this is the button’s icon. -- -- The functions below are all optional -- -- Determine if the button is visible by a player, return false to hide the button. access = function(player, data) return true end, -- Build the formspec formspec = function(player, data, fs) -- Button style nicked from i4 directly. fs([[ style[send_msg_button,confirm_trash_no,set_home;noclip=true;font_size=16; bgimg=i4_btn9.png;bgimg_hovered=i4_btn9_hovered.png; bgimg_pressed=i4_btn9_pressed.png;bgimg_middle=4,6] ]]) fs("image[5,10.65;3,0.5;i4_bg_goto.png]") fs("field[5,10.65;3,0.5;chat_msg_field;;]") fs("button[8,10.65;1,0.5;send_msg_button;Send]") -- No need to return anything end, -- Events handling happens here fields = function(player, data, fields) if fields.key_enter_field == "chat_msg_field" or fields.send_msg_button then minetest.chat_send_all("Broadcast: " .. fields.chat_msg_field) return false -- To close a footer button’s dialogue, return false. end return true -- To keep a footer button active, return true. end, }) ``` #### `i4.remove_footer_button(button_name)` Delete a footer button by name. #### `i4.override_footer_button(button_name, def)` Override a footer button by name. `def` is the button definition like seen in `i4.new_footer_button` #### `i4.footer_buttons` A list of registered footer buttons. ### 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 i4.register_craft_type("digging", { description = "Digging", icon = "default_tool_steelpick.png", }) ``` #### Registering a custom crafting recipe ```Lua i4.register_craft { type = "digging", result = "default:cobble 2", items = {"default:stone"}, } ``` ```Lua i4.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 i4.register_craft { grid = { "X #", " ## ", "X#X#", "X X", }, key = { ['#'] = "default:wood", ['X'] = "default:glass", }, result = "default:mese 3", } ``` Multiple recipes can also be registered at once: ```Lua i4.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 i4.register_craft { url = "https://raw.githubusercontent.com/minetest-mods/i4/main/tests/test_online_recipe.json" } ``` --- ### Minitabs Manage the tabs on the right panel of the inventory. Allow to make a sensible list sorted by specific groups of items. #### `i4.new_minitab(name, def)` Add a new minitab (limited to 6). - `name` is the tab name. - `def` is the definition table. Example: ```Lua i4.new_minitab("test", { description = "Test", -- Whether this tab is visible or not. Optional. access = function(player, data) return player:get_player_name() == "singleplayer" end, -- Whether a specific item is shown in the list or not. sorter = function(item, data) return item:find"wood" end }) ``` - `player` is an `ObjectRef` to the user. - `data` are the user data. - `item` is an item name string. #### `i4.remove_minitab(name)` Remove a minitab by name. - `name` is the name of the tab to remove. #### `i4.minitabs` A list of registered minitabs. --- ### Recipe filters Recipe filters can be used to filter the recipes shown to players. Progressive mode is implemented as a recipe filter. #### `i4.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 i4.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) ``` #### `i4.set_recipe_filter(name, function(recipe, player))` Remove all recipe filters and add a new one. #### `i4.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. #### `i4.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 i4.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) ``` #### `i4.search_filters` A map of search filters, indexed by name. --- ### Sorting methods Sorting methods are used to filter the player's main inventory. #### `i4.add_sorting_method(name, def)` Add a player inventory sorting method. - `name` is the method name. - `def` is the method definition. Example: ```Lua i4.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, }) ``` #### `i4.sorting_methods` A table containing all sorting methods. --- ### Item list compression `i4` can reduce the item list size by compressing a group of items. #### `i4.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 i4.compress("default:diamondblock", { replace = "diamond", by = {"bronze", "copper", "gold", "steel", "tin"} }) ``` #### `i4.compress_groups` A map of all compressed item groups, indexed by stereotypes. --- ### Waypoints `i4` allows you to manage the waypoints of a specific player. #### `i4.add_waypoint(player_name, def)` Add a waypoint to specific player. - `player_name` is the player name. - `def` is the waypoint definition table. Example: ```Lua i4.add_waypoint("Test", { player = "singleplayer", pos = {x = 0, y = 2, z = 0}, color = 0xffff00, -- image = "heart.png" (optional) }) ``` #### `i4.remove_waypoint(player_name, waypoint_name)` Remove a waypoint for specific player. - `player_name` is the player name. - `waypoint_name` is the waypoint name. Example: ```Lua i4.remove_waypoint("singleplayer", "Test") ``` #### `i4.get_waypoints(player_name)` Return a table of all waypoints of a specific player. - `player_name` is the player name. --- ### Miscellaneous #### `i4.hud_notif(name, msg[, img])` Show a Steam-like HUD notification on the bottom-left corner of the screen. - `name` is the player name. - `msg` is the HUD message to show. - `img` (optional) is the HUD image to show (preferably 16x16 px). #### `i4.get_recipes(item)` Return a table of recipes and usages of `item`. #### `i4.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. --- **[1]** Add `i4` to the `secure.http_mods` or `secure.trusted_mods` setting in `minetest.conf`.