Compare commits

...

13 Commits

Author SHA1 Message Date
trans_soup ddf0ada4ff minor fix.
replace an old leftover line.
2023-10-21 22:10:52 +02:00
trans_soup 81bdcf6951 fix decomposing leaves registration.
make decomposing leaves registration work with the new API support for
leveled nodes.
2023-10-21 22:10:00 +02:00
trans_soup a06b0a08af 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.
2023-10-21 22:08:46 +02:00
trans_soup 0c5d4891b7 add utility for extracting name parts.
add API function for splitting up an item identifier into its mod name
and item name parts.
2023-10-21 22:03:28 +02:00
trans_soup 8dfccdd315 remove unused variable. 2023-10-21 20:48:01 +02:00
trans_soup 29017dd835 Merge branch 'main' into leveled-nodes 2023-10-21 12:01:06 +02:00
trans_soup f228dcac53 fix name validations in `register_node` wrapper.
`blockgame.register_node` now works both when the provided name includes
a mod name, and when it doesn't.

previously, including a mod name would break things, making the actual
name used for registration include the mod name twice.
2023-10-21 11:56:50 +02:00
trans_soup 8259231013 fix error in decomposing leaves placement.
one place accidentally used the position of the placed node, when it
should have used the position below that.
2023-10-21 11:47:12 +02:00
trans_soup 01bbe58e45 start working on leveled nodes.
start working on generalizing registration of leveled nodes. currently
broken.
2023-10-21 11:41:33 +02:00
trans_soup bab117c98c add comment. 2023-10-21 11:15:25 +02:00
trans_soup 914f26e613 refactor: decomposition placement checks.
generalize a repeated node check into a single function.
2023-10-21 10:50:11 +02:00
trans_soup c5a13d68c9 fix floating decomposing leaves.
leaves will now, upon beginning decomposition, check if there are
decomposing leaves on top of them which can fall down onto them. this
fixes an error where this situation would leave the top leaves visually
floating over the bottom leaves, even when there was space for them to
stack.
2023-10-21 10:38:16 +02:00
trans_soup 8584d0ac3e make living logs and saplings fall down.
add alive logs and saplings to the `faling_node` group.
2023-10-21 10:19:16 +02:00
7 changed files with 205 additions and 58 deletions

View File

@ -23,6 +23,7 @@ load_file("random_tick")
load_file("increasing_abm")
load_file("loose_node")
load_file("fall_fix")
load_file("leveled_node")
load_file("privs")

View File

@ -0,0 +1,82 @@
local function is_same_kind (pos, kindname)
local node = minetest.get_node(pos)
local node_kindname = minetest.registered_items[node.name].kindname
return kindname == node_kindname
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 + blockgame.vector.dirs.down
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 = kindname .. "_" .. (below_def.level + diff)})
if diff == def.level then
minetest.remove_node(pos)
else
minetest.swap_node(pos, {name = kindname .. "_" .. (def.level - diff)})
end
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(name .. "_" .. def.level_max, basename)
end

View File

@ -21,3 +21,21 @@ end
function blockgame.starts_with (str, start)
return string.sub(str, 1, string.len(start)) == start
end
function blockgame.extract_id_parts (name)
local basename
local modname
local colon_pos = string.find(name, ":")
if colon_pos then
modname = string.sub(name, 1, colon_pos - 1)
basename = string.sub(name, colon_pos + 1)
else
modname = minetest.get_current_modname()
basename = name
end
return basename, modname, modname .. ":" .. basename
end

View File

@ -16,6 +16,18 @@ function blockgame.shallow_copy_table (tab)
return result
end
function blockgame.naive_deep_copy (tab)
local result = {}
for key, value in pairs(tab) do
if type(value) == "table" then
result[key] = blockgame.naive_deep_copy(value)
else
result[key] = value
end
end
return result
end
function blockgame.shuffle (tab)
local keys = blockgame.get_keys(tab)
local result = {}
@ -43,9 +55,13 @@ end
function blockgame.underride (tab, template)
local tab = tab or {}
local result = blockgame.shallow_copy_table(template)
local result = blockgame.naive_deep_copy(template)
for key, value in pairs(tab) do
result[key] = value
if type(value) == "table" then
result[key] = blockgame.underride(value, template[key] or {})
else
result[key] = value
end
end
return result
end

View File

@ -34,27 +34,40 @@ end
local events = blockgame.events.namespace("api")
function blockgame.register_node (name, def, modname)
-- TODO: take full name and then extract modname and base name from that, that'll probably be easier to maintain.
local modname = modname or minetest.get_current_modname()
local full_name = modname .. ":" .. name
function blockgame.register_node (fullname, def)
-- make sure the right names are used in the right contexts, by manually extracting them here.
-- this makes `blockgame.register_node` more flexible/reliable.
local modname
local basename
def.description = def.description or capitalize(name)
local colon_pos = string.find(fullname, ":")
if colon_pos then
modname = string.sub(fullname, 1, colon_pos - 1)
basename = string.sub(fullname, colon_pos + 1)
else
modname = minetest.get_current_modname()
basename = fullname
fullname = modname .. ":" .. basename
end
def.description = def.description or capitalize(basename)
def.tiles = def.tiles or {
modname .. "_" .. name .. ".png",
modname .. "_" .. basename .. ".png",
}
events.broadcast("before_register_node", {
name = name,
name = fullname,
def = def,
mod = modname,
basename = basename
})
minetest.register_node(full_name, def)
minetest.register_node(fullname, def)
events.broadcast("after_register_node", {
name = name,
name = fullname,
def = def,
mod = modname,
basename = basename
})
end

View File

@ -1,24 +1,25 @@
local modname = minetest.get_current_modname()
local function reg_leaves (name, def)
local texture = def.texture or name
def = blockgame.underride(def, {
description = name,
texture = texture,
tiles = {modname .. "_" .. texture .. ".png"},
drawtype = "allfaces_optional",
paramtype = "light",
sunlight_propagates = true,
})
def.groups = blockgame.underride(def.groups, {
local base_def = {
drawtype = "allfaces_optional",
paramtype = "light",
sunlight_propagates = true,
groups = {
planty = 1,
extends_leaves_support = 1,
air_flowable = 1,
falling_node = 1,
},
}
local function reg_leaves (name, def)
def = blockgame.underride(def, base_def)
local texture = def.texture or name
def = blockgame.underride(def, {
description = name,
tiles = {modname .. "_" .. texture .. ".png"},
})
blockgame.register_node(name, def)
@ -63,29 +64,44 @@ reg_leaves("leaves_alive", {
},
})
--[[
local function check_decompose (pos)
local node = minetest.get_node(pos)
return blockgame.item_matches(node.name, {"group:leaves_decomposing"})
end
]]--
-- TODO: generalize stacking node registration and put into API.
local decomposing_leaves_layers = 4
local after_place_stack = function (pos)
local node = minetest.get_node(pos)
if not blockgame.starts_with(node.name, modname .. ":leaves_decomposing") then return end
--[[
local function after_place_stack (pos)
if not check_decompose(pos) then return end
local below = pos + blockgame.vector.dirs.down
local below_node = minetest.get_node(below)
if not blockgame.starts_with(below_node.name, modname .. ":leaves_decomposing") then return end
if check_decompose(below) then
local node = minetest.get_node(pos)
local below_node = minetest.get_node(below)
local def = minetest.registered_nodes[node.name]
local below_def = minetest.registered_nodes[below_node.name]
local def = minetest.registered_nodes[node.name]
local below_def = minetest.registered_nodes[below_node.name]
if below_def.level == decomposing_leaves_layers then return end
local max_diff = decomposing_leaves_layers - below_def.level
local diff = math.min(max_diff, def.level)
if below_def.level ~= decomposing_leaves_layers then
local max_diff = decomposing_leaves_layers - below_def.level
local diff = math.min(max_diff, def.level)
minetest.swap_node(below, {name = modname .. ":leaves_decomposing_" .. (below_def.level + diff)})
if diff == def.level then
minetest.remove_node(pos)
else
minetest.swap_node(pos, {name = modname .. ":leaves_decomposing_" .. (def.level - diff)})
minetest.swap_node(below, {name = modname .. ":leaves_decomposing_" .. (below_def.level + diff)})
if diff == def.level then
minetest.remove_node(pos)
else
minetest.swap_node(pos, {name = modname .. ":leaves_decomposing_" .. (def.level - diff)})
end
end
end
local above = pos:offset(0, 1, 0)
if check_decompose(above) then
after_place_stack(above)
end
end
@ -105,26 +121,25 @@ local function reg_decomposing (level)
node_box = nil
end
reg_leaves("leaves_decomposing_" .. level, {
description = description,
level = level,
level_max = decomposing_leaves_layers,
texture = "leaves_decomposing",
drawtype = drawtype,
node_box = node_box,
on_construct = after_place_stack,
after_place_node = after_place_stack,
after_land = after_place_stack,
drop = modname .. ":leaves_decomposing_1 " .. level,
groups = {
leaves_decomposing = level,
},
walkable = false,
supports_falling = true,
})
reg_leaves("leaves_decomposing_" .. level, )
end
for level=1, decomposing_leaves_layers do
reg_decomposing(level)
end
minetest.register_alias(modname .. ":leaves_decomposing", modname .. ":leaves_decomposing_" .. decomposing_leaves_layers)
]]--
blockgame.register_leveled_node("leaves_decomposing", blockgame.underride({
description = "Decomposing Leaves",
level_max = decomposing_leaves_layers,
tiles = {
modname .. "_leaves_decomposing.png",
},
groups = {
leaves_decomposing = decomposing_leaves_layers,
},
walkable = false,
supports_falling = true,
level_max = decomposing_leaves_layers,
}, base_def))

View File

@ -15,6 +15,7 @@ local function reg_log (name, def)
def.groups = blockgame.underride(def.groups, {
woody = 1,
supports_leaves = 1,
falling_node = 1,
})
blockgame.register_node(name, def)
@ -23,6 +24,7 @@ end
reg_log("log", {
groups = {
supports_leaves = 0,
falling_node = 0,
},
})
reg_log("log_alive", {