From 143778621e7cef8c15a5b1e8ebbe131e245f7baa Mon Sep 17 00:00:00 2001 From: flux <25628292+fluxionary@users.noreply.github.com> Date: Mon, 20 Jun 2022 14:29:13 -0700 Subject: [PATCH] documentation, bugfixes --- README.md | 56 +++-- invsaw/inventory.lua | 2 +- moreblocks/API.md | 9 +- moreblocks/api/no_faces.lua | 4 +- moreblocks/api/trap.lua | 8 +- moreblocks/init.lua | 1 + moreblocks/resources/textures.lua | 36 ++- moreblocks/settings.lua | 5 + settingtypes.txt | 9 +- stairsplus/API.md | 349 ++++++++++++++++++++++-------- stairsplus/api/group_filters.lua | 12 +- stairsplus/api/node.lua | 12 +- stairsplus/api/recipe.lua | 4 +- stairsplus/api/shape.lua | 10 +- stairsplus/api/station.lua | 68 ++++-- stairsplus/circular_saw.lua | 9 +- stairsplus/groups/builtin.lua | 2 +- stairsplus/init.lua | 2 + stairsplus/shapes/init.lua | 4 +- 19 files changed, 444 insertions(+), 158 deletions(-) create mode 100644 moreblocks/settings.lua diff --git a/README.md b/README.md index cd2f7a3..e2c2c44 100644 --- a/README.md +++ b/README.md @@ -17,18 +17,6 @@ Stairsplus adds a large variety of new shapes for registered nodes: [Source repo](https://github.com/minetest-mods/moreblocks/) -## Minetest Version compatibility - -More Blocks is currently primarily tested with Minetest 5.5.0+. -It may or may not work with newer or older versions. Issues arising in older -versions than 5.0.0 will generally not be fixed. - -## Legacy mode - -The 3.0.0 release of moreblocks introduces a "legacy" mode, which is on by default, and is meant to -allow new servers to not commit to creating as many nodes as older versions, while not breaking anything -on existing servers. See `settingtypes.txt` for available settings. - # Mods in the pack ## moreblocks @@ -41,7 +29,7 @@ Allows the creation of 49 new shapes for registered nodes. ## stairsplus_legacy -Stairs+ registrations for various mods which were formerly done automatically as part of moreblocks. +Stairsplus registrations for various mods which were formerly done automatically as part of moreblocks. ## invsaw @@ -55,13 +43,47 @@ needed to be fully rewritten to be compatible w/ their modifications to the stai # Documentation -## for players +## For players -## for admins +Use of a decent inventory manager (e.g. +[unified_inventory](https://content.minetest.net/packages/RealBadAngel/unified_inventory/) or +[i3](https://content.minetest.net/packages/jp/i3/)) will help you figure out how to craft various nodes. -## for mod makers +## For admins -see moreblocks/API.md and stairsplus/API.md +### Minetest Version compatibility + +More Blocks is currently primarily tested with Minetest 5.5.0+. It may or may not work with newer or +older versions. Issues arising in older versions will generally not be fixed. + +### Legacy mode + +The 3.0.0 release of moreblocks introduces a "legacy" mode, which is on by default, and is meant to +allow new servers to not commit to creating as many nodes as older versions, while not breaking anything +on existing servers. See `settingtypes.txt` for available settings. + +### Settings + +See `settingtypes.txt` for available settings. + +### Dependencies + +Moreblocks and stairsplus do not have hard dependencies on other mods. Invsaw depends on `unified_inventory` +and stairsplus. + +### Compatability + +Moreblocks currently supports resources from a number of mods and minetest_game. Without these installed, +some things may not be craftable, may have low-quality textures, or may not have "node sounds" registered. +If available, resources will be used from `bucket`, `default`, `rhotator`, `screwdriver`, and `vessels`. + +If the `stairsplus_legacy` mod is enabled, stairsplus nodes will automatically be registered for the following +mods, if they are available: `basic_materials`, `default`, `farming`, `gloopblocks`, `prefab`, `technic`, +and `wool`. + +## For mod makers + +See moreblocks/API.md and stairsplus/API.md. # License diff --git a/invsaw/inventory.lua b/invsaw/inventory.lua index 7f9a981..2fa3b2f 100644 --- a/invsaw/inventory.lua +++ b/invsaw/inventory.lua @@ -5,7 +5,7 @@ function invsaw.initialize_inventory(player) local inv = player:get_inventory() station.initialize_metadata(meta, inv, {"legacy"}) - station.initialize_inventory(inv) + station.initialize_inventory(inv, {"legacy"}) end function invsaw.drop_inventory(player) diff --git a/moreblocks/API.md b/moreblocks/API.md index d67bc1f..a5bd855 100644 --- a/moreblocks/API.md +++ b/moreblocks/API.md @@ -1,4 +1,9 @@ -function moreblocks.api.register_all_faces(itemstring, base, redef) +* `moreblocks.api.register_all_faces(itemstring, base, [redef])` + Register an "All Faces" variant of a tree. -function moreblocks.api.register_trap(itemstring, base, redef) +* `moreblocks.api.register_no_faces(itemstring, base, [redef])` + Register a "No Faces" variant of a tree. + +* `moreblocks.api.register_trap(itemstring, base, [redef])` + Register a "Trap" variant of a node. A trap variant is a non-solid node that looks like the original. diff --git a/moreblocks/api/no_faces.lua b/moreblocks/api/no_faces.lua index eec36ce..611f3ec 100644 --- a/moreblocks/api/no_faces.lua +++ b/moreblocks/api/no_faces.lua @@ -18,10 +18,10 @@ function moreblocks.api.register_no_faces(itemstring, base, redef) minetest.register_node(itemstring, def) minetest.register_craft({ - output = itemstring .. " 8", + output = itemstring .. " 9", recipe = { {base, base, base}, - {base, "", base}, + {base, base, base}, {base, base, base}, } }) diff --git a/moreblocks/api/trap.lua b/moreblocks/api/trap.lua index dc1a6b3..736ce8e 100644 --- a/moreblocks/api/trap.lua +++ b/moreblocks/api/trap.lua @@ -1,6 +1,8 @@ local S = moreblocks.S local cm = moreblocks.resources.craft_materials +local outline_trap_nodes = moreblocks.settings.outline_trap_nodes + function moreblocks.api.register_trap(itemstring, base, redef) local def = table.copy(minetest.registered_nodes[base]) @@ -10,8 +12,10 @@ function moreblocks.api.register_trap(itemstring, base, redef) def.short_description = S("Trap @1", def.short_description) end - for i, tile in ipairs(def.tiles) do - def.tiles[i] = tile .. "^moreblocks_trap_box.png" + if outline_trap_nodes then + for i, tile in ipairs(def.tiles) do + def.tiles[i] = tile .. "^moreblocks_trap_box.png" + end end if def.drawtype ~= "glasslike_framed_optional" then diff --git a/moreblocks/init.lua b/moreblocks/init.lua index 71c8abb..aaab52c 100644 --- a/moreblocks/init.lua +++ b/moreblocks/init.lua @@ -30,6 +30,7 @@ moreblocks = { end, } +moreblocks.dofile("settings") moreblocks.dofile("util") moreblocks.dofile("resources", "init") moreblocks.dofile("api", "init") diff --git a/moreblocks/resources/textures.lua b/moreblocks/resources/textures.lua index c99c7c2..8dff5ed 100644 --- a/moreblocks/resources/textures.lua +++ b/moreblocks/resources/textures.lua @@ -1,6 +1,40 @@ local table_set_all = moreblocks.util.table_set_all -moreblocks.resources.textures = {} +moreblocks.resources.textures = { + desert_stone = "[combine:16x16^[noalpha^[colorize:#85513e", + glass = ([[ + [combine:16x16 + :0,0=\[combine\:1x16\^[noalpha\^[colorize\:#FFF + :0,0=\[combine\:16x1\^[noalpha\^[colorize\:#FFF + :0,15=\[combine\:16x1\^[noalpha\^[colorize\:#FFF + :15,0=\[combine\:1x16\^[noalpha\^[colorize\:#FFF + ]]):gsub("%s", ""), + glass_detail = ([[ + [combine:16x16 + :0,0=\[combine\:1x16\^[noalpha\^[colorize\:#FFF + :0,0=\[combine\:16x1\^[noalpha\^[colorize\:#FFF + :0,15=\[combine\:16x1\^[noalpha\^[colorize\:#FFF + :15,0=\[combine\:1x16\^[noalpha\^[colorize\:#FFF + ]]):gsub("%s", ""), + obsidian = "default_obsidian.png", + obsidian_glass = ([[ + [combine:16x16 + :0,0=\[combine\:1x16\^[noalpha\^[colorize\:#000 + :0,0=\[combine\:16x1\^[noalpha\^[colorize\:#000 + :0,15=\[combine\:16x1\^[noalpha\^[colorize\:#000 + :15,0=\[combine\:1x16\^[noalpha\^[colorize\:#000 + ]]):gsub("%s", ""), + obsidian_glass_detail = ([[ + [combine:16x16 + :0,0=\[combine\:1x16\^[noalpha\^[colorize\:#000 + :0,0=\[combine\:16x1\^[noalpha\^[colorize\:#000 + :0,15=\[combine\:16x1\^[noalpha\^[colorize\:#000 + :15,0=\[combine\:1x16\^[noalpha\^[colorize\:#000 + ]]):gsub("%s", ""), + sandstone = "default_sandstone.png", + stone = "[combine:16x16^[noalpha^[colorize:#686463", + wood = "[combine:16x16^[noalpha^[colorize:#654321", +} if moreblocks.has.default then table_set_all(moreblocks.resources.textures, { diff --git a/moreblocks/settings.lua b/moreblocks/settings.lua new file mode 100644 index 0000000..91a1a50 --- /dev/null +++ b/moreblocks/settings.lua @@ -0,0 +1,5 @@ +local s = minetest.settings + +moreblocks.settings = { + outline_trap_nodes = s:get_bool("moreblocks.outline_trap_nodes", true), +} diff --git a/settingtypes.txt b/settingtypes.txt index 64ae917..a8e71ba 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -1,13 +1,16 @@ -# will be created if it doesn't already exist +# Will be created if it doesn't already exist invsaw.priv (Priv to use the inventory saw) string interact -# will be created if it doesn't already exist +# Will be created if it doesn't already exist invsaw.creative_priv (Priv to use the inventory saw w/out a saw item) string creative # The item that a normal player has to have to use the saw in inventory invsaw.saw_item (Saw item) string stairsplus:circular_saw -# +# Add a yellow outline around trap nodes, to make them visibly distinct +moreblocks.outline_trap_nodes (Outline trap nodes) bool true + +# I guess if you want the saw to be creative-only? stairsplus.circular_saw_crafting (Allow crafting the circular saw) bool true # Defaults to true if creative_mode is enabled. diff --git a/stairsplus/API.md b/stairsplus/API.md index 941d2b5..1429412 100644 --- a/stairsplus/API.md +++ b/stairsplus/API.md @@ -1,112 +1,290 @@ # API documentation for Stairs+ -TODO: write new API docs +In general, function arguments specified in square brackets ("[ ]") are optional. -function stairsplus.api.register_alias_single(old_node, new_node, shape) -function stairsplus.api.register_alias_all(old_node, new_node) -function stairsplus.api.register_alias_custom(old_node, new_node, list) -function stairsplus.api.register_alias_group(old_node, new_node, group) -function stairsplus.api.register_alias_groups(old_node, new_node, groups) +## Shape API -function stairsplus.api.register_alias_force_single(old_node, new_node, shape) -function stairsplus.api.register_alias_force_all(old_node, new_node) -function stairsplus.api.register_alias_force_custom(old_node, new_node, list) -function stairsplus.api.register_alias_force_group(old_node, new_node, group) -function stairsplus.api.register_alias_force_groups(old_node, new_node, groups) +For registering new shapes. + +* `stairsplus.api.register_shape(name, def)` + An example of a node_box shape: + ```lua + stairsplus.api.register_shape("slab_8", { + name_format = "slab_%s_8", + aliases = {"slab_%s"}, + description = "@1 1/2 Slab", + shape_groups = {slab = 1, legacy = 1}, + eighths = 4, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + }) + ``` + An example of a mesh shape: + ```lua + local box_slope = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.5, -0.25, -0.25, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.25, 0.5}, + {-0.5, 0.25, 0.25, 0.5, 0.5, 0.5} + } + } + + stairsplus.api.register_shape("slope", { + name_format = "slope_%s", + description = "@1 Slope", + shape_groups = {slope = 1, legacy = 1}, + eighths = 4, + drawtype = "mesh", + mesh = "stairsplus_slope.obj", + collision_box = box_slope, + selection_box = box_slope, + }) + ``` + Hopefully most of the paramaters should be self explanatory. `eighths` is the number of 1/8th node + microblocks that the shape is "worth", i.e. how much material is used in crafting it. +* `stairsplus.api.register_shape_group(shape_group, shapes)` + Register a new shape group. + +The following tables are exposed for convenience, but shouldn't be directly modified: + +* `stairsplus.api.registered_shapes` + A hash of shape definitions by name. + +* `stairsplus.api.shapes_by_group` + A hash of lists of shapes in a group, by the shape group name. -function stairsplus.api.register_passthrough_group(group) -function stairsplus.api.register_passthrough_groups(groups) -function stairsplus.api.register_scale_group(group) -function stairsplus.api.register_scale_groups(groups) -function stairsplus.api.register_ignore_group(group) -function stairsplus.api.register_ignore_groups(groups) +## Node API -function stairsplus.api.build_groups(node, shape) +These are for registering shapes of a node -function stairsplus.api.on_place(itemstack, placer, pointed_thing) -function stairsplus.api.scale_light(light_source, shape_def) +* `stairsplus.api.register_on_register_single(function(node, shaped_name))` + Register a callback for when a shaped node is registered. Mostly useful for integration with + inventory managers. + +* `stairsplus.api.register_single(node, shape, [overrides], [meta])` + Register a single shape of a node. + If no "micro_8" shape is defined, it will be defined before registering another shape. Attempting to + register an already-registered shape will not override anything. + Many of the node's properties will be inherited from the + node and shape definition, but can be manually changed via `overrides`. `meta` is used to specify + whether special logic should be used while defining the shaped node. The following values are supported: + * `ignore_type = true` + Whether to ignore the base node's `type` - usually, it is an error to try to register a shape for a + non-node. + * `ignore_drawtype = true` + Whether to ignore the base node's `drawtye`. Usually, it is an error to try to register a shape for a + non-node-like drawtype. + * `ignore_paramtype2 = true` + Whether to ignore the base node's `paramtype2`. Usually, it is an error to register a shape for node + which is not compatible with a `facedir` drawtype. + * `align_style = "node" | "user" | "world"` + Whether to override the align_style for the textures used to draw the shaped node. The default behavior + is to use the value defined by the `stairsplus.default_align_style` setting, which defaults to `"user"`. + +* `stairsplus.api.register_all(node, [overrides], [meta])` + Register all registered shapes for a node. we do not recommend using this, due to the 32767 node limit. + we recommend using + +* `stairsplus.api.register_custom(node, shapes, [overrides], [meta])` + Register variants for a custom list of shapes. +* `stairsplus.api.register_group(node, shape_group, [overrides], [meta])` + Register variants for a defined shape group. +* `stairsplus.api.register_groups(node, shape_groups, [overrides], [meta])` + Register variants for a list of shape groups. + +* `stairsplus.api.format_name(node, shape)` + Get the itemstring for a shaped variant. It is not guaranteed that the resulting itemstring actually + exists. + +* `stairsplus.api.get_shapes(node)` + Get the defined shapes for a node. Returns `nil` if no shapes are registered for the node. + +* `stairsplus.api.get_shapes_hash(node)` + Get a hash where the keys are the shapes supported by the node. Mutating the return value is not + recommended. Will return `nil` if no shapes are registered for the node. + +* `stairsplus.api.get_schema_recipe_item(node, shape_or_item)` + If `shape_or_item` is an empty string, return an empty string. If it is an itemstring (contains a ":"), + that itemstring is returned. If it is a shape, and the shape is defined for the given node, returns + the name of the shaped node. If it is a shape, but the shape is not defined for the given node, returns + `nil`. If it is the special string `"node"`, then it returns the node argument. `shape_or_item` may + optionally specify a count value, which will modify the returned value accordingly. + ```lua + assert(stairsplus.api.get_schema_recipe_item("default:stone", "node 3") == "default:stone 3") + assert(stairsplus.api.get_schema_recipe_item("default:stone", "slope 3") == "default:slope_stone 3") + ``` + +* `stairsplus.api.get_micronode(node)` + Convenience method for `stairsplus.api.get_schema_recipe_item(node, "micro_8")`. + +* `stairsplus.api.get_node_of_shaped_node(shaped_node)` + Given a shaped node, get the "base" node it was made from. + +* `stairsplus.api.get_shape_of_shaped_node(shaped_node)` + Given a shaped node, get its shape. -function stairsplus.api.register_on_register_single(func) -function stairsplus.api.format_name(node, shape) -function stairsplus.api.register_single(node, shape, overrides, meta) -function stairsplus.api.register_all(node, overrides, meta) -function stairsplus.api.register_custom(node, list, overrides, meta) -function stairsplus.api.register_group(node, group, overrides, meta) -function stairsplus.api.register_groups(node, groups, overrides, meta) -function stairsplus.api.get_shapes(node) +## Alias API --- warning: don't mutate the return value -function stairsplus.api.get_shapes_hash(node) +* `stairsplus.api.register_alias_single(old_node, new_node, shape)` + Hopefully this is self-explanatory. +* `stairsplus.api.register_alias_all(old_node, new_node)` +* `stairsplus.api.register_alias_custom(old_node, new_node, list)` +* `stairsplus.api.register_alias_group(old_node, new_node, group)` +* `stairsplus.api.register_alias_groups(old_node, new_node, groups)` --- turn a recipe item into a shape if possible -function stairsplus.api.get_schema_recipe_item(node, shape_or_item) -function stairsplus.api.get_micronode(node) +* `stairsplus.api.register_alias_force_single(old_node, new_node, shape)` + `alias_force` implies that the shapes for the "old_node" already exist, so after aliasing them, + we remove them from internal data structures. +* `stairsplus.api.register_alias_force_all(old_node, new_node)` +* `stairsplus.api.register_alias_force_custom(old_node, new_node, list)` +* `stairsplus.api.register_alias_force_group(old_node, new_node, group)` +* `stairsplus.api.register_alias_force_groups(old_node, new_node, groups)` -function stairsplus.api.get_node_of_shaped_node(shaped_node) -function stairsplus.api.get_shape_of_shaped_node(shaped_node) +## Group API -function stairsplus.api.register_on_register_craft_schema(func) -function stairsplus.api.register_craft_schema(schema) -function stairsplus.api.register_schema_crafts_for_node(node) -function stairsplus.api.register_crafts_for_shapes(recipe) +Specify how to handle a node's groups when creating a shaped variant. By default, a node's +groups have their name transformed in the same way that the node's name is, e.g. `"wood"` will become e.g. +`"micro_wood_8"`, so that the shaped nodes can't be used in crafting recipes that call for `"group:wood"`. -api.registered_shapes = {} -api.shapes_by_group = {} -function stairsplus.api.register_shape(name, def) +* `stairsplus.api.register_passthrough_group(group)` + Mark a group as "passthrough", i.e. it will not be transformed when assigned to a shaped node. + This is necessary to e.g. allow nodes to dig-able (e.g. groups like `"cracky"`, `"oddly_breakable_by_hand"`). -function stairsplus.api.station.update_infotext(pos) -function stairsplus.api.station.build_formspec(pos) -function stairsplus.api.station.get_cost(shaped_node) -function stairsplus.api.station.get_current_node(pos) -function stairsplus.api.station.can_dig(pos) -function stairsplus.api.station.on_receive_fields(pos, formname, fields, sender) -function stairsplus.api.station.update_inventory(pos, taken_stack) -function stairsplus.api.station.on_metadata_inventory_put(pos, listname, index, stack, player) -function stairsplus.api.station.on_metadata_inventory_take(pos, listname, index, stack, player) --- Moving the inventory of the station around is not allowed because it --- is a fictional inventory. Moving inventory around would be rather --- impractical and make things more difficult to calculate: -function stairsplus.api.station.allow_metadata_inventory_move() -function stairsplus.api.station.allow_metadata_inventory_put(pos, listname, index, stack, player) -function stairsplus.api.station.on_construct(pos) -function stairsplus.api.station.after_place_node(pos, placer) -function stairsplus.api.register_station(name, shape_groups, def) +* `stairsplus.api.register_passthrough_groups(groups)` + Marks a list of groups as passthrough. +* `stairsplus.api.register_scaling_group(group)` + Like "passthrough", but this scales the group's *value* depending on the # of "eighths" that the shape + is worth. This is useful for groups like `"fall_damage_add_percent"` and `"slippery"`. -api.register_craft_schema({ - output = "panel_8 6", - recipe = {{"node", "node", "node"}}, -}) +* `stairsplus.api.register_scaling_groups(groups)` + Marks a list of groups as scaling. -api.register_craft_schema({ - type = "shapeless", - output = "micro_8 7", - recipe = {"stair_inner"}, -}) +* `stairsplus.api.register_ignore_group(group)` + Marks a group as something we should just ignore entirely when creating a shaped node. Useful + for things like `"connect_to_raillike"` or `"attached_node"`, which don't makde sense for a shaped + node. -api.register_schema_crafts_for_node("default:coalblock") +* `stairsplus.api.register_ignore_groups(groups)` + Marks a list of groups to ignore. -api.register_crafts_for_shapes({ - type = "cooking", - output = "default:stone", - recipe = "default:cobblestone", - cooktime = function(eights) return 3 * eights / 8 end, -}) +* `stairsplus.api.build_groups(node, shape)` + Given a node and a shape, return the groups to assign to a shaped node. -api.register_crafts_for_shapes({ - type = "fuel", - recipe = "default:coalblock", - burntime = function(eights) return 370 * eights / 8 end, -}) +## Legacy API + +These are methods that support legacy behavior which can optionally be disabled. + +* `stairsplus.api.on_place(itemstack, placer, pointed_thing)` + Handle placing a node. The legacy behavior is to try to rotate the node based on a number of + obscure factors. It can be useful sometimes, but confusing other times. + +* `stairsplus.api.scale_light(light_source, shape_def)` + How much light should a shaped glowing node emit? The legacy behavior was to drop the value by `1`. + The non-legacy behavior scales it down more, based on the number of eighths used in the shape. + +## Crafting API + +A powerful new API for registering crafting recipes involving shaped nodes. + +* `stairsplus.api.register_on_register_craft_schema(func)` + A callback for when a schema is registered. Useful for integrating inventory managers. + +* `stairsplus.api.register_craft_schema(schema)` + Register a crafting schema, which is like a normal crafting recipe, but it may have bare "shapes" in the + recipe/output. For every node w/ the variants in the recipe, a variant involving those shaped nodes + will be created (when all mods are loaded, so you don't have to worry about the order in which things + are defined). + ```lua + stairsplus.api.register_craft_schema({ + output = "panel_8 6", + recipe = {{"node", "node", "node"}}, + }) + + stairsplus.api.register_craft_schema({ + type = "shapeless", + output = "micro_8 7", + recipe = {"stair_inner"}, + }) + ``` + +* `stairsplus.api.register_schema_crafts_for_node(node)` + Creates real recipes for all schemas using available variants of the given node. Called automatically after all + mods are loaded for every node which has shaped nodes. Currently only supports "shaped" and "shapeless" recipe + types (these don't make much sense for cooking/fuel). Given the schemas above, if called for `"default:stone"`, + this would result in the following: + ```lua + minetest.register_craft({ + output = "default:panel_stone_8 6", + recipe = {{"default:stone", "default:stone", "default:stone"}}, + }) + + minetest.register_craft({ + type = "shapeless", + output = "default:micro_stone_8 7", + recipe = {"default:stair_stone_inner"}, + }) + ``` + +* `stairsplus.api.register_crafts_for_shapes(recipe)` + For "cooking" and "fuel" recipe types, register scaled variants for all *currently defined* + shaped variants. It is an error to try to register a cooking recipe for nodes with mis-matched shapes. + ```lua + stairsplus.api.register_crafts_for_shapes({ + type = "cooking", + output = "default:stone", + recipe = "default:cobblestone", + cooktime = 3, + }) + + stairsplus.api.register_crafts_for_shapes({ + type = "fuel", + recipe = "default:coalblock", + burntime = 370, + }) + ``` + which would result in concrete recipes like + ```lua + minetest.register_craft({ + type = "cooking", + output = "default:panel_stone_8", + recipe = "default:panel_cobblestone_8", + cooktime = 0.75, + }) + + minetest.register_craft({ + type = "fuel", + recipe = "default:panel_coalblock_8", + burntime = 92.5, + }) + ``` + +## Station API + +For the creation of crafting stations which can be used to transform nodes into shaped variants, and back. + +* `stairsplus.api.register_station(name, def)` + * `name`: an itemstring + * `def`: a regular node definition, with the following parameters: + * `shape_groups`: a list of shape groups that can be created with the station (required). + * `build_formspec = function(meta, inv)` + A function which will build the formspec for the node (not required, but you probably want to use it). + * `update_metadata = function(meta, inv)` + A function which updates the node's metadata (optional) # legacy API +Methods from the previous "moreblocks" version of stairsplus which are still provided so as not to break +compatability with older mods. + * `stairsplus:register_all(modname, subname, recipeitem, fields)` - Registers a stair, slab, panel, microblock, and any other types of - nodes to be added in the future. - This also registers the node with the circular saw. Example: ```lua stairsplus:register_all("moreblocks", "wood", "default:wood", { @@ -117,5 +295,6 @@ api.register_crafts_for_shapes({ }) ``` -function stairsplus:register_alias_all(modname_old, subname_old, modname_new, subname_new) -function stairsplus:register_alias_force_all(modname_old, subname_old, modname_new, subname_new) +* `stairsplus:register_alias_all(modname_old, subname_old, modname_new, subname_new)` + +* `stairsplus:register_alias_force_all(modname_old, subname_old, modname_new, subname_new)` diff --git a/stairsplus/api/group_filters.lua b/stairsplus/api/group_filters.lua index f539d36..a765d59 100644 --- a/stairsplus/api/group_filters.lua +++ b/stairsplus/api/group_filters.lua @@ -4,7 +4,7 @@ local in_creative_inventory = stairsplus.settings.in_creative_inventory local in_craft_guide = stairsplus.settings.in_craft_guide api.passthrough_groups = {} -api.scale_groups = {} +api.scaling_groups = {} api.ignore_groups = {} function api.register_passthrough_group(group) @@ -17,13 +17,13 @@ function api.register_passthrough_groups(groups) end end -function api.register_scale_group(group) - api.scale_groups[group] = true +function api.register_scaling_group(group) + api.scaling_groups[group] = true end -function api.register_scale_groups(groups) +function api.register_scaling_groups(groups) for _, group in ipairs(groups) do - api.register_scale_group(group) + api.register_scaling_group(group) end end @@ -52,7 +52,7 @@ function api.build_groups(node, shape) if api.passthrough_groups[group] then groups[group] = value - elseif api.scale_groups[group] then + elseif api.scaling_groups[group] then groups[group] = (shape_def.eighths / 8) * value elseif not api.ignore_groups[group] then diff --git a/stairsplus/api/node.lua b/stairsplus/api/node.lua index 573e190..2552482 100644 --- a/stairsplus/api/node.lua +++ b/stairsplus/api/node.lua @@ -231,20 +231,20 @@ function api.register_all(node, overrides, meta) end end -function api.register_custom(node, list, overrides, meta) - for _, shape in ipairs(list) do +function api.register_custom(node, shapes, overrides, meta) + for _, shape in ipairs(shapes) do api.register_single(node, shape, overrides, meta) end end -function api.register_group(node, group, overrides, meta) - for _, shape in ipairs(api.shapes_by_group[group] or {}) do +function api.register_group(node, shape_group, overrides, meta) + for _, shape in ipairs(api.shapes_by_group[shape_group] or {}) do api.register_single(node, shape, overrides, meta) end end -function api.register_groups(node, groups, overrides, meta) - for _, group in ipairs(groups) do +function api.register_groups(node, shape_groups, overrides, meta) + for _, group in ipairs(shape_groups) do api.register_group(node, group, overrides, meta) end end diff --git a/stairsplus/api/recipe.lua b/stairsplus/api/recipe.lua index f0b696d..b058faf 100644 --- a/stairsplus/api/recipe.lua +++ b/stairsplus/api/recipe.lua @@ -185,7 +185,7 @@ function api.register_crafts_for_shapes(recipe) type = "cooking", output = api.get_schema_recipe_item(recipe.output, shape), recipe = api.get_schema_recipe_item(recipe.recipe, shape), - cooktime = recipe.cooktime(api.registered_shapes[shape].eighths), + cooktime = recipe.cooktime * (api.registered_shapes[shape].eighths / 8), }) end @@ -196,7 +196,7 @@ function api.register_crafts_for_shapes(recipe) minetest.register_craft({ type = "fuel", recipe = api.get_schema_recipe_item(recipe.recipe, shape), - burntime = recipe.burntime(api.registered_shapes[shape].eighths), + burntime = recipe.burntime * (api.registered_shapes[shape].eighths / 8), }) end diff --git a/stairsplus/api/shape.lua b/stairsplus/api/shape.lua index 8cf3a03..336d5cf 100644 --- a/stairsplus/api/shape.lua +++ b/stairsplus/api/shape.lua @@ -19,11 +19,19 @@ api.shapes_by_group = {} function api.register_shape(name, def) stairsplus.log("info", "registering shape %q", name) + def.shape_groups = def.shape_groups or {} api.registered_shapes[name] = def - for group in pairs(def.shape_groups or {}) do + for group in pairs(def.shape_groups) do local shapes = api.shapes_by_group[group] or {} table.insert(shapes, name) api.shapes_by_group[group] = shapes end end + +function api.register_shape_group(shape_group, shapes) + for _, shape in ipairs(shapes) do + api.registered_shapes[shape].shape_groups[shape_group] = 1 + end + api.shapes_by_group[shape_group] = shapes +end diff --git a/stairsplus/api/station.lua b/stairsplus/api/station.lua index 8f23bf6..5820170 100644 --- a/stairsplus/api/station.lua +++ b/stairsplus/api/station.lua @@ -41,14 +41,14 @@ function station.can_dig(meta, inv) return inv:is_empty("stairsplus:input") and inv:is_empty("stairsplus:micro") end -function station.on_receive_fields(meta, inv, formname, fields, sender, build_formspec, update_infotext) +function station.on_receive_fields(meta, inv, formname, fields, sender, build_formspec, update_metadata) local max = tonumber(fields.max_offered) if max and max > 0 then meta:set_int("stairsplus:max_offered", max) -- Update to show the correct number of items: station.update_inventory(meta, inv) - if update_infotext then - update_infotext(meta, inv) + if update_metadata then + update_metadata(meta, inv) end if build_formspec then @@ -121,22 +121,22 @@ function station.update_inventory(meta, inv, taken_stack) end end -function station.on_inventory_put(meta, inv, listname, index, stack, player, update_infotext) +function station.on_inventory_put(meta, inv, listname, index, stack, player, update_metadata) station.update_inventory(meta, inv) - if update_infotext then - update_infotext(meta, inv) + if update_metadata then + update_metadata(meta, inv) end end -function station.on_inventory_take(meta, inv, listname, index, stack, player, update_infotext) +function station.on_inventory_take(meta, inv, listname, index, stack, player, update_metadata) if listname == "stairsplus:output" then station.update_inventory(meta, inv, stack) else station.update_inventory(meta, inv) end - if update_infotext then - update_infotext(meta, inv) + if update_metadata then + update_metadata(meta, inv) end end @@ -181,9 +181,13 @@ function station.allow_inventory_put(meta, inv, listname, index, stack, player) return math.min(count, available_count) end -function station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_infotext) +function station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_metadata) meta:set_string("stairsplus:shape_groups", minetest.write_json(shape_groups)) - if meta:get_int("stairsplus:max_offered") == 0 then + + if meta:get_int("max_offered") ~= 0 then + meta:set_int("stairsplus:max_offered", meta:get_int("max_offered")) + + elseif meta:get_int("stairsplus:max_offered") == 0 then meta:set_int("stairsplus:max_offered", default_stack_max) end @@ -191,16 +195,21 @@ function station.initialize_metadata(meta, inv, shape_groups, build_formspec, up meta:set_string("formspec", build_formspec(meta, inv)) end - if update_infotext then - update_infotext(meta, inv) + if update_metadata then + update_metadata(meta, inv) end end -function station.initialize_inventory(inv) +function station.initialize_inventory(inv, shape_groups) + local output_size = 0 + for _, group in ipairs(shape_groups) do + output_size = output_size + #api.shapes_by_group[group] + end + inv:set_size("stairsplus:input", 1) inv:set_size("stairsplus:micro", 1) inv:set_size("stairsplus:recycle", 1) - inv:set_size("stairsplus:output", 7 * 7) + inv:set_size("stairsplus:output", output_size) -- get rid of old lists for _, listname in ipairs({"input", "micro", "recycle", "output"}) do @@ -211,12 +220,13 @@ function station.initialize_inventory(inv) end end -function station.on_construct(pos, shape_groups, build_formspec, update_infotext) +function station.on_construct(pos, shape_groups, build_formspec, update_metadata) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - station.initialize_inventory(inv) - station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_infotext) + station.initialize_inventory(inv, shape_groups) + station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_metadata) + station.update_inventory(meta, inv) end function station.after_place_node(pos, placer) @@ -226,11 +236,23 @@ function station.after_place_node(pos, placer) end end -function api.register_station(name, shape_groups, def) +function api.register_station(name, def) + local shape_groups = def.shape_groups + local build_formspec = def.build_formspec + local update_metadata = def.update_metadata + + if not shape_groups then + error("station requires shape_groups defined") + end + + def.shape_groups = nil + def.build_formspec = nil + def.update_metadata = nil + def.after_place_node = def.after_place_node or station.after_place_node def.on_construct = def.on_construct or function(pos) - return station.on_construct(pos, shape_groups, def.build_formspec, def.update_infotext) + return station.on_construct(pos, shape_groups, build_formspec, update_metadata) end def.can_dig = def.can_dig or @@ -245,7 +267,7 @@ function api.register_station(name, shape_groups, def) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() return station.on_receive_fields( - meta, inv, formname, fields, sender, def.build_formspec, def.update_infotext + meta, inv, formname, fields, sender, build_formspec, update_metadata ) end @@ -267,14 +289,14 @@ function api.register_station(name, shape_groups, def) function(pos, listname, index, stack, player) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - return station.on_inventory_put(meta, inv, listname, index, stack, player, def.update_infotext) + return station.on_inventory_put(meta, inv, listname, index, stack, player, update_metadata) end def.on_metadata_inventory_take = def.on_metadata_inventory_take or function(pos, listname, index, stack, player) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - return station.on_inventory_take(meta, inv, listname, index, stack, player, def.update_infotext) + return station.on_inventory_take(meta, inv, listname, index, stack, player, update_metadata) end def._stairsplus_shape_groups = shape_groups diff --git a/stairsplus/circular_saw.lua b/stairsplus/circular_saw.lua index 80e404d..d3fdbf7 100644 --- a/stairsplus/circular_saw.lua +++ b/stairsplus/circular_saw.lua @@ -56,7 +56,7 @@ function circular_saw.build_formspec(meta, inv) ) end -function circular_saw.update_infotext(meta, inv) +function circular_saw.update_metadata(meta, inv) local parts = {} if station.can_dig(meta, inv) then table.insert(parts, S("Circular Saw is empty")) @@ -70,7 +70,7 @@ function circular_saw.update_infotext(meta, inv) meta:set_string("infotext", table.concat(parts, " ")) end -api.register_station("stairsplus:circular_saw", {"legacy"}, { +api.register_station("stairsplus:circular_saw", { description = S("Circular Saw"), drawtype = "nodebox", node_box = { @@ -97,8 +97,9 @@ api.register_station("stairsplus:circular_saw", {"legacy"}, { groups = {choppy = 2, oddly_breakable_by_hand = 2}, sounds = stairsplus.resources.sounds.wood, + shape_groups = {"legacy"}, build_formspec = circular_saw.build_formspec, - update_infotext = circular_saw.update_infotext, + update_metadata = circular_saw.update_metadata, }) local cm = stairsplus.resources.craft_materials @@ -121,6 +122,6 @@ minetest.register_lbm({ run_at_every_load = false, action = function(pos, node) local def = minetest.registered_nodes[node.name] - def.on_construct(pos) + def.on_construct(pos, {"legacy"}, circular_saw.build_formspec, circular_saw.update_metadata) end, }) diff --git a/stairsplus/groups/builtin.lua b/stairsplus/groups/builtin.lua index dcaae0d..2ce9f2a 100644 --- a/stairsplus/groups/builtin.lua +++ b/stairsplus/groups/builtin.lua @@ -9,7 +9,7 @@ stairsplus.api.register_passthrough_groups({ "disable_jump", }) -stairsplus.api.register_scale_groups({ +stairsplus.api.register_scaling_groups({ "bouncy", "fall_damage_add_percent", "slippery", diff --git a/stairsplus/init.lua b/stairsplus/init.lua index 67b30ea..4f279a6 100644 --- a/stairsplus/init.lua +++ b/stairsplus/init.lua @@ -43,3 +43,5 @@ stairsplus.dofile("resources", "init") stairsplus.dofile("circular_saw") stairsplus.dofile("compat2", "init") + +stairsplus.dofile("aliases") diff --git a/stairsplus/shapes/init.lua b/stairsplus/shapes/init.lua index ff1ffac..7a04245 100644 --- a/stairsplus/shapes/init.lua +++ b/stairsplus/shapes/init.lua @@ -4,5 +4,5 @@ stairsplus.dofile("shapes", "slabs") stairsplus.dofile("shapes", "slopes") stairsplus.dofile("shapes", "stairs") -stairsplus.api.shapes_by_group.basic = table.copy(stairsplus.settings.basic_shapes) -stairsplus.api.shapes_by_group.common = table.copy(stairsplus.settings.common_shapes) +stairsplus.api.register_shape_group("basic", stairsplus.settings.basic_shapes) +stairsplus.api.register_shape_group("common", stairsplus.settings.common_shapes)