From a06b0a08af407f5d46238941ee8e24711626badf Mon Sep 17 00:00:00 2001 From: trans_soup <> Date: Sat, 21 Oct 2023 22:04:25 +0200 Subject: [PATCH] fully implement leveled nodes. add API support for leveled nodes, used via these two functions: `blockgame.register_leveled_node` registers leveled nodes for each level up to a given maximum. `blockgame.check_for_stacking` checks whether a given node is supposed to stack with its vertical neighbors, and if so handles that. --- mods/bg_api/leveled_node.lua | 85 ++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/mods/bg_api/leveled_node.lua b/mods/bg_api/leveled_node.lua index f1d887b..e2ff414 100644 --- a/mods/bg_api/leveled_node.lua +++ b/mods/bg_api/leveled_node.lua @@ -1,83 +1,82 @@ -local function is_same_kind (pos, basename) +local function is_same_kind (pos, kindname) local node = minetest.get_node(pos) - local node_basename = minetest.registered_items[node.name].basename - return basename == node_basename + local node_kindname = minetest.registered_items[node.name].kindname + return kindname == node_kindname end -local function after_place_stack (pos) +function blockgame.check_for_stacking (pos) local node = minetest.get_node(pos) - if not blockgame.item_matches(node.name, {"groups:leveled"}) then return end + if not blockgame.item_matches(node.name, {"group:leveled"}) then return end local def = minetest.registered_nodes[node.name] - local basename = def.basename + local kindname = def.kindname local level_max = def.level_max local below = pos + blockgame.vector.dirs.down - if is_same_kind(below, basename) then - local below_node = minetest.get_node(pos) + if is_same_kind(below, kindname) then + local below_node = minetest.get_node(below) local below_def = minetest.registered_nodes[below_node.name] if below_def.level ~= level_max then local max_diff = level_max - below_def.level local diff = math.min(max_diff, def.level) - minetest.swap_node(below, {name = basename .. "_" .. (below_def.level + diff)}) + minetest.swap_node(below, {name = kindname .. "_" .. (below_def.level + diff)}) if diff == def.level then minetest.remove_node(pos) else - minetest.swap_node(pos, {name = basename .. "_" .. (def.level - diff)}) + minetest.swap_node(pos, {name = kindname .. "_" .. (def.level - diff)}) end end end local above = pos:offset(0, 1, 0) - if is_same_kind(above, basename) then - after_place_stack(above) + if is_same_kind(above, kindname) then + blockgame.check_for_stacking(above) end end -local function register_layer (basename, def, level) - local description = def.description .. " (" .. level .. "/" .. def.level_max .. ")" - if level == level_max then description = def.description end - def.description = description - local height = level / def.level_max - local drawtype = "nodebox" - local node_box = { - ["type"] = "fixed", - fixed = { -0.5, -0.5, -0.5, 0.5, -0.5 + height, 0.5 }, - } - if level == level_max then - drawtype = def.drawtype - node_box = nil +local function register_layer (kindname, def, level, modname) + local def = blockgame.naive_deep_copy(def) + def.level = level + + if def.level ~= def.level_max then + def.description = def.description .. " (" .. level .. "/" .. def.level_max .. ")" end - def.drawtype = drawtype - def.node_box = node_box - def.on_construct = after_place_stack - def.after_place_node = after_place_stack - def.after_land = after_place_stack + if level ~= def.level_max then + def.drawtype = "nodebox" + def.node_box = { + ["type"] = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.5 + def.level/def.level_max, 0.5 }, + } + end + + def.on_construct = blockgame.check_for_stacking + def.after_place_node = blockgame.check_for_stacking + def.after_land = blockgame.check_for_stacking def.groups = def.groups or {} - def.groups = blockgame.underride(def.groups, { - leveled = level, - }) + def.groups.leveled = level local layer_modname = minetest.get_current_modname() - def.drop = def.drop or layer_modname .. ":" .. basename .. "_1 " .. level + def.drop = modname .. ":" .. kindname .. "_1 " .. level - blockgame.register_node(basename .. "_" .. level, def) + blockgame.register_node(def.kindname .. "_" .. level, def) end -function blockgame.register_leveled_node (basename, def) - local level_max = def.level_max - if not level_max then return false end +local events = blockgame.events.namespace("api") - def.basename = basename +function blockgame.register_leveled_node (name, def) + if not def.level_max then return false end - for level=1, level_max do - register_layer(basename, def, level) + local basename, modname, fullname = blockgame.extract_id_parts(name) + def.kindname = fullname + + for level=1, def.level_max do + register_layer(basename, def, level, modname) end - minetest.register_alias(basename, basename .. "_" .. level_max) - return true + + minetest.register_alias(name .. "_" .. def.level_max, basename) end