Compare commits

...

14 Commits

Author SHA1 Message Date
trans_soup 06149b463f update readme. 2023-10-16 21:46:18 +02:00
trans_soup 2439b1264f make all leaf variants use `air_flowable` group. 2023-10-16 21:42:25 +02:00
trans_soup 9a3afd6d5a add support for group `air_flowable`.
replace the placeholder api functionality for checking whether air flows
through a node, with something that relies on a dedicated group (instead
of a hard-coded list in the api code).
2023-10-16 21:40:57 +02:00
trans_soup 6ac310f674 integrate bg_grass into bg_terrain. 2023-10-16 21:40:29 +02:00
trans_soup dcb0eb257e update decomposition to use increasing ABM:s. 2023-10-16 21:30:57 +02:00
trans_soup 453add021d implement increasing ABM:s.
create public api function that registers "increasing ABM:s"; these
abstract over using numerical values associated with individual nodes in
ABM:s, allowing for straightforward creation of processes that occur
over time.
2023-10-16 21:27:59 +02:00
trans_soup d04e92a15c add decomposition of leaves into dirt.
make leaves decompose over time into dirt when near dirty nodes. also
remove placeholder pummel recipe that turns leaves into dirt.
2023-10-16 20:41:09 +02:00
trans_soup 06110f157b refactor leaves node registrations. 2023-10-16 20:32:52 +02:00
trans_soup 5bc048eb12 separate leaf growth from other tree growth. 2023-10-16 19:18:29 +02:00
trans_soup 6478e66ef7 add `get_neighbors` function to api. 2023-10-16 19:17:52 +02:00
trans_soup da9fb8970d change stone texture to custom texture.
(which accidentally looks very similar to minecraft clay.)
2023-10-16 18:31:56 +02:00
trans_soup 809d394e9a remove unused textures. 2023-10-16 18:31:47 +02:00
trans_soup b6699fcc68 add loose versions of some terrain nodes.
add loose versions of dirt, grass, and cobblestone nodes.
2023-10-16 10:50:25 +02:00
trans_soup 263e98d526 add basic api support for loose nodes.
expose an api function to register "loose" versions of existing nodes,
and implement some behaviour for such nodes; they will fall down if
there is air below them, and will eventually become their non-loose
counterparts if there is not air below them.
2023-10-16 10:46:32 +02:00
23 changed files with 239 additions and 59 deletions

View File

@ -20,10 +20,12 @@ you can turn a log into planks by pummeling it with stone. there must be air on
you can grow a tree by placing a dirty node (dirt or grass) on top of a nut. this will create a sapling, which will grow into something vaguely resembling a tree (including roots in the ground). note that there's currently no way to get nuts, so you'll have to use cheats for now if you want trees.
you can create dirt by pummeling leaves with leaves.
you can create dirt by placing leaves next to dirt or grass; eventually they'll start decomposing. this does not work for growing leaves (which are unobtainable as an item anyways).
you start running over time as you move. this also makes you jump higher (although it does not make you take less fall damage).
# warning
updates might introduce changes that are not backwards-compatible. i'll probably use [semantic versioning](https://semver.org/) eventually.
i'll try to make sure new code includes ways of converting stuff in old worlds to work with the new code, but can't guarantee it.
i'll try to make sure new code includes ways of converting stuff in old worlds to work with the new code, but don't guarantee it.

View File

@ -0,0 +1,31 @@
function blockgame.register_increasing_abm (def)
local id = def.id or "unknown"
local label = def.label or "unlabeled"
local nodenames = def.nodenames or {}
local neighbors = def.neighbors or {}
local interval = def.interval or 60
local chance = def.chance or 10
-- TODO: fully validate def, make sure it has the necessary functions specified.
blockgame.register_abm({
label = label,
nodenames = nodenames,
neighbors = neighbors,
interval = interval,
chance = chance,
action = function (pos, node)
local meta = minetest.get_meta(pos)
local value = meta:get_int(id) or 0
local data = {
value = value,
}
value = def.rate(pos, node, data)
meta:set_int(id, value)
if not def.check(pos, node, data) then return end
def.action(pos, node, data)
end,
})
end

View File

@ -17,5 +17,7 @@ load_file("util_node")
load_file("wrappers")
load_file("random_tick")
load_file("loose_nodes")
load_file("increasing_abm")
load_file("cleanup")

View File

@ -0,0 +1,63 @@
-- TODO: collapse nodes when the node under them is removed.
local function attempt_collapse_at (pos)
local below = pos + blockgame.vector.dirs.down
if minetest.get_node(below).name ~= "air" then return end
minetest.spawn_falling_node(pos)
end
local function place_loose_node (itemstack, placer, pointed)
local result = minetest.item_place(itemstack, placer, pointed)
attempt_collapse_at(pointed.above)
return result
end
-- collapse nodes that somehow managed to stay in the air.
blockgame.register_abm({
label = "collapse collapsible nodes",
nodenames = {"group:loose"},
neighbors = {"air"},
interval = 15,
chance = 1,
action = attempt_collapse_at,
})
local function attempt_settle_at (pos)
local below = pos + blockgame.vector.dirs.down
if minetest.get_node(below).name == "air" then return end
local def = minetest.registered_nodes[minetest.get_node(pos).name]
minetest.set_node(pos, {name = def.stable_version})
end
-- settle nodes that are still (in the future, it will take some time for loose nodes that are still to settle).
blockgame.register_abm({
label = "settle collapsible nodes",
nodenames = {"group:loose"},
interval = 30,
chance = 10,
action = attempt_settle_at,
})
function blockgame.register_loose_version (name)
local def = minetest.registered_nodes[name]
if not def then return false end
local groups = {}
for key, value in pairs(def.groups) do
groups[key] = value
end
groups.loose = 1
blockgame.register_node(name .. "_loose", {
description = "Loose " .. def.description,
tiles = def.tiles, -- temporary
groups = groups,
on_place = place_loose_node,
stable_version = name,
})
return true
end

View File

@ -11,20 +11,13 @@ end
-- probably temporary; will probably use groups for this later.
local air_flowable = {
"air",
"bg_tree:leaves",
"bg_tree:leaves_alive",
}
function blockgame.air_flows_through (pos, node)
node = node or minetest.get_node(pos)
local node_name = node.name
for _, name in pairs(air_flowable) do
if name == node_name then return true end
end
return false
if node_name == "air" then return true end
return minetest.get_item_group(node_name, "air_flowable") > 0
end
@ -55,3 +48,14 @@ function blockgame.random_walk (data)
end
return pos
end
function blockgame.get_neighbors (pos, neighborhood)
neighborhood = neighborhood or blockgame.vector.dirs
local neighbors = {}
for _, dir in pairs(neighborhood) do
table.insert(neighbors, pos + dir)
end
return neighbors
end

View File

@ -1,2 +0,0 @@
load_file("grow")
load_file("death")

View File

@ -1,3 +0,0 @@
name = bg_grass
description = adds grass spreading and related mechanics to blockgame.
depends = bg_terrain, bg_api

View File

@ -3,4 +3,7 @@ local modname = minetest.get_current_modname()
load_file("node")
load_file("biome")
load_file("grass_grow")
load_file("grass_death")
load_file("cleanup")

View File

@ -30,7 +30,12 @@ blockgame.register_node(modname .. ":grass", {
},
drop = modname .. ":dirt",
})
blockgame.reg_simple_node("dirt", "Dirt", {
cracky = 3,
dirty = 1,
})
blockgame.register_loose_version(modname .. ":dirt")
blockgame.register_loose_version(modname .. ":grass")
blockgame.register_loose_version(modname .. ":cobblestone")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

View File

@ -0,0 +1,48 @@
local modname = minetest.get_current_modname()
local api = blockgame.tree
local vec = blockgame.vector
-- NODE NAMES
local leaves = modname .. ":leaves"
local leaves_decomposing = modname .. ":leaves_decomposing"
-- END OF NODE NAMES
blockgame.register_increasing_abm({
id = "bg_tree:begin_decompose",
label = "decompose leaves",
nodenames = {leaves},
neighbors = {"group:dirty"},
interval = 15,
chance = 4,
rate = function (pos, node, data)
return data.value + math.random(4, 6)
end,
check = function (pos, node, data)
return data.value >= 20
end,
action = function (pos, node, data)
minetest.set_node(pos, {name = leaves_decomposing})
end,
})
blockgame.register_increasing_abm({
id = "bg_tree:decompose",
label = "decompose leaves",
nodenames = {leaves_decomposing},
neighbors = {"group:dirty"},
interval = 30,
chance = 10,
rate = function (pos, node, data)
-- TODO: decompose faster depending on surrounding dirty nodes & other decomposing leaves.
-- can probably do that with a flood fill that counts up a "score" depending on the nodes it encounters.
return data.value + math.random(1, 9)
end,
check = function (pos, node, data)
return data.value >= 30
end,
action = function (pos, node, data)
minetest.set_node(pos, {name = "bg_terrain:dirt"})
end,
})

View File

@ -64,7 +64,6 @@ blockgame.register_abm({
neighbors = {"group:dirty", log_alive},
interval = 15,
chance = 4,
catch_up = true,
action = function (pos, node, active_object_count, active_object_count_wider)
local below = vec.get_below(pos)
@ -75,9 +74,6 @@ blockgame.register_abm({
end
end
if blockgame.chance(2) then
extend_leaves_from(pos)
end
if blockgame.chance(2) then
extend_leaves_from(pos)
end
@ -87,10 +83,6 @@ blockgame.register_abm({
local target = pos + side
blockgame.attempt_place(target, {name = log_alive})
if blockgame.chance(2) then
extend_leaves_from(target)
end
end
if blockgame.chance(4) then

View File

@ -0,0 +1,37 @@
local modname = minetest.get_current_modname()
local api = blockgame.tree
local vec = blockgame.vector
-- NODE NAMES
local log = modname .. ":log"
local log_alive = modname .. ":log_alive"
local leaves = modname .. ":leaves"
local leaves_alive = modname .. ":leaves_alive"
local root = modname .. ":root"
-- END OF NODE NAMES
local max_grow_distance = 2
blockgame.register_abm({
label = "grow leaves",
nodenames = {leaves_alive},
neighbors = {log_alive, leaves_alive},
interval = 15,
chance = 8,
action = function (pos, node)
-- TODO: give leaves energy over time, that they spend when creating new leaves.
local meta = minetest.get_meta(pos)
local distance = meta:get_int("leaf_distance") or 1
if distance >= max_grow_distance then return end
local neighbors = blockgame.get_neighbors(pos)
for _, target in pairs(neighbors) do
if blockgame.chance(6) then
blockgame.attempt_place(target, {name = leaves_alive})
minetest.get_meta(target):set_int("leaf_distance", distance + 1)
end
end
end,
})

View File

@ -1,5 +1,11 @@
load_file("api")
load_file("decoration")
load_file("node")
load_file("decoration")
load_file("grow")
load_file("grow_leaves")
load_file("decompose")
load_file("recipes")

View File

@ -29,30 +29,31 @@ blockgame.reg_simple_node("sapling", "Sapling", {
planty = 1,
})
blockgame.register_node(modname .. ":leaves", {
description = "Leaves",
drawtype = "glasslike",
tiles = {
modname .. "_leaves.png",
},
paramtype = "light",
sunlight_propagates = true,
groups = {
planty = 1,
},
local function reg_leaves (name, desc, groups, drop)
blockgame.register_node(modname .. ":" .. name, {
description = desc,
drawtype = "glasslike",
tiles = {
modname .. "_" .. name .. ".png",
},
paramtype = "light",
sunlight_propagates = true,
groups = groups,
drop = drop,
})
end
reg_leaves("leaves", "Leaves", {
planty = 1,
air_flowable = 1,
})
blockgame.register_node(modname .. ":leaves_alive", {
description = "Growing Leaves",
drawtype = "glasslike",
tiles = {
modname .. "_leaves_alive.png",
},
paramtype = "light",
sunlight_propagates = true,
groups = {
planty = 1,
},
drop = modname .. ":leaves",
reg_leaves("leaves_alive", "Growing Leaves", {
planty = 1,
air_flowable = 1,
}, modname .. ":leaves")
reg_leaves("leaves_decomposing", "Decomposing Leaves", {
planty = 1,
air_flowable = 1,
})
blockgame.reg_simple_node("nut", "Nut", {

View File

@ -4,12 +4,3 @@ local modname = minetest.get_current_modname()
-- TODO: when recipes add support for groups, use `dirty` group here instead of specific nodes.
blockgame.crafting.register_stack_recipe("bg_terrain:grass", modname .. ":nut", {name = modname .. ":sapling"})
blockgame.crafting.register_stack_recipe("bg_terrain:dirt", modname .. ":nut", {name = modname .. ":sapling"})
blockgame.crafting.register_pummel_recipe({
label = "pummel leaves into dirt",
used_item = modname .. ":leaves",
target_node = modname .. ":leaves",
on_success = function (pos, used_node, target_node)
minetest.set_node(pos, {name = "bg_terrain:dirt"})
end,
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB