1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2025-09-16 09:16:22 +02:00

builder changes to allow multiple entities per tile

This commit is contained in:
grilledham
2018-05-07 12:18:18 +01:00
parent 91b864f58c
commit 094bfe8928
7 changed files with 379 additions and 258 deletions

View File

@@ -5,15 +5,15 @@ map_gen_rows_per_tick = 8 -- Inclusive integer between 1 and 32. Used for map_ge
--require "map_gen.shared.generate_not_threaded"
require "map_gen.shared.generate"
local function no_resources(x, y, world_x, world_y, tile, entity, surface)
local function no_resources(x, y, world_x, world_y, tile, surface)
for _, e in ipairs(surface.find_entities_filtered({type = "resource", area = {{world_x, world_y}, {world_x + 1, world_y + 1}}})) do
e.destroy()
end
return tile, entity
return tile
end
local function less_resources(x, y, world_x, world_y, tile, entity, surface)
local function less_resources(x, y, world_x, world_y, tile, surface)
for _, e in ipairs(surface.find_entities_filtered({type = "resource", area = {{world_x, world_y}, {world_x + 1, world_y + 1}}})) do
if e.name == "crude-oil" then
-- e.amount = .995 * e.amount
@@ -22,15 +22,15 @@ local function less_resources(x, y, world_x, world_y, tile, entity, surface)
end
end
return tile, entity
return tile
end
local function no_enemies(x, y, world_x, world_y, tile, entity, surface)
local function no_enemies(x, y, world_x, world_y, tile, surface)
for _, e in ipairs(surface.find_entities_filtered({force = "enemy", position = {world_x, world_y}})) do
e.destroy()
end
return tile, entity
return tile
end
local small_dot = circle_builder(96)

View File

@@ -8,12 +8,12 @@ local function value(base, mult)
end
end
local function no_resources(x, y, world_x, world_y, tile, entity, surface)
local function no_resources(x, y, world_x, world_y, tile, surface)
for _, e in ipairs(surface.find_entities_filtered({ type = "resource", area = {{world_x, world_y }, {world_x + 1, world_y + 1 } } })) do
e.destroy()
end
return tile, entity
return tile
end
local arm1 = translate(rectangle_builder(2, 3), 0, -5)

View File

@@ -54,7 +54,7 @@ end
local init = false
local safe_distance = 480
local function effect(x, y, world_x, world_y, tile, entity, surface)
local function effect(x, y, world_x, world_y, tile, surface)
if not init then
init = true
@@ -107,7 +107,7 @@ local function effect(x, y, world_x, world_y, tile, entity, surface)
end
--]]
return tile, entity
return tile
end
map = apply_effect(map, effect)

13
map_gen/presets/test.lua Normal file
View File

@@ -0,0 +1,13 @@
require "map_gen.shared.generate"
local land = rectangle_builder(32,16)
local circle = circle_builder(4)
local patch = resource_module_builder(circle, "iron-ore")
local tree = spawn_entity(circle, "tree-01")
local shape = builder_with_resource(land, patch)
return shape

View File

