Compare commits
14 Commits
20b29c833f
...
06149b463f
Author | SHA1 | Date |
---|---|---|
trans_soup | 06149b463f | |
trans_soup | 2439b1264f | |
trans_soup | 9a3afd6d5a | |
trans_soup | 6ac310f674 | |
trans_soup | dcb0eb257e | |
trans_soup | 453add021d | |
trans_soup | d04e92a15c | |
trans_soup | 06110f157b | |
trans_soup | 5bc048eb12 | |
trans_soup | 6478e66ef7 | |
trans_soup | da9fb8970d | |
trans_soup | 809d394e9a | |
trans_soup | b6699fcc68 | |
trans_soup | 263e98d526 |
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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")
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
load_file("grow")
|
||||
load_file("death")
|
|
@ -1,3 +0,0 @@
|
|||
name = bg_grass
|
||||
description = adds grass spreading and related mechanics to blockgame.
|
||||
depends = bg_terrain, bg_api
|
|
@ -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")
|
||||
|
|
|
@ -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")
|
||||
|
|
Before Width: | Height: | Size: 232 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 411 B |
Before Width: | Height: | Size: 175 B |
Before Width: | Height: | Size: 279 B |
Before Width: | Height: | Size: 129 B |
|
@ -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,
|
||||
})
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
})
|
|
@ -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")
|
||||
|
|
|
@ -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", {
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
After Width: | Height: | Size: 6.5 KiB |