Skip to content
Snippets Groups Projects
Commit 60d4f91e authored by Duane Robertson's avatar Duane Robertson
Browse files

Optimize mapgen.

parent 0e5fd71e
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,9 @@ local node = setmetatable({}, {
loud_walking.node = node
local math_abs = math.abs
local math_floor = math.floor
local cloud_i = 0.5
local glass = {"loud_walking:sky_scrith", "loud_walking:cloud_scrith", "loud_walking:transparent_scrith"}
......@@ -98,9 +101,9 @@ mushroom_stones[node["loud_walking:stone_with_algae"]] = true
mushroom_stones[node["loud_walking:stone_with_lichen"]] = true
local function connection(x, y, z)
local min_x = math.floor((x + 32) / csize.x)
local min_y = math.floor((y + 32) / csize.y)
local min_z = math.floor((z + 32) / csize.z)
local min_x = math_floor((x + 32) / csize.x)
local min_y = math_floor((y + 32) / csize.y)
local min_z = math_floor((z + 32) / csize.z)
--local seed_noise = minetest.get_perlin({offset = 0, scale = 32768,
--seed = 5202, spread = {x = 80, y = 80, z = 80}, octaves = 2,
......@@ -137,12 +140,12 @@ end
local pod_size = {x=300, y=100, z=200}
local half_pod = {x=math.floor(pod_size.x / 2), y=math.floor(pod_size.y / 2), z=math.floor(pod_size.z / 2)}
local half_pod = {x=math_floor(pod_size.x / 2), y=math_floor(pod_size.y / 2), z=math_floor(pod_size.z / 2)}
local bridge_size = 50
local fcsize = {x=pod_size.x + bridge_size, y=pod_size.y + bridge_size, z=pod_size.z + bridge_size}
local bevel = half_pod.y
local room_size = 20
local control_off = math.floor(room_size / 4)
local control_off = math_floor(room_size / 4)
local biome_look = {}
local cave_look = {}
......@@ -157,8 +160,8 @@ local function place_schematic(pos, schem, center)
end
if center then
pos.x = pos.x - math.floor(schem.size.x / 2)
pos.z = pos.z - math.floor(schem.size.z / 2)
pos.x = pos.x - math_floor(schem.size.x / 2)
pos.z = pos.z - math_floor(schem.size.z / 2)
end
for z1 = 0, schem.size.z - 1 do
......@@ -201,9 +204,9 @@ end
local function get_biome(x, y, z)
local px = math.floor(x / fcsize.x)
local py = math.floor(y / fcsize.y)
local pz = math.floor(z / fcsize.z)
local px = math_floor(x / fcsize.x)
local py = math_floor(y / fcsize.y)
local pz = math_floor(z / fcsize.z)
if px % 10 == 6 and pz % 10 == 6 then
return "control"
......@@ -233,62 +236,32 @@ local function get_biome(x, y, z)
end
local function get_height_old(dx, dz, terrain_scale, ocean, index)
local terr
local half = {x=math.floor(csize.x / 2 + 0.5), y=math.floor(csize.y / 2 + 0.5), z=math.floor(csize.z / 2 + 0.5)}
terrain_scale = terrain_scale or 1
--if index == true then
-- terr = minetest.get_perlin(terrain_noise):get2d({x=dx, y=dz})
-- -- Still need csize here...
-- dx = (dx + 32) % 80
-- dz = (dz + 32) % 80
if not index then
index = dz * csize.x + dx + 1
terr = terrain[index]
else
terr = terrain[index]
end
terr = math.floor(terr * terrain_scale + 0.5)
local d = half.y - 2 - math.abs(math.abs(dx - (half.x - 0.5)) - math.abs(dz - (half.z - 0.5)))
if math.abs(terr) > d then
if terr > 0 then
terr = math.floor(d + 0.5)
elseif not ocean then
terr = math.floor(0.5 - d)
end
end
return terr
end
local function get_height(fdx, fdz, y, index, heights, terrain_scale, ocean)
local py = math.floor(y / fcsize.y)
local py = math_floor(y / fcsize.y)
if not terrain_scale then
return
end
if not heights[py] then
print('new height')
heights[py] = minetest.get_perlin_map(terrain_noise, csize):get2dMap_flat({x=minp.x, y=minp.z})
end
local terr = math.floor(heights[py][index] * terrain_scale + 0.5)
local terr = math_floor(heights[py][index] * terrain_scale + 0.5)
local d = - math.abs(math.abs(fdx - (half_pod.x - 0.5)) - math.abs(fdz - (half_pod.z - 0.5)))
if math.abs(fdx - half_pod.x) > math.abs(fdz - half_pod.z) then
local d = - math_abs(math_abs(fdx - (half_pod.x - 0.5)) - math_abs(fdz - (half_pod.z - 0.5)))
if math_abs(fdx - half_pod.x) > math_abs(fdz - half_pod.z) then
d = d + half_pod.x - 2
else
d = d + half_pod.z - 2
end
if math.abs(terr) > d then
if math_abs(terr) > d then
if terr > 0 then
terr = math.floor(d + 0.5)
terr = math_floor(d + 0.5)
elseif not ocean then
terr = math.floor(0.5 - d)
terr = math_floor(0.5 - d)
end
end
......@@ -297,6 +270,8 @@ end
local function generate(p_minp, p_maxp, seed)
--local ta0, ta1, ta2 = 0, 0, 0
local t0 = os.clock()
minp, maxp = p_minp, p_maxp
vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
vm:get_data(data)
......@@ -312,43 +287,58 @@ local function generate(p_minp, p_maxp, seed)
cloud = minetest.get_perlin_map(cloud_noise, csize):get2dMap_flat(minp)
cave = minetest.get_perlin_map(cave_noise, csize):get3dMap_flat(minp)
local t1 = os.clock()
local index = 0
local index3d = 0
local last_biome, last_px, last_py, last_pz, node_top, node_filler, node_water_top, node_water, depth_top, depth_water_top, depth_filler, node_stone, ocean, swamp, beach, dunes, height
local biome, cave_lining
for z = minp.z, maxp.z do
local dz = z - minp.z
local fdz = z % fcsize.z
local pz = math_floor(z / fcsize.z)
for x = minp.x, maxp.x do
index = index + 1
local dx = x - minp.x
local fdx = x % fcsize.x
local px = math_floor(x / fcsize.x)
local in_cave = false
index3d = dz * csize.y * csize.x + dx + 1
local ivm = a:index(x, minp.y, z)
local cave_height = 0
last_py = nil
for y = minp.y, maxp.y do
local dy = y - minp.y
local fdy = y % fcsize.y
local biome, cave_lining = get_biome(x, y, z)
local node_top = biomes[biome].node_top or "default:dirt_with_grass"
local node_filler = biomes[biome].node_filler or "default:dirt"
local node_water_top = biomes[biome].node_water_top or "default:water_source"
local node_water = biomes[biome].node_water or "default:water_source"
local depth_top = biomes[biome].depth_top or 1
local depth_water_top = biomes[biome].node_water_top or 1
local depth_filler = biomes[biome].depth_filler or 1
local node_stone = biomes[biome].node_stone or "default:stone"
local ocean = string.find(biome, "ocean") and true or false
local swamp = string.find(biome, "swamp") and true or false
local beach = string.find(biome, "beach") and true or false
local dunes = string.find(biome, "dunes") and true or false
local height = half_pod.y - 5
if not (biome == "underground" or biome == 'control') then
height = get_height(fdx, fdz, y, index, heights, biomes[biome].terrain_scale, ocean)
local py = math_floor(y / fcsize.y)
if py ~= last_py or px ~= last_px or pz ~= last_pz then
biome, cave_lining = get_biome(x, y, z)
end
if biome ~= last_biome then
node_top = biomes[biome].node_top or "default:dirt_with_grass"
node_filler = biomes[biome].node_filler or "default:dirt"
node_water_top = biomes[biome].node_water_top or "default:water_source"
node_water = biomes[biome].node_water or "default:water_source"
depth_top = biomes[biome].depth_top or 1
depth_water_top = biomes[biome].node_water_top or 1
depth_filler = biomes[biome].depth_filler or 1
node_stone = biomes[biome].node_stone or "default:stone"
ocean = string.find(biome, "ocean") and true or false
swamp = string.find(biome, "swamp") and true or false
beach = string.find(biome, "beach") and true or false
dunes = string.find(biome, "dunes") and true or false
end
if py ~= last_py then
height = half_pod.y - 5
if not (biome == "underground" or biome == 'control') then
height = get_height(fdx, fdz, y, index, heights, biomes[biome].terrain_scale, ocean)
end
end
if not (data[ivm] == node['air'] or data[ivm] == node['ignore']) then
-- nop
elseif biome == "control" and math.abs(fdx - half_pod.x) < 3 and math.abs(fdz - half_pod.z) < 3 then
elseif biome == "control" and math_abs(fdx - half_pod.x) < 3 and math_abs(fdz - half_pod.z) < 3 then
data[ivm] = node["loud_walking:air_ladder"]
elseif fdz >= pod_size.z or fdx >= pod_size.x or fdy >= pod_size.y then
if (fdy == half_pod.y and fdx == half_pod.x) or (fdy == half_pod.y and fdz == half_pod.z) then
......@@ -361,7 +351,7 @@ local function generate(p_minp, p_maxp, seed)
lightmap[ivm] = 0
in_cave = false
elseif (fdx == 0 or fdx == pod_size.x - 1) or (fdz == 0 or fdz == pod_size.z - 1) or (fdy == 0 or fdy == pod_size.y - 1) or math.min(fdx, pod_size.x - fdx) + math.min(fdy, pod_size.y - fdy) + math.min(fdz, pod_size.z - fdz) < bevel + 1 then
if math.abs(fdy - half_pod.y - 2) < 2 and (fdz == half_pod.z or fdx == half_pod.x) then
if math_abs(fdy - half_pod.y - 2) < 2 and (fdz == half_pod.z or fdx == half_pod.x) then
data[ivm] = node["air"]
else
if biome == "control" then
......@@ -382,9 +372,9 @@ local function generate(p_minp, p_maxp, seed)
data[ivm] = node['loud_walking:scrith']
elseif biome == "control" and fdy % 5 == 0 then
data[ivm] = node["loud_walking:control_floor"]
elseif biome == "control" and (math.abs(fdx - half_pod.x) < 3 or math.abs(fdz - half_pod.z) < 3) then
elseif biome == "control" and (math_abs(fdx - half_pod.x) < 3 or math_abs(fdz - half_pod.z) < 3) then
data[ivm] = node["air"]
elseif biome == "control" and ((math.abs(fdx - half_pod.x) % room_size == 3 and (math.abs(fdz - half_pod.z) - 12) % room_size > 3) or (math.abs(fdz - half_pod.z) % room_size == 3 and (math.abs(fdx - half_pod.x) - 12) % room_size > 3)) then
elseif biome == "control" and ((math_abs(fdx - half_pod.x) % room_size == 3 and (math_abs(fdz - half_pod.z) - 12) % room_size > 3) or (math_abs(fdz - half_pod.z) % room_size == 3 and (math_abs(fdx - half_pod.x) - 12) % room_size > 3)) then
data[ivm] = node["loud_walking:control_wall"]
elseif biome == "control" then
--
......@@ -474,26 +464,41 @@ local function generate(p_minp, p_maxp, seed)
cave_height = 0
end
last_biome = biome
last_py = py
ivm = ivm + a.ystride
index3d = index3d + csize.x
end
last_px = px
end
last_pz = pz
end
local t2 = os.clock()
local index = 0
for z = minp.z, maxp.z do
local fdz = z % fcsize.z
local pz = math_floor(z / fcsize.z)
for x = minp.x, maxp.x do
local fdx = x % fcsize.x
local px = math_floor(x / fcsize.x)
index = index + 1
last_py = nil
for y = minp.y, maxp.y do
local fdy = y % fcsize.y
local py = math_floor(y / fcsize.y)
if fdz % 5 == 0 and fdx % 5 == 0 then
local fdy = y % fcsize.y
local pod = fdz < pod_size.z and fdx < pod_size.x and fdy < pod_size.y
local biome, cave_lining = get_biome(x, y, z)
if py ~= last_py or px ~= last_px or pz ~= last_pz then
biome, cave_lining = get_biome(x, y, z)
end
local ocean = string.find(biome, "ocean") and true or false
local height = get_height(fdx, fdz, y, index, heights, biomes[biome].terrain_scale, ocean)
if py ~= last_py then
height = get_height(fdx, fdz, y, index, heights, biomes[biome].terrain_scale, ocean)
end
if biome ~= 'control' and pod and fdy == height + ground and biomes[biome].special_tree_prob and math.random(biomes[biome].special_tree_prob) == 1 then
local rx = x + math.random(5) - 1
......@@ -521,6 +526,8 @@ local function generate(p_minp, p_maxp, seed)
end
end
local t3 = os.clock()
if false and pod and biome == "control" then
for dy = 0, 15 do
for dz = 0, 1 do
......@@ -561,7 +568,7 @@ local function generate(p_minp, p_maxp, seed)
end
end
elseif sr == 4 then
if dy < 15 and (x > 0 and x < 20 and z > 0 and z < 20) and (((x == 1 or x == 19) and math.abs(z - 10) > 3) or ((z == 1 or z == 19) and math.abs(x - 10) > 3)) then
if dy < 15 and (x > 0 and x < 20 and z > 0 and z < 20) and (((x == 1 or x == 19) and math_abs(z - 10) > 3) or ((z == 1 or z == 19) and math_abs(x - 10) > 3)) then
data[ivm + 3 * a.ystride] = node["loud_walking:controls"]
end
end
......@@ -574,6 +581,8 @@ local function generate(p_minp, p_maxp, seed)
end
end
local t4 = os.clock()
vm:set_data(data)
minetest.generate_ores(vm, minp, maxp)
--vm:set_param2_data(p2data)
......@@ -581,6 +590,10 @@ local function generate(p_minp, p_maxp, seed)
vm:update_liquids()
vm:calc_lighting(minp, maxp, false)
vm:write_to_map()
local t5 = os.clock()
print(' times: '..(t1 - t0)..', '..(t2 - t1)..', '..(t3 - t2)..', '..(t5 - t4)..' = '..(t5 - t0))
--print(' also: '..ta1..', '..ta2)
end
......@@ -593,7 +606,7 @@ local function generate_old(p_minp, p_maxp, seed)
csize = vector.add(vector.subtract(maxp, minp), 1)
-- Deal with memory issues. This, of course, is supposed to be automatic.
local mem = math.floor(collectgarbage("count")/1024)
local mem = math_floor(collectgarbage("count")/1024)
if mem > 300 then
print("Loud Walking: Manually collecting garbage...")
collectgarbage("collect")
......@@ -606,8 +619,8 @@ local function generate_old(p_minp, p_maxp, seed)
math.randomseed(seed_noise:get2d({x=minp.x, y=minp.z}))
-- Keep this first after seeding!
local px = math.floor((minp.x + 32) / csize.x)
local pz = math.floor((minp.z + 32) / csize.z)
local px = math_floor((minp.x + 32) / csize.x)
local pz = math_floor((minp.z + 32) / csize.z)
local biome = get_biome(px, pz)
local cave_lining = cave_stones[math.random(#cave_stones)]
if math.random(3) == 1 then
......@@ -629,7 +642,7 @@ local function generate_old(p_minp, p_maxp, seed)
local swamp = string.find(biome, "swamp") and true or false
local beach = string.find(biome, "beach") and true or false
local dunes = string.find(biome, "dunes") and true or false
local half = {x=math.floor(csize.x / 2 + 0.5), y=math.floor(csize.y / 2 + 0.5), z=math.floor(csize.z / 2 + 0.5)}
local half = {x=math_floor(csize.x / 2 + 0.5), y=math_floor(csize.y / 2 + 0.5), z=math_floor(csize.z / 2 + 0.5)}
local ground = half.y
beach = beach or dunes
......@@ -666,14 +679,14 @@ local function generate_old(p_minp, p_maxp, seed)
for y = minp.y, maxp.y do
local dy = y - minp.y
if pod then
if biome == "control" and math.abs(dx - half.x) < 3 and math.abs(dz - half.z) < 3 then
if biome == "control" and math_abs(dx - half.x) < 3 and math_abs(dz - half.z) < 3 then
data[ivm] = node["loud_walking:air_ladder"]
elseif math.min(dx, csize.x - dx) + math.min(dy, csize.y - dy) + math.min(dz, csize.z - dz) < bevel then
data[ivm] = node["air"]
lightmap[ivm] = 0
in_cave = false
elseif (dx == 0 or dx == csize.x - 1) or (dz == 0 or dz == csize.z - 1) or (dy == 0 or dy == csize.y - 1) or math.min(dx, csize.x - dx) + math.min(dy, csize.y - dy) + math.min(dz, csize.z - dz) < bevel + 1 then
if math.abs(dy - half.y - 2) < 2 and (dz == half.z or dx == half.x) then
if math_abs(dy - half.y - 2) < 2 and (dz == half.z or dx == half.x) then
data[ivm] = node["air"]
else
if biome == "control" then
......@@ -693,9 +706,9 @@ local function generate_old(p_minp, p_maxp, seed)
in_cave = false
elseif biome == "control" and dy % 5 == 0 then
data[ivm] = node["loud_walking:control_floor"]
elseif biome == "control" and (math.abs(dx - half.x) < 3 or math.abs(dz - half.z) < 3) then
elseif biome == "control" and (math_abs(dx - half.x) < 3 or math_abs(dz - half.z) < 3) then
data[ivm] = node["air"]
elseif biome == "control" and ((math.abs(dx - half.x) % 20 == 3 and (math.abs(dz - half.z) - 12) % 20 > 3) or (math.abs(dz - half.z) % 20 == 3 and (math.abs(dx - half.x) - 12) % 20 > 3)) then
elseif biome == "control" and ((math_abs(dx - half.x) % 20 == 3 and (math_abs(dz - half.z) - 12) % 20 > 3) or (math_abs(dz - half.z) % 20 == 3 and (math_abs(dx - half.x) - 12) % 20 > 3)) then
data[ivm] = node["loud_walking:control_wall"]
elseif biome == "control" then
--
......@@ -780,7 +793,7 @@ local function generate_old(p_minp, p_maxp, seed)
lightmap[ivm] = 0
in_cave = false
end
elseif biome == "control" and math.abs(dx - half.x) < 3 and math.abs(dz - half.z) < 3 then
elseif biome == "control" and math_abs(dx - half.x) < 3 and math_abs(dz - half.z) < 3 then
data[ivm] = node["loud_walking:air_ladder"]
elseif connection and dy == half.y and ((dx == half.x and connection % 4 == 0) or (dz == half.z and connection % 2 == 1)) then
data[ivm] = node["loud_walking:scrith"]
......@@ -863,7 +876,7 @@ local function generate_old(p_minp, p_maxp, seed)
end
end
elseif sr == 4 then
if dy < 15 and (x > 0 and x < 20 and z > 0 and z < 20) and (((x == 1 or x == 19) and math.abs(z - 10) > 3) or ((z == 1 or z == 19) and math.abs(x - 10) > 3)) then
if dy < 15 and (x > 0 and x < 20 and z > 0 and z < 20) and (((x == 1 or x == 19) and math_abs(z - 10) > 3) or ((z == 1 or z == 19) and math_abs(x - 10) > 3)) then
data[ivm + 3 * a.ystride] = node["loud_walking:controls"]
end
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment