almost done, mostly documentation left

This commit is contained in:
flux
2022-06-18 16:23:11 -07:00
parent 53a50fc5a4
commit 23f7446bef
42 changed files with 744 additions and 310 deletions

View File

@ -17,6 +17,7 @@ stds.minetest = {
"default",
"table",
"math",
"string",
}
}

View File

@ -2,6 +2,78 @@
TODO: write new API docs
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)
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)
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)
function stairsplus.api.build_groups(node, shape)
function stairsplus.api.on_place(itemstack, placer, pointed_thing)
function stairsplus.api.scale_light(light_source, shape_def)
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)
-- warning: don't mutate the return value
function stairsplus.api.get_shapes_hash(node)
-- 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)
function stairsplus.api.get_node_of_shaped_node(shaped_node)
function stairsplus.api.get_shape_of_shaped_node(shaped_node)
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)
api.registered_shapes = {}
api.shapes_by_group = {}
function stairsplus.api.register_shape(name, def)
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)
api.register_craft_schema({
output = "panel_8 6",
@ -45,4 +117,5 @@ api.register_crafts_for_shapes({
})
```
need to also support legacy aliasing
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)

View File

@ -1,6 +1,7 @@
local api = stairsplus.api
local in_creative_inventory = stairsplus.settings.in_creative_inventory
local in_craft_guide = stairsplus.settings.in_craft_guide
api.passthrough_groups = {}
api.scale_groups = {}
@ -41,7 +42,8 @@ function api.build_groups(node, shape)
local groups = {
[("shape_%s"):format(shape)] = 1,
not_in_creative_inventory = in_creative_inventory and 1 or nil,
not_in_creative_inventory = (not in_creative_inventory) and 1 or nil,
not_in_craft_guide = (not in_craft_guide) and 1 or nil,
}
local shape_def = api.registered_shapes[shape]

View File

@ -97,7 +97,6 @@ else
api.on_place = minetest.item_place
end
function api.scale_light(light_source, shape_def)
if not light_source or light_source == 0 then
return 0

View File

@ -1,6 +1,7 @@
-- for registering variants of a specific node
local api = stairsplus.api
local table_equals = stairsplus.util.table_equals
local table_set_all = stairsplus.util.table_set_all
local table_sort_keys = stairsplus.util.table_sort_keys
@ -14,6 +15,12 @@ api.shapes_by_node = {}
api.node_by_shaped_node = {}
api.shape_by_shaped_node = {}
api.registered_on_register_singles = {}
function api.register_on_register_single(func)
table.insert(api.registered_on_register_singles, func)
end
local function check_node_validity(node_def, meta)
local type_ = node_def.type
if not meta.ignore_type and type_ ~= "node" then
@ -64,9 +71,11 @@ function api.register_single(node, shape, overrides, meta)
stairsplus.log("info", "registering %s %s", shape, node)
meta = meta or {}
overrides = overrides or {}
if not minetest.registered_nodes[node] then
error(("%q is not defined"):format(node))
error(("node %q is not defined"):format(node))
end
local node_def = table.copy(minetest.registered_nodes[node])
check_node_validity(node_def, meta)
@ -117,7 +126,7 @@ function api.register_single(node, shape, overrides, meta)
climbable = node_def.climbable,
move_resistance = node_def.move_resistance,
on_place = api.on_place,
on_place = function(...) return api.on_place(...) end,
}
-- see-through nodes tend to look better if we just use the first tile
@ -143,7 +152,11 @@ function api.register_single(node, shape, overrides, meta)
end
end
overrides.groups = nil
if not table_equals(overrides.groups, node_def.groups) then
overrides = table.copy(overrides)
overrides.groups = nil
end
table_set_all(def, overrides)
-- set backface_culling and align_style
@ -205,6 +218,10 @@ function api.register_single(node, shape, overrides, meta)
shapes[shape] = true
api.shapes_by_node[node] = shapes
for _, func in ipairs(api.registered_on_register_singles) do
func(node, shaped_name)
end
return shaped_name
end
@ -262,6 +279,9 @@ function api.get_schema_recipe_item(node, shape_or_item)
elseif name == "node" then
name = node
elseif not name:match(":") then
return
end
if count then

View File

@ -1,10 +1,6 @@
-- for registering recipe schemas
-- TODO: should register schemas w/ unified_inventory and i3 and whatever else,
-- and hide the recipes for the individual nodes (possibly a setting for such)
local api = stairsplus.api
local recipes_in_creative_inventory = stairsplus.settings.recipes_in_creative_inventory
api.registered_recipe_schemas = {}
api.registered_on_register_craft_schemas = {}
@ -144,11 +140,6 @@ local function register_for_schema(node, schema)
stairsplus.log("info", "registering recipe %s", minetest.serialize(recipe):sub(#("return ")))
if not recipes_in_creative_inventory then
-- i don't think anything supports this but...
recipe.groups = {not_in_creative_inventory = 1}
end
minetest.register_craft(recipe)
end
@ -180,38 +171,36 @@ local function shapes_match(a, b)
return true
end
function api.register_crafts_for_shapes(def)
if def.type == "cooking" then
function api.register_crafts_for_shapes(recipe)
if recipe.type == "cooking" then
assert(
shapes_match(def.output, def.recipe),
("error: shapes of %s and %s do not match"):format(def.output, def.recipe)
shapes_match(recipe.output, recipe.recipe),
("error: shapes of %s and %s do not match"):format(recipe.output, recipe.recipe)
)
local shapes = api.get_shapes(def.recipe)
local shapes = api.get_shapes(recipe.recipe)
for _, shape in ipairs(shapes) do
minetest.register_craft({
type = "cooking",
output = api.get_schema_recipe_item(def.output, shape),
recipe = api.get_schema_recipe_item(def.recipe, shape),
cooktime = def.cooktime(api.registered_shapes[shape].eighths),
groups = (not recipes_in_creative_inventory) and {not_in_creative_inventory = 1} or nil
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),
})
end
elseif def.type == "fuel" then
local shapes = api.get_shapes(def.recipe)
elseif recipe.type == "fuel" then
local shapes = api.get_shapes(recipe.recipe)
for _, shape in ipairs(shapes) do
minetest.register_craft({
type = "fuel",
recipe = api.get_schema_recipe_item(def.recipe, shape),
burntime = def.burntime(api.registered_shapes[shape].eighths),
groups = (not recipes_in_creative_inventory) and {not_in_creative_inventory = 1} or nil
recipe = api.get_schema_recipe_item(recipe.recipe, shape),
burntime = recipe.burntime(api.registered_shapes[shape].eighths),
})
end
else
error(("unsupported recipe type %s"):format(def.type))
error(("unsupported recipe type %s"):format(recipe.type))
end
end

View File

@ -2,19 +2,23 @@
local api = stairsplus.api
local S = stairsplus.S
local F = minetest.formspec_escape
local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) or 99
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
]]
function station.update_infotext(pos)
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
return def.update_infotext(pos)
end
local function get_cost(shaped_node)
function station.build_formspec(pos)
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
return def.build_formspec(pos)
end
function station.get_cost(shaped_node)
if shaped_node == "" then
return 0
end
@ -28,7 +32,7 @@ local function get_cost(shaped_node)
return shape_def and shape_def.eighths
end
local function get_current_node(pos)
function station.get_current_node(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
@ -48,29 +52,28 @@ local function get_current_node(pos)
end
end
function station.update_infotext(pos)
function station.can_dig(pos)
local meta = minetest.get_meta(pos)
local parts = {}
if station.can_dig(pos) then
table.insert(parts, S("Circular Saw is empty"))
end
local owner = meta:get_string("owner")
if owner ~= "" then
table.insert(parts, S("(owned by @1)", meta:get_string("owner")))
end
meta:set_string("infotext", table.concat(parts, " "))
local inv = meta:get_inventory()
return inv:is_empty("input") and inv:is_empty("micro")
end
function station.on_receive_fields(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
local max = tonumber(fields.max_offered)
if max and max > 0 then
meta:set_int("max_offered", max)
-- Update to show the correct number of items:
station.update_inventory(pos)
station.update_infotext(pos)
end
end
-- Player has taken something out of the box or placed something inside
-- that amounts to count microblocks:
function station.update_inventory(pos, taken_stack)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local node = get_current_node(pos)
local node = station.get_current_node(pos)
if not node then
for i = 1, inv:get_size("output") do
@ -84,9 +87,9 @@ function station.update_inventory(pos, taken_stack)
local recycle_stack = inv:get_stack("recycle", 1)
local current_value = 8 * input_stack:get_count() + micro_stack:get_count()
local new_value = current_value + get_cost(recycle_stack:get_name()) * recycle_stack:get_count()
local new_value = current_value + station.get_cost(recycle_stack:get_name()) * recycle_stack:get_count()
if taken_stack then
new_value = new_value - get_cost(taken_stack:get_name()) * taken_stack:get_count()
new_value = new_value - station.get_cost(taken_stack:get_name()) * taken_stack:get_count()
end
local new_micros = new_value % 8
local new_blocks = math.floor(new_value / 8)
@ -132,16 +135,19 @@ function station.update_inventory(pos, taken_stack)
end
end
-- The amount of items offered per shape can be configured:
function station.on_receive_fields(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
local max = tonumber(fields.max_offered)
if max and max > 0 then
meta:set_int("max_offered", max)
-- Update to show the correct number of items:
function station.on_metadata_inventory_put(pos, listname, index, stack, player)
station.update_inventory(pos)
station.update_infotext(pos)
end
function station.on_metadata_inventory_take(pos, listname, index, stack, player)
if listname == "output" then
station.update_inventory(pos, stack)
else
station.update_inventory(pos)
station.update_infotext(pos)
end
station.update_infotext(pos)
end
-- Moving the inventory of the station around is not allowed because it
@ -166,14 +172,14 @@ function station.allow_metadata_inventory_put(pos, listname, index, stack, playe
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local current_node = get_current_node(pos)
local current_node = station.get_current_node(pos)
if current_node and node ~= current_node then
return 0
end
local count = stack:get_count()
local cost = get_cost(shaped_node)
local cost = station.get_cost(shaped_node)
local input_stack = inv:get_stack("input", 1)
local micro_stack = inv:get_stack("micro", 1)
@ -187,61 +193,10 @@ function station.allow_metadata_inventory_put(pos, listname, index, stack, playe
return math.min(count, available_count)
end
function station.on_metadata_inventory_put(pos, listname, index, stack, player)
station.update_inventory(pos)
station.update_infotext(pos)
end
function station.on_metadata_inventory_take(pos, listname, index, stack, player)
if listname == "output" then
station.update_inventory(pos, stack)
else
station.update_inventory(pos)
end
station.update_infotext(pos)
end
function station.build_formspec()
local fancy_inv = ""
if stairsplus.has.default then
-- prepend background and slot styles from default if available
fancy_inv = default.gui_bg .. default.gui_bg_img .. default.gui_slots
end
return ([[
size[11,10]
%s
label[0,0;%s]
list[current_name;input;1.7,0;1,1;]
label[0,1;%s]
list[current_name;micro;1.7,1;1,1;]
label[0,2;%s]
list[current_name;recycle;1.7,2;1,1;]
field[0.3,3.5;1,1;max_offered;%s:;${max_offered}]
button[1,3.2;1.7,1;Set;%s]
list[current_name;output;2.8,0;8,6;]
list[current_player;main;1.5,6.25;8,4;]
listring[current_name;output]
listring[current_player;main]
listring[current_name;recycle]
listring[current_name;micro]
listring[current_player;main]
listring[current_name;input]
listring[current_player;main]
]]):format(
fancy_inv, S("Nodes"), F(S("Microblocks")), F(S("Input")), F(S("Max")), F(S("Set"))
)
end
function station.on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", station.build_formspec())
meta:set_string("formspec", station.build_formspec(pos))
meta:set_string("max_offered", default_stack_max) -- How many items of this kind are offered by default?
local inv = meta:get_inventory()
@ -249,7 +204,7 @@ function station.on_construct(pos)
inv:set_size("input", 1) -- Input slot for full blocks of material x.
inv:set_size("micro", 1) -- Storage for 1-7 surplus microblocks.
inv:set_size("recycle", 1) -- Surplus partial blocks can be placed here.
inv:set_size("output", 6 * 8) -- 6x8 versions of stair-parts of material x.
inv:set_size("output", 6 * 9) -- 6x9 versions of stair-parts of material x.
station.update_infotext(pos)
end
@ -261,12 +216,6 @@ function station.after_place_node(pos, placer)
end
end
function station.can_dig(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("input") and inv:is_empty("micro")
end
function api.register_station(name, shape_groups, def)
def.after_place_node = def.after_place_node or station.after_place_node
def.on_construct = def.on_construct or station.on_construct

View File

@ -1,12 +1,56 @@
--[[
More Blocks: circular saw
Copyright © 2011-2020 Hugo Locurcio, Sokomine and contributors.
Licensed under the zlib license. See LICENSE.md for more information.
--]]
local api = stairsplus.api
local station = api.station
local S = stairsplus.S
local cm = stairsplus.resources.craft_materials
local F = minetest.formspec_escape
local formspec_style = stairsplus.resources.formspec_style
local function update_infotext(pos)
local meta = minetest.get_meta(pos)
local parts = {}
if station.can_dig(pos) then
table.insert(parts, S("Circular Saw is empty"))
end
local owner = meta:get_string("owner")
if owner ~= "" then
table.insert(parts, S("(owned by @1)", meta:get_string("owner")))
end
meta:set_string("infotext", table.concat(parts, " "))
end
local function build_formspec()
return ([[
size[12,10]
%s
label[0,0;%s]
list[current_name;input;1.7,0;1,1;]
label[0,1;%s]
list[current_name;micro;1.7,1;1,1;]
label[0,2;%s]
list[current_name;recycle;1.7,2;1,1;]
field[0.3,3.5;1,1;max_offered;%s:;${max_offered}]
button[1,3.2;1.7,1;Set;%s]
list[current_name;output;2.8,0;9,6;]
list[current_player;main;1.5,6.25;8,4;]
listring[current_name;output]
listring[current_player;main]
listring[current_name;recycle]
listring[current_name;micro]
listring[current_player;main]
listring[current_name;input]
listring[current_player;main]
]]):format(
formspec_style, S("Nodes"), F(S("Microblocks")), F(S("Input")), F(S("Max")), F(S("Set"))
)
end
api.register_station("stairsplus:circular_saw", {"legacy"}, {
description = S("Circular Saw"),
@ -34,17 +78,31 @@ api.register_station("stairsplus:circular_saw", {"legacy"}, {
paramtype2 = "facedir",
groups = {choppy = 2, oddly_breakable_by_hand = 2},
sounds = stairsplus.resources.sounds.wood,
build_formspec = build_formspec,
update_infotext = update_infotext,
})
if cm.steel_ingot then
if stairsplus.settings.circular_saw_crafting then
minetest.register_craft({
output = "stairsplus:circular_saw",
recipe = {
{"", cm.steel_ingot, ""},
{"group:wood", "group:wood", "group:wood"},
{"group:wood", "", "group:wood"},
}
})
end
local cm = stairsplus.resources.craft_materials
if stairsplus.settings.circular_saw_crafting and cm.steel_ingot then
minetest.register_craft({
output = "stairsplus:circular_saw",
recipe = {
{"", cm.steel_ingot, ""},
{"group:wood", "group:wood", "group:wood"},
{"group:wood", "", "group:wood"},
}
})
end
minetest.register_lbm({
label = "Upgrade legacy saws",
name = "stairsplus:replace_legacy_saws",
nodenames = {"stairsplus:circular_saw"},
run_at_every_load = false,
action = function(pos, node)
local def = minetest.registered_nodes[node.name]
def.on_construct(pos)
end,
})

View File

@ -0,0 +1,91 @@
-- luacheck: read globals i3
if not stairsplus.has.i3 then
return
end
local api = stairsplus.api
i3.register_craft_type("stairsplus:craft_schema", {
description = "Stairs+ craft schema",
icon = "stairsplus_circular_saw_top.png",
})
i3.register_craft_type("stairsplus:craft_schema", {
description = "Stairs+ circular saw",
icon = "stairsplus_circular_saw_top.png",
})
local function convert_schema_recipe_item(item)
if item == "" or item:match(":") then
return item
end
local name, count = item:match("^([^ ]+) (%d+)")
if not name then
name = item
end
count = tonumber(count)
if name == "node" then
name = "mapgen_stone"
if count then
return ("%s %s"):format(name, count)
else
return name
end
else
if count then
return ("group:shape_%s %s"):format(name, count)
else
return ("group:shape_%s"):format(name)
end
end
end
api.register_on_register_craft_schema(function(schema)
stairsplus.log("action", "register unified_inventory recipe")
local recipe = table.copy(schema)
recipe.output = convert_schema_recipe_item(recipe.output)
if recipe.replacements then
for _, replacement in ipairs(recipe.replacements) do
for i, item in ipairs(replacement) do
replacement[i] = convert_schema_recipe_item(item)
end
end
end
if recipe.type == "shapeless" then
for i, item in ipairs(recipe.recipe) do
recipe.recipe[i] = convert_schema_recipe_item(item)
end
elseif recipe.type == "shaped" or recipe.type == nil then
local tmp = {}
for _, row in ipairs(recipe.recipe) do
for i, item in ipairs(row) do
table.insert(tmp, convert_schema_recipe_item(item))
end
end
recipe.recipe = tmp
end
i3.register_craft({
type = "stairsplus:craft_schema",
result = recipe.output,
items = recipe.recipe,
})
end)
api.register_on_register_single(function(node, shaped_name)
i3.register_craft({
type = "stairsplus:circular_saw",
result = shaped_name,
items = {node},
})
end)

View File

@ -1,5 +1,5 @@
-- compatability stuff for after the API is created, but before we start using it
--stairsplus.dofile("compat1", "i3")
--stairsplus.dofile("compat1", "unified_inventory")
stairsplus.dofile("compat1", "i3")
stairsplus.dofile("compat1", "unified_inventory")

View File

@ -4,11 +4,13 @@ if not stairsplus.has.unified_inventory then
return
end
unified_inventory.register_craft_type("stairsplus", {
local api = stairsplus.api
unified_inventory.register_craft_type("stairsplus:craft_schema", {
-- ^ Unique identifier for `register_craft`
description = "Stairs+ craft schema",
-- ^ Text shown below the crafting arrow
icon = "dummy.png",
icon = "stairsplus_circular_saw_top.png",
-- ^ Image shown above the crafting arrow
width = 3,
height = 3,
@ -16,8 +18,34 @@ unified_inventory.register_craft_type("stairsplus", {
uses_crafting_grid = true,
})
unified_inventory.register_craft_type("stairsplus:circular_saw", {
-- ^ Unique identifier for `register_craft`
description = "Stairs+ circular saw",
-- ^ Text shown below the crafting arrow
icon = "stairsplus_circular_saw_top.png",
-- ^ Image shown above the crafting arrow
width = 1,
height = 1,
-- ^ Maximal input dimensions of the recipes
uses_crafting_grid = true,
})
unified_inventory.register_category("stairsplus:cuttable", {
symbol = "stairsplus:circular_saw",
label = "Cuttable in the circular saw",
index = 0,
items = {}
})
unified_inventory.register_category("stairsplus:cut_node", {
symbol = "stairsplus:circular_saw",
label = "Nodes cut in the circular saw",
index = 0,
items = {}
})
local function convert_schema_recipe_item(item)
if item == "" then
if item == "" or item:match(":") then
return item
end
@ -28,17 +56,67 @@ local function convert_schema_recipe_item(item)
count = tonumber(count)
error("more logic here")
if count then
return ("%s %s"):format(name, count)
if name == "node" then
name = "mapgen_stone"
if count then
return ("%s %s"):format(name, count)
else
return name
end
else
return name
if count then
return ("group:shape_%s %s"):format(name, count)
else
return ("group:shape_%s"):format(name)
end
end
end
stairsplus.api.register_on_register_craft_schema(function(schema)
api.register_on_register_craft_schema(function(schema)
stairsplus.log("action", "register unified_inventory recipe")
local recipe = table.copy(schema)
recipe.output = convert_schema_recipe_item(recipe.output)
if recipe.replacements then
for _, replacement in ipairs(recipe.replacements) do
for i, item in ipairs(replacement) do
replacement[i] = convert_schema_recipe_item(item)
end
end
end
if recipe.type == "shapeless" then
for i, item in ipairs(recipe.recipe) do
recipe.recipe[i] = convert_schema_recipe_item(item)
end
elseif recipe.type == "shaped" or recipe.type == nil then
for _, row in ipairs(recipe.recipe) do
for i, item in ipairs(row) do
row[i] = convert_schema_recipe_item(item)
end
end
end
unified_inventory.register_craft({
output = recipe.output,
type = "stairsplus:craft_schema",
items = recipe.recipe,
width = 3,
})
end)
api.register_on_register_single(function(node, shaped_name)
unified_inventory.register_craft({
output = shaped_name,
type = "stairsplus:circular_saw",
items = {node},
width = 1,
})
unified_inventory.add_category_item("stairsplus:cuttable", node)
unified_inventory.add_category_item("stairsplus:cut_node", shaped_name)
end)

View File

@ -77,7 +77,7 @@ function stairs.register_stair_outer(subname, node, groups, tiles, description,
api.register_single(node, "stair_outer", {
groups = groups,
tiles = tiles,
description = full_description or S("Inner @1", description),
description = full_description or S("Outer @1", description),
sounds = sounds,
}, meta)

View File

@ -46,7 +46,6 @@ register_craft_schema({
recipe = {"slab_1", "slab_1", "slab_1", "slab_1"},
})
register_craft_schema({
type = "shapeless",
output = "slab_12",

View File

@ -7,6 +7,12 @@ register_craft_schema({
recipe = {"stair", "stair"},
})
register_craft_schema({
type = "shapeless",
output = "node 3",
recipe = {"stair", "stair", "stair", "stair"},
})
register_craft_schema({
output = "stair 8",
recipe = {
@ -79,7 +85,55 @@ register_craft_schema({
recipe = {"panel_8", "micro_8"},
})
register_craft_schema({ -- See mirrored variation of the recipe below.
register_craft_schema({
output = "stair_alt_1",
recipe = {
{"panel_1", ""},
{"", "panel_1"},
},
})
register_craft_schema({
output = "stair_alt_1",
recipe = {
{"", "panel_1"},
{"panel_1", ""},
},
})
register_craft_schema({
output = "stair_alt_2",
recipe = {
{"panel_2", ""},
{"", "panel_2"},
},
})
register_craft_schema({
output = "stair_alt_2",
recipe = {
{"", "panel_2"},
{"panel_2", ""},
},
})
register_craft_schema({
output = "stair_alt_4",
recipe = {
{"panel_4", ""},
{"", "panel_4"},
},
})
register_craft_schema({
output = "stair_alt_4",
recipe = {
{"", "panel_4"},
{"panel_4", ""},
},
})
register_craft_schema({
output = "stair_alt_8",
recipe = {
{"panel_8", ""},
@ -87,7 +141,7 @@ register_craft_schema({ -- See mirrored variation of the recipe below.
},
})
register_craft_schema({ -- Mirrored variation of the recipe above.
register_craft_schema({
output = "stair_alt_8",
recipe = {
{"", "panel_8"},

View File

@ -12,9 +12,3 @@ stairsplus.api.register_passthrough_groups({
"explody",
"oddly_breakable_by_hand",
})
stairsplus.api.register_scale_groups({
})
stairsplus.api.register_ignore_groups({
})

View File

@ -1,11 +1,3 @@
--[[
More Blocks: Stairs+
Copyright © 2011-2020 Hugo Locurcio and contributors.
Licensed under the zlib license. See LICENSE.md for more information.
--]]
-- Nodes will be called <modname>:{stair,slab,panel,micro,slope}_<subname>
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
@ -35,7 +27,7 @@ stairsplus = {
end,
}
-- order matters TODO document that... though i probably won't
-- please don't change the order in which things are loaded, without understanding why they're ordered like this
stairsplus.dofile("settings")
stairsplus.dofile("util")

View File

@ -3,25 +3,75 @@
#: circular_saw.lua
Circular Saw=
Input material=
Left-over=
Max=
Recycle output=
Set=
owned by @1=
Circular Saw is empty=
Circular Saw is working on @1=
#: stairsplus/common.lua
Microblocks=
Nodes=
Input=
Max=
(owned by @1)=
Set=
#: shapes/micros.lua
@1 1/16 Microblock=
@1 1/8 Microblock=
@1 1/4 Microblock=
@1 Microblock=
@1 Slab=
@1 3/4 Microblock=
@1 7/8 Microblock=
@1 15/16 Microblock=
#: shapes/panels.lua
@1 1/16 Panel=
@1 1/8 Panel=
@1 1/4 Panel=
@1 1/2 Panel=
@1 3/4 Panel=
@1 7/8 Panel=
@1 15/16 Panel=
#: shapes/slabs.lua
@1 1/16 Slab=
@1 1/8 Slab=
@1 1/4 Slab=
@1 1/2 Slab=
@1 3/4 Slab=
@1 7/8 Slab=
@1 15/16 Slab=
@1 1/16 Slab Three Sides=
@1 1/16 Slab Three Sides U=
@1 1/16 Slab Two Sides=
#: shapes/slopes.lua
@1 1/2 Slope=
@1 1/2 Slope Raised=
@1 Slope=
@1 Panel=
@1 Stairs=
@1 Slope Cut=
@1 Slope Inner=
@1 Slope Inner Cut=
@1 Slope Inner Cut Half=
@1 Slope Inner Cut Half Raised=
@1 Slope Inner Half=
@1 Slope Inner Half Raised=
@1 Slope Outer=
@1 Slope Outer Cut=
@1 Slope Outer Cut Half=
@1 Slope Outer Cut Half Raised=
@1 Slope Outer Half=
@1 Slope Outer Half Raised=
#: stairsplus/registrations.lua
#: shapes/stairs.lua
@1 Stair=
@1 1/16 Alt Stair=
@1 1/8 Alt Stair=
@1 1/4 Alt Stair=
@1 1/2 Alt Stair=
@1 Inner Stair=
@1 Outer Stair=
@1 Half Stair=
@1 Right Half Stair=
Concrete=
Cement=
Brass Block=
# compat2/stairs.lua
Inner @1=
Outer @1=

View File

@ -1,4 +1,5 @@
name = stairsplus
version = 3.0.0
title = Stairs+
description = Microblock API
optional_depends = default, i3, stairs, unified_inventory

View File

@ -0,0 +1,7 @@
stairsplus.resources.formspec_style = ""
if stairsplus.has.default then
-- prepend background and slot styles from default if available
stairsplus.resources.formspec_style = default.gui_bg .. default.gui_bg_img .. default.gui_slots
end

View File

@ -1,21 +1,29 @@
local s = minetest.settings
stairsplus.settings = {
in_creative_inventory = s:get_bool("stairsplus.in_creative_inventory",
s:get_bool("stairsplus_in_creative_inventory", false)
),
recipes_in_creative_inventory = s:get_bool("stairsplus.recipes_in_creative_inventory",
s:get_bool("stairsplus_in_creative_inventory", false)
),
circular_saw_crafting = s:get_bool("stairsplus.circular_saw_crafting", true),
ex_nihilo = s:get_bool("stairsplus.ex_nihilo",
s:get_bool("creative_mode", false)
),
in_creative_inventory = s:get_bool("stairsplus.in_creative_inventory",
s:get_bool("moreblocks.stairsplus_in_creative_inventory", true)
),
in_craft_guide = s:get_bool("stairsplus.in_craft_guide", false),
default_align_style = s:get("stairsplus.default_align_style") or "user",
basic_shapes = string.split(s:get("stairsplus.common_shapes") or table.concat({
"micro_8", "slab_8", "stair", "stair_inner", "stair_outer",
}, ","), ","),
common_shapes = string.split(s:get("stairsplus.common_shapes") or table.concat({
"micro_8", "panel_8", "slab_1", "slab_8", "stair", "stair_inner", "stair_outer",
"slope", "slope_half", "slope_half_raised", "slope_inner", "slope_inner_cut", "slope_inner_half",
"slope_inner_cut_half", "slope_inner_half_raised", "slope_inner_cut_half_raised", "slope_outer",
"slope_outer_cut", "slope_cut", "slope_outer_half", "slope_outer_cut_half", "slope_outer_half_raised",
"slope_outer_cut_half_raised",
}, ","), ","),
legacy_mode = s:get_bool("stairsplus.legacy_mode", true),
legacy_place_mechanic = s:get_bool("stairsplus.legacy_place_mechanic", true),
}

View File

@ -3,3 +3,6 @@ stairsplus.dofile("shapes", "panels")
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)

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, basic = 1},
shape_groups = {micro = 1, obligatory = 1, legacy = 1},
eighths = 1,
drawtype = "nodebox",
node_box = {

View File

@ -38,7 +38,7 @@ stairsplus.api.register_shape("panel_8", {
name_format = "panel_%s_8",
aliases = {"panel_%s", "panel_bottom_%s"},
description = "@1 1/2 Panel",
shape_groups = {panel = 1, common = 1, legacy = 1},
shape_groups = {panel = 1, legacy = 1},
eighths = 2,
drawtype = "nodebox",
node_box = {

View File

@ -1,7 +1,7 @@
stairsplus.api.register_shape("slab_1", {
name_format = "slab_%s_1",
description = "@1 1/16 Slab",
shape_groups = {slab = 1, common = 1, legacy = 1},
shape_groups = {slab = 1, legacy = 1},
eighths = 1,
drawtype = "nodebox",
node_box = {
@ -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, basic = 1},
shape_groups = {slab = 1, legacy = 1},
eighths = 4,
drawtype = "nodebox",
node_box = {

View File

@ -11,7 +11,7 @@ local box_slope = {
stairsplus.api.register_shape("slope", {
name_format = "slope_%s",
description = "@1 Slope",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 4,
drawtype = "mesh",
mesh = "stairsplus_slope.obj",
@ -32,7 +32,7 @@ local box_slope_half = {
stairsplus.api.register_shape("slope_half", {
name_format = "slope_%s_half",
description = "@1 1/2 Slope",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 2,
drawtype = "mesh",
mesh = "stairsplus_slope_half.obj",
@ -53,7 +53,7 @@ local box_slope_half_raised = {
stairsplus.api.register_shape("slope_half_raised", {
name_format = "slope_%s_half_raised",
description = "@1 1/2 Slope Raised",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 6,
drawtype = "mesh",
mesh = "stairsplus_slope_half_raised.obj",
@ -77,7 +77,7 @@ local box_slope_inner = {
stairsplus.api.register_shape("slope_inner", {
name_format = "slope_%s_inner",
description = "@1 Slope Inner",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 6,
drawtype = "mesh",
mesh = "stairsplus_slope_inner.obj",
@ -88,7 +88,7 @@ stairsplus.api.register_shape("slope_inner", {
stairsplus.api.register_shape("slope_inner_cut", {
name_format = "slope_%s_inner_cut",
description = "@1 Slope Inner Cut",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 6,
drawtype = "mesh",
mesh = "stairsplus_slope_inner_cut.obj",
@ -112,7 +112,7 @@ local box_slope_inner_half = {
stairsplus.api.register_shape("slope_inner_half", {
name_format = "slope_%s_inner_half",
description = "@1 Slope Inner Half",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 3,
drawtype = "mesh",
mesh = "stairsplus_slope_inner_half.obj",
@ -123,7 +123,7 @@ stairsplus.api.register_shape("slope_inner_half", {
stairsplus.api.register_shape("slope_inner_cut_half", {
name_format = "slope_%s_inner_cut_half",
description = "@1 Slope Inner Cut Half",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 4,
drawtype = "mesh",
mesh = "stairsplus_slope_inner_cut_half.obj",
@ -147,7 +147,7 @@ local box_slope_inner_half_raised = {
stairsplus.api.register_shape("slope_inner_half_raised", {
name_format = "slope_%s_inner_half_raised",
description = "@1 Slope Inner Half Raised",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 6,
drawtype = "mesh",
mesh = "stairsplus_slope_inner_half_raised.obj",
@ -158,7 +158,7 @@ stairsplus.api.register_shape("slope_inner_half_raised", {
stairsplus.api.register_shape("slope_inner_cut_half_raised", {
name_format = "slope_%s_inner_cut_half_raised",
description = "@1 Slope Inner Cut Half Raised",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 7,
drawtype = "mesh",
mesh = "stairsplus_slope_inner_cut_half_raised.obj",
@ -181,7 +181,7 @@ local box_slope_outer = {
stairsplus.api.register_shape("slope_outer", {
name_format = "slope_%s_outer",
description = "@1 Slope Outer",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 3,
drawtype = "mesh",
mesh = "stairsplus_slope_outer.obj",
@ -192,7 +192,7 @@ stairsplus.api.register_shape("slope_outer", {
stairsplus.api.register_shape("slope_outer_cut", {
name_format = "slope_%s_outer_cut",
description = "@1 Slope Outer Cut",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 2,
drawtype = "mesh",
mesh = "stairsplus_slope_outer_cut.obj",
@ -203,7 +203,7 @@ stairsplus.api.register_shape("slope_outer_cut", {
stairsplus.api.register_shape("slope_cut", {
name_format = "slope_%s_cut",
description = "@1 Slope Cut",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 4,
drawtype = "mesh",
mesh = "stairsplus_slope_cut.obj",
@ -224,7 +224,7 @@ local box_slope_outer_half = {
stairsplus.api.register_shape("slope_outer_half", {
name_format = "slope_%s_outer_half",
description = "@1 Slope Outer Half",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 2,
drawtype = "mesh",
mesh = "stairsplus_slope_outer_half.obj",
@ -235,7 +235,7 @@ stairsplus.api.register_shape("slope_outer_half", {
stairsplus.api.register_shape("slope_outer_cut_half", {
name_format = "slope_%s_outer_cut_half",
description = "@1 Slope Outer Cut Half",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 1,
drawtype = "mesh",
mesh = "stairsplus_slope_outer_cut_half.obj",
@ -256,7 +256,7 @@ local box_slope_outer_half_raised = {
stairsplus.api.register_shape("slope_outer_half_raised", {
name_format = "slope_%s_outer_half_raised",
description = "@1 Slope Outer Half Raised",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 6,
drawtype = "mesh",
mesh = "stairsplus_slope_outer_half_raised.obj",
@ -267,7 +267,7 @@ stairsplus.api.register_shape("slope_outer_half_raised", {
stairsplus.api.register_shape("slope_outer_cut_half_raised", {
name_format = "slope_%s_outer_cut_half_raised",
description = "@1 Slope Outer Cut Half Raised",
shape_groups = {slope = 1, common = 1, legacy = 1},
shape_groups = {slope = 1, legacy = 1},
eighths = 3,
drawtype = "mesh",
mesh = "stairsplus_slope_outer_cut_half_raised.obj",

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, basic = 1},
shape_groups = {stair = 1, legacy = 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, basic = 1},
shape_groups = {stair = 1, legacy = 1},
eighths = 7,
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, basic = 1},
shape_groups = {stair = 1, legacy = 1},
eighths = 5,
drawtype = "nodebox",
node_box = {

View File

@ -23,6 +23,37 @@ stairsplus.util = {
return sorted
end,
table_equals = function(t1, t2)
if t1 == t2 then
return true
end
local tt1 = type(t1)
local tt2 = type(t2)
if tt1 ~= tt2 then
return false
end
if tt1 ~= "table" or tt2 ~= "table" then
return t1 == t2
end
for k1, v1 in pairs(t1) do
if not v1 == t2[k1] then
return false
end
end
for k2, v2 in pairs(t2) do
if not t1[k2] == v2 then
return false
end
end
return true
end,
check_call = function(func)
-- wrap a function w/ logic to avoid crashing the game
local f = function(...)