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.
This commit is contained in:
parent
0c5d4891b7
commit
a06b0a08af
1 changed files with 42 additions and 43 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue