1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
vzxv.mundane_block("vzxv_trees:seed","Dirt","moistdirt")
vzxv.mundane_block("vzxv_trees:root","Tree root",{"vzxvmoistdirt.png^vzxvroot.png"})
vzxv.mundane_block("vzxv_trees:core","Tree root",{"vzxvmoistdirt.png^vzxvroot.png"})
vzxv.mundane_block("vzxv_trees:trunk","Tree trunk", {
"vzxvlog.png","vzxvlog.png","vzxvbark.png"
})
local function traverse(pos, callback)
local traversed = {}
local depth = 0
local function t(pos)
depth = depth + 1
if depth > 500 then return end
local strpos = ('%s,%s,%s'):format(pos.x,pos.y,pos.z)
if traversed[strpos] then
return
else
traversed[strpos] = true
end
local node = minetest.get_node(pos)
if callback(pos, node) then
t{pos.x + 1, pos.y , pos.z }
t{pos.x - 1, pos.y , pos.z }
t{pos.x , pos.y + 1, pos.z }
t{pos.x , pos.y - 1, pos.z }
t{pos.x , pos.y , pos.z + 1}
t{pos.x , pos.y , pos.z - 1}
end
end
return t(pos)
end
local function update_tree(core_pos)
local core_meta = minetest.get_meta(core_pos)
local core = core_meta:to_table()
if not core or not core.live then
print "warning: attempt to update nonexistent tree"
return
end
local height = 0
while 1 do
local pos = {core_pos.x,core_pos.y+height+1,core_pos.z}
local node = minetest.get_node(pos)
if node.name == "vzxv_trees:trunk"
and minetest.get_meta(pos):contains "live" then
height = height + 1
else break end
end
if height == 0 then
-- die
minetest.set_node(core_pos,{name="vzxv_tree:root"})
return
end
local root_budget = 0
if core.prev_mass then
if math.log(core.prev_mass * 10) < (core.prev_mass / 5) + height * 2 then
root_budget = 5
elseif math.random(50) then
end
end
local root_mass = 0
traverse(pos, function(pos, node)
if node.name == "vzxv:root"
and minetest.get_meta(pos):contains "live" then
root_mass = root_mass + 1
return true
end
end)
core.prev = root_mass
local energy_generated = math.log(root_mass * 10)
local energy_cost = (root_mass / 5) + height * 2
core.energy = core.energy + energy_generated - energy_cost
core_meta:from_table(core)
end
function vzxv.generate_tree(pos)
local core_pos = {x=pos.x,y=pos.y-1,z=pos.z}
minetest.set_node(core_pos,{name="vzxv_trees:core"})
local core = minetest.get_meta(core_pos)
local height = math.random(8,20)
for i=0, height do
local p = {x=pos.x,y=pos.y+i,z=pos.z}
local node = minetest.get_node(p)
if node.name ~= "air" and node.name ~= "ignore" then return end
minetest.set_node({x=pos.x,y=pos.y+i,z=pos.z},{name="vzxv_trees:trunk"})
minetest.get_meta(p):set_int("live", 1)
end
core:from_table {energy=height*10,live=1}
end
|