Compare commits
23 Commits
06149b463f
...
6e205f15b7
Author | SHA1 | Date |
---|---|---|
trans_soup | 6e205f15b7 | |
trans_soup | 31b2242c38 | |
trans_soup | d884e75a24 | |
trans_soup | 19d63efcf5 | |
trans_soup | 5a3d81787c | |
trans_soup | 33fbd7c35e | |
trans_soup | d753612f0b | |
trans_soup | 548d33d146 | |
trans_soup | 18117daade | |
trans_soup | aaeef448f0 | |
trans_soup | 5d98c3dadc | |
trans_soup | 0ff0c9274f | |
trans_soup | 790e00ef5c | |
trans_soup | 5879ecbd67 | |
trans_soup | 1ef3759ae6 | |
trans_soup | 8dccef9389 | |
trans_soup | 20b2dfa0c7 | |
trans_soup | 8ff3df7f7f | |
trans_soup | d28bfbdaf3 | |
trans_soup | a3012de73f | |
trans_soup | c41d161802 | |
trans_soup | 098e07a1e6 | |
trans_soup | 812e0a7e3b |
|
@ -20,12 +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 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 can create dirt by placing leaves next to dirt or grass; eventually they'll start decomposing. this does not work for growing or living leaves (which are unobtainable as items 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.
|
||||
updates might introduce changes that are not backwards-compatible. will 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 don't guarantee it.
|
||||
will 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,29 @@
|
|||
-- TODO: collapse nodes when the node under them is removed.
|
||||
|
||||
local function attempt_collapse_at (pos, node)
|
||||
node = node or minetest.get_node(pos)
|
||||
|
||||
local below = pos + blockgame.vector.dirs.down
|
||||
if minetest.get_node(below).name ~= "air" then return end
|
||||
|
||||
local node_def = minetest.registered_nodes[node.name]
|
||||
if type(node_def.fall_check) == "function" then
|
||||
if not node_def.fall_check(pos, node) then return end
|
||||
end
|
||||
|
||||
minetest.spawn_falling_node(pos)
|
||||
end
|
||||
|
||||
-- collapse nodes that somehow managed to stay in the air.
|
||||
blockgame.register_abm({
|
||||
label = "collapse falling nodes",
|
||||
nodenames = {"group:can_fall"},
|
||||
neighbors = {"air"},
|
||||
interval = 15,
|
||||
chance = 1,
|
||||
action = attempt_collapse_at,
|
||||
})
|
||||
|
||||
return {
|
||||
attempt_collapse_at = attempt_collapse_at,
|
||||
}
|
|
@ -17,7 +17,8 @@ load_file("util_node")
|
|||
load_file("wrappers")
|
||||
|
||||
load_file("random_tick")
|
||||
load_file("loose_nodes")
|
||||
load_file("falling_node")
|
||||
load_file("loose_node")
|
||||
load_file("increasing_abm")
|
||||
|
||||
load_file("cleanup")
|
||||
|
|
|
@ -1,27 +1,7 @@
|
|||
-- TODO: collapse nodes when the node under them is removed.
|
||||
local fall_api = load_file("falling_node")
|
||||
local attempt_collapse_at = fall_api.attempt_collapse_at
|
||||
|
||||
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
|
||||
|
@ -33,13 +13,19 @@ 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",
|
||||
label = "settle loose nodes",
|
||||
nodenames = {"group:loose"},
|
||||
interval = 30,
|
||||
chance = 10,
|
||||
action = attempt_settle_at,
|
||||
})
|
||||
|
||||
local function place_loose_node (itemstack, placer, pointed)
|
||||
local result = minetest.item_place(itemstack, placer, pointed)
|
||||
attempt_collapse_at(pointed.above)
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
|
||||
function blockgame.register_loose_version (name)
|
||||
|
@ -51,6 +37,7 @@ function blockgame.register_loose_version (name)
|
|||
groups[key] = value
|
||||
end
|
||||
groups.loose = 1
|
||||
groups.can_fall = 1
|
||||
|
||||
blockgame.register_node(name .. "_loose", {
|
||||
description = "Loose " .. def.description,
|
|
@ -48,14 +48,3 @@ 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
|
||||
|
|
|
@ -26,3 +26,26 @@ function blockgame.shuffle (tab)
|
|||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function blockgame.any (tab, check)
|
||||
for key, value in pairs(tab) do
|
||||
if check(value, key, tab) then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function blockgame.every (tab, check)
|
||||
for key, value in pairs(tab) do
|
||||
if not check(value, key, tab) then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function blockgame.underride (tab, template)
|
||||
local tab = tab or {}
|
||||
local result = blockgame.shallow_copy_table(template)
|
||||
for key, value in pairs(tab) do
|
||||
result[key] = value
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
|
|
@ -34,3 +34,16 @@ end
|
|||
function api.get_below (pos)
|
||||
return pos + api.dirs.down
|
||||
end
|
||||
|
||||
function api.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
|
||||
|
||||
function api.get_sides_of (pos)
|
||||
return api.get_neighbors(pos, api.sides)
|
||||
end
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
local utils = load_file("util_misc")
|
||||
|
||||
local walk_speed = 1
|
||||
local walk_time = 2
|
||||
local walk_time = 4
|
||||
local speedup_time = 6
|
||||
local run_factor = 3
|
||||
local slowdown_factor = 8
|
||||
local run_factor = 2.5
|
||||
local slowdown_factor = 12
|
||||
local jump_height = 1
|
||||
local jump_factor = 1.5
|
||||
local jump_factor = 1.4
|
||||
|
||||
local speed_data = {}
|
||||
|
||||
|
|
|
@ -10,10 +10,10 @@ local leaves_decomposing = modname .. ":leaves_decomposing"
|
|||
-- END OF NODE NAMES
|
||||
|
||||
blockgame.register_increasing_abm({
|
||||
id = "bg_tree:begin_decompose",
|
||||
id = modname .. ":begin_decompose",
|
||||
label = "decompose leaves",
|
||||
nodenames = {leaves},
|
||||
neighbors = {"group:dirty"},
|
||||
neighbors = {"group:dirty", leaves_decomposing},
|
||||
interval = 15,
|
||||
chance = 4,
|
||||
rate = function (pos, node, data)
|
||||
|
@ -28,21 +28,25 @@ blockgame.register_increasing_abm({
|
|||
})
|
||||
|
||||
blockgame.register_increasing_abm({
|
||||
id = "bg_tree:decompose",
|
||||
id = modname .. ":decompose",
|
||||
label = "decompose leaves",
|
||||
nodenames = {leaves_decomposing},
|
||||
neighbors = {"group:dirty"},
|
||||
interval = 30,
|
||||
chance = 10,
|
||||
interval = 20,
|
||||
chance = 8,
|
||||
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
|
||||
return data.value >= 25
|
||||
end,
|
||||
action = function (pos, node, data)
|
||||
minetest.set_node(pos, {name = "bg_terrain:dirt"})
|
||||
if blockgame.chance(2) then
|
||||
minetest.set_node(pos, {name = "bg_terrain:dirt"})
|
||||
else
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
|
|
@ -64,33 +64,12 @@ blockgame.register_abm({
|
|||
neighbors = {"group:dirty", log_alive},
|
||||
interval = 15,
|
||||
chance = 4,
|
||||
action = function (pos, node, active_object_count, active_object_count_wider)
|
||||
local below = vec.get_below(pos)
|
||||
|
||||
action = function (pos, node)
|
||||
if blockgame.chance(4) then
|
||||
local root_source = api.find_bottom_log(pos, 8)
|
||||
if root_source ~= nil then
|
||||
spread_roots_from(root_source + blockgame.vector.dirs.down)
|
||||
end
|
||||
end
|
||||
|
||||
if blockgame.chance(2) then
|
||||
extend_leaves_from(pos)
|
||||
end
|
||||
|
||||
if blockgame.chance(2) then
|
||||
local side = vec.random_side()
|
||||
local target = pos + side
|
||||
|
||||
blockgame.attempt_place(target, {name = log_alive})
|
||||
end
|
||||
|
||||
if blockgame.chance(4) then
|
||||
minetest.set_node(pos, {name = log_alive})
|
||||
|
||||
if minetest.get_node(below).name == log_alive and blockgame.chance(4) then return end
|
||||
|
||||
blockgame.attempt_place(pos + vector.new(0, 1, 0), {name = modname .. ":sapling"})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
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_growing = modname .. ":leaves_growing"
|
||||
local leaves_alive = modname .. ":leaves_alive"
|
||||
local root = modname .. ":root"
|
||||
|
||||
-- END OF NODE NAMES
|
||||
|
||||
local max_grow_distance = 2
|
||||
|
||||
-- TODO: turn this into an increasing ABM.
|
||||
blockgame.register_abm({
|
||||
label = "grow leaves",
|
||||
nodenames = {leaves_alive},
|
||||
neighbors = {log_alive, leaves_alive},
|
||||
nodenames = {leaves_growing},
|
||||
neighbors = {log_alive, leaves_growing, leaves_alive},
|
||||
interval = 15,
|
||||
chance = 8,
|
||||
action = function (pos, node)
|
||||
|
@ -26,12 +24,13 @@ blockgame.register_abm({
|
|||
local distance = meta:get_int("leaf_distance") or 1
|
||||
if distance >= max_grow_distance then return end
|
||||
|
||||
local neighbors = blockgame.get_neighbors(pos)
|
||||
local neighbors = blockgame.vector.get_neighbors(pos)
|
||||
for _, target in pairs(neighbors) do
|
||||
if blockgame.chance(6) then
|
||||
blockgame.attempt_place(target, {name = leaves_alive})
|
||||
if blockgame.chance(2) then
|
||||
blockgame.attempt_place(target, {name = leaves_growing})
|
||||
minetest.get_meta(target):set_int("leaf_distance", distance + 1)
|
||||
end
|
||||
end
|
||||
minetest.set_node(pos, {name = leaves_alive})
|
||||
end,
|
||||
})
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
local modname = minetest.get_current_modname()
|
||||
|
||||
-- NODE NAMES
|
||||
|
||||
local sapling = modname .. ":sapling"
|
||||
local log_alive = modname .. ":log_alive"
|
||||
local leaves_growing = modname .. ":leaves_growing"
|
||||
local root_alive = modname .. ":root_alive"
|
||||
|
||||
-- END OF NODE NAMES
|
||||
|
||||
local function supports_sapling (name)
|
||||
if name == log_alive or name == root_alive then return true end
|
||||
return minetest.get_item_group(name, "dirty") > 0
|
||||
end
|
||||
|
||||
blockgame.register_increasing_abm({
|
||||
id = modname .. ":grow_sapling",
|
||||
label = "grow sapling",
|
||||
nodenames = {sapling},
|
||||
neighbors = {"group:dirty", log_alive},
|
||||
interval = 15,
|
||||
chance = 4,
|
||||
rate = function (pos, node, data)
|
||||
-- TODO: find connected living logs and leaves, and nearby light levels, to calculate growth rate.
|
||||
return data.value + math.random(1, 99)
|
||||
end,
|
||||
check = function (pos, node, data)
|
||||
if data.value < 200 then return false end
|
||||
|
||||
local below = pos + blockgame.vector.dirs.down
|
||||
local below_name = minetest.get_node(below).name
|
||||
if not supports_sapling(below_name) then return false end
|
||||
|
||||
local above = pos + blockgame.vector.dirs.up
|
||||
if minetest.get_node(above).name ~= "air" then return false end
|
||||
|
||||
return true
|
||||
end,
|
||||
action = function (pos, node, data)
|
||||
-- TODO: decrease energy (`data.value`) when growing, but don't completely reset it to 0.
|
||||
-- (this will require the api adding support for increasing_abm actions modifying their data.)
|
||||
local above = pos + blockgame.vector.dirs.up
|
||||
|
||||
if not blockgame.chance(4) then
|
||||
minetest.set_node(above, {name = sapling})
|
||||
end
|
||||
minetest.set_node(pos, {name = log_alive})
|
||||
|
||||
local sides = blockgame.vector.get_sides_of(pos)
|
||||
for _, side in pairs(sides) do
|
||||
blockgame.attempt_place(side, {name = leaves_growing})
|
||||
end
|
||||
end,
|
||||
})
|
|
@ -4,6 +4,7 @@ load_file("node")
|
|||
load_file("decoration")
|
||||
|
||||
load_file("grow")
|
||||
load_file("grow_sapling")
|
||||
load_file("grow_leaves")
|
||||
|
||||
load_file("decompose")
|
||||
|
|
|
@ -1,59 +1,86 @@
|
|||
local modname = minetest.get_current_modname()
|
||||
|
||||
blockgame.register_node(modname .. ":log", {
|
||||
description = "Log",
|
||||
tiles = {
|
||||
modname .. "_log_top.png",
|
||||
modname .. "_log_top.png",
|
||||
modname .. "_log.png",
|
||||
},
|
||||
groups = {
|
||||
local function reg_log (name, def)
|
||||
def = def or {}
|
||||
|
||||
def.description = def.description or "Log"
|
||||
|
||||
local texture = def.texture or name
|
||||
def.tiles = blockgame.underride(def.tiles, {
|
||||
modname .. "_" .. texture .. "_top.png",
|
||||
modname .. "_" .. texture .. "_top.png",
|
||||
modname .. "_" .. texture .. ".png",
|
||||
})
|
||||
|
||||
def.groups = blockgame.underride(def.groups, {
|
||||
woody = 1,
|
||||
supports_leaves = 1,
|
||||
})
|
||||
|
||||
blockgame.register_node(modname .. ":" .. name, def)
|
||||
end
|
||||
|
||||
reg_log("log")
|
||||
reg_log("log_alive", {
|
||||
groups = {
|
||||
planty = 1,
|
||||
},
|
||||
texture = "log",
|
||||
drop = modname .. ":log",
|
||||
})
|
||||
blockgame.register_node(modname .. ":log_alive", {
|
||||
description = "Growing Log",
|
||||
tiles = {
|
||||
modname .. "_log_top_alive.png",
|
||||
modname .. "_log_top_alive.png",
|
||||
modname .. "_log_alive.png",
|
||||
},
|
||||
reg_log("sapling", {
|
||||
groups = {
|
||||
woody = 1,
|
||||
planty = 1,
|
||||
},
|
||||
drop = modname .. ":log",
|
||||
})
|
||||
|
||||
blockgame.reg_simple_node("sapling", "Sapling", {
|
||||
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,
|
||||
})
|
||||
|
||||
local function leaves_fall_check (pos, node)
|
||||
return blockgame.every(blockgame.vector.get_neighbors(pos), function (pos)
|
||||
return minetest.get_item_group(minetest.get_node(pos).name, "supports_leaves") == 0
|
||||
end)
|
||||
end
|
||||
|
||||
reg_leaves("leaves", "Leaves", {
|
||||
planty = 1,
|
||||
air_flowable = 1,
|
||||
local function reg_leaves (name, def)
|
||||
def.description = def.description or name
|
||||
def.texture = def.texture or name
|
||||
def.tiles = {modname .. "_" .. def.texture .. ".png"}
|
||||
|
||||
def.drawtype = "glasslike"
|
||||
def.paramtype = "light"
|
||||
def.sunlight_propagates = true
|
||||
|
||||
def.groups = blockgame.underride(def.groups, {
|
||||
planty = 1,
|
||||
supports_leaves = 1,
|
||||
air_flowable = 1,
|
||||
can_fall = 1,
|
||||
})
|
||||
|
||||
blockgame.register_node(modname .. ":" .. name, def)
|
||||
end
|
||||
|
||||
reg_leaves("leaves", {
|
||||
description = "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,
|
||||
reg_leaves("leaves_growing", {
|
||||
description = "Growing Leaves",
|
||||
drop = modname .. ":leaves",
|
||||
texture = "leaves_alive",
|
||||
fall_check = leaves_fall_check,
|
||||
})
|
||||
reg_leaves("leaves_alive", {
|
||||
description = "Leaves",
|
||||
drop = modname .. ":leaves",
|
||||
fall_check = leaves_fall_check,
|
||||
})
|
||||
reg_leaves("leaves_decomposing", {
|
||||
description = "Decomposing Leaves",
|
||||
groups = {
|
||||
supports_leaves = 0,
|
||||
},
|
||||
})
|
||||
|
||||
blockgame.reg_simple_node("nut", "Nut", {
|
||||
|
@ -63,3 +90,6 @@ blockgame.reg_simple_node("nut", "Nut", {
|
|||
blockgame.reg_simple_node("root", "Root", {
|
||||
woody = 1,
|
||||
})
|
||||
blockgame.reg_simple_node("root_alive", "Growing Root", {
|
||||
woody = 1,
|
||||
})
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Loading…
Reference in New Issue