--[[ Everness. Never ending discovery in Everness mapgen. Copyright (C) 2024 SaKeL This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to juraj.vajda@gmail.com --]] -- how often node timers for plants will tick, +/- some random value function Everness.tick_bamboo(self, pos) minetest.get_node_timer(pos):start(math.random(83, 143)) end -- how often a growth failure tick is retried (e.g. too dark) function Everness.tick_bamboo_again(self, pos) minetest.get_node_timer(pos):start(math.random(40, 80)) end --- Rotate placed bamboo based on the stem below/above function Everness.place_bamboo(self, pos, placer, itemstack, pointed_thing) local node_under = minetest.get_node(vector.new(pos.x, pos.y - 1, pos.z)) local node_above = minetest.get_node(vector.new(pos.x, pos.y + 1, pos.z)) if minetest.get_item_group(node_under.name, 'bamboo') > 0 then minetest.swap_node(pos, { name = itemstack:get_name(), param2 = node_under.param2 }) return elseif minetest.get_item_group(node_above.name, 'bamboo') > 0 then minetest.swap_node(pos, { name = itemstack:get_name(), param2 = node_above.param2 }) return end local rand_param2 = math.random(0, 3) minetest.swap_node(pos, { name = itemstack:get_name(), param2 = rand_param2 }) end --- Dig bamboo all the way up and simulate digging particles function Everness.dig_up_bamboo(self, pos, oldnode, oldmetadata, digger) if digger == nil then return end local pos_above = { x = pos.x, y = pos.y + 1, z = pos.z } local pos_below = { x = pos.x, y = pos.y - 1, z = pos.z } local node_above = minetest.get_node(pos_above) local node_below = minetest.get_node(pos_below) if minetest.get_item_group(node_below.name, 'bamboo') > 0 then self:tick_bamboo(pos_below) end if minetest.get_item_group(node_above.name, 'bamboo') > 0 then minetest.node_dig(pos_above, node_above, digger) minetest.add_particlespawner({ amount = 10, time = 0.5, minpos = { x = pos_above.x - 0.7, y = pos_above.y, z = pos_above.z - 0.7 }, maxpos = { x = pos_above.x + 0.7, y = pos_above.y + 0.75, z = pos_above.z + 0.7 }, minvel = { x = -0.5, y = -4, z = -0.5 }, maxvel = { x = 0.5, y = -2, z = 0.5 }, minacc = { x = -0.5, y = -4, z = -0.5 }, maxacc = { x = 0.5, y = -2, z = 0.5 }, minexptime = 0.5, maxexptime = 1, minsize = 0.5, maxsize = 1, collisiondetection = true, node = { name = node_above.name } }) end end function Everness.grow_bamboo(self, pos, elapsed) local _pos = vector.new(pos) _pos.y = _pos.y - 1 -- local name = minetest.get_node(_pos).name local node_below = minetest.get_node(_pos) local _node = minetest.get_node(pos) if minetest.get_item_group(node_below.name, 'soil') == 0 and minetest.get_item_group(node_below.name, 'sand') == 0 and minetest.get_item_group(node_below.name, 'everness_sand') == 0 then if minetest.get_item_group(node_below.name, 'bamboo') > 0 then self:grow_bamboo(_pos, elapsed) return end self:tick_bamboo_again(pos) return end _pos.y = _pos.y + 1 local height = 0 while minetest.get_item_group(_node.name, 'bamboo') > 0 and height < 16 do height = height + 1 _pos.y = _pos.y + 1 _node = minetest.get_node(_pos) end -- stop growing - random height between 12 - 16 nodes if height > 11 and height < 16 then if math.random(1, 3) == 2 then return end end if height >= 16 then return end if _node.name ~= 'air' then self:tick_bamboo_again(_pos) return end if minetest.get_node_light(_pos) < 9 then self:tick_bamboo_again(pos) return end local height_offset = height -- variant appearance for this growth stages local rand_param2 = math.random(0, 3) if height < 5 then local next_plant_schem = self.bamboo.growth_stages[height] for i, v in ipairs(next_plant_schem) do local pos_to_swap = vector.new(_pos.x, _pos.y - height_offset, _pos.z) local node_to_swap = minetest.get_node(pos_to_swap) height_offset = height_offset - 1 if i == 1 then if minetest.get_item_group(node_to_swap.name, 'seed') == 0 and node_to_swap.name ~= 'air' then rand_param2 = node_to_swap.param2 end end minetest.set_node(pos_to_swap, { name = v.name, param2 = rand_param2 }) if i == #next_plant_schem then self:tick_bamboo(_pos) return end end end -- grow verically while keeping the top 3 nodes with leaves local start_pos = vector.new(_pos.x, _pos.y - 3, _pos.z) local prev_node = minetest.get_node(vector.new(start_pos.x, start_pos.y - 1, start_pos.z)) minetest.set_node(start_pos, { name = 'everness:bamboo_3', param2 = prev_node.param2 }) for k, v in ipairs(self.bamboo.top_leaves_schem) do minetest.set_node( vector.new(start_pos.x, start_pos.y + k, start_pos.z), { name = v.name, param2 = prev_node.param2 } ) end self:tick_bamboo(_pos) return false end