@@ -5,9 +5,25 @@ function degrees(angle)
return angle * deg_to_rad
end
function get_tile(tile)
if type(tile) == "table" then
return tile.tile
else
return tile
end
end
function add_entity(tile, entity)
if tile.entities then
table.insert(tile.entities, entity)
else
tile.entities = {entity}
end
end
-- shape builders
function empty_builder()
return false
return nil
end
function full_builder()
@@ -16,7 +32,7 @@ end
function tile_builder(tile)
return function()
return tile;
return tile
end
end
@@ -98,7 +114,7 @@ function sine_fill_builder(width, height)
return y2 < math.sin(x2)
else
return y2 > math.sin(x2)
end
end
end
end
@@ -142,9 +158,9 @@ function decompress(pic)
local data = pic.data
local width = pic.width
local height = pic.height
local uncompressed = {}
for y = 1, height do
local row = data[y]
local u_row = {}
@@ -153,14 +169,14 @@ function decompress(pic)
for index = 1, #row, 2 do
local pixel = tile_map[row[index]]
local count = row[index + 1]
for i = 1, count do
u_row[x] = pixel
x = x + 1
end
end
end
return {width = width, height = height, data = uncompressed}
end
@@ -168,7 +184,7 @@ function picture_builder(pic)
local data = pic.data
local width = pic.width
local height = pic.height
-- the plus one is because lua tables are one based.
local half_width = math.floor(width / 2) + 1
local half_height = math.floor(height / 2) + 1
@@ -177,12 +193,9 @@ function picture_builder(pic)
y = math.floor(y)
local x2 = x + half_width
local y2 = y + half_height
if y2 > 0 and y2 <= height and x2 > 0 and x2 <= width then
local pixel = data[y2][x2]
return pixel
else
return false
return data[y2][x2]
end
end
end
@@ -212,13 +225,6 @@ function rotate(builder, angle)
end
end
function scale_rotate_translate(builder, x_scale, y_scale, angle, x_offset, y_offset)
local transform = translate(rotate(scale(builder, x_scale, y_scale), angle), x_offset, y_offset)
return function(x, y, world_x, world_y, surface)
return transform(x, y, world_x, world_y, surface)
end
end
function flip_x(builder)
return function(x, y, world_x, world_y, surface)
return builder(-x, y, world_x, world_y, surface)
@@ -241,31 +247,33 @@ end
function compound_or(builders)
return function(x, y, world_x, world_y, surface)
for _, v in ipairs(builders) do
local tile, entity = v(x, y, world_x, world_y, surface)
local tile = v(x, y, world_x, world_y, surface)
if tile then
return tile, entity
return tile
end
end
return false
return nil
end
end
-- Wont work correctly with resource_module_builder becasues I don't know which one to return.
function compound_and(builders)
return function(x, y, world_x, world_y, surface)
local tile
for _, v in ipairs(builders) do
if not v(x, y, world_x, world_y, surface) then
return false
tile = v(x, y, world_x, world_y, surface)
if not tile then
return nil
end
end
return true
return tile
end
end
function invert(builder)
return function(x, y, world_x, world_y, surface)
local tile, entity = builder(x, y, world_x, world_y, surface)
return not tile, entity
local tile = builder(x, y, world_x, world_y, surface)
return not tile
end
end
@@ -274,7 +282,7 @@ function throttle_x(builder, x_in, x_size)
if x % x_size < x_in then
return builder(x, y, world_x, world_y, surface)
else
return false
return nil
end
end
end
@@ -284,7 +292,7 @@ function throttle_y(builder, y_in, y_size)
if y % y_size < y_in then
return builder(x, y, world_x, world_y, surface)
else
return false
return nil
end
end
end
@@ -294,7 +302,7 @@ function throttle_xy(builder, x_in, x_size, y_in, y_size)
if x % x_size < x_in and y % y_size < y_in then
return builder(x, y, world_x, world_y, surface)
else
return false
return nil
end
end
end
@@ -304,7 +312,7 @@ function throttle_xy(builder, x_in, x_size, y_in, y_size)
if x % x_size < x_in and y % y_size < y_in then
return builder(x, y, world_x, world_y, surface)
else
return false
return nil
end
end
end
@@ -314,7 +322,7 @@ function throttle_world_xy(builder, x_in, x_size, y_in, y_size)
if world_x % x_size < x_in and world_y % y_size < y_in then
return builder(x, y, world_x, world_y, surface)
else
return false
return nil
end
end
end
@@ -331,12 +339,8 @@ 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
return shape(local_x, local_y, world_x, world_y, surface) or
else_shape(local_x, local_y, world_x, world_y, surface)
end
end
@@ -347,10 +351,10 @@ function linear_grow(shape, size)
local n = math.ceil((math.sqrt(8 * t + 1) - 1) / 2)
local t_upper = n * (n + 1) * 0.5
local t_lower = t_upper - n
local y = (local_y - size * (t_lower + n / 2 - 0.5)) / n
local x = local_x / n
return shape(x, y, world_x, world_y, surface)
end
end
@@ -361,25 +365,22 @@ function grow(in_shape, out_shape, size, offset)
local tx = math.ceil(math.abs(local_x) / half_size)
local ty = math.ceil(math.abs(local_y) / half_size)
local t = math.max(tx, ty)
local tile, entity
for i = t, 2.5 * t, 1 do
local out_t = 1 / (i - offset)
local in_t = 1 / i
tile = out_shape(out_t * local_x, out_t * local_y, world_x, world_y, surface)
if tile then
return false
if out_shape(out_t * local_x, out_t * local_y, world_x, world_y, surface) then
return nil
end
tile, entity = in_shape(in_t * local_x, in_t * local_y, world_x, world_y, surface)
local tile = in_shape(in_t * local_x, in_t * local_y, world_x, world_y, surface)
if tile then
return tile, entity
return tile
end
end
return false
return nil
end
end
@@ -387,20 +388,20 @@ function project(shape, size, r)
local ln_r = math.log(r)
local r2 = 1 / (r - 1)
local a = 1 / size
return function(local_x, local_y, world_x, world_y, surface)
local offset = 0.5 * size
local sn = math.ceil(local_y + offset)
local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1)
local rn = r ^ n
local rn2 = 1 / rn
local c = size * rn
local sn_upper = size * (r ^ (n + 1) - 1) * r2
local x = local_x * rn2
local y = (local_y - (sn_upper - 0.5 * c) + offset) * rn2
return shape(x, y, world_x, world_y, surface)
end
end
@@ -410,50 +411,49 @@ function project_overlap(shape, size, r)
local r2 = 1 / (r - 1)
local a = 1 / size
local offset = 0.5 * size
return function(local_x, local_y, world_x, world_y, surface)
local sn = math.ceil(local_y + offset)
local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1)
local rn = r ^ n
local rn2 = 1 / rn
local c = size * rn
local sn_upper = size * (r ^ (n + 1) - 1) * r2
local x = local_x * rn2
local y = (local_y - (sn_upper - 0.5 * c) + offset) * rn2
local tile
local entity
tile, entity = shape(x, y, world_x, world_y, surface)
tile = shape(x, y, world_x, world_y, surface)
if tile then
return tile, entity
return tile
end
local n_above = n - 1
local rn_above = rn / r
local rn2_above = 1 / rn_above
local c_above = size * rn_above
local sn_upper_above = sn_upper - c
local x_above = local_x * 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 = shape(x_above, y_above, world_x, world_y, surface)
if tile then
return tile, entity
return tile
end
local n_below = n + 1
local rn_below = rn * r
local rn2_below = 1 / rn_below
local c_below = size * rn_below
local sn_upper_below = sn_upper + c_below
local x_below = local_x * 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)
end
end
@@ -461,7 +461,9 @@ end
-- ore generation.
-- builder is the shape of the ore patch.
function resource_module_builder(builder, resource_type, amount_function)
amount_function = amount_function or function(a, b) return 603 end
amount_function = amount_function or function(a, b)
return 404
end
return function(x, y, world_x, world_y, surface)
if builder(x, y, world_x, world_y, surface) then
return {
@@ -480,9 +482,12 @@ function builder_with_resource(land_builder, resource_module)
local tile = land_builder(x, y, world_x, world_y, surface)
if tile then
local entity = resource_module(x, y, world_x, world_y, surface)
return tile, entity
return {
tile = tile,
entities = {entity}
}
else
return false
return nil
end
end
end
@@ -497,11 +502,11 @@ function single_pattern_builder(shape, width, height)
else
half_height = half_width
end
return function(local_x, local_y, world_x, world_y, surface)
local_y = ((local_y + half_height) % height) - half_height
local_x = ((local_x + half_width) % width) - half_width
return shape(local_x, local_y, world_x, world_y, surface)
end
end
@@ -515,11 +520,11 @@ function single_pattern_overlap_builder(shape, width, height)
else
half_height = half_width
end
return function(local_x, local_y, world_x, world_y, surface)
local_y = ((local_y + half_height) % height) - half_height
local_x = ((local_x + half_width) % width) - half_width
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
@@ -531,10 +536,10 @@ end
function single_x_pattern_builder(shape, width)
shape = shape or empty_builder
local half_width = width / 2
return function(local_x, local_y, world_x, world_y, surface)
local_x = ((local_x + half_width) % width) - half_width
return shape(local_x, local_y, world_x, world_y, surface)
end
end
@@ -542,10 +547,10 @@ end
function single_y_pattern_builder(shape, height)
shape = shape or empty_builder
local half_height = height / 2
return function(local_x, local_y, world_x, world_y, surface)
local_y = ((local_y + half_height) % height) - half_height
return shape(local_x, local_y, world_x, world_y, surface)
end
end
@@ -553,17 +558,17 @@ end
function grid_pattern_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
return shape(local_x2, local_y2, world_x, world_y, surface)
end
@@ -572,39 +577,47 @@ 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 tile = shape(local_x2, local_y2, world_x, world_y, surface)
if tile then
return tile
end
-- edges
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
tile = shape(local_x2 + width, local_y2, world_x, world_y, surface)
if tile then
return tile
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
tile = shape(local_x2 - width, local_y2, world_x, world_y, surface)
if tile then
return tile
end
local row_i_up = (row_pos - 1) % rows + 1
local row_up = pattern[row_i_up] or {}
shape = row_up[col_i] or empty_builder
tile, entity = shape(local_x2, local_y2 + height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(local_x2, local_y2 + height, world_x, world_y, surface)
if tile then
return tile
end
local row_i_down = (row_pos + 1) % rows + 1
local row_down = pattern[row_i_down] or {}
shape = row_down[col_i] or empty_builder
@@ -615,58 +628,74 @@ end
function grid_pattern_full_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 row_i_up = (row_pos - 1) % rows + 1
local row_up = pattern[row_i_up] or {}
local row_i_down = (row_pos + 1) % rows + 1
local row_down = pattern[row_i_down] or {}
local col_i_left = (col_pos - 1) % columns + 1
local col_i_right = (col_pos + 1) % columns + 1
-- start from top left, move left to right then down
local shape = row_up[col_i_left] or empty_builder
local tile, entity = shape(local_x2 + width, local_y2 + height, world_x, world_y, surface)
if tile then return tile, entity end
local tile = shape(local_x2 + width, local_y2 + height, world_x, world_y, surface)
if tile then
return tile
end
shape = row_up[col_i] or empty_builder
tile, entity = shape(local_x2, local_y2 + height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(local_x2, local_y2 + height, world_x, world_y, surface)
if tile then
return tile
end
shape = row_up[col_i_right] or empty_builder
tile, entity = shape(local_x2 - width, local_y2 + height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(local_x2 - width, local_y2 + height, world_x, world_y, surface)
if tile then
return tile
end
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
tile = shape(local_x2 + width, local_y2, world_x, world_y, surface)
if tile then
return tile
end
local shape = row[col_i] or empty_builder
tile, entity = shape(local_x2, local_y2, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(local_x2, local_y2, world_x, world_y, surface)
if tile then
return tile
end
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
tile = shape(local_x2 - width, local_y2, world_x, world_y, surface)
if tile then
return tile
end
shape = row_down[col_i_left] or empty_builder
tile, entity = shape(local_x2 + width, local_y2 - height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(local_x2 + width, local_y2 - height, world_x, world_y, surface)
if tile then
return tile
end
shape = row_down[col_i] or empty_builder
tile, entity = shape(local_x2, local_y2 - height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(local_x2, local_y2 - height, world_x, world_y, surface)
if tile then
return tile
end
shape = row_down[col_i_right] or empty_builder
return shape(local_x2 - width, local_y2 - height, world_x, world_y, surface)
end
@@ -674,7 +703,7 @@ end
function segment_pattern_builder(pattern)
local count = #pattern
return function(local_x, local_y, world_x, world_y, surface)
local angle = math.atan2(-local_y, local_x)
local index = math.floor(angle / tau * count) % count + 1
@@ -686,41 +715,40 @@ end
function pyramid_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 {}
if row_pos % 2 ~= 0 then
local_x = local_x - half_width
end
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
if col_pos > row_pos / 2 or -col_pos > (row_pos + 1) / 2 then
return false
end
local shape = row[col_i] or empty_builder
return shape(local_x2, local_y2, world_x, world_y, surface)
end
end
function pyramid_inner_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 x_odd
local x_even
if row_pos % 2 == 0 then
@@ -730,13 +758,11 @@ function pyramid_inner_overlap_builder(pattern, columns, rows, width, height)
x_even = local_x - half_width
x_odd = local_x
local_x = local_x - half_width
end
end
x_even = ((x_even + half_width) % width) - half_width
x_odd = ((x_odd + half_width) % width) - half_width
local col_pos = math.floor(local_x / width + 0.5)
local offset = 1
@@ -746,58 +772,73 @@ function pyramid_inner_overlap_builder(pattern, columns, rows, width, height)
offset_odd = 1
end
local col_i = (col_pos - offset) % columns + 1
local col_i_odd = (col_pos - offset_odd) % columns + 1
if col_pos > row_pos / 2 or -col_pos > (row_pos + 1) / 2 then
return false
end
local row_i_up = (row_pos - 1) % rows + 1
local row_up = pattern[row_i_up] or {}
local row_i_down = (row_pos + 1) % rows + 1
local row_down = pattern[row_i_down] or {}
local col_i_left = (col_pos - 1) % columns + 1
local col_i_right = (col_pos + 1) % columns + 1
local col_i_left2 = (col_pos - 2) % columns + 1
local col_i_right2 = (col_pos + 0) % columns + 1
-- start from top left, move left to right then down
local shape = row_up[col_i_left] or empty_builder
local tile, entity = shape(x_even + width, local_y2 + height, world_x, world_y, surface)
if tile then return tile, entity end
local tile = shape(x_even + width, local_y2 + height, world_x, world_y, surface)
if tile then
return tile
end
shape = row_up[col_i_odd] or empty_builder
tile, entity = shape(x_odd, local_y2 + height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(x_odd, local_y2 + height, world_x, world_y, surface)
if tile then
return tile
end
shape = row_up[col_i_right] or empty_builder
tile, entity = shape(x_even - width, local_y2 + height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(x_even - width, local_y2 + height, world_x, world_y, surface)
if tile then
return tile
end
shape = row[col_i_left] or empty_builder
tile, entity = shape(x_even + width, local_y2, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(x_even + width, local_y2, world_x, world_y, surface)
if tile then
return tile
end
local shape = row[col_i] or empty_builder
tile, entity = shape(x_even, local_y2, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(x_even, local_y2, world_x, world_y, surface)
if tile then
return tile
end
shape = row[col_i_right] or empty_builder
tile, entity = shape(x_even - width, local_y2, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(x_even - width, local_y2, world_x, world_y, surface)
if tile then
return tile
end
shape = row_down[col_i_left] or empty_builder
tile, entity = shape(x_even + width, local_y2 - height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(x_even + width, local_y2 - height, world_x, world_y, surface)
if tile then
return tile
end
shape = row_down[col_i_odd] or empty_builder
tile, entity = shape(x_odd, local_y2 - height, world_x, world_y, surface)
if tile then return tile, entity end
tile = shape(x_odd, local_y2 - height, world_x, world_y, surface)
if tile then
return tile
end
shape = row_down[col_i_right] or empty_builder
return shape(x_even - width, local_y2 - height, world_x, world_y, surface)
end
@@ -806,20 +847,20 @@ end
function grid_pattern_offset_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 local_y2 = local_y2 + height * math.floor((row_pos + 1) / rows)
local local_x2 = local_x2 + width * math.floor((col_pos + 1) / columns)
local shape = row[col_i] or empty_builder
return shape(local_x2, local_y2, world_x, world_y, surface)
end
@@ -828,67 +869,128 @@ end
-- tile converters
function change_tile(builder, old_tile, new_tile)
return function(local_x, local_y, world_x, world_y, surface)
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
if tile == old_tile then
tile = new_tile
local tile = builder(local_x, local_y, world_x, world_y, surface)
if type(tile) == "table" then
if tile.tile == old_tile then
tile.tile = new_tile
return tile
end
else
if tile == old_tile then
return new_tile
end
end
return tile, entity
end
end
function change_collision_tile(builder, collides, new_tile)
return function(local_x, local_y, world_x, world_y, surface)
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
if tile.collides_with(collides) then
tile = new_tile
local tile = builder(local_x, local_y, world_x, world_y, surface)
if type(tile) == "table" then
if tile.tile.collides_with(collides) then
tile.tile = new_tile
return tile
end
else
if tile.collides_with(collides) then
return new_tile
end
end
return tile, entity
end
end
-- only changes tiles made by the factorio map generator.
function change_map_gen_tile(builder, old_tile, new_tile)
return function(local_x, local_y, world_x, world_y, surface)
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
if type(tile) == "boolean" and tile then
local gen_tile = surface.get_tile(world_x, world_y).name
if old_tile == gen_tile then
tile = new_tile
local tile = builder(local_x, local_y, world_x, world_y, surface)
if type(tile) == "table" then
if type(tile.tile) == "boolean" and tile.tile then
local gen_tile = surface.get_tile(world_x, world_y).name
if old_tile == gen_tile then
tile.tile = new_tile
return tile
end
end
else
if type(tile) == "boolean" and tile then
local gen_tile = surface.get_tile(world_x, world_y).name
if old_tile == gen_tile then
return new_tile
end
end
end
return tile, entity
end
end
-- only changes tiles made by the factorio map generator.
function change_map_gen_collision_tile(builder, collides, new_tile)
return function(local_x, local_y, world_x, world_y, surface)
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
if type(tile) == "boolean" and tile then
local gen_tile = surface.get_tile(world_x, world_y)
if gen_tile.collides_with(collides) then
tile = new_tile
local tile = builder(local_x, local_y, world_x, world_y, surface)
local function handle_tile(tile)
if type(tile) == "boolean" and tile then
local gen_tile = surface.get_tile(world_x, world_y)
if gen_tile.collides_with(collides) then
return new_tile
end
end
return tile
end
return tile, entity
if type(tile) == "table" then
tile.tile = handle_tile(tile.tile)
else
tile = handle_tile(tile)
end
return tile
end
end
local water_tiles = {
["water"] = true,
["deepwater"] = true,
["water-green"] = true,
["deepwater-green"] = true
}
function spawn_fish(builder, spawn_rate)
return function(local_x, local_y, world_x, world_y, surface)
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
if type(tile) == "string" then
if tile == "water" or tile == "deepwater" or tile == "water-green" or tile == "deepwater-green" then
if spawn_rate >= math.random() then
entity = {name = "fish", position = {world_x, world_y}}
local function handle_tile(tile)
if type(tile) == "string" then
if water_tiles[tile] and spawn_rate >= math.random() then
return {name = "fish", position = {world_x, world_y}}
end
elseif tile then
if surface.get_tile(world_x, world_y).collides_with("water-tile") and spawn_rate >= math.random() then
return {name = "fish", position = {world_x, world_y}}
end
end
elseif tile then
if surface.get_tile(world_x, world_y).collides_with("water-tile") and spawn_rate >= math.random() then
entity = {name = "fish", position = {world_x, world_y}}
return nil
end
local tile = builder(local_x, local_y, world_x, world_y, surface)
if type(tile) == "table" then
local entity = handle_tile(tile.tile)
if entity then
add_entity(tile, entity)
end
else
local entity = handle_tile(tile)
if entity then
tile = {
tile = tile,
entities = {entity}
}
end
end
return tile, entity
return tile
end
end
@@ -904,9 +1006,8 @@ end
function apply_effect(builder, func)
return function(local_x, local_y, world_x, world_y, surface)
local tile, entity = builder(local_x, local_y, world_x, world_y, surface)
tile, entity = func(local_x, local_y, world_x, world_y, tile, entity, surface)
return tile, entity
local tile = builder(local_x, local_y, world_x, world_y, surface)
return func(local_x, local_y, world_x, world_y, tile, surface)
end
end

View File

@@ -7,33 +7,39 @@ map_gen_rows_per_tick = map_gen_rows_per_tick or 4
map_gen_rows_per_tick = math.min(32, math.max(1, map_gen_rows_per_tick))
local function do_row(row, data)
local y = data.top_y + row
local top_x = data.top_x
for x = top_x, top_x + 31 do
-- local coords need to be 'centered' to allow for correct rotation and scaling.
local tile, entity = MAP_GEN(x + 0.5, y + 0.5, x, y, data.surface)
local function do_tile(tile, x, y)
if not tile then
table.insert(data.tiles, {name = "out-of-map", position = {x, y}})
elseif type(tile) == "string" then
table.insert(data.tiles, {name = tile, position = {x, y}})
end
if map_gen_decoratives then
tile_decoratives = check_decorative(tile, x, y)
for _, tbl in ipairs(tile_decoratives) do
table.insert(data.decoratives, tbl)
end
local y = data.top_y + row
local top_x = data.top_x
for x = top_x, top_x + 31 do
-- local coords need to be 'centered' to allow for correct rotation and scaling.
local tile = MAP_GEN(x + 0.5, y + 0.5, x, y, data.surface)
if type(tile) == "table" then
do_tile(tile.tile, x, y)
local entities = tile.entities
if entities then
for _, entity in ipairs(entities) do
table.insert(data.entities, entity)
end
end
tile_entities = check_entities(tile, x, y)
for _, entity in ipairs(tile_entities) do
table.insert(data.entities, entity)
local decoratives = tile.decoratives
if decoratives then
for _, decorative in ipairs(decoratives) do
table.insert(data.decoratives, decorative)
end
end
end
if entity then
table.insert(data.entities, entity)
else
do_tile(tile, x, y)
end
end
end
@@ -46,17 +52,17 @@ local function do_place_decoratives(data)
if not map_gen_decoratives then
return
end
for _, e in pairs(surface.find_entities_filtered{area = area, type = "decorative"}) do
for _, e in pairs(surface.find_entities_filtered {area = area, type = "decorative"}) do
e.destroy()
end
for _, e in pairs(surface.find_entities_filtered{area = area, type = "simple-entity"}) do
for _, e in pairs(surface.find_entities_filtered {area = area, type = "simple-entity"}) do
e.destroy()
end
local surface = data.surface
for _, d in pairs(data.decoratives) do
surface.create_decoratives{check_collision = false, decoratives = {d}}
surface.create_decoratives {check_collision = false, decoratives = {d}}
end
end
@@ -69,9 +75,9 @@ local function do_place_entities(data)
end
end
local function run_chart_update(data)
local x = data.top_x /32
local y = data.top_y /32
local function run_chart_update(data)
local x = data.top_x / 32
local y = data.top_y / 32
if game.forces.player.is_chunk_charted(data.surface, {x, y}) then
-- Don't use full area, otherwise adjacent chunks get charted
game.forces.player.chart(
@@ -80,7 +86,7 @@ local function run_chart_update(data)
{data.top_x, data.top_y},
{data.top_x + 1, data.top_y + 1}
}
)
)
end
end
@@ -113,9 +119,9 @@ function run_combined_module(event)
game.print("MAP_GEN not set")
return
end
local area = event.area
local data = {
state = 0,
top_x = area.left_top.x,
@@ -217,7 +223,7 @@ local decorative_options = {
local function check_decorative(tile, x, y)
local options = decorative_options[tile]
local tile_decoratives = {}
for _, e in ipairs(options) do
name = e[1]
high_roll = e[2]
@@ -225,7 +231,7 @@ local function check_decorative(tile, x, y)
table.insert(tile_decoratives, {name = name, amount = 1, position = {x, y}})
end
end
return tile_decoratives
end
@@ -322,7 +328,7 @@ local entity_options = {
function check_entities(tile, x, y)
local options = entity_options[tile]
local tile_entity_list = {}
for _, e in ipairs(options) do
name = e[1]
high_roll = e[2]
@@ -330,6 +336,6 @@ function check_entities(tile, x, y)
table.insert(tile_entity_list, {name = name, position = {x, y}})
end
end
return tile_entity_list
end

View File

@@ -50,12 +50,13 @@ local Event = require "utils.event"
--MAP_GEN = require "map_gen.presets.hearts"
--MAP_GEN = require "map_gen.presets.women"
--MAP_GEN = require "map_gen.presets.fractal_balls"
--MAP_GEN = require "map_gen.presets.fruit_loops"
MAP_GEN = require "map_gen.presets.fruit_loops"
--MAP_GEN = require "map_gen.presets.fish_islands"
--MAP_GEN = require "map_gen.presets.ContraSpiral"
--MAP_GEN = require "map_gen.presets.cookies"
--MAP_GEN = require "map_gen.presets.plus"
MAP_GEN = require "map_gen.presets.honeycomb"
--MAP_GEN = require "map_gen.presets.honeycomb"
--MAP_GEN = require "map_gen.presets.test"