90 lines
2.5 KiB
Lua
90 lines
2.5 KiB
Lua
local function is_same_kind (pos, kindname)
|
|
local node = minetest.get_node(pos)
|
|
local node_kindname = minetest.registered_items[node.name].kindname
|
|
return kindname and node_kindname and kindname == node_kindname
|
|
end
|
|
|
|
local function stack_attempt (pos, source_level)
|
|
local node = minetest.get_node(pos)
|
|
local def = minetest.registered_nodes[node.name]
|
|
if def.level == level_max then return source_level end
|
|
|
|
local level_max = def.level_max
|
|
local kindname = def.kindname
|
|
|
|
local max_diff = level_max - def.level
|
|
local diff = math.min(max_diff, source_level)
|
|
|
|
minetest.swap_node(pos, {name = kindname .. "_" .. (def.level + diff)})
|
|
return source_level - diff
|
|
end
|
|
|
|
function blockgame.check_for_stacking (pos)
|
|
local node = minetest.get_node(pos)
|
|
if not blockgame.item_matches(node.name, {"group:leveled"}) then return end
|
|
local def = minetest.registered_nodes[node.name]
|
|
local kindname = def.kindname
|
|
local level_max = def.level_max
|
|
|
|
local below = pos:offset(0, -1, 0)
|
|
if is_same_kind(below, kindname) then
|
|
local new_level = stack_attempt(below, def.level)
|
|
|
|
if new_level ~= def.level then
|
|
minetest.swap_node(pos, {name = kindname .. "_" .. new_level})
|
|
end
|
|
end
|
|
|
|
local above = pos:offset(0, 1, 0)
|
|
if is_same_kind(above, kindname) then
|
|
blockgame.check_for_stacking(above)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
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
|
|
|
|
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.leveled = level
|
|
|
|
local layer_modname = minetest.get_current_modname()
|
|
def.drop = modname .. ":" .. kindname .. "_1 " .. level
|
|
|
|
blockgame.register_node(def.kindname .. "_" .. level, def)
|
|
end
|
|
|
|
local events = blockgame.events.namespace("api")
|
|
|
|
function blockgame.register_leveled_node (name, def)
|
|
if not def.level_max then return false end
|
|
|
|
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(fullname, fullname .. "_" .. def.level_max)
|
|
minetest.register_alias(fullname .. "_" .. 0, "air")
|
|
end
|