blockgame/mods/bg_tree/decompose.lua
trans_soup 3fa17f8b68 make decomposition require dirty nodes nearby.
decomposition will no longer happen unless the decomposing leaves are
touching a dirty node. thus, they can now be used for decoration in
non-dirty locations.
2023-10-19 17:14:39 +02:00

105 lines
3 KiB
Lua

local modname = minetest.get_current_modname()
local api = blockgame.tree
-- NODE NAMES
local leaves = modname .. ":leaves"
local leaves_decomposing = modname .. ":leaves_decomposing"
local decompose_time_speed = 1
-- TODO: add setting for this as well.
minetest.register_chatcommand(modname .. ":set_decompose_time_speed", {
params = "<value>",
description = "set the speed at which decomposition happens.",
privs = {
control_time = true,
},
func = function (player_name, speed)
speed = tonumber(speed)
if speed == nil then
minetest.chat_send_player(player_name, "time speed must be a number.")
return
end
if speed < 0 or speed > 256 then
minetest.chat_send_player(player_name, "time speed must be between 0 and 256 (inclusive).")
return
end
decompose_time_speed = speed
minetest.chat_send_all(player_name .. " set the leaves decomposition time speed to " .. speed .. ".")
end,
})
local decompose_scores = {
dirty = 100,
leaves_decomposing = 20,
}
local start_decompose_cost = 4000
blockgame.register_increasing_abm({
id = modname .. ":begin_decompose",
label = "decompose leaves",
nodenames = {leaves},
neighbors = {"group:dirty", leaves_decomposing},
interval = 15,
chance = 8,
rate = function (pos, node, data)
local score = blockgame.score_nearby_nodes(pos, 2, decompose_scores, function (gain, distance)
return math.floor(gain / (distance ^ 3))
end)
return data.value + score * decompose_time_speed
end,
check = function (pos, node, data)
return data.value >= start_decompose_cost
end,
action = function (pos, node, data)
-- NOTE: might wanna access the 4 from somewhere, instead of directly knowing it.
-- that way this won't have to change if decomposing leaves max levels change.
local level = math.random(1, 4)
minetest.set_node(pos, {name = leaves_decomposing .. "_" .. level})
end,
})
local decompose_cost = 30000
local average_leaves_per_dirt = 4
blockgame.register_increasing_abm({
id = modname .. ":decompose",
label = "decompose leaves",
nodenames = {"group:leaves_decomposing"},
neighbors = {"group:dirty"},
interval = 15,
chance = 10,
rate = function (pos, node, data)
local score = 20
local bonus = blockgame.score_nearby_nodes(pos, 4, decompose_scores, function (gain, distance)
return math.floor(gain / (distance ^ 3))
end)
score = score + bonus
return data.value + score * decompose_time_speed
end,
check = function (pos, node, data)
return data.value >= decompose_cost
end,
action = function (pos, node, data)
-- currently, larger leaf piles have a greater chance of turning into dirt instead of disappearing.
-- might wanna make it so that instead, dirt is layered as well?
local def = minetest.registered_nodes[node.name]
local dirt_chance = def.level_max - def.level + 1
if blockgame.chance(dirt_chance * average_leaves_per_dirt) then
minetest.set_node(pos, {name = "bg_terrain:dirt"})
else
minetest.remove_node(pos)
minetest.check_for_falling(pos)
end
end,
})