planet_mars/mapgen.lua

207 lines
4.8 KiB
Lua
Raw Normal View History

2018-10-31 01:00:32 -07:00
local has_bedrock_mod = minetest.get_modpath("bedrock")
2018-10-31 06:20:23 -07:00
local has_vacuum_mod = minetest.get_modpath("vacuum")
2018-10-31 01:00:32 -07:00
-- http://dev.minetest.net/PerlinNoiseMap
2018-10-31 02:07:38 -07:00
-- https://github.com/pyrollo/cratermg/blob/master/init.lua (thx Pyrollo:)
2018-10-31 01:00:32 -07:00
2018-10-31 02:07:38 -07:00
-- basic planet height noise
local height_params = {
offset = 0,
scale = 5,
spread = {x=256, y=256, z=256},
2018-10-31 02:19:17 -07:00
seed = 5477835,
2018-10-31 02:07:38 -07:00
octaves = 2,
persist = 0.5
2018-10-31 01:00:32 -07:00
}
2018-10-31 02:34:08 -07:00
-- mountain noise
local mountain_params = {
offset = 0,
scale = 5,
spread = {x=256, y=256, z=256},
seed = 34252,
octaves = 3,
persist = 0.5
}
2018-10-31 02:19:17 -07:00
2018-10-31 03:53:45 -07:00
-- clay noise
local clay_params = {
offset = 0,
scale = 1,
2018-10-31 05:52:52 -07:00
spread = {x=32, y=16, z=48},
seed = 17893325,
octaves = 2,
persist = 0.5
}
-- clay noise
local cave_params = {
offset = 0,
scale = 1,
spread = {x=128, y=64, z=128},
2018-10-31 03:53:45 -07:00
seed = 981364,
octaves = 2,
persist = 0.5
2018-10-31 03:53:45 -07:00
}
2018-10-31 02:19:17 -07:00
2018-10-31 05:52:52 -07:00
local c_base = minetest.get_content_id("default:desert_stone")
2018-10-31 03:53:45 -07:00
local c_stone = minetest.get_content_id("default:desert_stone")
2018-10-31 02:07:38 -07:00
local c_sand = minetest.get_content_id("default:desert_sand")
2018-10-31 05:52:52 -07:00
local c_dirt = minetest.get_content_id("default:dirt")
local c_meselamp = minetest.get_content_id("default:meselamp")
2018-10-31 01:00:32 -07:00
local c_air = minetest.get_content_id("air")
2018-10-31 06:20:23 -07:00
local c_vacuum = c_air
if has_vacuum_mod then
c_vacuum = minetest.get_content_id("vacuum:vacuum")
end
2018-10-31 01:00:32 -07:00
local c_clay = minetest.get_content_id("default:clay")
2018-10-31 02:19:17 -07:00
local c_bedrock = c_base
2018-10-31 01:00:32 -07:00
if has_bedrock_mod then
c_bedrock = minetest.get_content_id("bedrock:bedrock")
end
2018-10-31 02:07:38 -07:00
local y_start = planet_mars.y_start
local y_height = planet_mars.y_height
2018-10-31 01:00:32 -07:00
2018-10-31 02:34:08 -07:00
-- perlin noise
local height_perlin
local mountain_perlin
2018-10-31 03:53:45 -07:00
local clay_perlin
2018-10-31 05:52:52 -07:00
local cave_perlin
2018-10-31 02:34:08 -07:00
-- reuse maps
local height_perlin_map = {}
local mountain_perlin_map = {}
2018-10-31 03:53:45 -07:00
local clay_perlin_map = {}
2018-10-31 05:52:52 -07:00
local cave_perlin_map = {}
2018-10-31 01:00:32 -07:00
minetest.register_on_generated(function(minp, maxp, seed)
2018-10-31 02:07:38 -07:00
if minp.y < y_start or minp.y > (y_start + y_height) then
-- not in range
2018-10-31 01:00:32 -07:00
return
end
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
local side_length = maxp.x - minp.x + 1 -- 80
local map_lengths_xyz = {x=side_length, y=side_length, z=side_length}
2018-10-31 02:34:08 -07:00
height_perlin = height_perlin or minetest.get_perlin_map(height_params, map_lengths_xyz)
mountain_perlin = mountain_perlin or minetest.get_perlin_map(mountain_params, map_lengths_xyz)
2018-10-31 03:53:45 -07:00
clay_perlin = clay_perlin or minetest.get_perlin_map(clay_params, map_lengths_xyz)
2018-10-31 05:52:52 -07:00
cave_perlin = cave_perlin or minetest.get_perlin_map(cave_params, map_lengths_xyz)
2018-10-31 01:00:32 -07:00
2018-10-31 02:34:08 -07:00
height_perlin:get2dMap_flat({x=minp.x, y=minp.z}, height_perlin_map)
mountain_perlin:get2dMap_flat({x=minp.x, y=minp.z}, mountain_perlin_map)
2018-10-31 03:53:45 -07:00
clay_perlin:get3dMap_flat(minp, clay_perlin_map)
2018-10-31 05:52:52 -07:00
cave_perlin:get3dMap_flat(minp, cave_perlin_map)
2018-10-31 02:07:38 -07:00
local perlin_index = 1
local height_fill_factor = 0.8
local height_hill_factor = 1 - height_fill_factor
2018-10-31 01:00:32 -07:00
for z=minp.z,maxp.z do
for x=minp.x,maxp.x do
2018-10-31 02:07:38 -07:00
-- normalized factor from 0...1
2018-10-31 03:53:45 -07:00
local height_perlin_factor = math.min(1, math.abs( height_perlin_map[perlin_index] * 0.1 ) )
local mountain_perlin_factor = math.min(1, math.abs( mountain_perlin_map[perlin_index] * 0.18 ) )
2018-10-31 01:00:32 -07:00
2018-10-31 02:07:38 -07:00
-- weighted hill top and solid bottom
2018-10-31 02:34:08 -07:00
local abs_height = y_start + (y_height * 0.99) + (y_height * height_perlin_factor * 0.01)
2018-10-31 03:53:45 -07:00
local abs_mountain_height = y_start + (y_height * 0.9) + (y_height * mountain_perlin_factor * 0.1)
2018-10-31 02:07:38 -07:00
for y=minp.y,maxp.y do
local index = area:index(x,y,z)
2018-10-31 01:00:32 -07:00
2018-10-31 02:19:17 -07:00
if y < y_start + 10 then
-- bedrock (if available)
data[index] = c_bedrock
elseif y < abs_height then
2018-10-31 02:07:38 -07:00
-- solid
data[index] = c_base
2018-10-31 01:00:32 -07:00
2018-10-31 03:53:45 -07:00
elseif y < abs_mountain_height then
-- mountain
data[index] = c_stone
2018-10-31 02:07:38 -07:00
elseif y < abs_height + 2 then
-- top layer
data[index] = c_sand
2018-10-31 01:00:32 -07:00
2018-10-31 02:07:38 -07:00
else
-- non-solid
2018-10-31 06:20:23 -07:00
data[index] = c_vacuum
2018-10-31 01:00:32 -07:00
end
2018-10-31 02:07:38 -07:00
end --y
2018-10-31 01:00:32 -07:00
2018-10-31 02:07:38 -07:00
perlin_index = perlin_index + 1
2018-10-31 01:00:32 -07:00
end --x
end --z
2018-10-31 03:53:45 -07:00
perlin_index = 1
-- generate ores
for z=minp.z,maxp.z do
for y=minp.y,maxp.y do
for x=minp.x,maxp.x do
local index = area:index(x,y,z)
2018-10-31 05:52:52 -07:00
local is_clay = math.abs(clay_perlin_map[perlin_index]) > 0.5
local is_cave = math.abs(cave_perlin_map[perlin_index]) > 0.5
local is_cave_dirt = math.abs(cave_perlin_map[perlin_index]) < 0.55
2018-10-31 06:20:23 -07:00
local is_deep = y < (y_start + (y_height * 0.95))
2018-10-31 05:52:52 -07:00
if data[index] == c_base then
-- base material found
2018-10-31 06:20:23 -07:00
if is_cave and is_deep then
-- caves only deep below
2018-10-31 05:52:52 -07:00
if is_cave_dirt then
-- cave with dirt and lamps
if math.random(0, 15) == 1 then
data[index] = c_meselamp
else
data[index] = c_dirt
end
else
-- cave with air
data[index] = c_air
end
elseif is_clay then
-- clay deposit
data[index] = c_clay
2018-10-31 06:20:23 -07:00
2018-10-31 05:52:52 -07:00
end
2018-10-31 06:20:23 -07:00
-- TODO: trees/grass?
2018-10-31 03:53:45 -07:00
end
perlin_index = perlin_index + 1
end --x
end --y
end --z
2018-10-31 01:00:32 -07:00
vm:set_data(data)
vm:write_to_map()
end)