diff --git a/map_gen/presets/hub_spiral.lua b/map_gen/presets/hub_spiral.lua new file mode 100644 index 00000000..8b1790f2 --- /dev/null +++ b/map_gen/presets/hub_spiral.lua @@ -0,0 +1,56 @@ +local b = require 'map_gen.shared.builders' + +local spiral = b.circular_spiral_grow_n_threads(2, 4, 64, 8) +spiral = b.any {spiral, b.circle(4)} +spiral = b.choose(b.circle(16), spiral, b.empty_shape) + +--local squares = b.single_x_pattern(spiral, 64) +local squares = b.single_pattern_overlap(spiral, 64, 64) +squares = b.linear_grow(squares, 64) + +local function crop(x, y) + return x > 0 and y > 0 +end + +crop = b.rotate(crop, degrees(-45)) + +--local quarter = b.choose(crop, squares, b.empty_shape) +local quarter = squares + +local count = 4 +local delta = tau / count +local angle = (3 / 8) * tau +local whole = {} +for i = 1, count do + whole[i] = b.rotate(quarter, angle) + angle = angle + delta +end + +local ore_shape = b.segment_pattern(whole) +local ore_shape = b.circular_spiral_grow_n_threads(16, 128, 2048, 8) +ore_shape = b.flip_x(ore_shape) + +local iron = b.apply_entity(b.full_shape, b.resource(ore_shape, 'iron-ore')) +local copper = b.apply_entity(b.full_shape, b.resource(ore_shape, 'copper-ore')) +local stone = b.apply_entity(b.full_shape, b.resource(ore_shape, 'stone')) +local coal = b.apply_entity(b.full_shape, b.resource(ore_shape, 'coal')) +local uranium = b.apply_entity(b.full_shape, b.resource(ore_shape, 'uranium-ore')) +local oil = b.apply_entity(b.full_shape, b.resource(ore_shape, 'crude-oil')) + +local void_spiral = b.circular_spiral_grow_n_threads(8, 32, 512, 8) +void_spiral = b.rotate(void_spiral, degrees(-39)) +local void_circle = b.circle(256) +local void = b.choose(void_circle, void_spiral, b.empty_shape) + +local walk_spiral = b.circular_spiral_n_threads(5, 512, 8) +walk_spiral = b.flip_x(walk_spiral) + +local map = + b.circular_spiral_grow_pattern(16, 32, 512, {b.full_shape, iron, stone, coal, b.full_shape, copper, uranium, oil}) + +--map = b.subtract(map, void) +map = b.any {b.circle(64), map, walk_spiral} + +--local map = b.apply_entity(main_spiral, ore) + +return map diff --git a/map_gen/shared/builders.lua b/map_gen/shared/builders.lua index 13259780..99d2f047 100644 --- a/map_gen/shared/builders.lua +++ b/map_gen/shared/builders.lua @@ -159,7 +159,6 @@ function Builders.rectangular_spiral(x_size, optional_y_size) end function Builders.circular_spiral(in_thickness, total_thickness) - local out_thickness = total_thickness - in_thickness local half_total_thickness = total_thickness * 0.5 return function(x, y) local d = math.sqrt(x * x + y * y) @@ -167,12 +166,11 @@ function Builders.circular_spiral(in_thickness, total_thickness) local angle = 1 + inv_pi * math.atan2(x, y) local offset = d + (angle * half_total_thickness) - return offset % total_thickness >= out_thickness + return offset % total_thickness < in_thickness end end function Builders.circular_spiral_grow(in_thickness, total_thickness, grow_factor) - local out_thickness = total_thickness - in_thickness local half_total_thickness = total_thickness * 0.5 local inv_grow_factor = 1 / grow_factor return function(x, y) @@ -180,18 +178,17 @@ function Builders.circular_spiral_grow(in_thickness, total_thickness, grow_facto local factor = (d * inv_grow_factor) + 1 local total_thickness2 = total_thickness * factor - local out_thickness2 = out_thickness * factor + local in_thickness2 = in_thickness * factor local half_total_thickness2 = half_total_thickness * factor local angle = 1 + inv_pi * math.atan2(x, y) local offset = d + (angle * half_total_thickness2) - return offset % total_thickness2 >= out_thickness2 + return offset % total_thickness2 < in_thickness2 end end function Builders.circular_spiral_n_threads(in_thickness, total_thickness, n_threads) - local out_thickness = total_thickness - in_thickness local half_total_thickness = total_thickness * 0.5 * n_threads return function(x, y) local d = math.sqrt(x * x + y * y) @@ -199,12 +196,11 @@ function Builders.circular_spiral_n_threads(in_thickness, total_thickness, n_thr local angle = 1 + inv_pi * math.atan2(x, y) local offset = d + (angle * half_total_thickness) - return offset % total_thickness >= out_thickness + return offset % total_thickness < in_thickness end end function Builders.circular_spiral_grow_n_threads(in_thickness, total_thickness, grow_factor, n_threads) - local out_thickness = total_thickness - in_thickness local half_total_thickness = total_thickness * 0.5 * n_threads local inv_grow_factor = 1 / grow_factor return function(x, y) @@ -212,13 +208,13 @@ function Builders.circular_spiral_grow_n_threads(in_thickness, total_thickness, local factor = (d * inv_grow_factor) + 1 local total_thickness2 = total_thickness * factor - local out_thickness2 = out_thickness * factor + local in_thickness2 = in_thickness * factor local half_total_thickness2 = half_total_thickness * factor local angle = 1 + inv_pi * math.atan2(x, y) local offset = d + (angle * half_total_thickness2) - return offset % total_thickness2 >= out_thickness2 + return offset % total_thickness2 < in_thickness2 end end @@ -1028,6 +1024,65 @@ function Builders.single_spiral_rotate_pattern(shape, width, optional_height) end end +function Builders.circular_spiral_pattern(in_thickness, total_thickness, pattern) + local n_threads = #pattern + total_thickness = total_thickness * n_threads + local half_total_thickness = total_thickness * 0.5 + local delta = total_thickness / n_threads + return function(x, y, world) + local d = math.sqrt(x * x + y * y) + + local angle = 1 + inv_pi * math.atan2(x, y) + + local offset = d + (angle * half_total_thickness) + if offset % total_thickness < in_thickness then + return pattern[1](x, y, world) + end + + for i = 2, n_threads do + offset = offset + delta + if offset % total_thickness < in_thickness then + return pattern[i](x, y, world) + end + end + + return false + end +end + +function Builders.circular_spiral_grow_pattern(in_thickness, total_thickness, grow_factor, pattern) + local n_threads = #pattern + total_thickness = total_thickness * n_threads + local half_total_thickness = total_thickness * 0.5 + local inv_grow_factor = 1 / grow_factor + local delta = total_thickness / n_threads + return function(x, y, world) + local d = math.sqrt(x * x + y * y) + + local factor = (d * inv_grow_factor) + 1 + local total_thickness2 = total_thickness * factor + local in_thickness2 = in_thickness * factor + local half_total_thickness2 = half_total_thickness * factor + local delta2 = delta * factor + + local angle = 1 + inv_pi * math.atan2(x, y) + + local offset = d + (angle * half_total_thickness2) + if offset % total_thickness2 < in_thickness2 then + return pattern[1](x, y, world) + end + + for i = 2, n_threads do + offset = offset + delta2 + if offset % total_thickness2 < in_thickness2 then + return pattern[i](x, y, world) + end + end + + return false + end +end + function Builders.segment_pattern(pattern) local count = #pattern