Optimize mapgen.
parent
0e5fd71e59
commit
60d4f91e57
175
mapgen.lua
175
mapgen.lua
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue