diff --git a/lua/engine.lua b/lua/engine.lua index d307c15..367c44b 100644 --- a/lua/engine.lua +++ b/lua/engine.lua @@ -37,6 +37,19 @@ local default_biome = , maxp = { x = 1e5, y = 1e5, z = 1e5 } } +local cave_shape_chunk_size = 8 + +local cluster_shape_chunks_x = 4 +local cluster_shape_chunks_y = 6 +local cluster_shape_chunks_z = 4 + +local function reduced_pos(pos) + return + { x = math.floor(pos.x / (cave_shape_chunk_size * cluster_shape_chunks_x)) + , y = math.floor(pos.y / (cave_shape_chunk_size * cluster_shape_chunks_y)) + , z = math.floor(pos.z / (cave_shape_chunk_size * cluster_shape_chunks_z)) + } +end -- Convert 3d relative coordinates to an index on a flat array local function from_3d_to_flat(dx, dy, dz, nx, ny) return (nx * ny * dz) + (nx * dy) + dx + 1 @@ -252,7 +265,13 @@ local function get_connectivity_noise_params(shape_size) return { offset = 50, scale = 50, - spread = { x = factor * 250, y = factor * 100, z = factor * 250 }, + spread = + reduced_pos( + { x = factor * 250 + , y = factor * 100 + , z = factor * 250 + } + ), seed = 297948, octaves = 2, persistence = 0.2, @@ -269,7 +288,13 @@ local function get_verticality_noise_params(shape_size) return { offset = 50, scale = 50, - spread = { x = factor * 100, y = factor * 250, z = factor * 100 }, + spread = + reduced_pos( + { x = factor * 100 + , y = factor * 250 + , z = factor * 100 + } + ), seed = 35644, octaves = 2, persistence = 0.2, @@ -278,26 +303,30 @@ local function get_verticality_noise_params(shape_size) } end --- Get the distance of each cave shape to calculate their weight. -local function shape_distance_weight(shape_size, dx, dy) +-- Get whether a cave shape is within distance. +local function shape_within_distance(shape_size, dx, dy) local factor = math.max(math.abs(shape_size) ^ 0.5, 1) - local max_distance = 100 / factor + local max_distance = 30 / factor - if dx^2 + dy^2 > max_distance^2 then - return 0 - else - return 1 / (dx^5 + dy^5) - end + return dx^2 + dy^2 <= max_distance^2 +end + +local function shape_def_distance(def, x, y) + local dx = math.abs(x - def.connectivity_point) + local dy = math.abs(y - def.verticality_point) + + return dx^2 + dy^2 end -- Get a flat map containing all flat threshold values local function get_threshold_flat(minp, maxp) local connectivity = get_flat_from_noise_params( - minp, maxp, + reduced_pos(minp), reduced_pos(maxp), get_connectivity_noise_params(#noordstar_caves.registered_shapes) ) + local verticality = get_flat_from_noise_params( - minp, maxp, + reduced_pos(minp), reduced_pos(maxp), get_verticality_noise_params(#noordstar_caves.registered_shapes) ) @@ -305,41 +334,37 @@ local function get_threshold_flat(minp, maxp) -- Get noise for all cave shapes for key, def in pairs(noordstar_caves.registered_shapes) do - noise[key] = { - key = key, - noise = get_flat_from_shape_def(def, minp, maxp), - def = def - } + noise[key] = get_flat_from_shape_def(def, reduced_pos(minp), reduced_pos(maxp)) end + -- Create a (reduced) flat array + local reduced = Flat3dArray:from_func( + reduced_pos(minp), reduced_pos(maxp), + function(i, pos) + local x = connectivity:get_pos(pos) + local y = verticality:get_pos(pos) + + local value = 0 + + for key, def in pairs(noordstar_caves.registered_shapes) do + local dx = math.abs(x - def.connectivity_point) + local dy = math.abs(y - def.verticality_point) + + if shape_within_distance(#noordstar_caves.registered_shapes, dx, dy) then + value = math.max(value, noise[key]:get_pos(pos)) + end + end + + return value + end + ) + -- Create the flat array - return Flat3dArray:from_func(minp, maxp, function(i, pos) - local total = 0 - local count = 0 - - local x = connectivity:get_pos(pos) - local y = verticality:get_pos(pos) - - for _, n in pairs(noise) do - local v = n.noise:get_pos(pos) - - local dx = math.abs(x - n.def.connectivity_point) - local dy = math.abs(y - n.def.verticality_point) - - local w = math.abs(shape_distance_weight( - #noordstar_caves.registered_shapes, dx, dy - )) - - total = total + v * w - count = count + w - end - - if count <= 0 then - return -1000 - else - return total / count - end + local x = Flat3dArray:from_func(minp, maxp, function(i, pos) + return reduced:get_pos(reduced_pos(pos)) end) + + return x end @@ -470,13 +495,13 @@ local function biome_def_to_content_id(def, nt, original_block) local node_air = get_node(def.node_air, minetest.get_content_id("air")) local node_floor = get_node(def.node_floor, original_block) - local node_stone = original_block + local node_stone = get_node(nil, original_block) local node_roof = get_node(def.node_roof, original_block) - local node_unknown = original_block + local node_unknown = get_node(nil, original_block) local node_wall = get_node(def.node_wall, original_block) if nt == node_type.unknown then - return node_unknown + return node_unknown() elseif nt == node_type.floor then return node_floor() elseif nt == node_type.wall then @@ -486,7 +511,7 @@ local function biome_def_to_content_id(def, nt, original_block) elseif nt == node_type.content then return node_air() elseif nt == node_type.stone then - return node_stone + return node_stone() else return original_block end