264 lines
6.3 KiB
Lua
264 lines
6.3 KiB
Lua
local load_time_start = os.clock()
|
|
|
|
local ast_hdif_max = 3
|
|
|
|
local function log(msg)
|
|
print("[sun_flowers] " .. msg)
|
|
end
|
|
|
|
local function stem(h, pr)
|
|
local tab,n = {{0,h-1,0}},2
|
|
local ast = 1
|
|
for y = 0,h-2 do
|
|
tab[n] = {0,y,0}
|
|
n = n+1
|
|
if ast ~= ast_hdif_max
|
|
and pr:next(1,ast) == 1 then
|
|
for i = -1,1,2 do
|
|
for _,crd in pairs({
|
|
{i,0},
|
|
{0,i},
|
|
}) do
|
|
if pr:next(1,3) == 1 then
|
|
tab[n] = {crd[1],y,crd[2]}
|
|
n = n+1
|
|
end
|
|
end
|
|
ast = ast_hdif_max
|
|
end
|
|
else
|
|
ast = ast-1
|
|
end
|
|
end
|
|
return tab--,n
|
|
end
|
|
|
|
--[[ used before doors update
|
|
local to_meta,num = {},1
|
|
local function do_metas(tag)
|
|
local state = tag and 0 or 1
|
|
for _,pos in pairs(to_meta) do
|
|
minetest.get_meta(pos):set_int("state", state)
|
|
end
|
|
to_meta,num = {},1
|
|
end
|
|
|
|
local function panel_meta(pos)
|
|
to_meta[num] = pos
|
|
num = num+1
|
|
end--]]
|
|
|
|
local c_air = minetest.get_content_id("air")
|
|
local c_ignore = minetest.get_content_id("ignore")
|
|
local c_stengl = minetest.get_content_id("default:fence_wood")
|
|
local c_stempel_tag = minetest.get_content_id("mesecons_solarpanel:solar_panel_on")
|
|
local c_stempel_nacht = minetest.get_content_id("mesecons_solarpanel:solar_panel_off")
|
|
local c_blutenblatt = minetest.get_content_id("doors:trapdoor_open")
|
|
local c_blutenblatt_geschlossen = minetest.get_content_id("doors:trapdoor")
|
|
|
|
--local param2ps_list = {[0]={-1,0}, {0,-1}, {1,0}, {0,1}}
|
|
local param2ps_list = {[10]={-1,0}, [19]={0,-1}, [4]={1,0}, [13]={0,1}}
|
|
local function make_flower(h, pr, area, data, param2s, shine, pz,py,px)
|
|
for _,crd in pairs(stem(h, pr)) do
|
|
local z,y,x = unpack(crd)
|
|
local vi = area:index(px+x, py+y, pz+z)
|
|
if data[vi] == c_air
|
|
or data[vi] == c_ignore then
|
|
data[vi] = c_stengl
|
|
end
|
|
end
|
|
local blutenblatt, stempel
|
|
if shine then
|
|
blutenblatt = c_blutenblatt
|
|
stempel = c_stempel_tag
|
|
else
|
|
blutenblatt = c_blutenblatt_geschlossen
|
|
stempel = c_stempel_nacht
|
|
end
|
|
local y = py+h
|
|
for par,crd in pairs(param2ps_list) do
|
|
local z = pz+crd[1]
|
|
local x = px+crd[2]
|
|
local vi = area:index(x, y, z)
|
|
if data[vi] == c_air
|
|
or data[vi] == c_ignore then
|
|
data[vi] = blutenblatt
|
|
param2s[vi] = par
|
|
--panel_meta({x=x,y=y,z=z})
|
|
end
|
|
end
|
|
local vi = area:index(px, y, pz)
|
|
if data[vi] == c_air
|
|
or data[vi] == c_ignore then
|
|
data[vi] = stempel
|
|
param2s[vi] = 1
|
|
end
|
|
end
|
|
|
|
-- nicht zum generieren verwenden
|
|
local function spawn_flower(pos)
|
|
local t1 = os.clock()
|
|
|
|
local pr = PseudoRandom(pos.x+pos.y*3+pos.z*5+463)
|
|
local h = pr:next(3,7)
|
|
--local tag = minetest.get_node_light(pos) >= 12
|
|
local tag = math.abs(minetest.get_timeofday()-0.5) < 0.25
|
|
|
|
local manip = minetest.get_voxel_manip()
|
|
local emerged_pos1, emerged_pos2 = manip:read_from_map({x=pos.x-1, y=pos.y, z=pos.z-1},
|
|
{x=pos.x+1, y=pos.y+h, z=pos.z+1})
|
|
local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
|
|
local nodes = manip:get_data()
|
|
local param2s = manip:get_param2_data()
|
|
|
|
make_flower(h, pr, area, nodes, param2s, tag, pos.z,pos.y,pos.x)
|
|
|
|
manip:set_data(nodes)
|
|
manip:set_param2_data(param2s)
|
|
manip:write_to_map()
|
|
log("flower grew", 2, t1)
|
|
--[[
|
|
t1 = os.clock()
|
|
do_metas(tag)
|
|
log("metas set", 2, t1)--]]
|
|
t1 = os.clock()
|
|
manip:update_map()
|
|
log("map updated", 2, t1)
|
|
end
|
|
|
|
minetest.register_node("sun_flowers:spawner", {
|
|
node_placement_prediction = "",
|
|
tiles = {"default_furnace_fire_fg.png"},
|
|
inventory_image = "default_sapling.png^default_furnace_fire_fg.png",
|
|
stack_max = 1024,
|
|
groups = {snappy=2,dig_immediate=3},
|
|
sounds = default.node_sound_leaves_defaults(),
|
|
on_construct = function(pos)
|
|
spawn_flower(pos)
|
|
end,
|
|
})
|
|
|
|
|
|
--mapgen
|
|
local function soil_node(id)
|
|
local name = minetest.get_name_from_content_id(id)
|
|
local def = minetest.registered_nodes[name]
|
|
if not def
|
|
or not def.groups
|
|
or def.groups.soil ~= 1
|
|
or not string.find(name, "grass") then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local soils = {}
|
|
local function is_soil(id)
|
|
local soil = soils[id]
|
|
if soil ~= nil then
|
|
return soil
|
|
end
|
|
soil = soil_node(id)
|
|
soils[id] = soil
|
|
return soil
|
|
end
|
|
|
|
local perlinmap
|
|
minetest.register_on_generated(function(minp, maxp, seed)
|
|
--avoid calculating perlin noises for unneeded places
|
|
if maxp.y <= -6
|
|
or minp.y >= 150 then
|
|
return
|
|
end
|
|
|
|
local t1 = os.clock()
|
|
|
|
local x0,z0,x1 = minp.x,minp.z,maxp.x
|
|
-- Assume X and Z lengths are equal
|
|
local divs = (x1-x0)
|
|
|
|
if not perlinmap then
|
|
perlinmap = minetest.get_perlin_map({
|
|
offset = 0,
|
|
scale = 1,
|
|
seed = 4213,
|
|
octaves = 3,
|
|
persist = 0.6,
|
|
spread = {x=100, y=100, z=100},
|
|
}, {x=divs+1, y=divs+1, z=1})
|
|
end
|
|
|
|
local tag = math.abs(minetest.get_timeofday()-0.5) < 0.25
|
|
local pr = PseudoRandom(seed+42)
|
|
|
|
local vm, area, data, param2s, pmap
|
|
|
|
local heightmap = minetest.get_mapgen_object("heightmap")
|
|
if not heightmap then
|
|
return
|
|
end
|
|
local hmi = 1
|
|
|
|
local flower_placed = false
|
|
for j=0,divs do
|
|
for i=0,divs do
|
|
local x,z = x0+i,z0+j
|
|
if (x+z)%2 == 0 -- chess pattern to not make them connect so much
|
|
and pr:next(1,8) == 1 then
|
|
local y = heightmap[hmi] -- ground y
|
|
if y > 4
|
|
and y >= minp.y
|
|
and y <= maxp.y then
|
|
if not pmap then
|
|
pmap = perlinmap:get2dMap_flat({x=x0, y=z0})
|
|
end
|
|
local noise = pmap[hmi]
|
|
if noise > 0.9
|
|
and (noise-0.9)*10 > pr:next(0,1000)/1000 then
|
|
if not vm then
|
|
local emin, emax
|
|
vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
|
data = vm:get_data()
|
|
param2s = vm:get_param2_data()
|
|
end
|
|
if is_soil(data[area:index(x,y,z)]) then
|
|
flower_placed = true
|
|
make_flower(pr:next(3,7), pr, area, data, param2s, tag, z,y+1,x)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
hmi = hmi+1
|
|
end
|
|
end
|
|
|
|
if not flower_placed then
|
|
return
|
|
end
|
|
|
|
local t2 = os.clock()
|
|
vm:set_data(data)
|
|
vm:set_param2_data(param2s)
|
|
vm:set_lighting({day=0, night=0})
|
|
vm:calc_lighting()
|
|
vm:write_to_map()
|
|
log("data set", 2, t2)
|
|
|
|
--[[
|
|
t2 = os.clock()
|
|
do_metas(tag)
|
|
log("metas set", 2, t2)--]]
|
|
|
|
log("done", 1, t1)
|
|
end)
|
|
|
|
|
|
local time = math.floor(tonumber(os.clock()-load_time_start)*100+0.5)/100
|
|
local msg = "[sun_flowers] loaded after ca. "..time
|
|
if time > 0.05 then
|
|
print(msg)
|
|
else
|
|
minetest.log("info", msg)
|
|
end
|