compatability and legacy mostly done. schema recipes are all messed up for some reason.

This commit is contained in:
flux 2022-06-15 16:18:11 -07:00
parent 38f610a200
commit 92ce2e1f52
47 changed files with 1232 additions and 710 deletions

View File

@ -17,5 +17,8 @@ jobs:
- name: luacheck moreblocks
run: $HOME/.luarocks/bin/luacheck --config ./moreblocks/.luacheckrc -q ./moreblocks
- name: luacheck stairsplus (expected to fail until more work is done)
- name: luacheck stairsplus
run: $HOME/.luarocks/bin/luacheck --config ./stairsplus/.luacheckrc -q ./stairsplus
- name: luacheck stairsplus_legacy
run: $HOME/.luarocks/bin/luacheck --config ./stairsplus/.luacheckrc -q ./stairsplus_legacy

View File

@ -14,24 +14,26 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- turned into a modpack (i.e. properly separated moreblocks and stairsplus)
- refactored and rewrote a ton of stuff
- got rid of some dead code (e.g. "ownership.lua")
- more API for creating node variants, e.g. trap nodes, all_faces, shapes
- parameterized resources (sounds, textures, craft materials) to make it easier to integrate w/ other minetest "games"
- actually implement luachecking - stop ignoring problems
- fix some unreported bugs (e.g. dependencies which weren't declared, unused code)
- i'm rewriting large parts of the mod and creating a sane API, i'm bumping the version
- create a default-on "legacy" mode to allow new servers to not commit to creating so many useless shapes by default
- i'm rewriting large parts of the mod and creating a saner API, i'm bumping the version
- \[moreblocks] more API for creating node variants, e.g. trap nodes, all_faces, shapes
- \[stairsplus] create a default-on "legacy" mode to allow new servers to not commit to creating so many useless nodes and shapes by default
### Fixed
- [stairsplus:register_custom_subset computes the wrong "cost" for elements](https://github.com/minetest-mods/moreblocks/issues/190)
- \* [Material disappears from Recycle output slot](https://github.com/minetest-mods/moreblocks/issues/189)
- \* [Would it be possible to port to mineclone?](https://github.com/minetest-mods/moreblocks/issues/188) - no plan to
actually make moreblocks mineclone-aware, but will lay the groundwork to make this very easy.
- [Material disappears from Recycle output slot](https://github.com/minetest-mods/moreblocks/issues/189)
- [Would it be possible to port to mineclone?](https://github.com/minetest-mods/moreblocks/issues/188) - no plan to
actually make moreblocks mineclone-aware, but laid the groundwork to make this very easy.
- [Minor issue causing warnings in MT 5.5.0 with texture alpha clipping](https://github.com/minetest-mods/moreblocks/issues/187)
- maybe: [world aligned textures](https://github.com/minetest-mods/moreblocks/issues/179)
- maybe: [Make microblocks work for nodes with layered textures](Make microblocks work for nodes with layered textures)
- \* [Make variants of nodes that can burn also burnable](https://github.com/minetest-mods/moreblocks/issues/177)
- [Add screenshot in README.md #151](https://github.com/minetest-mods/moreblocks/issues/151)
- maybe: [Make microblocks work for nodes with layered textures](https://github.com/minetest-mods/moreblocks/issues/178)
- [Make variants of nodes that can burn also burnable](https://github.com/minetest-mods/moreblocks/issues/177)
- \* [Add screenshot in README.md](https://github.com/minetest-mods/moreblocks/issues/151)
- \* [Slab back to full block](https://github.com/minetest-mods/moreblocks/issues/112)
- [Conserve left-over microblocks](https://github.com/minetest-mods/moreblocks/pull/108)
- maybe some of the other bugs/PRS, but they mostly either seem to be fixed or unfixable
\* not yet fixed, but planned

View File

@ -9,8 +9,7 @@ world block sandbox game.
### Download the mod
To install More Blocks, clone this Git repository into your Minetest's `mods/`
directory:
To install More Blocks, clone this Git repository into your Minetest's `mods/` directory:
```bash
git clone https://github.com/minetest-mods/moreblocks.git
@ -20,6 +19,8 @@ You can also
[download a ZIP archive](https://github.com/minetest-mods/moreblocks/archive/master.zip)
of More Blocks.
It is also available through the in-game `Content` tab.
### Enable the mod
Once you have installed More Blocks, you need to enable it in Minetest.
@ -58,19 +59,18 @@ on that line.
## Version compatibility
More Blocks is currently primarily tested with Minetest 5.3.0.
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.
## License
Copyright © 2011-2020 Hugo Locurcio and contributors
Copyright © 2011-2022 Hugo Locurcio and contributors
- More Blocks code is licensed under the zlib license, see
[`LICENSE.md`](LICENSE.md) for details.
- This is an altered version of the code which is not distributed by Hugo Locurcio.
- Unless otherwise specified, More Blocks textures are licensed under
[CC BY-SA 3.0 Unported](https://creativecommons.org/licenses/by-sa/3.0/).
`moreblocks_copperpatina.png` was created by pithydon, and is licensed under
[CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/).
- `moreblocks_copperpatina.png` was created by pithydon, and is licensed under
[CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/).

23
TODO.md Normal file
View File

@ -0,0 +1,23 @@
please don't accept a PR with this file, this is meant to be a checklist of things that i think need to be done before
\[wip] status can be removed
### ag TODO
```
stairsplus/craft_schemas.lua
3:-- TODO: add more of these, e.g. crafting/combining micro/panel/slabs, convert any single node to micro_8, etc.
stairsplus/api/station.lua
13:TODO this isn't actually modular in the right way for adding different kinds of stations
14:TODO e.g. some of this stuff is very particular to the saw itself
stairsplus/API.md
3:TODO: write new API docs
```
### other things
* finish legacy support
* finish compatability support
* create a way to analyze and reduce node_count
* ? create a way for players to request nodes or groups?

View File

@ -76,6 +76,10 @@ if moreblocks.has.stairsplus and cm.jungle_wood then
stairsplus.api.register_alias_all("moreblocks:jungle_wood", cm.jungle_wood)
end
if moreblocks.has.stairsplus then
stairsplus.api.register_alias_all("moreblocks:split_stone_tile_alt", "moreblocks:checker_stone_tile")
end
minetest.register_lbm({
name = "moreblocks:reduce_wood_tile_redundancy",
nodenames = {

View File

@ -39,7 +39,6 @@ moreblocks = {
end,
}
moreblocks.dofile("settings")
moreblocks.dofile("util")
moreblocks.dofile("resources", "init")
moreblocks.dofile("api", "init")

View File

@ -1,9 +0,0 @@
--[[
More Blocks: configuration handling
Copyright © 2011-2020 Hugo Locurcio and contributors.
Licensed under the zlib license. See LICENSE.md for more information.
--]]
moreblocks.settings = {
}

View File

@ -1,5 +1,8 @@
# API documentation for Stairs+
TODO: write new API docs
# legacy API
* `stairsplus:register_all(modname, subname, recipeitem, fields)`

View File

@ -15,6 +15,24 @@ function api.register_alias_all(old_node, new_node)
end
end
function api.register_alias_custom(old_node, new_node, list)
for _, shape in ipairs(list) do
api.register_alias_single(old_node, new_node, shape)
end
end
function api.register_alias_group(old_node, new_node, group)
for _, shape in ipairs(api.shapes_by_group[group] or {}) do
api.register_alias_single(old_node, new_node, shape)
end
end
function api.register_alias_groups(old_node, new_node, groups)
for _, group in ipairs(groups) do
api.register_alias_group(old_node, new_node, group)
end
end
function api.register_alias_force_single(old_node, new_node, shape)
local old_shaped_node = api.format_name(old_node, shape)
local new_shaped_node = api.format_name(new_node, shape)
@ -48,3 +66,21 @@ function api.register_alias_force_all(old_node, new_node)
api.register_alias_force_single(old_node, new_node, shape)
end
end
function api.register_alias_force_custom(old_node, new_node, list)
for _, shape in ipairs(list) do
api.register_alias_force_single(old_node, new_node, shape)
end
end
function api.register_alias_force_group(old_node, new_node, group)
for _, shape in ipairs(api.shapes_by_group[group] or {}) do
api.register_alias_force_single(old_node, new_node, shape)
end
end
function api.register_alias_force_groups(old_node, new_node, groups)
for _, group in ipairs(groups) do
api.register_alias_force_group(old_node, new_node, group)
end
end

35
stairsplus/api/groups.lua Normal file
View File

@ -0,0 +1,35 @@
local api = stairsplus.api
api.passthrough_groups = {}
api.scale_groups = {}
api.ignore_groups = {}
function api.register_passthrough_group(group)
api.passthrough_groups[group] = true
end
function api.register_passthrough_groups(groups)
for _, group in ipairs(groups) do
api.register_passthrough_group(group)
end
end
function api.register_scale_group(group)
api.scale_groups[group] = true
end
function api.register_scale_groups(groups)
for _, group in ipairs(groups) do
api.register_scale_group(group)
end
end
function api.register_ignore_group(group)
api.ignore_groups[group] = true
end
function api.register_ignore_groups(groups)
for _, group in ipairs(groups) do
api.register_ignore_group(group)
end
end

View File

@ -1,7 +1,8 @@
stairsplus.api = {}
stairsplus.dofile("api", "shape")
stairsplus.dofile("api", "groups")
stairsplus.dofile("api", "node")
stairsplus.dofile("api", "station")
stairsplus.dofile("api", "alias")
stairsplus.dofile("api", "recipe")
stairsplus.dofile("api", "station")

View File

@ -10,7 +10,9 @@ local table_sort_keys = stairsplus.util.table_sort_keys
local S = stairsplus.S
local legacy_mode = stairsplus.settings.legacy_mode
local legacy_place_mechanic = stairsplus.settings.legacy_place_mechanic
local in_creative_inventory = stairsplus.settings.in_creative_inventory
local default_align_style = stairsplus.settings.default_align_style
api.nodes_by_shape = {}
api.shapes_by_node = {}
@ -25,57 +27,175 @@ local function scale_light(light_source, shape_def)
return math.max(1, math.min(math.round(light_source * shape_def.eighths / 4), light_source))
end
local function check_node_validity(node_def, meta)
local type_ = node_def.type
if not meta.ignore_type and type_ ~= "node" then
error(("cannot register non-node %q w/ stairsplus"):format(node_def.name))
end
local drawtype = node_def.drawtype
if not meta.ignore_drawtype and (
drawtype == "airlike" or
drawtype == "liquid" or
drawtype == "flowingliquid" or
drawtype == "torchlike" or
drawtype == "signlike" or
drawtype == "plantlike" or
drawtype == "firelike" or
drawtype == "fencelike" or
drawtype == "raillike" or
drawtype == "nodebox" or
drawtype == "mesh" or
drawtype == "plantlike_rooted"
) then
error(("cannot register %q w/ drawtype %q w/ stairsplus"):format(node_def.name, drawtype))
end
local paramtype2 = node_def.paramtype2
if not meta.ignore_paramtype2 and (
paramtype2 == "flowingliquid" or
paramtype2 == "wallmounted" or
paramtype2 == "leveled" or
paramtype2 == "degrotate" or
paramtype2 == "meshoptions" or
paramtype2 == "color" or
paramtype2 == "colorfacedir" or
paramtype2 == "colorwallmounted" or
paramtype2 == "glasslikeliquidlevel" or
paramtype2 == "colordegrotate"
) then
error(("cannot register %q w/ paramtype2 %q w/ stairsplus"):format(node_def.name, paramtype2))
end
end
local function build_groups(shape, node_groups)
local groups = {
[("shape_%s"):format(shape)] = 1,
not_in_creative_inventory = in_creative_inventory and 1 or 0,
}
local shape_def = api.registered_shapes[shape]
for group, value in pairs(node_groups) do
if api.passthrough_groups[group] then
groups[group] = value
elseif api.scale_groups[group] then
groups[group] = (shape_def.eighths / 8) * value
elseif not api.ignore_groups[group] then
groups[shape_def.name_format:format(group)] = value
end
end
return groups
end
local wall_right_dirmap = {9, 18, 7, 12}
local wall_left_dirmap = {11, 16, 5, 14}
local ceil_dirmap = {20, 23, 22, 21}
function api.legacy_on_place(itemstack, placer, pointed_thing)
if not minetest.is_player(placer) then
return minetest.item_place(itemstack, placer, pointed_thing)
end
local controls = placer:get_player_control()
local sneak = controls.sneak
local aux = controls.aux1
local shaped_node_name = itemstack:get_name()
local shape = api.get_shape_of_shaped_node(shaped_node_name)
local under = pointed_thing.under
local under_node = minetest.get_node(under)
local under_shape = api.get_shape_of_shaped_node(under_node.name)
local same_cat = shape == under_shape
-- standard (floor) facedir, also used for sneak placement against the lower half of the wall
local p2 = placer and minetest.dir_to_facedir(placer:get_look_dir()) or 0
-- check which face and which quadrant we are interested in
-- this is used both to check if we're handling parallel placement in the same-category case,
-- and in general for sneak placement
local face_pos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
local face_off = vector.subtract(face_pos, under)
-- we cannot trust face_off to tell us the correct directionif the
-- under node has a non-standard shape, so use the distance between under and above
local wallmounted = minetest.dir_to_wallmounted(vector.subtract(pointed_thing.above, under))
if same_cat and not aux then
p2 = under_node.param2
-- flip if placing above or below an upright or upside-down node
-- TODO should we also flip when placing next to a side-mounted node?
if wallmounted < 2 then
if p2 < 4 then
p2 = (p2 + 2) % 4
p2 = ceil_dirmap[p2 + 1]
elseif p2 > 19 then
p2 = ceil_dirmap[p2 - 19] - 20
p2 = (p2 + 2) % 4
end
end
else
-- for same-cat placement, aux is used to disable param2 copying
if same_cat then
aux = not aux
end
local remap = nil
-- standard placement against the wall
local use_wallmap = (wallmounted > 1 and not sneak) or (wallmounted < 2 and sneak)
-- standard placement against the ceiling, or sneak placement against the upper half of the wall
local use_ceilmap = wallmounted == 1 and not sneak
use_ceilmap = use_ceilmap or (wallmounted > 1 and sneak and face_off.y > 0)
if use_wallmap then
local left = (p2 == 0 and face_off.x < 0) or
(p2 == 1 and face_off.z > 0) or
(p2 == 2 and face_off.x > 0) or
(p2 == 3 and face_off.z < 0)
if aux then
left = not left
end
remap = left and wall_left_dirmap or wall_right_dirmap
elseif use_ceilmap then
remap = ceil_dirmap
end
if aux then
p2 = (p2 + 2) % 4
end
if remap then
p2 = remap[p2 + 1]
end
end
return minetest.item_place(itemstack, placer, pointed_thing, p2)
end
function api.format_name(node, shape)
local mod, name = node:match("^([^:]+):(.*)$")
local shape_def = api.registered_shapes[shape]
return ("%s:%s"):format(mod, shape_def.name_format:format(name))
end
local function check_node_validity(node_def)
if node_def.type ~= "node" then
error(("cannot register non-node %q w/ stairsplus"):format(node_def.name))
end
if (
node_def.drawtype == "airlike" or
node_def.drawtype == "liquid" or
node_def.drawtype == "flowingliquid" or
node_def.drawtype == "torchlike" or
node_def.drawtype == "signlike" or
node_def.drawtype == "plantlike" or
node_def.drawtype == "firelike" or
node_def.drawtype == "fencelike" or
node_def.drawtype == "raillike" or
node_def.drawtype == "nodebox" or
node_def.drawtype == "mesh" or
node_def.drawtype == "plantlike_rooted"
) then
error(("cannot register %q w/ drawtype %q w/ stairsplus"):format(node_def.name, node_def.drawtype))
end
if (
node_def.paramtype2 == "flowingliquid" or
node_def.paramtype2 == "wallmounted" or
node_def.paramtype2 == "leveled" or
node_def.paramtype2 == "degrotate" or
node_def.paramtype2 == "meshoptions" or
node_def.paramtype2 == "color" or
node_def.paramtype2 == "colorfacedir" or
node_def.paramtype2 == "colorwallmounted" or
node_def.paramtype2 == "glasslikeliquidlevel" or
node_def.paramtype2 == "colordegrotate"
) then
error(("cannot register %q w/ paramtype2 %q w/ stairsplus"):format(node_def.name, node_def.paramtype2))
end
end
function api.register_single(node, shape, overrides)
function api.register_single(node, shape, overrides, meta)
stairsplus.log("info", "registering %s %s", shape, node)
meta = meta or {}
overrides = overrides or {}
local node_def = table.copy(minetest.registered_nodes[node])
check_node_validity(node_def)
check_node_validity(node_def, meta)
if shape ~= "micro_8" and not (api.nodes_by_shape.micro_8 or {})[node] then
-- always make sure a microblock exists
api.register_single(node, "micro_8", overrides)
api.register_single(node, "micro_8", overrides, meta)
end
if (api.nodes_by_shape[shape] or {})[node] then
@ -84,15 +204,7 @@ function api.register_single(node, shape, overrides)
local shape_def = api.registered_shapes[shape]
local groups = {
[shape] = 1,
not_in_creative_inventory = in_creative_inventory and 1 or 0,
}
for group, value in pairs(node_def.groups) do
groups[shape_def.name_format:format(group)] = value
end
-- shaped_node definition
local def = {
description = S(shape_def.description, node_def.description or node),
@ -105,6 +217,8 @@ function api.register_single(node, shape, overrides)
paramtype2 = shape_def.paramtype2 or "facedir",
light_source = scale_light(node_def.light_source, shape_def),
groups = build_groups(shape, node_def.groups),
tiles = node_def.tiles,
overlay_tiles = node_def.overlay_tiles,
use_texture_alpha = node_def.use_texture_alpha,
@ -117,9 +231,9 @@ function api.register_single(node, shape, overrides)
diggable = node_def.diggable,
climbable = node_def.climbable,
move_resistance = node_def.move_resistance,
groups = groups,
}
-- see-through nodes tend to look better if we just use the first tile
if (node_def.drawtype or ""):match("glass") then
if #def.tiles > 1 then
def.tiles = {def.tiles[1]}
@ -134,6 +248,7 @@ function api.register_single(node, shape, overrides)
def.short_description = S(shape_def.description, node_def.short_description)
end
-- if there's a drop defined, and we can drop a shaped version, do so
if node_def.drop then
local item = api.get_shaped_node(node_def.drop, shape)
if item then
@ -141,11 +256,48 @@ function api.register_single(node, shape, overrides)
end
end
table_set_all(def, overrides or {})
if legacy_place_mechanic then
def.on_place = api.legacy_on_place
end
table_set_all(def, overrides)
-- set backface_culling and align_style
local align_style = meta.align_style or default_align_style
for i, tile in ipairs(def.tiles) do
if type(tile) == "string" then
def.tiles[i] = {
name = tile,
backface_culling = true,
align_style = align_style,
}
elseif not (tile.animation or tile.color) then
tile.backface_culling = true
tile.align_style = align_style
end
end
if def.overlay_tiles then
for i, tile in ipairs(def.overlay_tiles) do
if type(tile) == "string" then
def.tiles[i] = {
name = tile,
backface_culling = true,
align_style = align_style,
}
elseif not (tile.animation or tile.color) then
tile.backface_culling = true
tile.align_style = align_style
end
def.overlay_tiles[i] = tile
end
end
-- register node
local shaped_name = api.format_name(node, shape)
minetest.register_node(":" .. shaped_name, def)
-- alias old name formats
if shape_def.aliases then
local mod, name = node:match("^([^:]+):(.*)$")
for _, alias in ipairs(shape_def.aliases) do
@ -163,29 +315,31 @@ function api.register_single(node, shape, overrides)
local shapes = api.shapes_by_node[node] or {}
shapes[shape] = true
api.shapes_by_node[node] = shapes
return shaped_name
end
function api.register_all(node, overrides)
function api.register_all(node, overrides, meta)
for shape in pairs(api.registered_shapes) do
api.register_single(node, shape, overrides)
api.register_single(node, shape, overrides, meta)
end
end
function api.register_custom(node, list, overrides)
function api.register_custom(node, list, overrides, meta)
for _, shape in ipairs(list) do
api.register_single(node, shape, overrides)
api.register_single(node, shape, overrides, meta)
end
end
function api.register_group(node, group, overrides)
function api.register_group(node, group, overrides, meta)
for _, shape in ipairs(api.shapes_by_group[group] or {}) do
api.register_single(node, shape, overrides)
api.register_single(node, shape, overrides, meta)
end
end
function api.register_groups(node, groups, overrides)
function api.register_groups(node, groups, overrides, meta)
for _, group in ipairs(groups) do
api.register_group(node, group, overrides)
api.register_group(node, group, overrides, meta)
end
end
@ -193,21 +347,35 @@ function api.get_shapes(node)
return table_sort_keys(api.shapes_by_node[node])
end
-- warning: don't mutate the return value
function api.get_shapes_hash(node)
return api.shapes_by_node[node]
end
function api.get_shaped_node(node, shape_or_item)
local t = ItemStack(shape_or_item):to_table()
if api.registered_shapes[t.name] then
t.name = api.format_name(node, t.name)
elseif t.name == "node" then
t.name = node
local name, count = shape_or_item:match("^([^ ]+) (%d+)")
if not name then
name = shape_or_item
end
return ItemStack(t):to_string()
if name == "" then
return ""
end
count = tonumber(count)
if api.registered_shapes[name] then
name = api.format_name(node, name)
elseif name == "node" then
name = node
end
if count then
return ("%s %s"):format(name, count)
else
return name
end
end
function api.get_micronode(node)

View File

@ -33,9 +33,15 @@ api.register_crafts_for_shapes({
local api = stairsplus.api
local function is_valid_item(item, shapes)
local item_name = ItemStack(item):get_name()
local item_name = item:match("^([^ ]*)")
return shapes[item_name] or item_name == "" or item_name:match(":")
return shapes[item_name] or item_name == "" or item_name == "node" or item_name:match(":")
end
local function is_valid_output(item, shapes)
local item_name = item:match("^([^ ]+)")
return shapes[item_name] or item_name == "node" or item_name:match(":")
end
local function verify_schema(schema)
@ -45,14 +51,14 @@ local function verify_schema(schema)
table.insert(problems, ("unimplemented schema type %q"):format(schema.type))
end
if not is_valid_item(schema.output, api.registered_shapes) then
if not is_valid_output(schema.output, api.registered_shapes) then
table.insert(problems, ("don't know how to handle output %q"):format(schema.output))
end
if schema.replacements then
for _, replacement in ipairs(schema.replacements) do
for _, item in ipairs(replacement) do
if not is_valid_item(schema.output, api.registered_shapes) then
if not is_valid_item(item, api.registered_shapes) then
table.insert(problems, ("don't know how to handle replacement item %q"):format(item))
end
end
@ -61,7 +67,7 @@ local function verify_schema(schema)
if schema.type == "shapeless" then
for _, item in ipairs(schema.recipe) do
if not is_valid_item(schema.output, api.registered_shapes) then
if not is_valid_item(item, api.registered_shapes) then
table.insert(problems, ("don't know how to handle craft item %q"):format(item))
end
end
@ -69,7 +75,7 @@ local function verify_schema(schema)
else
for _, row in ipairs(schema.recipe) do
for _, item in ipairs(row) do
if not is_valid_item(schema.output, api.registered_shapes) then
if not is_valid_item(item, api.registered_shapes) then
table.insert(problems, ("don't know how to handle craft item %q"):format(item))
end
end
@ -89,11 +95,13 @@ function api.register_craft_schema(schema)
error(problems)
end
stairsplus.log("info", "registering craft schema %s", minetest.write_json(schema))
table.insert(api.registered_recipe_schemas, schema)
end
local function has_the_right_shapes(schema, shapes)
if not is_valid_item(schema.output, shapes) then
if not is_valid_output(schema.output, shapes) then
return false
end
@ -130,15 +138,19 @@ end
local function register_for_schema(node, shapes, schema)
local recipe = table.copy(schema)
if shapes[recipe.output] then
if is_valid_output(recipe.output, shapes) then
recipe.output = api.get_shaped_node(node, recipe.output)
else
return
end
if recipe.replacements then
for _, replacement in ipairs(recipe.replacements) do
for i, item in ipairs(replacement) do
if shapes[item] then
if is_valid_item(item, shapes) then
replacement[i] = api.get_shaped_node(node, item)
else
return
end
end
end
@ -146,21 +158,27 @@ local function register_for_schema(node, shapes, schema)
if recipe.type == "shapeless" then
for i, item in ipairs(recipe.recipe) do
if shapes[item] then
if is_valid_item(item, shapes) then
recipe.recipe[i] = api.get_shaped_node(node, item)
else
return
end
end
elseif recipe.type == "shaped" or recipe.type == nil then
for _, row in ipairs(schema.recipe) do
for i, item in ipairs(row) do
if shapes[item] then
if is_valid_item(item, shapes) then
row[i] = api.get_shaped_node(node, item)
else
return
end
end
end
end
stairsplus.log("info", "registering recipe %s", minetest.serialize(recipe):sub(#("return ")))
minetest.register_craft(recipe)
end

View File

@ -18,6 +18,7 @@ api.registered_shapes = {}
api.shapes_by_group = {}
function api.register_shape(name, def)
stairsplus.log("info", "registering shape %q", name)
api.registered_shapes[name] = def
for group in pairs(def.shape_groups or {}) do

View File

@ -9,6 +9,11 @@ local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) o
local station = {}
--[[
TODO this isn't actually modular in the right way for adding different kinds of stations
TODO e.g. some of this stuff is very particular to the saw itself
]]
local function get_cost(shaped_node)
if shaped_node == "" then
return 0

View File

@ -1,3 +1,5 @@
stairsplus.compat = {}
stairsplus.dofile("compat", "stairs")
stairsplus.dofile("compat", "legacy")

View File

@ -1,4 +1,4 @@
-- legacy: register all the expected variants for e.g. default, wool, gloopblocks, etc.
-- legacy: export old API for mods which depend on it
-- provide a configuration option to *disable* legacy. it must be enabled by default, to prevent breaking
-- existing servers
local api = stairsplus.api

View File

@ -1,163 +0,0 @@
--[[
More Blocks: registrations
Copyright © 2011-2020 Hugo Locurcio and contributors.
Licensed under the zlib license. See LICENSE.md for more information.
--]]
local S = stairsplus.S
-- default registrations
if minetest.get_modpath("default") then
local default_nodes = { -- Default stairs/slabs/panels/microblocks:
"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",
}
for _, name in pairs(default_nodes) do
local mod = "default"
local nodename = mod .. ":" .. name
local ndef = table.copy(minetest.registered_nodes[nodename])
ndef.sunlight_propagates = true
-- Stone and desert_stone drop cobble and desert_cobble respectively.
if type(ndef.drop) == "string" then
ndef.drop = ndef.drop:gsub(".+:", "")
end
-- Use the primary tile for all sides of cut glasslike nodes and disregard paramtype2.
if #ndef.tiles > 1 and ndef.drawtype and ndef.drawtype:find("glass") then
ndef.tiles = {ndef.tiles[1]}
ndef.paramtype2 = nil
end
mod = "moreblocks"
stairsplus:register_all(mod, name, nodename, ndef)
minetest.register_alias_force("stairs:stair_" .. name, mod .. ":stair_" .. name)
minetest.register_alias_force("stairs:stair_outer_" .. name, mod .. ":stair_" .. name .. "_outer")
minetest.register_alias_force("stairs:stair_inner_" .. name, mod .. ":stair_" .. name .. "_inner")
minetest.register_alias_force("stairs:slab_" .. name, mod .. ":slab_" .. name)
end
end
-- farming registrations
if minetest.get_modpath("farming") then
local farming_nodes = {"straw"}
for _, name in pairs(farming_nodes) do
local mod = "farming"
local nodename = mod .. ":" .. name
local ndef = table.copy(minetest.registered_nodes[nodename])
ndef.sunlight_propagates = true
mod = "moreblocks"
stairsplus:register_all(mod, name, nodename, ndef)
minetest.register_alias_force("stairs:stair_" .. name, mod .. ":stair_" .. name)
minetest.register_alias_force("stairs:stair_outer_" .. name, mod .. ":stair_" .. name .. "_outer")
minetest.register_alias_force("stairs:stair_inner_" .. name, mod .. ":stair_" .. name .. "_inner")
minetest.register_alias_force("stairs:slab_" .. name, mod .. ":slab_" .. name)
end
end
-- wool registrations
if minetest.get_modpath("wool") then
local dyes = {"white", "grey", "black", "red", "yellow", "green", "cyan",
"blue", "magenta", "orange", "violet", "brown", "pink",
"dark_grey", "dark_green"}
for _, name in pairs(dyes) do
local mod = "wool"
local nodename = mod .. ":" .. name
local ndef = table.copy(minetest.registered_nodes[nodename])
ndef.sunlight_propagates = true
stairsplus:register_all(mod, name, nodename, ndef)
end
end
-- basic_materials, keeping the original other-mod-oriented names
-- for backwards compatibility
if minetest.get_modpath("basic_materials") then
stairsplus:register_all("technic", "concrete", "basic_materials:concrete_block", {
description = S("Concrete"),
tiles = {"basic_materials_concrete_block.png", },
groups = {cracky = 1, level = 2, concrete = 1},
sounds = stairsplus.node_sound_stone_defaults(),
})
minetest.register_alias("prefab:concrete_stair", "technic:stair_concrete")
minetest.register_alias("prefab:concrete_slab", "technic:slab_concrete")
stairsplus:register_all("gloopblocks", "cement", "basic_materials:cement_block", {
description = S("Cement"),
tiles = {"basic_materials_cement_block.png"},
groups = {cracky = 2, not_in_creative_inventory = 1},
sounds = stairsplus.node_sound_stone_defaults(),
sunlight_propagates = true,
})
stairsplus:register_all("technic", "brass_block", "basic_materials:brass_block", {
description = S("Brass Block"),
groups = {cracky = 1, not_in_creative_inventory = 1},
tiles = {"basic_materials_brass_block.png"},
})
end
-- Alias cuts of split_stone_tile_alt which was renamed checker_stone_tile.
stairsplus:register_alias_all("moreblocks", "split_stone_tile_alt", "moreblocks", "checker_stone_tile")
-- The following LBM is necessary because the name stair_split_stone_tile_alt
-- conflicts with another node and so the alias for that specific node gets
-- ignored.
minetest.register_lbm({
name = "moreblocks:fix_split_stone_tile_alt_name_collision",
nodenames = {"moreblocks:stair_split_stone_tile_alt"},
action = function(pos, node)
minetest.set_node(pos, {
name = "moreblocks:stair_checker_stone_tile",
param2 = minetest.get_node(pos).param2
})
minetest.log('action', "LBM replaced " .. node.name ..
" at " .. minetest.pos_to_string(pos))
end,
})

View File

@ -1 +1,63 @@
if not stairsplus.has.stairs then
return
end
local api = stairsplus.api
local S = stairsplus.S
local default_align_style = stairsplus.settings.default_align_style
-- stairs compat: override what stairs does, and "fix" any stairs which were already registered...
function stairs.register_stair(subname, node, groups, tiles, description, sounds, worldaligntex)
api.register_single(node, "stair", {
groups = groups,
tiles = tiles,
description = description,
sounds = sounds,
}, {
align_style = worldaligntex and "world" or default_align_style
})
minetest.register_alias(("stairs:stair_%s"):format(subname), api.format_name(node, "stair"))
end
function stairs.register_slab(subname, node, groups, images, description, sounds, worldaligntex)
api.register_single(node, "slab_8", {
groups = groups,
tiles = images,
description = description,
sounds = sounds,
}, {
align_style = worldaligntex and "world" or default_align_style
})
minetest.register_alias(("stairs:slab_%s"):format(subname), api.format_name(node, "slab_8"))
end
function stairs.register_stair_inner(subname, node, groups, tiles, description, sounds, worldaligntex, full_description)
api.register_single(node, "stair_inner", {
groups = groups,
tiles = tiles,
description = full_description or S("Inner @1", description),
sounds = sounds,
}, {
align_style = worldaligntex and "world" or default_align_style
})
minetest.register_alias(("stairs:stair_inner_%s"):format(subname), api.format_name(node, "stair_inner"))
end
function stairs.register_stair_outer(subname, node, groups, tiles, description, sounds, worldaligntex, full_description)
api.register_single(node, "stair_outer", {
groups = groups,
tiles = tiles,
description = full_description or S("Inner @1", description),
sounds = sounds,
}, {
align_style = worldaligntex and "world" or default_align_style
})
minetest.register_alias(("stairs:stair_outer_%s"):format(subname), api.format_name(node, "stair_outer"))
end

View File

@ -1,425 +0,0 @@
local register_craft_schema = stairsplus.api.register_craft_schema
-- micros
---- micro_8
register_craft_schema({
type = "shapeless",
output = "micro_8 7",
recipe = {"stair_inner"},
})
register_craft_schema({
type = "shapeless",
output = "micro_8 6",
recipe = {"stair"},
})
register_craft_schema({
type = "shapeless",
output = "micro_8 5",
recipe = {"stair_outer"},
})
register_craft_schema({
type = "shapeless",
output = "micro_8 4",
recipe = {"slab_8"},
})
register_craft_schema({
type = "shapeless",
output = "micro_8 4",
recipe = {"stair_alt_8"},
})
register_craft_schema({
type = "shapeless",
output = "micro_8 3",
recipe = {"stair_right_half"},
})
register_craft_schema({
type = "shapeless",
output = "micro_8 2",
recipe = {"panel_8"},
})
-- panels
---- panel_8
register_craft_schema({
output = "panel_8 12",
recipe = {
{"node", ""},
{"node", "node"},
},
})
register_craft_schema({
output = "panel_8 12",
recipe = {
{"", "node"},
{"node", "node"},
},
})
register_craft_schema({
type = "shapeless",
output = "panel_8",
recipe = {"micro_8", "micro_8"},
})
-- slabs
register_craft_schema({
output = "slab_8 6",
recipe = {{"node", "node", "node"}},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
output = "slab_8",
recipe = {{"panel_8", "panel_8"}},
})
register_craft_schema({
output = "slab_8",
recipe = {
{"panel_8"},
{"panel_8"},
},
})
register_craft_schema({
type = "shapeless",
output = "slab_8 3",
recipe = {"stair", "stair"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slab_4", "slab_4"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slab_2", "slab_2", "slab_2", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8 2",
recipe = {"slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slope_half", "slope_half"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slope_outer_half", "slope_inner_half"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slope_outer_cut_half", "slope_inner_cut_half"},
})
register_craft_schema({
type = "shapeless",
output = "slab_4",
recipe = {"slab_2", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "slab_4 2",
recipe = {"slab_1", "slab_1", "slab_1", "slab_1"},
})
register_craft_schema({
type = "shapeless",
output = "slab_12",
recipe = {"slab_8", "slab_4"},
})
register_craft_schema({
type = "shapeless",
output = "slab_12",
recipe = {"slab_4", "slab_4", "slab_4"},
})
register_craft_schema({
type = "shapeless",
output = "slab_12",
recipe = {"slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "slab_2 2",
recipe = {"slab_1", "slab_1"},
})
register_craft_schema({
type = "shapeless",
output = "slab_14",
recipe = {"slab_12", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "slab_14",
recipe = {"slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "slab_15",
recipe = {"slab_14", "slab_1"},
})
-- slopes
register_craft_schema({
type = "shapeless",
output = "slope_half_raised",
recipe = {"slope_half", "slope_half", "slope_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_half_raised",
recipe = {"slab_8", "slope_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_inner_half_raised",
recipe = {"slab_8", "slope_inner_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_outer_half_raised",
recipe = {"slab_8", "slope_outer_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_inner_cut_half_raised",
recipe = {"slab_8", "slope_inner_cut_half"},
})
-- stairs
register_craft_schema({
output = "stair 8",
recipe = {
{"node", "", ""},
{"node", "node", ""},
{"node", "node", "node"},
},
})
register_craft_schema({
output = "stair 8",
recipe = {
{"", "", "node"},
{"", "node", "node"},
{"node", "node", "node"},
},
})
register_craft_schema({
type = "shapeless",
output = "stair",
recipe = {"panel_8", "slab_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair",
recipe = {"panel_8", "panel_8", "panel_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair",
recipe = {"panel_8", "panel_8", "panel_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_inner",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_outer",
recipe = {"micro_8", "slab_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_outer",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_half",
recipe = {"micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_half",
recipe = {"panel_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_right_half",
recipe = {"stair_half"},
})
register_craft_schema({ -- See mirrored variation of the recipe below.
output = "stair_alt_8",
recipe = {
{"panel_8", ""},
{"", "panel_8"},
},
})
register_craft_schema({ -- Mirrored variation of the recipe above.
output = "stair_alt_8",
recipe = {
{"", "panel_8"},
{"panel_8", ""},
},
})
-- node
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"panel_8", "panel_8", "panel_8", "panel_8"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slab_8", "slab_8"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slab_4", "slab_4", "slab_4", "slab_4"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slab_12", "slab_4"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slab_14", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slab_15", "slab_1"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope", "slope"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_half", "slope_half_raised"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_half", "slope_half", "slope_half", "slope_half"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer", "slope_inner"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer_half", "slope_inner_half_raised"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer_half_raised", "slope_inner_half"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer_cut", "slope_inner_cut"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer_cut_half", "slope_inner_cut_half_raised"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_cut", "slope_cut"},
})

View File

@ -0,0 +1,6 @@
stairsplus.dofile("craft_schemas", "micro_8_all")
stairsplus.dofile("craft_schemas", "other")
stairsplus.dofile("craft_schemas", "slopes")
stairsplus.dofile("craft_schemas", "stairs")
stairsplus.dofile("craft_schemas", "standard_composition")

View File

@ -0,0 +1,12 @@
local api = stairsplus.api
local register_craft_schema = api.register_craft_schema
for shape, shape_def in pairs(api.registered_shapes) do
if shape ~= "micro_8" then
register_craft_schema({
type = "shapeless",
output = ("micro_8 %i"):format(shape_def.eighths),
recipe = {shape},
})
end
end

View File

@ -0,0 +1,86 @@
local api = stairsplus.api
local register_craft_schema = api.register_craft_schema
---- panel_8
register_craft_schema({
output = "panel_8 12",
recipe = {
{"node", ""},
{"node", "node"},
},
})
register_craft_schema({
output = "panel_8 12",
recipe = {
{"", "node"},
{"node", "node"},
},
})
-- slabs
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slab_2", "slab_2", "slab_2", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8 2",
recipe = {"slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1", "slab_1"},
})
register_craft_schema({
type = "shapeless",
output = "slab_4 2",
recipe = {"slab_1", "slab_1", "slab_1", "slab_1"},
})
register_craft_schema({
type = "shapeless",
output = "slab_12",
recipe = {"slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2"},
})
register_craft_schema({
type = "shapeless",
output = "slab_14",
recipe = {"slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2"},
})
-- node
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"panel_8", "panel_8", "panel_8", "panel_8"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slab_4", "slab_4", "slab_4", "slab_4"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2", "slab_2"},
})

View File

@ -0,0 +1,106 @@
local api = stairsplus.api
local register_craft_schema = api.register_craft_schema
-- slopes
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slope_half", "slope_half"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slope_outer_half", "slope_inner_half"},
})
register_craft_schema({
type = "shapeless",
output = "slab_8",
recipe = {"slope_outer_cut_half", "slope_inner_cut_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_half_raised",
recipe = {"slope_half", "slope_half", "slope_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_half_raised",
recipe = {"slab_8", "slope_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_inner_half_raised",
recipe = {"slab_8", "slope_inner_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_outer_half_raised",
recipe = {"slab_8", "slope_outer_half"},
})
register_craft_schema({
type = "shapeless",
output = "slope_inner_cut_half_raised",
recipe = {"slab_8", "slope_inner_cut_half"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope", "slope"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_half", "slope_half_raised"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_half", "slope_half", "slope_half", "slope_half"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer", "slope_inner"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer_half", "slope_inner_half_raised"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer_half_raised", "slope_inner_half"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer_cut", "slope_inner_cut"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_outer_cut_half", "slope_inner_cut_half_raised"},
})
register_craft_schema({
type = "shapeless",
output = "node",
recipe = {"slope_cut", "slope_cut"},
})

View File

@ -0,0 +1,96 @@
local api = stairsplus.api
local register_craft_schema = api.register_craft_schema
register_craft_schema({
type = "shapeless",
output = "slab_8 3",
recipe = {"stair", "stair"},
})
register_craft_schema({
output = "stair 8",
recipe = {
{"node", "", ""},
{"node", "node", ""},
{"node", "node", "node"},
},
})
register_craft_schema({
output = "stair 8",
recipe = {
{"", "", "node"},
{"", "node", "node"},
{"node", "node", "node"},
},
})
register_craft_schema({
type = "shapeless",
output = "stair",
recipe = {"panel_8", "slab_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair",
recipe = {"panel_8", "panel_8", "panel_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair",
recipe = {"panel_8", "panel_8", "panel_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_inner",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_outer",
recipe = {"micro_8", "slab_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_outer",
recipe = {"micro_8", "micro_8", "micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_half",
recipe = {"micro_8", "micro_8", "micro_8"},
})
register_craft_schema({
type = "shapeless",
output = "stair_half",
recipe = {"panel_8", "micro_8"},
})
register_craft_schema({ -- See mirrored variation of the recipe below.
output = "stair_alt_8",
recipe = {
{"panel_8", ""},
{"", "panel_8"},
},
})
register_craft_schema({ -- Mirrored variation of the recipe above.
output = "stair_alt_8",
recipe = {
{"", "panel_8"},
{"panel_8", ""},
},
})

View File

@ -0,0 +1,109 @@
local api = stairsplus.api
local register_craft_schema = api.register_craft_schema
local slices = {1, 2, 4, 8, 12, 14, 15}
local valid_slice = {
[1] = true,
[2] = true,
[4] = true,
[8] = true,
[12] = true,
[14] = true,
[15] = true,
}
local promotion = {
micro = "panel_8",
panel = "slab_8",
slab = "node",
}
local demotion = {
node = "slab",
slab = "panel",
panel = "micro",
}
for _, shape in ipairs({"micro", "panel", "slab"}) do
for _, slice1 in ipairs(slices) do
local shape1 = ("%s_%s"):format(shape, slice1)
local def1 = api.registered_shapes[shape1]
for _, slice2 in ipairs(slices) do
local shape2 = ("%s_%s"):format(shape, slice2)
local def2 = api.registered_shapes[shape2]
local slice3 = slice1 + slice2
if valid_slice[slice3] then
local shape3 = ("%s_%s"):format(shape, slice3)
local def3 = api.registered_shapes[shape3]
local n = math.floor((def1.eighths + def2.eighths) / def3.eighths)
register_craft_schema({
output = ("%s %s"):format(shape3, n),
recipe = {
{shape1},
{shape2},
},
})
elseif slice3 == 16 then
register_craft_schema({
output = ("%s"):format(promotion[shape]),
recipe = {
{shape1},
{shape2},
},
})
end
end
end
end
-- split in half horizontally
register_craft_schema({
output = "slab_8 6",
recipe = {{"node", "node", "node"}},
})
for _, shape in ipairs({"micro", "panel", "slab"}) do
for _, slice1 in ipairs({2, 4, 8}) do
local slice2 = slice1 / 2
local shape1 = ("%s_%s"):format(shape, slice1)
local shape2 = ("%s_%s"):format(shape, slice2)
local def1 = api.registered_shapes[shape1]
local def2 = api.registered_shapes[shape2]
local n = math.floor(def1.eighths / def2.eighths)
register_craft_schema({
output = ("%s %s"):format(shape2, n),
recipe = {
{shape1, shape1, shape1},
},
})
end
end
-- split in half vertically
for _, shape in ipairs({"panel", "slab"}) do
for _, slice in ipairs(slices) do
local shape1 = ("%s_%s"):format(shape, slice)
local shape2 = ("%s_%s"):format(demotion[shape], slice)
local def1 = api.registered_shapes[shape1]
local def2 = api.registered_shapes[shape2]
local n = math.floor(def1.eighths / def2.eighths)
register_craft_schema({
output = ("%s %s"):format(shape2, n),
recipe = {
{shape1},
{shape1},
{shape1},
},
})
end
end

View File

@ -0,0 +1,22 @@
stairsplus.api.register_passthrough_groups({
"not_in_creative_inventory",
"dig_immediate",
"float",
"level",
"slippery",
"falling_node",
"disable_jump",
})
stairsplus.api.register_scale_groups({
"bouncy",
"fall_damage_add_percent",
"slippery",
})
stairsplus.api.register_ignore_groups({
"attached_node",
"connect_to_raillike",
"tool",
})

View File

@ -0,0 +1,20 @@
if not stairsplus.has.default then
return
end
stairsplus.api.register_passthrough_groups({
"crumbly",
"cracky",
"snappy",
"choppy",
"fleshy",
"flammable",
"explody",
"oddly_breakable_by_hand",
})
stairsplus.api.register_scale_groups({
})
stairsplus.api.register_ignore_groups({
})

View File

@ -0,0 +1,2 @@
stairsplus.dofile("groups", "builtin")
stairsplus.dofile("groups", "default")

View File

@ -20,13 +20,7 @@ stairsplus = {
S = S,
has = {
basic_materials = minetest.get_modpath("basic_materials"),
default = minetest.get_modpath("default"),
gloopblocks = minetest.get_modpath("gloopblocks"),
stairs = minetest.get_modpath("stairs"),
technic = minetest.get_modpath("technic"),
prefab = minetest.get_modpath("prefab"),
wool = minetest.get_modpath("wool"),
},
log = function(level, messagefmt, ...)
@ -40,9 +34,12 @@ stairsplus = {
stairsplus.dofile("settings")
stairsplus.dofile("util")
stairsplus.dofile("resources", "init")
stairsplus.dofile("api", "init")
stairsplus.dofile("shapes", "init")
stairsplus.dofile("craft_schemas")
stairsplus.dofile("groups", "init")
stairsplus.dofile("craft_schemas", "init")
stairsplus.dofile("resources", "init")
stairsplus.dofile("circular_saw")
stairsplus.dofile("compat", "init")

View File

@ -1,4 +1,4 @@
name = stairsplus
title = Stairs+
description = Microblock API
optional_depends = basic_materials, default, gloopblocks, stairs, technic, prefab, wool
optional_depends = stairs

View File

@ -9,5 +9,8 @@ stairsplus.settings = {
s:get_bool("creative_mode", false)
),
default_align_style = s:get("stairsplus.default_align_style") or "user",
legacy_mode = s:get_bool("stairsplus.legacy_mode", true),
legacy_place_mechanic = s:get_bool("stairsplus.legacy_place_mechanic", true),
}

View File

@ -38,7 +38,7 @@ stairsplus.api.register_shape("micro_8", {
name_format = "micro_%s_8",
aliases = {"micro_%s", "micro_%s_bottom"},
description = "@1 Microblock", -- leave out the 1/2 to not confuse people too much...
shape_groups = {micro = 1, obligatory = 1, common = 1, legacy = 1},
shape_groups = {micro = 1, obligatory = 1, common = 1, legacy = 1, basic = 1},
eighths = 1,
drawtype = "nodebox",
node_box = {

View File

@ -39,7 +39,7 @@ stairsplus.api.register_shape("slab_8", {
name_format = "slab_%s_8",
aliases = {"slab_%s"},
description = "@1 1/2 Slab",
shape_groups = {slab = 1, common = 1, legacy = 1},
shape_groups = {slab = 1, common = 1, legacy = 1, basic = 1},
eighths = 4,
drawtype = "nodebox",
node_box = {

View File

@ -1,7 +1,7 @@
stairsplus.api.register_shape("stair", {
name_format = "stair_%s",
description = "@1 Stair",
shape_groups = {stair = 1, common = 1, legacy = 1},
shape_groups = {stair = 1, common = 1, legacy = 1, basic = 1},
eighths = 6,
drawtype = "nodebox",
node_box = {
@ -46,7 +46,7 @@ stairsplus.api.register_shape("stair_right_half", {
stairsplus.api.register_shape("stair_inner", {
name_format = "stair_%s_inner",
description = "@1 Inner Stair",
shape_groups = {stair = 1, common = 1, legacy = 1},
shape_groups = {stair = 1, common = 1, legacy = 1, basic = 1},
eighths = 5,
drawtype = "nodebox",
node_box = {
@ -62,7 +62,7 @@ stairsplus.api.register_shape("stair_inner", {
stairsplus.api.register_shape("stair_outer", {
name_format = "stair_%s_outer",
description = "@1 Outer Stair",
shape_groups = {stair = 1, common = 1, legacy = 1},
shape_groups = {stair = 1, common = 1, legacy = 1, basic = 1},
eighths = 5,
drawtype = "nodebox",
node_box = {

View File

@ -0,0 +1,31 @@
std = "lua51+luajit+minetest+moreblocks"
unused_args = false
max_line_length = 120
stds.minetest = {
read_globals = {
"DIR_DELIM",
"minetest",
"core",
"dump",
"vector",
"nodeupdate",
"VoxelManip",
"VoxelArea",
"PseudoRandom",
"ItemStack",
"default",
"table",
}
}
stds.moreblocks = {
globals = {
"stairsplus_legacy",
},
read_globals = {
"default",
"stairs",
"stairsplus",
},
}

View File

@ -0,0 +1,12 @@
-- not every fork of basic_materials has all the nodes
if minetest.registered_nodes["basic_materials:concrete_block"] then
stairsplus_legacy.register_legacy("basic_materials:concrete_block")
end
if minetest.registered_nodes["basic_materials:cement_block"] then
stairsplus_legacy.register_legacy("basic_materials:cement_block")
end
if minetest.registered_nodes["basic_materials:brass_block"] then
stairsplus_legacy.register_legacy("basic_materials:brass_block")
end

View File

@ -0,0 +1,102 @@
if stairsplus_legacy.has.stairs then
stairsplus_legacy.override_stairs("wood", "default:wood")
stairsplus_legacy.override_stairs("junglewood", "default:junglewood")
stairsplus_legacy.override_stairs("pine_wood", "default:pine_wood")
stairsplus_legacy.override_stairs("acacia_wood", "default:acacia_wood")
stairsplus_legacy.override_stairs("aspen_wood", "default:aspen_wood")
stairsplus_legacy.override_stairs("cobble", "default:cobble")
stairsplus_legacy.override_stairs("stone", "default:stone")
stairsplus_legacy.override_stairs("mossycobble", "default:mossycobble")
stairsplus_legacy.override_stairs("stonebrick", "default:stonebrick")
stairsplus_legacy.override_stairs("stone_block", "default:stone_block")
stairsplus_legacy.override_stairs("desert_stone", "default:desert_stone")
stairsplus_legacy.override_stairs("desert_cobble", "default:desert_cobble")
stairsplus_legacy.override_stairs("desert_stonebrick", "default:desert_stonebrick")
stairsplus_legacy.override_stairs("desert_stone_block", "default:desert_stone_block")
stairsplus_legacy.override_stairs("sandstone", "default:sandstone")
stairsplus_legacy.override_stairs("sandstonebrick", "default:sandstonebrick")
stairsplus_legacy.override_stairs("sandstone_block", "default:sandstone_block")
stairsplus_legacy.override_stairs("desert_sandstone", "default:desert_sandstone")
stairsplus_legacy.override_stairs("desert_sandstone_brick", "default:desert_sandstone_brick")
stairsplus_legacy.override_stairs("desert_sandstone_block", "default:desert_sandstone_block")
stairsplus_legacy.override_stairs("silver_sandstone", "default:silver_sandstone")
stairsplus_legacy.override_stairs("silver_sandstone_brick", "default:silver_sandstone_brick")
stairsplus_legacy.override_stairs("silver_sandstone_block", "default:silver_sandstone_block")
stairsplus_legacy.override_stairs("obsidian", "default:obsidian")
stairsplus_legacy.override_stairs("obsidianbrick", "default:obsidianbrick")
stairsplus_legacy.override_stairs("obsidian_block", "default:obsidian_block")
stairsplus_legacy.override_stairs("brick", "default:brick")
stairsplus_legacy.override_stairs("steelblock", "default:steelblock")
stairsplus_legacy.override_stairs("tinblock", "default:tinblock")
stairsplus_legacy.override_stairs("copperblock", "default:copperblock")
stairsplus_legacy.override_stairs("bronzeblock", "default:bronzeblock")
stairsplus_legacy.override_stairs("goldblock", "default:goldblock")
stairsplus_legacy.override_stairs("ice", "default:ice")
stairsplus_legacy.override_stairs("snowblock", "default:snowblock")
stairsplus_legacy.override_stairs("glass", "default:glass",
{tiles = {"stairs_glass_split.png"}}, {ignore_paramtype2 = true})
stairsplus_legacy.override_stairs("obsidian_glass", "default:obsidian_glass",
{tiles = {"stairs_obsidian_glass_split.png"}}, {ignore_paramtype2 = true})
end
local default_nodes = { -- Default stairs/slabs/panels/microblocks:
"stone",
"stone_block",
"cobble",
"mossycobble",
"brick",
"sandstone",
"steelblock",
"goldblock",
"copperblock",
"bronzeblock",
"diamondblock",
"tinblock",
"desert_stone",
"desert_stone_block",
"desert_cobble",
"meselamp",
"tree",
"wood",
"jungletree",
"junglewood",
"pine_tree",
"pine_wood",
"acacia_tree",
"acacia_wood",
"aspen_tree",
"aspen_wood",
"obsidian",
"obsidian_block",
"obsidianbrick",
"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",
}
for _, name in ipairs(default_nodes) do
local node = ("default:%s"):format(name)
stairsplus_legacy.register_legacy(node)
stairsplus.api.register_alias_all(("moreblocks:%s"):format(name), node)
end
-- glass problems
local glass = {
"glass",
"obsidian_glass",
}
for _, name in ipairs(glass) do
local node = ("default:%s"):format(name)
stairsplus_legacy.register_legacy(node, nil, {ignore_paramtype2 = true})
stairsplus.api.register_alias_all(("moreblocks:%s"):format(name), node)
end

View File

@ -0,0 +1,10 @@
if stairsplus_legacy.has.stairs then
stairsplus_legacy.override_stairs("straw", "farming:straw")
end
local farming_nodes = {"straw"}
for _, name in pairs(farming_nodes) do
local node = ("farming:%s"):format(name)
stairsplus_legacy.register_legacy(node)
stairsplus.api.register_alias_all(("moreblocks:%s"):format(name), node)
end

View File

@ -0,0 +1,6 @@
if stairsplus_legacy.has.basic_materials and stairsplus_legacy.settings.basic_materials then
stairsplus.api.register_alias_force_all("gloopblocks:cement", "basic_materials:cement_block")
else
stairsplus_legacy.register_legacy("gloopblocks:cement")
end

View File

@ -0,0 +1,90 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
stairsplus_legacy = {
version = {3, 0, 0},
fork = "minetest_mods",
modname = modname,
modpath = modpath,
S = S,
has = {
basic_materials = minetest.get_modpath("basic_materials"),
default = minetest.get_modpath("default"),
farming = minetest.get_modpath("farming"),
gloopblocks = minetest.get_modpath("gloopblocks"),
prefab = minetest.get_modpath("prefab"),
stairs = minetest.get_modpath("stairs"),
technic = minetest.get_modpath("technic"),
wool = minetest.get_modpath("wool"),
},
log = function(level, messagefmt, ...)
return minetest.log(level, ("[%s] %s"):format(modname, messagefmt:format(...)))
end,
dofile = function(...)
return dofile(table.concat({modpath, ...}, DIR_DELIM) .. ".lua")
end,
}
stairsplus_legacy.dofile("settings")
function stairsplus_legacy.register_legacy(node, overrides, meta)
if stairsplus_legacy.settings.stairsplus_legacy_mode then
stairsplus.api.register_group(node, "legacy", overrides, meta)
else
stairsplus.api.register_group(node, "common", overrides, meta)
end
end
if stairsplus_legacy.has.stairs then
local stair_name_formats = {
stair = "stairs:stair_%s",
slab_8 = "stairs:slab_%s",
stair_inner = "stairs:stair_inner_%s",
stair_outer = "stairs:stair_outer_%s",
}
function stairsplus_legacy.override_stairs(name, node, overrides, meta)
for shape, name_format in pairs(stair_name_formats) do
local stair_name = name_format:format(name)
if minetest.registered_nodes[stair_name] then
stairsplus.api.register_single(node, shape, overrides, meta)
local shaped_name = stairsplus.api.format_name(node, shape)
minetest.register_alias_force(stair_name, shaped_name)
end
end
end
end
if stairsplus_legacy.has.basic_materials and stairsplus_legacy.settings.basic_materials then
stairsplus_legacy.dofile("basic_materials")
end
if stairsplus_legacy.has.default and stairsplus_legacy.settings.default then
stairsplus_legacy.dofile("default")
end
if stairsplus_legacy.has.farming and stairsplus_legacy.settings.farming then
stairsplus_legacy.dofile("farming")
end
if stairsplus_legacy.has.gloopblocks and stairsplus_legacy.settings.gloopblocks then
stairsplus_legacy.dofile("gloopblocks")
end
if stairsplus_legacy.has.technic and stairsplus_legacy.settings.technic then
stairsplus_legacy.dofile("technic")
end
if stairsplus_legacy.has.prefab and stairsplus_legacy.settings.prefab then
stairsplus_legacy.dofile("prefab")
end
if stairsplus_legacy.has.wool and stairsplus_legacy.settings.wool then
stairsplus_legacy.dofile("wool")
end

View File

@ -0,0 +1,5 @@
name = stairsplus_legacy
title = Stairs+ legacy support
description = Support for old registrations which were part of moreblocks/stairsplus
depends = stairsplus
optional_depends = basic_materials, default, farming, gloopblocks, stairs, prefab, technic, wool

View File

@ -0,0 +1,9 @@
if stairsplus_legacy.has.basic_materials and stairsplus_legacy.settings.basic_materials then
stairsplus.api.register_alias_force_all("prefab:concrete", "basic_materials:concrete_block")
elseif stairsplus_legacy.has.technic and stairsplus_legacy.settings.technic then
stairsplus.api.register_alias_force_all("prefab:concrete", "technic:concrete")
else
stairsplus_legacy.register_legacy("prefab:concrete")
end

View File

@ -0,0 +1,13 @@
local s = minetest.settings
stairsplus_legacy.settings = {
basic_materials = s:get_bool("stairsplus_legacy.basic_materials", true),
default = s:get_bool("stairsplus_legacy.default", true),
farming = s:get_bool("stairsplus_legacy.farming", true),
gloopblocks = s:get_bool("stairsplus_legacy.gloopblocks", true),
technic = s:get_bool("stairsplus_legacy.technic", true),
prefab = s:get_bool("stairsplus_legacy.prefab", true),
wool = s:get_bool("stairsplus_legacy.wool", true),
stairsplus_legacy_mode = s:get_bool("stairsplus.legacy_mode")
}

View File

@ -0,0 +1,9 @@
if stairsplus_legacy.has.basic_materials and stairsplus_legacy.settings.basic_materials then
stairsplus.api.register_alias_force_all("technic:brass_block", "basic_materials:concrete_block")
stairsplus.api.register_alias_force_all("technic:brass_block", "basic_materials:brass_block")
else
stairsplus_legacy.register_legacy("technic:brass_block")
stairsplus_legacy.register_legacy("technic:concrete")
end

View File

@ -0,0 +1,11 @@
local dyes = {"white", "grey", "black", "red", "yellow", "green", "cyan",
"blue", "magenta", "orange", "violet", "brown", "pink",
"dark_grey", "dark_green"}
for _, name in pairs(dyes) do
local mod = "wool"
local nodename = mod .. ":" .. name
local ndef = table.copy(minetest.registered_nodes[nodename])
ndef.sunlight_propagates = true
stairsplus:register_all(mod, name, nodename, ndef)
end