MistUnky f85010c2bc bla
2022-06-02 13:41:21 -04:00

264 lines
6.9 KiB
Lua

sumpf = rawget(_G, "sumpf") or {}
local jungletree_seed = 112
local function jungletree_get_random(pos)
return PseudoRandom(math.abs(pos.x+pos.y*3+pos.z*5)+jungletree_seed)
end
-- Nodes
local leaves = {"green","yellow","red"}
local spawn_jungletree
minetest.register_node("jungletree:sapling", {
description = "jungle tree sapling",
drawtype = "plantlike",
tiles = {"jungletree_sapling.png"},
inventory_image = "jungletree_sapling.png",
wield_image = "jungletree_sapling.png",
paramtype = "light",
walkable = false,
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1},
on_construct = function(pos)
if minetest.settings:get_bool"creative_mode" then
spawn_jungletree(pos)
end
end
})
local tab = {
description = "jungle tree leaves",
is_ground_content = false, -- because default:jungletree's is_ground_content
waving = 1, --warum 1?
paramtype = "light",
groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
drop = {
max_items = 1,
items = {
{
items = {'jungletree:sapling'},
rarity = 20,
},
{
items = {},
}
}
},
sounds = default.node_sound_leaves_defaults(),
}
-- Remove a bit from the bottom of the plantlike leaves node to reduce
-- Z-fighting when waving leaves are disabled.
-- There is still a bit of overlap for some reason
local tex_sc = (1.0 - (1.0 / math.sqrt(2.0))) * 100.0 - 4.0
for color = 1, 3 do
local leaf_name = "jungletree:leaves_"..leaves[color]
tab.visual_scale = math.sqrt(2)
tab.drawtype = "plantlike"
tab.tiles = {"jungletree_leaves_" .. leaves[color] ..
".png^[lowpart:" .. tex_sc ..
":jungletree_invmat.png^[makealpha:255,126,126"}
tab.inventory_image = minetest.inventorycube("jungletree_leaves_" ..
leaves[color] .. ".png")
tab.drop.items[2].items[1] = leaf_name
minetest.register_node(leaf_name, table.copy(tab))
end
-- tree functions and abm
local c_leaves_green = minetest.get_content_id("jungletree:leaves_green")
local c_leaves_red = minetest.get_content_id("jungletree:leaves_red")
local c_leaves_yellow = minetest.get_content_id("jungletree:leaves_yellow")
local c_jungletree = minetest.get_content_id("default:jungletree")
local ndtable = {c_leaves_green, c_leaves_red, c_leaves_yellow}
local airlike_cs = {minetest.get_content_id("air"),
minetest.get_content_id("ignore")}
local function soft_node(id)
for i = 1,#airlike_cs do
if airlike_cs[i] == id then
return true
end
end
return false
end
local function tree_branch(pos, area, nodes, pr)
--choose random leaves
--green leaves are more common
local leaf = 1
if pr:next(1,5) < 2 then
leaf = pr:next(1,3)
end
nodes[area:indexp(pos)] = c_jungletree
for i = pr:next(1,2), -pr:next(1,2), -1 do
for k = pr:next(1,2), -pr:next(1,2), -1 do
local vi = area:index(pos.x+i, pos.y, pos.z+k)
if soft_node(nodes[vi]) then
nodes[vi] = ndtable[leaf]
end
if math.abs(i+k) < 1 then
vi = vi + area.ystride
if soft_node(nodes[vi]) then
nodes[vi] = ndtable[leaf]
end
end
end
end
end
local function small_jungletree(pos, height, area, nodes, pr)
for _,p in ipairs({
{x=pos.x, y=pos.y+height+pr:next(0,1), z=pos.z},
{x=pos.x, y=pos.y+height+pr:next(0,1), z=pos.z},
{x=pos.x+1, y=pos.y+height-pr:next(1,2), z=pos.z},
{x=pos.x-1, y=pos.y+height-pr:next(1,2), z=pos.z},
{x=pos.x, y=pos.y+height-pr:next(1,2), z=pos.z+1},
{x=pos.x, y=pos.y+height-pr:next(1,2), z=pos.z-1},
}) do
tree_branch(p, area, nodes, pr)
end
local vi = area:index(pos.x, pos.y-1, pos.z)
for _ = -1, height do
nodes[vi] = c_jungletree
vi = vi + area.ystride
end
for i = height, 4, -1 do
if math.sin(i*i/height) < 0.2
and pr:next(0,2) ~= 2 then -- < 1.5
tree_branch({x=pos.x+pr:next(0,1), y=pos.y+i, z=pos.z-pr:next(0,1)},
area, nodes, pr)
end
end
end
local function big_jungletree(pos, height, area, nodes, pr)
local h_root = pr:next(0,1)-1
local vi = area:index(pos.x, pos.y-2, pos.z)
for _ = -2, h_root do
nodes[vi + area.zstride + 1] = c_jungletree
nodes[vi - area.zstride + 2] = c_jungletree
nodes[vi - 2 * area.zstride] = c_jungletree
nodes[vi - 1] = c_jungletree
vi = vi + area.ystride
end
for i = height, -2, -1 do
if i > 3
and math.sin(i*i/height) < 0.2
and pr:next(0,2) < 1.5 then
tree_branch({x=pos.x+pr:next(0,1), y=pos.y+i, z=pos.z-pr:next(0,1)},
area, nodes, pr)
end
if i == height then
for _,p in ipairs({
{x=pos.x+1, y=pos.y+i, z=pos.z+1},
{x=pos.x+2, y=pos.y+i, z=pos.z-1},
{x=pos.x, y=pos.y+i, z=pos.z-2},
{x=pos.x-1, y=pos.y+i, z=pos.z},
{x=pos.x+1, y=pos.y+i, z=pos.z+2},
{x=pos.x+3, y=pos.y+i, z=pos.z-1},
{x=pos.x, y=pos.y+i, z=pos.z-3},
{x=pos.x-2, y=pos.y+i, z=pos.z},
{x=pos.x+1, y=pos.y+i, z=pos.z},
{x=pos.x+1, y=pos.y+i, z=pos.z-1},
{x=pos.x, y=pos.y+i, z=pos.z-1},
{x=pos.x, y=pos.y+i, z=pos.z},
}) do
tree_branch(p, area, nodes, pr)
end
else
for _,p in pairs({
{pos.x+1, pos.y+i, pos.z},
{pos.x+1, pos.y+i, pos.z-1},
{pos.x, pos.y+i, pos.z-1},
{pos.x, pos.y+i, pos.z},
}) do
nodes[area:index(p[1], p[2], p[3])] = c_jungletree
end
end
end
end
function sumpf.generate_jungletree(pos, area, nodes, pr, ymax)
local h_max = 15
-- should fix trees on upper chunk corners
local max_heigth = ymax+16-pos.y
if max_heigth < 21 then
h_max = max_heigth-5-1
end
local height = 5 + pr:next(1,h_max)
if height < 10 then
small_jungletree(pos, height, area, nodes, pr)
else
big_jungletree(pos, height, area, nodes, pr)
end
end
function spawn_jungletree(pos)
local t1 = minetest.get_us_time()
local pr = jungletree_get_random(pos)
local height = 5 + pr:next(1,15)
local small = height < 10
local vwidth, vheight, vdepth
if small then
vheight = 2
vdepth = -1
vwidth = 3
else
vheight = 1
vdepth = -2
vwidth = 5
end
vheight = height+vheight
local manip = minetest.get_voxel_manip()
local emerged_pos1, emerged_pos2 = manip:read_from_map(
{x = pos.x - vwidth, y = pos.y + vdepth, z = pos.z - vwidth},
{x = pos.x + vwidth, y = pos.y + vheight, z = pos.z + vwidth})
local area = VoxelArea:new{MinEdge=emerged_pos1, MaxEdge=emerged_pos2}
local nodes = manip:get_data()
if small then
small_jungletree(pos, height, area, nodes, pr)
else
big_jungletree(pos, height, area, nodes, pr)
end
manip:set_data(nodes)
manip:write_to_map()
sumpf.inform("a jungletree grew at " .. minetest.pos_to_string(pos), 2, t1)
end
minetest.register_abm({
nodenames = {"jungletree:sapling"},
neighbors = {"group:soil"},
interval = 40,
chance = 5,
action = function(pos)
if sumpf.tree_allowed(pos, 7) then
spawn_jungletree(pos)
end
end
})
--very old mod compatible
--minetest.register_alias("jungletree:leaves", "jungletree:leaves_green")
minetest.log("info", "[jungletree] loaded!")