mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-14 10:13:13 +02:00
new builder functions
This commit is contained in:
parent
9a63f3a4f5
commit
40761191ee
@ -1,5 +1,4 @@
|
|||||||
-- helpers
|
-- helpers
|
||||||
|
|
||||||
tau = 2 * math.pi
|
tau = 2 * math.pi
|
||||||
deg_to_rad = tau / 360
|
deg_to_rad = tau / 360
|
||||||
function degrees(angle)
|
function degrees(angle)
|
||||||
@ -7,7 +6,6 @@ function degrees(angle)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- shape builders
|
-- shape builders
|
||||||
|
|
||||||
function empty_builder(x, y)
|
function empty_builder(x, y)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -124,9 +122,9 @@ function decompress(pic)
|
|||||||
local data = pic.data
|
local data = pic.data
|
||||||
local width = pic.width
|
local width = pic.width
|
||||||
local height = pic.height
|
local height = pic.height
|
||||||
|
|
||||||
local uncompressed = {}
|
local uncompressed = {}
|
||||||
|
|
||||||
for y = 1, height do
|
for y = 1, height do
|
||||||
local row = data[y]
|
local row = data[y]
|
||||||
local u_row = {}
|
local u_row = {}
|
||||||
@ -135,14 +133,14 @@ function decompress(pic)
|
|||||||
for index = 1, #row, 2 do
|
for index = 1, #row, 2 do
|
||||||
local pixel = tile_map[row[index]]
|
local pixel = tile_map[row[index]]
|
||||||
local count = row[index + 1]
|
local count = row[index + 1]
|
||||||
|
|
||||||
for i = 1, count do
|
for i = 1, count do
|
||||||
u_row[x] = pixel
|
u_row[x] = pixel
|
||||||
x = x + 1
|
x = x + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {width = width, height = height, data = uncompressed}
|
return {width = width, height = height, data = uncompressed}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -150,7 +148,7 @@ function picture_builder(pic)
|
|||||||
local data = pic.data
|
local data = pic.data
|
||||||
local width = pic.width
|
local width = pic.width
|
||||||
local height = pic.height
|
local height = pic.height
|
||||||
|
|
||||||
-- the plus one is because lua tables are one based.
|
-- the plus one is because lua tables are one based.
|
||||||
local half_width = math.floor(width / 2) + 1
|
local half_width = math.floor(width / 2) + 1
|
||||||
local half_height = math.floor(height / 2) + 1
|
local half_height = math.floor(height / 2) + 1
|
||||||
@ -159,7 +157,7 @@ function picture_builder(pic)
|
|||||||
y = math.floor(y)
|
y = math.floor(y)
|
||||||
local x2 = x + half_width
|
local x2 = x + half_width
|
||||||
local y2 = y + half_height
|
local y2 = y + half_height
|
||||||
|
|
||||||
if y2 > 0 and y2 <= height and x2 > 0 and x2 <= width then
|
if y2 > 0 and y2 <= height and x2 > 0 and x2 <= width then
|
||||||
local pixel = data[y2][x2]
|
local pixel = data[y2][x2]
|
||||||
return pixel
|
return pixel
|
||||||
@ -170,7 +168,6 @@ function picture_builder(pic)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- transforms and shape helpers
|
-- transforms and shape helpers
|
||||||
|
|
||||||
function translate(builder, x_offset, y_offset)
|
function translate(builder, x_offset, y_offset)
|
||||||
return function(x, y, world_x, world_y, surface)
|
return function(x, y, world_x, world_y, surface)
|
||||||
return builder(x - x_offset, y - y_offset, world_x, world_y, surface)
|
return builder(x - x_offset, y - y_offset, world_x, world_y, surface)
|
||||||
@ -312,6 +309,17 @@ function choose(condition, true_shape, false_shape)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function shape_or_else(shape, else_shape)
|
||||||
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
|
local tile, entity = shape(local_x, local_y, world_x, world_y, surface)
|
||||||
|
if (tile) then
|
||||||
|
return tile, entity
|
||||||
|
else
|
||||||
|
return else_shape(local_x, local_y, world_x, world_y, surface)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function linear_grow(shape, size)
|
function linear_grow(shape, size)
|
||||||
local half_size = size / 2
|
local half_size = size / 2
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
@ -319,10 +327,10 @@ function linear_grow(shape, size)
|
|||||||
local n = math.ceil((math.sqrt(8 * t + 1) - 1) / 2)
|
local n = math.ceil((math.sqrt(8 * t + 1) - 1) / 2)
|
||||||
local t_upper = n * (n + 1) * 0.5
|
local t_upper = n * (n + 1) * 0.5
|
||||||
local t_lower = t_upper - n
|
local t_lower = t_upper - n
|
||||||
|
|
||||||
local y = (local_y - size * (t_lower + n / 2 - 0.5)) / n
|
local y = (local_y - size * (t_lower + n / 2 - 0.5)) / n
|
||||||
local x = local_x / n
|
local x = local_x / n
|
||||||
|
|
||||||
return shape(x, y, world_x, world_y, surface)
|
return shape(x, y, world_x, world_y, surface)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -333,24 +341,24 @@ function grow(in_shape, out_shape, size, offset)
|
|||||||
local tx = math.ceil(math.abs(local_x) / half_size)
|
local tx = math.ceil(math.abs(local_x) / half_size)
|
||||||
local ty = math.ceil(math.abs(local_y) / half_size)
|
local ty = math.ceil(math.abs(local_y) / half_size)
|
||||||
local t = math.max(tx, ty)
|
local t = math.max(tx, ty)
|
||||||
|
|
||||||
local tile, entity
|
local tile, entity
|
||||||
|
|
||||||
for i = t, 2.5 * t, 1 do
|
for i = t, 2.5 * t, 1 do
|
||||||
local out_t = 1 / (i - offset)
|
local out_t = 1 / (i - offset)
|
||||||
local in_t = 1 / i
|
local in_t = 1 / i
|
||||||
|
|
||||||
tile = out_shape(out_t * local_x, out_t * local_y, world_x, world_y, surface)
|
tile = out_shape(out_t * local_x, out_t * local_y, world_x, world_y, surface)
|
||||||
if tile then
|
if tile then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
tile, entity = in_shape(in_t * local_x, in_t * local_y, world_x, world_y, surface)
|
tile, entity = in_shape(in_t * local_x, in_t * local_y, world_x, world_y, surface)
|
||||||
if tile then
|
if tile then
|
||||||
return tile, entity
|
return tile, entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -359,20 +367,20 @@ function project(shape, size, r)
|
|||||||
local ln_r = math.log(r)
|
local ln_r = math.log(r)
|
||||||
local r2 = 1 / (r - 1)
|
local r2 = 1 / (r - 1)
|
||||||
local a = 1 / size
|
local a = 1 / size
|
||||||
|
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local offset = 0.5 * size
|
local offset = 0.5 * size
|
||||||
local sn = math.ceil(local_y + offset)
|
local sn = math.ceil(local_y + offset)
|
||||||
|
|
||||||
local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1)
|
local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1)
|
||||||
local rn = r ^ n
|
local rn = r ^ n
|
||||||
local rn2 = 1 / rn
|
local rn2 = 1 / rn
|
||||||
local c = size * rn
|
local c = size * rn
|
||||||
|
|
||||||
local sn_upper = size * (r ^ (n + 1) - 1) * r2
|
local sn_upper = size * (r ^ (n + 1) - 1) * r2
|
||||||
local x = local_x * rn2
|
local x = local_x * rn2
|
||||||
local y = (local_y - (sn_upper - 0.5 * c) + offset) * rn2
|
local y = (local_y - (sn_upper - 0.5 * c) + offset) * rn2
|
||||||
|
|
||||||
return shape(x, y, world_x, world_y, surface)
|
return shape(x, y, world_x, world_y, surface)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -382,61 +390,60 @@ function project_overlap(shape, size, r)
|
|||||||
local r2 = 1 / (r - 1)
|
local r2 = 1 / (r - 1)
|
||||||
local a = 1 / size
|
local a = 1 / size
|
||||||
local offset = 0.5 * size
|
local offset = 0.5 * size
|
||||||
|
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local sn = math.ceil(local_y + offset)
|
local sn = math.ceil(local_y + offset)
|
||||||
|
|
||||||
local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1)
|
local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1)
|
||||||
local rn = r ^ n
|
local rn = r ^ n
|
||||||
local rn2 = 1 / rn
|
local rn2 = 1 / rn
|
||||||
local c = size * rn
|
local c = size * rn
|
||||||
|
|
||||||
local sn_upper = size * (r ^ (n + 1) - 1) * r2
|
local sn_upper = size * (r ^ (n + 1) - 1) * r2
|
||||||
local x = local_x * rn2
|
local x = local_x * rn2
|
||||||
local y = (local_y - (sn_upper - 0.5 * c) + offset) * rn2
|
local y = (local_y - (sn_upper - 0.5 * c) + offset) * rn2
|
||||||
|
|
||||||
local tile
|
local tile
|
||||||
local entity
|
local entity
|
||||||
|
|
||||||
tile, entity = shape(x, y, world_x, world_y, surface)
|
tile, entity = shape(x, y, world_x, world_y, surface)
|
||||||
if tile then
|
if tile then
|
||||||
return tile, entity
|
return tile, entity
|
||||||
end
|
end
|
||||||
|
|
||||||
local n_above = n - 1
|
local n_above = n - 1
|
||||||
local rn_above = rn / r
|
local rn_above = rn / r
|
||||||
local rn2_above = 1 / rn_above
|
local rn2_above = 1 / rn_above
|
||||||
local c_above = size * rn_above
|
local c_above = size * rn_above
|
||||||
|
|
||||||
local sn_upper_above = sn_upper - c
|
local sn_upper_above = sn_upper - c
|
||||||
local x_above = local_x * rn2_above
|
local x_above = local_x * rn2_above
|
||||||
local y_above = (local_y - (sn_upper_above - 0.5 * c_above) + offset) * rn2_above
|
local y_above = (local_y - (sn_upper_above - 0.5 * c_above) + offset) * rn2_above
|
||||||
|
|
||||||
tile, entity = shape(x_above, y_above, world_x, world_y, surface)
|
tile, entity = shape(x_above, y_above, world_x, world_y, surface)
|
||||||
if tile then
|
if tile then
|
||||||
return tile, entity
|
return tile, entity
|
||||||
end
|
end
|
||||||
|
|
||||||
local n_below = n + 1
|
local n_below = n + 1
|
||||||
local rn_below = rn * r
|
local rn_below = rn * r
|
||||||
local rn2_below = 1 / rn_below
|
local rn2_below = 1 / rn_below
|
||||||
local c_below = size * rn_below
|
local c_below = size * rn_below
|
||||||
|
|
||||||
local sn_upper_below = sn_upper + c_below
|
local sn_upper_below = sn_upper + c_below
|
||||||
local x_below = local_x * rn2_below
|
local x_below = local_x * rn2_below
|
||||||
local y_below = (local_y - (sn_upper_below - 0.5 * c_below) + offset) * rn2_below
|
local y_below = (local_y - (sn_upper_below - 0.5 * c_below) + offset) * rn2_below
|
||||||
|
|
||||||
return shape(x_below, y_below, world_x, world_y, surface)
|
return shape(x_below, y_below, world_x, world_y, surface)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ore generation.
|
-- ore generation.
|
||||||
|
|
||||||
-- builder is the shape of the ore patch.
|
-- builder is the shape of the ore patch.
|
||||||
function resource_module_builder(builder, resource_type, amount_function)
|
function resource_module_builder(builder, resource_type, amount_function)
|
||||||
amount_function = amount_function or function(a, b)
|
amount_function = amount_function or function(a, b)
|
||||||
return 603
|
return 603
|
||||||
end
|
end
|
||||||
return function(x, y, world_x, world_y, surface)
|
return function(x, y, world_x, world_y, surface)
|
||||||
if builder(x, y, world_x, world_y, surface) then
|
if builder(x, y, world_x, world_y, surface) then
|
||||||
return {
|
return {
|
||||||
@ -463,7 +470,6 @@ function builder_with_resource(land_builder, resource_module)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- pattern builders.
|
-- pattern builders.
|
||||||
|
|
||||||
function single_pattern_builder(shape, width, height)
|
function single_pattern_builder(shape, width, height)
|
||||||
shape = shape or empty_builder
|
shape = shape or empty_builder
|
||||||
local half_width = width / 2
|
local half_width = width / 2
|
||||||
@ -473,11 +479,11 @@ function single_pattern_builder(shape, width, height)
|
|||||||
else
|
else
|
||||||
half_height = half_width
|
half_height = half_width
|
||||||
end
|
end
|
||||||
|
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local_y = ((local_y + half_height) % height) - half_height
|
local_y = ((local_y + half_height) % height) - half_height
|
||||||
local_x = ((local_x + half_width) % width) - half_width
|
local_x = ((local_x + half_width) % width) - half_width
|
||||||
|
|
||||||
return shape(local_x, local_y, world_x, world_y, surface)
|
return shape(local_x, local_y, world_x, world_y, surface)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -491,11 +497,11 @@ function single_pattern_overlap_builder(shape, width, height)
|
|||||||
else
|
else
|
||||||
half_height = half_width
|
half_height = half_width
|
||||||
end
|
end
|
||||||
|
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local_y = ((local_y + half_height) % height) - half_height
|
local_y = ((local_y + half_height) % height) - half_height
|
||||||
local_x = ((local_x + half_width) % width) - half_width
|
local_x = ((local_x + half_width) % width) - half_width
|
||||||
|
|
||||||
return shape(local_x, local_y, world_x, world_y, surface) or
|
return shape(local_x, local_y, world_x, world_y, surface) or
|
||||||
shape(local_x + width, local_y, world_x, world_y, surface) or
|
shape(local_x + width, local_y, world_x, world_y, surface) or
|
||||||
shape(local_x - width, local_y, world_x, world_y, surface) or
|
shape(local_x - width, local_y, world_x, world_y, surface) or
|
||||||
@ -507,10 +513,10 @@ end
|
|||||||
function single_x_pattern_builder(shape, width)
|
function single_x_pattern_builder(shape, width)
|
||||||
shape = shape or empty_builder
|
shape = shape or empty_builder
|
||||||
local half_width = width / 2
|
local half_width = width / 2
|
||||||
|
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local_x = ((local_x + half_width) % width) - half_width
|
local_x = ((local_x + half_width) % width) - half_width
|
||||||
|
|
||||||
return shape(local_x, local_y, world_x, world_y, surface)
|
return shape(local_x, local_y, world_x, world_y, surface)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -518,10 +524,10 @@ end
|
|||||||
function single_y_pattern_builder(shape, height)
|
function single_y_pattern_builder(shape, height)
|
||||||
shape = shape or empty_builder
|
shape = shape or empty_builder
|
||||||
local half_height = height / 2
|
local half_height = height / 2
|
||||||
|
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local_y = ((local_y + half_height) % height) - half_height
|
local_y = ((local_y + half_height) % height) - half_height
|
||||||
|
|
||||||
return shape(local_x, local_y, world_x, world_y, surface)
|
return shape(local_x, local_y, world_x, world_y, surface)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -529,25 +535,68 @@ end
|
|||||||
function grid_pattern_builder(pattern, columns, rows, width, height)
|
function grid_pattern_builder(pattern, columns, rows, width, height)
|
||||||
local half_width = width / 2
|
local half_width = width / 2
|
||||||
local half_height = height / 2
|
local half_height = height / 2
|
||||||
|
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local local_y2 = ((local_y + half_height) % height) - half_height
|
local local_y2 = ((local_y + half_height) % height) - half_height
|
||||||
local row_pos = math.floor(local_y / height + 0.5)
|
local row_pos = math.floor(local_y / height + 0.5)
|
||||||
local row_i = row_pos % rows + 1
|
local row_i = row_pos % rows + 1
|
||||||
local row = pattern[row_i] or {}
|
local row = pattern[row_i] or {}
|
||||||
|
|
||||||
local local_x2 = ((local_x + half_width) % width) - half_width
|
local local_x2 = ((local_x + half_width) % width) - half_width
|
||||||
local col_pos = math.floor(local_x / width + 0.5)
|
local col_pos = math.floor(local_x / width + 0.5)
|
||||||
local col_i = col_pos % columns + 1
|
local col_i = col_pos % columns + 1
|
||||||
|
|
||||||
local shape = row[col_i] or empty_builder
|
local shape = row[col_i] or empty_builder
|
||||||
return shape(local_x2, local_y2, world_x, world_y, surface)
|
return shape(local_x2, local_y2, world_x, world_y, surface)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function grid_pattern_overlap_builder(pattern, columns, rows, width, height)
|
||||||
|
local half_width = width / 2
|
||||||
|
local half_height = height / 2
|
||||||
|
|
||||||
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
|
local local_y2 = ((local_y + half_height) % height) - half_height
|
||||||
|
local row_pos = math.floor(local_y / height + 0.5)
|
||||||
|
local row_i = row_pos % rows + 1
|
||||||
|
local row = pattern[row_i] or {}
|
||||||
|
|
||||||
|
local local_x2 = ((local_x + half_width) % width) - half_width
|
||||||
|
local col_pos = math.floor(local_x / width + 0.5)
|
||||||
|
local col_i = col_pos % columns + 1
|
||||||
|
|
||||||
|
local shape = row[col_i] or empty_builder
|
||||||
|
|
||||||
|
local tile, entity = shape(local_x2, local_y2, world_x, world_y, surface)
|
||||||
|
if tile then return tile, entity end
|
||||||
|
|
||||||
|
local col_i_left = (col_pos - 1) % columns + 1
|
||||||
|
shape = row[col_i_left] or empty_builder
|
||||||
|
tile, entity = shape(local_x2 + width, local_y2, world_x, world_y, surface)
|
||||||
|
if tile then return tile, entity end
|
||||||
|
|
||||||
|
local col_i_right = (col_pos + 1) % columns + 1
|
||||||
|
shape = row[col_i_right] or empty_builder
|
||||||
|
tile, entity = shape(local_x2 - width, local_y2, world_x, world_y, surface)
|
||||||
|
if tile then return tile, entity end
|
||||||
|
|
||||||
|
local row_i_up = (row_pos - 1) % rows + 1
|
||||||
|
local row_up = pattern[row_i_up] or {}
|
||||||
|
shape = row_up[col_i]
|
||||||
|
tile, entity = shape(local_x2, local_y2 + height, world_x, world_y, surface)
|
||||||
|
if tile then return tile, entity end
|
||||||
|
|
||||||
|
local row_i_down = (row_pos + 1) % rows + 1
|
||||||
|
local row_down = pattern[row_i_down] or {}
|
||||||
|
shape = row_down[col_i]
|
||||||
|
tile, entity = shape(local_x2, local_y2 - height, world_x, world_y, surface)
|
||||||
|
if tile then return tile, entity end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function segment_pattern_builder(pattern)
|
function segment_pattern_builder(pattern)
|
||||||
local count = #pattern
|
local count = #pattern
|
||||||
|
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local angle = math.atan2(-local_y, local_x)
|
local angle = math.atan2(-local_y, local_x)
|
||||||
local index = math.floor(angle / tau * count) % count + 1
|
local index = math.floor(angle / tau * count) % count + 1
|
||||||
@ -557,7 +606,6 @@ function segment_pattern_builder(pattern)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- tile converters
|
-- tile converters
|
||||||
|
|
||||||
function change_tile(builder, old_tile, new_tile)
|
function change_tile(builder, old_tile, new_tile)
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
|
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
|
||||||
@ -624,6 +672,16 @@ function spawn_fish(builder, spawn_rate)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function spawn_entity(builder, name)
|
||||||
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
|
if builder(local_x, local_y, world_x, world_y, surface) then
|
||||||
|
return {name = name, position = {world_x, world_y}}
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function apply_effect(builder, func)
|
function apply_effect(builder, func)
|
||||||
return function(local_x, local_y, world_x, world_y, surface)
|
return function(local_x, local_y, world_x, world_y, surface)
|
||||||
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
|
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
|
||||||
|
Loading…
Reference in New Issue
Block a user