forest_new/init.lua

476 lines
12 KiB
Lua

-- 3D noises
local np_cave1 = {
offset = 0,
scale = 1,
spread = {x=30, y=30, z=30},
seed = 5203,
octaves = 3,
persist = 0.6
}
local np_cave2 = {
offset = 0,
scale = 1,
spread = {x=30, y=30, z=30},
seed = 7660,
octaves = 3,
persist = 0.6
}
local np_cave3 = {
offset = 0,
scale = 1,
spread = {x=30, y=30, z=30},
seed = 3289,
octaves = 3,
persist = 0.6
}
local np_cave4 = {
offset = 0,
scale = 1,
spread = {x=150, y=150, z=150},
seed = 5435,
octaves = 3,
persist = 0.6
}
-- 2D noises
--[[local np_n5 = {
offset = 0,
scale = 1,
spread = {x=80, y=80, z=80},
seed = 9849,
octaves = 3,
persist = 0.6
}
local np_n6 = {
offset = 0,
scale = 1,
spread = {x=200, y=200, z=200},
seed = 7237,
octaves = 3,
persist = 0.6
}
local np_n7 = {
offset = 0,
scale = 1,
spread = {x=600, y=600, z=600},
seed = 5096,
octaves = 3,
persist = 0.6
}
local np_n8 = {
offset = 0,
scale = 1,
spread = {x=20, y=20, z=20},
seed = 7230,
octaves = 3,
persist = 0.6
}
local np_n9 = {
offset = 0,
scale = 1,
spread = {x=20, y=20, z=20},
seed = 9933,
octaves = 3,
persist = 0.6
}]]
-- elevation noises
local np_valleys_1a = {
offset = 0,
scale = 1,
spread = {x=50, y=50, z=50},
seed = 6831,
octaves = 3,
persist = 0.2
}
local np_valleys_1b = {
offset = 0,
scale = 1,
spread = {x=50, y=50, z=50},
seed = 1590,
octaves = 3,
persist = 0.2
}
local np_valleys_2a = {
offset = 0,
scale = 1,
spread = {x=25, y=25, z=25},
seed = 4385,
octaves = 3,
persist = 0.2
}
local np_valleys_2b = {
offset = 0,
scale = 1,
spread = {x=25, y=25, z=25},
seed = 9726,
octaves = 3,
persist = 0.2
}
local np_valleys_3a = {
offset = 0,
scale = 1,
spread = {x=10, y=10, z=10},
seed = 1792,
octaves = 3,
persist = 0.2
}
local np_valleys_3b = {
offset = 0,
scale = 1,
spread = {x=10, y=10, z=10},
seed = 1016,
octaves = 3,
persist = 0.2
}
local np_valleys_depth = {
offset = 0,
scale = 1,
spread = {x=300, y=300, z=300},
seed = 8110,
octaves = 3,
persist = 0.2
}
local np_terrain_height = {
offset = 0,
scale = 1,
spread = {x=400, y=400, z=400},
seed = 2698,
octaves = 3,
persist = 0.2
}
local data = {}
local first_mapgen = true
local nobj_cave1, nobj_cave2, nobj_cave3, nobj_cave4
local nobj_valleys_1a, nobj_valleys_1b
local nobj_valleys_2a, nobj_valleys_2b
local nobj_valleys_3a, nobj_valleys_3b
local nobj_valleys_depth
local nobj_terrain_height
local function initialize(chulens)
first_mapgen = false
nobj_cave1 = minetest.get_perlin_map(np_cave1, chulens)
nobj_cave2 = minetest.get_perlin_map(np_cave2, chulens)
nobj_cave3 = minetest.get_perlin_map(np_cave3, chulens)
nobj_cave4 = minetest.get_perlin_map(np_cave4, chulens)
nobj_valleys_1a = minetest.get_perlin_map(np_valleys_1a, chulens)
nobj_valleys_1b = minetest.get_perlin_map(np_valleys_1b, chulens)
nobj_valleys_2a = minetest.get_perlin_map(np_valleys_2a, chulens)
nobj_valleys_2b = minetest.get_perlin_map(np_valleys_2b, chulens)
nobj_valleys_3a = minetest.get_perlin_map(np_valleys_3a, chulens)
nobj_valleys_3b = minetest.get_perlin_map(np_valleys_3b, chulens)
nobj_valleys_depth = minetest.get_perlin_map(np_valleys_depth, chulens)
nobj_terrain_height = minetest.get_perlin_map(np_terrain_height, chulens)
end
local nvals_cave1 = {}
local nvals_cave2 = {}
local nvals_cave3 = {}
local nvals_cave4 = {}
local nvals_valleys_1a = {}
local nvals_valleys_1b = {}
local nvals_valleys_2a = {}
local nvals_valleys_2b = {}
local nvals_valleys_3a = {}
local nvals_valleys_3b = {}
local nvals_valleys_depth = {}
local nvals_terrain_height = {}
minetest.register_on_generated(function(minp, maxp)
local t0 = os.clock()
local x1 = maxp.x
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x
local y0 = minp.y
local z0 = minp.z
-- perlinmap stuff
local sidelen = x1 - x0 + 1
local chulens = {x=sidelen, y=sidelen, z=sidelen}
local minp2d = {x=x0, y=z0}
if first_mapgen then
initialize(chulens)
end
print ("[forest] Generating map from "..minetest.pos_to_string(minp).." to "..minetest.pos_to_string(maxp))
--local c_dstone = minetest.get_content_id("default:desert_stone")
--local c_dsand = minetest.get_content_id("default:desert_sand")
local c_water = minetest.get_content_id("default:water_source")
local c_stone = minetest.get_content_id("default:stone")
--local c_sand = minetest.get_content_id("default:sand")
local c_grass = minetest.get_content_id("default:dirt_with_grass")
--local c_snow = minetest.get_content_id("default:dirt_with_snow")
local c_dirt = minetest.get_content_id("default:dirt")
--local c_gravel = minetest.get_content_id("default:gravel")
--[[local c_grasses = {
minetest.get_content_id("default:grass_1"),
minetest.get_content_id("default:grass_2"),
minetest.get_content_id("default:grass_3"),
minetest.get_content_id("default:grass_4"),
minetest.get_content_id("default:grass_5")
}]]
--local c_jungle = minetest.get_content_id("default:junglegrass")
--local c_flowers = {minetest.get_content_id("flowers:dandelion_yellow"), minetest.get_content_id("flowers:dandelion_yellow"), minetest.get_content_id("flowers:dandelion_yellow"), minetest.get_content_id("flowers:geranium"), minetest.get_content_id("flowers:tulip"), minetest.get_content_id("flowers:rose")}
--local c_papyrus = minetest.get_content_id("default:papyrus")
--local c_shrub = minetest.get_content_id("default:dry_shrub")
--local c_lava = minetest.get_content_id("default:lava_source")
--local c_cactus = minetest.get_content_id("default:cactus")
--local c_air = minetest.get_content_id("air")
-- LVM stuff
local manip, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
manip:get_data(data)
-- 3D noises
nobj_cave1:get3dMap_flat(minp, nvals_cave1)
nobj_cave2:get3dMap_flat(minp, nvals_cave2)
nobj_cave3:get3dMap_flat(minp, nvals_cave3)
nobj_cave4:get3dMap_flat(minp, nvals_cave4)
-- 2D noises
--local nvals_n5 = minetest.get_perlin_map(np_n5, chulens):get2dMap_flat(minp2d)
--local nvals_n6 = minetest.get_perlin_map(np_n6, chulens):get2dMap_flat(minp2d)
--local nvals_n7 = minetest.get_perlin_map(np_n7, chulens):get2dMap_flat(minp2d)
--local nvals_n8 = minetest.get_perlin_map(np_n8, chulens):get2dMap_flat(minp2d)
--local nvals_n9 = minetest.get_perlin_map(np_n9, chulens):get2dMap_flat(minp2d)
-- elevation 2D noises
nobj_valleys_1a:get2dMap_flat(minp2d, nvals_valleys_1a)
nobj_valleys_1b:get2dMap_flat(minp2d, nvals_valleys_1b)
nobj_valleys_2a:get2dMap_flat(minp2d, nvals_valleys_2a)
nobj_valleys_2b:get2dMap_flat(minp2d, nvals_valleys_2b)
nobj_valleys_3a:get2dMap_flat(minp2d, nvals_valleys_3a)
nobj_valleys_3b:get2dMap_flat(minp2d, nvals_valleys_3b)
nobj_valleys_depth:get2dMap_flat(minp2d, nvals_valleys_depth)
nobj_terrain_height:get2dMap_flat(minp2d, nvals_terrain_height)
local nixz = 1 -- 2D noise index
for z = minp.z, maxp.z do
for x = minp.x, maxp.x do
local valleys1a = nvals_valleys_1a[nixz]
local valleys1b = nvals_valleys_1b[nixz]
local valleys2a = nvals_valleys_2a[nixz]
local valleys2b = nvals_valleys_2b[nixz]
local valleys3a = nvals_valleys_3a[nixz]
local valleys3b = nvals_valleys_3b[nixz]
local valleys_depth = math.abs(nvals_valleys_depth[nixz])
local terrain_height = nvals_terrain_height[nixz]
local valleys1 = math.abs(valleys1a - valleys1b) * valleys_depth
local valleys2 = math.sqrt(valleys1 * math.abs(valleys2a - valleys2b)) * valleys_depth
local valleys3 = math.sqrt(valleys2 * math.abs(valleys3a - valleys3b)) * valleys_depth
local c = terrain_height + 1
local elevation = (valleys1*20 + valleys2*15 + valleys3*10) * c + terrain_height * 50
if elevation < 0 then
elevation = -2 * math.sqrt(-elevation)
end
elevation = math.floor(elevation + 0.5)
local top = c_grass
local fill = c_dirt
local stone = c_stone
--[[if math.max(elevation, 1) >= minp.y then
n5v = nvals_n5[nixz]
n6v = nvals_n6[nixz]
n7v = nvals_n7[nixz]
n8v = nvals_n8[nixz]
n9v = nvals_n9[nixz]
if elevation < n8v * 5 then
if n7v < 0.88 then
if n5v - n6v > 0.8 then
ground1 = c_gravel
ground2 = c_gravel
ground3 = c_stone
ground4 = c_stone
plant = nil
elseif n6v < 0 then
if n5v < -0.4 then
ground1 = c_dsand
ground2 = c_dsand
ground3 = c_dstone
ground4 = c_stone
plant = nil
else
ground1 = c_sand
ground2 = c_sand
ground3 = c_stone
ground4 = c_stone
plant = nil
end
elseif n5v + n6v * 5 > 2 then
if n6v > 0.8 then
ground1 = c_gravel
ground2 = c_gravel
ground3 = c_stone
ground4 = c_stone
plant = nil
else
ground1 = c_grass
ground2 = c_dirt
ground3 = c_stone
ground4 = c_stone
plant = {def = c_papyrus, percent = 4, height = math.random(2, 5)}
end
else
ground1 = c_sand
ground2 = c_sand
ground3 = c_stone
ground4 = c_stone
plant = {def = c_grasses[math.random(5)], percent = 15}
end
elseif n5v * 2 - n6v < 0 then
ground1 = c_gravel
ground2 = c_gravel
ground3 = c_stone
ground4 = c_stone
plant = nil
else
ground1 = c_stone
ground2 = c_stone
ground3 = c_stone
ground4 = c_stone
plant = nil
end
elseif n7v < 0.88 then
if n5v + 2 * n6v > -0.4 then
if n5v > 0 then
ground1 = c_grass
ground2 = c_dirt
ground3 = c_stone
ground4 = c_stone
plant = nil
else
ground1 = c_grass
ground2 = c_dirt
ground3 = c_stone
ground4 = c_stone
if math.random(2) == 2 then
plant = {def = c_grasses[math.random(5)], percent = 20}
else
plant = {def = c_flowers[math.random(6)], percent = -n5v}
end
end
elseif n6v < -0.4 then
ground1 = c_dsand
ground2 = c_dsand
ground3 = c_dstone
ground4 = c_stone
if math.random(2) == 2 then
plant = {def = c_cactus, percent = 2, height = math.random(2, 6)}
else
plant = {def = c_shrub, percent = 5}
end
else
ground1 = c_sand
ground2 = c_sand
ground3 = c_dstone
ground4 = c_stone
if math.random(2) == 2 then
plant = {def = c_cactus, percent = 0.25, height = math.random(2, 4)}
else
plant = {def = c_jungle, percent = 25}
end
end
elseif n5v ^ 2 + n6v ^ 2 < 0.16 and n7v > 0.9 then
ground1 = c_air
ground2 = c_lava
ground3 = c_stone
ground4 = c_stone
plant = nil
elevation = math.min(
elevation, get_elevation({x = x, z = z + 1}),
get_elevation({x = x, z = z - 1}),
get_elevation({x = x + 1, z = z}),
get_elevation({x = x - 1, z = z})
)
elseif n5v > -0.6 then
ground1 = c_stone
ground2 = c_stone
ground3 = c_stone
ground4 = c_stone
plant = nil
else
ground1 = c_gravel
ground2 = c_gravel
ground3 = c_stone
ground4 = c_stone
plant = nil
end]]
for y = minp.y, math.min(math.max(elevation, 1), maxp.y) do
local pos = area:index(x, y, z) -- LVM index for node
local nixyz = (z - z0) * 6400 + (y - y0) * 80 + (x - x0) + 1 -- noise index for node
local cave1 = nvals_cave1[nixyz]
local cave2 = nvals_cave2[nixyz]
local cave3 = nvals_cave3[nixyz]
local cave4 = nvals_cave4[nixyz]
local node
if y == elevation then
node = elevation >= 1 and top or fill
elseif y > elevation then
node = c_water
elseif y + math.random(2, 6) >= elevation then
node = fill
else
node = stone
end
if math.max(cave1, cave2, cave3) - math.min(cave1, cave2, cave3) > cave4 / 5 or node == c_water then
data[pos] = node
end
end
--[[if elevation > 0 and plant then
if math.random() * 100 < plant.percent then
if plant.height then
for i = 1, plant.height do
if area:contains(x, elevation + i, z) then
data[area:index(x, elevation + i, z)] = plant.def
end
end
elseif area:contains(x, elevation + 1, z) then
data[area:index(x, elevation + 1, z)] = plant.def
end
end
end]]
--end
nixz = nixz + 1 -- increment 2D noise index
end
end
manip:set_data(data)
minetest.generate_ores(manip, minp, maxp)
manip:update_liquids()
manip:set_lighting({day=0, night=0})
manip:calc_lighting()
manip:write_to_map(data)
local t1 = os.clock()
print ("[forest] Time taken: " .. math.floor((t1-t0)*1e6)/1000 .. " ms")
end)