Skip to content
Snippets Groups Projects
Commit 9670c271 authored by ShadowNinja's avatar ShadowNinja Committed by BlockMen
Browse files

Clean up treegen code

parent c32957f9
Branches
No related tags found
No related merge requests found
......@@ -127,56 +127,6 @@ end
minetest.register_on_punchnode(on_punchnode)
--
-- Grow trees
--
minetest.register_abm({
nodenames = {"default:sapling"},
interval = 10,
chance = 50,
action = function(pos, node)
local nu = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name
local is_soil = minetest.get_item_group(nu, "soil")
if is_soil == 0 then
return
end
minetest.log("action", "A sapling grows into a tree at "..minetest.pos_to_string(pos))
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
local data = vm:get_data()
default.grow_tree(data, a, pos, math.random(1, 4) == 1, math.random(1,100000))
vm:set_data(data)
vm:write_to_map(data)
vm:update_map()
end
})
minetest.register_abm({
nodenames = {"default:junglesapling"},
interval = 10,
chance = 50,
action = function(pos, node)
local nu = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name
local is_soil = minetest.get_item_group(nu, "soil")
if is_soil == 0 then
return
end
minetest.log("action", "A jungle sapling grows into a tree at "..minetest.pos_to_string(pos))
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map({x=pos.x-16, y=pos.y-1, z=pos.z-16}, {x=pos.x+16, y=pos.y+16, z=pos.z+16})
local a = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
local data = vm:get_data()
default.grow_jungletree(data, a, pos, math.random(1,100000))
vm:set_data(data)
vm:write_to_map(data)
vm:update_map()
end
})
--
-- Lavacooling
--
......
--
-- Grow trees
--
local random = math.random
local function can_grow(pos)
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
if not node_under then
return false
end
local name_under = node_under.name
local is_soil = minetest.get_item_group(name_under, "soil")
if is_soil == 0 then
return false
end
return true
end
minetest.register_abm({
nodenames = {"default:sapling"},
interval = 10,
chance = 50,
action = function(pos, node)
if not can_grow(pos) then
return
end
minetest.log("action", "A sapling grows into a tree at "..minetest.pos_to_string(pos))
default.grow_tree(pos, random(1, 4) == 1)
end
})
minetest.register_abm({
nodenames = {"default:junglesapling"},
interval = 10,
chance = 50,
action = function(pos, node)
if not can_grow(pos) then
return
end
minetest.log("action", "A jungle sapling grows into a tree at "..
minetest.pos_to_string(pos))
default.grow_jungletree(pos)
end
})
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_apple = minetest.get_content_id("default:apple")
local function add_trunk_and_leaves(data, a, pos, tree_cid, leaves_cid,
height, size, iters, is_apple_tree)
local x, y, z = pos.x, pos.y, pos.z
-- Trunk
for y_dist = 0, height - 1 do
local vi = a:index(x, y + y_dist, z)
if y_dist == 0 or data[vi] == c_air or data[vi] == leaves_cid then
data[vi] = tree_cid
end
end
-- Force leaves near the trunk
for z_dist = -1, 1 do
for y_dist = -size, 1 do
local vi = a:index(x - 1, y + height + y_dist, z + z_dist)
for x_dist = -1, 1 do
if data[vi] == c_air then
if is_apple_tree and random(1, 8) == 1 then
data[vi] = c_apple
else
data[vi] = leaves_cid
end
end
vi = vi + 1
end
end
end
-- Randomly add leaves in 2x2x2 clusters.
for i = 1, iters do
local clust_x = x + random(-size, size - 1)
local clust_y = y + height + random(-size, 0)
local clust_z = z + random(-size, size - 1)
for xi = 0, 1 do
for yi = 0, 1 do
for zi = 0, 1 do
local vi = a:index(clust_x + xi, clust_y + yi, clust_z + zi)
if data[vi] == c_air then
if is_apple_tree and random(1, 8) == 1 then
data[vi] = c_apple
else
data[vi] = leaves_cid
end
end
end
end
end
end
end
local c_tree = minetest.get_content_id("default:tree")
local c_leaves = minetest.get_content_id("default:leaves")
local c_apple = minetest.get_content_id("default:apple")
function default.grow_tree(data, a, pos, is_apple_tree, seed)
--[[
NOTE: Tree-placing code is currently duplicated in the engine
and in games that have saplings; both are deprecated but not
replaced yet
]]--
local pr = PseudoRandom(seed)
local th = pr:next(4, 5)
local x, y, z = pos.x, pos.y, pos.z
for yy = y, y+th-1 do
local vi = a:index(x, yy, z)
if a:contains(x, yy, z) and (data[vi] == c_air or yy == y) then
data[vi] = c_tree
end
end
y = y+th-1 -- (x, y, z) is now last piece of trunk
local leaves_a = VoxelArea:new{MinEdge={x=-2, y=-1, z=-2}, MaxEdge={x=2, y=2, z=2}}
local leaves_buffer = {}
-- Force leaves near the trunk
local d = 1
for xi = -d, d do
for yi = -d, d do
for zi = -d, d do
leaves_buffer[leaves_a:index(xi, yi, zi)] = true
end
end
end
-- Add leaves randomly
for iii = 1, 8 do
local d = 1
local xx = pr:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
local yy = pr:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
local zz = pr:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)
for xi = 0, d do
for yi = 0, d do
for zi = 0, d do
leaves_buffer[leaves_a:index(xx+xi, yy+yi, zz+zi)] = true
end
end
end
end
-- Add the leaves
for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
for zi = leaves_a.MinEdge.z, leaves_a.MaxEdge.z do
if a:contains(x+xi, y+yi, z+zi) then
local vi = a:index(x+xi, y+yi, z+zi)
if data[vi] == c_air or data[vi] == c_ignore then
if leaves_buffer[leaves_a:index(xi, yi, zi)] then
if is_apple_tree and pr:next(1, 100) <= 10 then
data[vi] = c_apple
else
data[vi] = c_leaves
end
end
end
end
end
end
end
function default.grow_tree(pos, is_apple_tree, bad)
--[[
NOTE: Tree-placing code is currently duplicated in the engine
and in games that have saplings; both are deprecated but not
replaced yet
--]]
if bad then
error("Deprecated use of default.grow_tree")
end
local x, y, z = pos.x, pos.y, pos.z
local height = random(4, 5)
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map(
{x = pos.x - 2, y = pos.y, z = pos.z - 2},
{x = pos.x + 2, y = pos.y + height + 1, z = pos.z + 2}
)
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
local data = vm:get_data()
add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree)
vm:set_data(data)
vm:write_to_map()
vm:update_map()
end
local c_jungletree = minetest.get_content_id("default:jungletree")
local c_jungleleaves = minetest.get_content_id("default:jungleleaves")
function default.grow_jungletree(data, a, pos, seed)
--[[
NOTE: Tree-placing code is currently duplicated in the engine
and in games that have saplings; both are deprecated but not
replaced yet
]]--
local pr = PseudoRandom(seed)
local x, y, z = pos.x, pos.y, pos.z
for xi = -1, 1 do
for zi = -1, 1 do
if pr:next(1, 3) >= 2 then
local vi1 = a:index(x+xi, y, z+zi)
local vi2 = a:index(x+xi, y-1, z+zi)
if a:contains(x+xi, y-1, z+zi) and data[vi2] == c_air then
data[vi2] = c_jungletree
elseif a:contains(x+xi, y, z+zi) and data[vi1] == c_air then
data[vi1] = c_jungletree
end
end
end
end
local th = pr:next(8, 12)
for yy = y, y+th-1 do
local vi = a:index(x, yy, z)
if a:contains(x, yy, z) and (data[vi] == c_air or yy == y) then
data[vi] = c_jungletree
end
end
y = y+th-1 -- (x, y, z) is now last piece of trunk
local leaves_a = VoxelArea:new{MinEdge={x=-3, y=-2, z=-3}, MaxEdge={x=3, y=2, z=3}}
local leaves_buffer = {}
-- Force leaves near the trunk
local d = 1
for xi = -d, d do
for yi = -d, d do
for zi = -d, d do
leaves_buffer[leaves_a:index(xi, yi, zi)] = true
end
end
end
-- Add leaves randomly
for iii = 1, 30 do
local d = 1
local xx = pr:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
local yy = pr:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
local zz = pr:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)
for xi = 0, d do
for yi = 0, d do
for zi = 0, d do
leaves_buffer[leaves_a:index(xx+xi, yy+yi, zz+zi)] = true
end
end
end
end
-- Add the leaves
for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
for zi = leaves_a.MinEdge.z, leaves_a.MaxEdge.z do
if a:contains(x+xi, y+yi, z+zi) then
local vi = a:index(x+xi, y+yi, z+zi)
if data[vi] == c_air or data[vi] == c_ignore then
if leaves_buffer[leaves_a:index(xi, yi, zi)] then
data[vi] = c_jungleleaves
end
end
end
end
end
end
function default.grow_jungletree(pos, bad)
--[[
NOTE: Tree-placing code is currently duplicated in the engine
and in games that have saplings; both are deprecated but not
replaced yet
--]]
if bad then
error("Deprecated use of default.grow_jungletree")
end
local x, y, z = pos.x, pos.y, pos.z
local height = random(8, 12)
local vm = minetest.get_voxel_manip()
local minp, maxp = vm:read_from_map(
{x = pos.x - 3, y = pos.y - 1, z = pos.z - 3},
{x = pos.x + 3, y = pos.y + height + 1, z = pos.z + 3})
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
local data = vm:get_data()
add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves, height, 3, 30, false)
-- Roots
for z_dist = -1, 1 do
local vi_1 = a:index(x - 1, y - 1, z + z_dist)
local vi_2 = a:index(x - 1, y, z + z_dist)
for x_dist = -1, 1 do
if random(1, 3) >= 2 then
if data[vi_1] == c_air then
data[vi_1] = c_jungletree
elseif data[vi_2] == c_air then
data[vi_2] = c_jungletree
end
end
vi_1 = vi_1 + 1
vi_2 = vi_2 + 1
end
end
vm:set_data(data)
vm:write_to_map()
vm:update_map()
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment