diff --git a/config.lua b/config.lua index 52935178..a4429ba9 100644 --- a/config.lua +++ b/config.lua @@ -1,4 +1,4 @@ -_DEBUG = false +_DEBUG = true global.scenario = {} global.spys = {"valansch", "air20"} diff --git a/control.lua b/control.lua index 83bfa265..05e7337e 100644 --- a/control.lua +++ b/control.lua @@ -159,6 +159,17 @@ Event.add( local gui = player.gui gui.top.style = 'slot_table_spacing_horizontal_flow' - gui.left.style = 'slot_table_spacing_vertical_flow' + gui.left.style = 'slot_table_spacing_vertical_flow' end ) + +local direction_bit_mask = 0xc0000000 +local section_bit_mask = 0x30000000 +local level_bit_mask = 0x0fffffff +local direction_bit_shift = 30 +local section_bit_shift = 28 + +function get_direction(part) + local dir = bit32.band(part, direction_bit_mask) + return bit32.rshift(dir, direction_bit_shift - 1) +end diff --git a/map_gen/presets/crash_site.lua b/map_gen/presets/crash_site.lua index 83e3457b..d7eaef1a 100644 --- a/map_gen/presets/crash_site.lua +++ b/map_gen/presets/crash_site.lua @@ -1,27 +1,50 @@ +require('map_gen.presets.crash_site.blueprint_extractor') + local b = require 'map_gen.shared.builders' local Random = require 'map_gen.shared.random' local OutpostBuilder = require 'map_gen.presets.crash_site.outpost_builder' -local outpost_seed = 5000 +local outpost_seed = 1000 local outpost_blocks = 9 local outpost_variance = 3 local outpost_min_step = 2 local outpost_max_level = 4 +local striaght_wall = OutpostBuilder.make_4_way(require('map_gen.presets.crash_site.outpost_data.gun_turrent_straight')) +local outer_corner_wall = + OutpostBuilder.make_4_way(require('map_gen.presets.crash_site.outpost_data.gun_turrent_outer_corner')) +local inner_corner_wall = + OutpostBuilder.make_4_way(require('map_gen.presets.crash_site.outpost_data.gun_turret_inner_corner')) + +local templates = { + {striaght_wall, outer_corner_wall, inner_corner_wall}, + {[22] = {entity = {name = 'stone-furnace'}}}, + {[22] = {entity = {name = 'assembling-machine-2'}}}, + {[22] = {entity = {name = 'oil-refinery'}}} +} + local outpost_builder = OutpostBuilder.new(outpost_seed) +local shape = + outpost_builder:do_outpost(outpost_blocks, outpost_variance, outpost_min_step, outpost_max_level, templates) local pattern = {} +local grid_size = (outpost_blocks + 2) * 6 +local half_grid_size = grid_size * 0.5 for r = 1, 100 do local row = {} pattern[r] = row for c = 1, 100 do - row[c] = outpost_builder:do_outpost(outpost_blocks, outpost_variance, outpost_min_step, outpost_max_level) + local s = + outpost_builder:do_outpost(outpost_blocks, outpost_variance, outpost_min_step, outpost_max_level, templates) + s = b.translate(s, -half_grid_size, -half_grid_size) + row[c] = s end end -local outposts = b.grid_pattern(pattern, 100, 100, 20, 20) -local map = b.apply_entity(b.tile('grass-1'), outposts) +local outposts = b.grid_pattern(pattern, 100, 100, grid_size, grid_size) +local map = b.if_else(outposts, b.full_shape) +map = b.change_tile(map, true, 'grass-1') return map diff --git a/map_gen/presets/crash_site/blueprint_extractor.lua b/map_gen/presets/crash_site/blueprint_extractor.lua new file mode 100644 index 00000000..b3379c5b --- /dev/null +++ b/map_gen/presets/crash_site/blueprint_extractor.lua @@ -0,0 +1,197 @@ +local function get_mins(entities, tiles) + local min_x, min_y = math.huge, math.huge + + for _, e in ipairs(entities) do + local p = e.position + local x, y = p.x, p.y + + if x < min_x then + min_x = x + end + if y < min_y then + min_y = y + end + end + + for _, e in ipairs(tiles) do + local p = e.position + local x, y = p.x, p.y + + if x < min_x then + min_x = x + end + if y < min_y then + min_y = y + end + end + + return min_x, min_y +end + +local function output(result) + local str = {} + table.insert(str, 'return {\n') + + for i, entry in pairs(result) do + table.insert(str, '[') + table.insert(str, i) + table.insert(str, '] = {') + + local e = entry.entity + if e then + table.insert(str, 'entity = {') + + table.insert(str, "name = '") + table.insert(str, e.name) + table.insert(str, "'") + + local dir = e.direction + if dir then + table.insert(str, ', direction = ') + table.insert(str, dir) + end + + local offset = e.offset + if offset then + table.insert(str, ', offset = ') + table.insert(str, offset) + end + + table.insert(str, '}') + end + + local t = entry.tile + if t then + if e then + table.insert(str, ', ') + end + table.insert(str, "tile = '") + table.insert(str, t.name) + table.insert(str, "'") + end + + table.insert(str, '}') + table.insert(str, ',\n') + end + table.remove(str) + + table.insert(str, '\n}') + + str = table.concat(str) + + game.write_file('bp.lua', str) +end + +function extract1(size) + local cs = game.player.cursor_stack + + if not (cs.valid_for_read and cs.name == 'blueprint' and cs.is_blueprint_setup()) then + game.print('invalid blueprint') + return + end + + size = size or 6 + + local es = cs.get_blueprint_entities() or {} + local ts = cs.get_blueprint_tiles() or {} + + local min_x, min_y = get_mins(es, ts) + + min_x = 1 - math.ceil(min_x) + min_y = 1 - math.ceil(min_y) + + local result = {} + for _, e in ipairs(es) do + local p = e.position + local x, y = p.x + min_x, p.y + min_y + local x2, y2 = math.ceil(x), math.ceil(y) + local i = (y2 - 1) * size + x2 + + local entry = result[i] + if not entry then + entry = {} + result[i] = entry + end + + entry.entity = e + end + + for _, e in ipairs(ts) do + local p = e.position + local x, y = p.x + min_x, p.y + min_y + x, y = math.ceil(x), math.ceil(y) + local i = (y - 1) * size + x + + local entry = result[i] + if not entry then + entry = {} + result[i] = entry + end + + entry.tile = e + end + output(result) +end + +function extract4(size) + local cs = game.player.cursor_stack + + if not (cs.valid_for_read and cs.name == 'blueprint' and cs.is_blueprint_setup()) then + game.print('invalid blueprint') + return + end + + size = size or 6 + + local es = cs.get_blueprint_entities() or {} + local ts = cs.get_blueprint_tiles() or {} + + local min_x, min_y = get_mins(es, ts) + + min_x = 1 - math.floor(min_x) + min_y = 1 - math.floor(min_y) + + local result = {} + for _, e in ipairs(es) do + local p = e.position + local x, y = p.x + min_x, p.y + min_y + local x2, y2 = math.floor(x), math.floor(y) + local i = (y2 - 1) * size + x2 + + local offset = 0 + if x2 ~= x then + offset = offset + 1 + end + if y2 ~= y then + offset = offset + 2 + end + + if offset ~= 0 then + e.offset = offset + end + + local entry = result[i] + if not entry then + entry = {} + result[i] = entry + end + + entry.entity = e + end + + for _, e in ipairs(ts) do + local p = e.position + local x, y = p.x + min_x, p.y + min_y + x, y = math.ceil(x), math.ceil(y) + local i = (y - 1) * size + x + + local entry = result[i] + if not entry then + entry = {} + result[i] = entry + end + + entry.tile = e + end + output(result) +end diff --git a/map_gen/presets/crash_site/outpost_builder.lua b/map_gen/presets/crash_site/outpost_builder.lua index d9f535e4..d3308945 100644 --- a/map_gen/presets/crash_site/outpost_builder.lua +++ b/map_gen/presets/crash_site/outpost_builder.lua @@ -1,5 +1,6 @@ local Random = require 'map_gen.shared.random' local Token = require 'utils.global_token' +local b = require 'map_gen.shared.builders' local direction_bit_mask = 0xc0000000 local section_bit_mask = 0x30000000 @@ -25,11 +26,19 @@ local wall_east_inner = 0x60000001 local wall_south_inner = 0xa0000001 local wall_west_inner = 0xe0000001 +local part_size = 6 +local inv_part_size = 1 / part_size + local function get_direction(part) local dir = bit32.band(part, direction_bit_mask) return bit32.rshift(dir, direction_bit_shift - 1) end +local function get_4_way_direction(part) + local dir = bit32.band(part, direction_bit_mask) + return bit32.rshift(dir, direction_bit_shift) +end + local function get_section(part) local sec = bit32.band(part, section_bit_mask) return bit32.rshift(sec, section_bit_shift) @@ -91,7 +100,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) elseif pv == -1 then blocks[i] = wall_north_outer else - blocks[i] = wall_north_inner + blocks[i] = wall_east_inner end x = x + 1 @@ -110,7 +119,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) pv = 0 elseif y < ty then pv = 1 - blocks[i] = wall_north_outer + blocks[i] = wall_east_outer y = y + 1 i = i + size while y < ty do @@ -143,7 +152,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) if pv == 0 then blocks[i] = wall_east_straight elseif pv == -1 then - blocks[i] = wall_east_inner + blocks[i] = wall_south_inner else blocks[i] = wall_east_outer end @@ -174,7 +183,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) end else pv = -1 - blocks[i] = wall_east_outer + blocks[i] = wall_south_outer x = x - 1 i = i - 1 while x > tx do @@ -198,7 +207,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) if pv == 0 then blocks[i] = wall_south_straight elseif pv == -1 then - blocks[i] = wall_south_inner + blocks[i] = wall_west_inner else blocks[i] = wall_south_outer end @@ -229,7 +238,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) end else pv = -1 - blocks[i] = wall_south_outer + blocks[i] = wall_west_outer y = y - 1 i = i - size while y > ty do @@ -255,7 +264,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) elseif pv == -1 then blocks[i] = wall_west_outer else - blocks[i] = wall_west_inner + blocks[i] = wall_north_inner end y = y - 1 @@ -316,7 +325,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) pv = 0 elseif x < start_x then pv = 1 - blocks[i] = wall_west_outer + blocks[i] = wall_north_outer x = x + 1 i = i + 1 while x < start_x do @@ -341,7 +350,7 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step) elseif pv == -1 then blocks[i] = wall_west_outer else - blocks[i] = wall_west_inner + blocks[i] = wall_north_inner end y = y - 1 @@ -483,53 +492,132 @@ local callback = end ) -function Public:do_outpost(outpost_blocks, outpost_variance, outpost_min_step, max_level) +local function outpost_shape(templates, blocks) + local walls = templates[1] or {} + local size = blocks.size + + return function(x, y) + x, y = math.floor(x), math.floor(y) + local x2, y2 = math.floor(x * inv_part_size), math.floor(y * inv_part_size) + if x2 < 1 or x2 > size or y2 < 1 or y2 > size then + return true + end + + local block = blocks[(y2 - 1) * size + x2] + if not block then + return true + end + + local level = get_level(block) + + local x3, y3 = x - x2 * part_size + 1, y - y2 * part_size + 1 + + local i = (y3 - 1) * part_size + x3 + + if level == 1 then + local section = get_section(block) + + local dir = get_4_way_direction(block) + local lookup = dir + 1 + + local wall = walls[section + 1] + + if not wall then + return true + end + + local entry = wall[lookup][i] + + if not entry then + return true + end + + local tile = entry.tile or true + local entity = entry.entity + + if entity then + local e_dir = (dir * 2 + (entry.direction or 0)) % 8 + return {tile = tile, entities = {{name = entity.name, direction = e_dir}}} + end + + return tile + else + local template = templates[level] + if not template then + return true + end + + local entry = template[i] + if not entry then + return + end + + local entity = entry.entity + local tile = entry.tile or true + if entity then + return {tile = tile, entities = {{name = entity.name, direction = entity.direction}}} + end + return tile + end + end +end + +function Public:do_outpost(outpost_blocks, outpost_variance, outpost_min_step, max_level, templates) local blocks = {size = outpost_blocks} do_walls(self, blocks, outpost_variance, outpost_min_step) fill(blocks) do_levels(blocks, max_level) - local size = blocks.size + return outpost_shape(templates, blocks) +end - return function(x, y) - x, y = math.floor(x), math.floor(y) - if x < 1 or x > size or y < 1 or y > size then - return +function Public.make_4_way(data) + local north = {} + local east = {} + local south = {} + local west = {} + local res = {north, east, south, west} + + for i, entry in pairs(data) do + local y = math.ceil(i * inv_part_size) + local x = i - (y - 1) * part_size + + local e = entry.entity + local offset = e.offset + + local x2, x3, x4, y2, y3, y4 + + x2 = part_size - y + 1 + y2 = x + x3 = part_size - x + 1 + y3 = part_size - y + 1 + x4 = y + y4 = part_size - x + 1 + + local i2 = (y2 - 1) * part_size + x2 + local i3 = (y3 - 1) * part_size + x3 + local i4 = (y4 - 1) * part_size + x4 + + if offset == 3 then + i = i + 7 + i2 = i2 + 6 + i4 = i4 + 1 + elseif offset == 1 then + i = i + 1 + i4 = i4 + 1 + elseif offset == 2 then + i = i + 6 + i2 = i2 + 6 end - local part = blocks[(y - 1) * blocks.size + x] - - if part then - local direction = get_direction(part) - local section = get_section(part) - local level = get_level(part) - - local name - if level == 2 then - name = 'wooden-chest' - elseif level == 3 then - name = 'iron-chest' - elseif level == 4 then - name = 'steel-chest' - elseif level > 4 then - name = 'pipe' - elseif level < 1 then - name = 'small-electric-pole' - else - if section == section_straight then - name = 'stone-wall' - elseif section == section_outer_corner then - name = 'inserter' - elseif section == section_inner_corner then - name = 'transport-belt' - else - name = 'pipe' - end - end - return {name = name, force = 'player', direction = direction, callback = callback} - end + north[i] = entry + east[i2] = entry + south[i3] = entry + west[i4] = entry end + + return res end return Public diff --git a/map_gen/presets/crash_site/outpost_data/gun_turrent_outer_corner.lua b/map_gen/presets/crash_site/outpost_data/gun_turrent_outer_corner.lua new file mode 100644 index 00000000..4eda5e2c --- /dev/null +++ b/map_gen/presets/crash_site/outpost_data/gun_turrent_outer_corner.lua @@ -0,0 +1,23 @@ +return { + [1] = {entity = {name = 'stone-wall'}}, + [2] = {entity = {name = 'stone-wall'}}, + [3] = {entity = {name = 'stone-wall'}}, + [4] = {entity = {name = 'stone-wall'}}, + [5] = {entity = {name = 'stone-wall'}}, + [6] = {entity = {name = 'stone-wall'}}, + [7] = {entity = {name = 'stone-wall'}}, + [8] = {entity = {name = 'stone-wall'}}, + [9] = {entity = {name = 'stone-wall'}}, + [10] = {entity = {name = 'stone-wall'}}, + [11] = {entity = {name = 'stone-wall'}}, + [12] = {entity = {name = 'stone-wall'}}, + [13] = {entity = {name = 'stone-wall'}}, + [14] = {entity = {name = 'stone-wall'}}, + [19] = {entity = {name = 'stone-wall'}}, + [20] = {entity = {name = 'stone-wall'}}, + [22] = {entity = {name = 'gun-turret', offset = 3}}, + [25] = {entity = {name = 'stone-wall'}}, + [26] = {entity = {name = 'stone-wall'}}, + [31] = {entity = {name = 'stone-wall'}}, + [32] = {entity = {name = 'stone-wall'}} + } diff --git a/map_gen/presets/crash_site/outpost_data/gun_turrent_straight.lua b/map_gen/presets/crash_site/outpost_data/gun_turrent_straight.lua new file mode 100644 index 00000000..2aeaffb1 --- /dev/null +++ b/map_gen/presets/crash_site/outpost_data/gun_turrent_straight.lua @@ -0,0 +1,16 @@ +return { + [1] = {entity = {name = 'stone-wall'}}, + [2] = {entity = {name = 'stone-wall'}}, + [3] = {entity = {name = 'stone-wall'}}, + [4] = {entity = {name = 'stone-wall'}}, + [5] = {entity = {name = 'stone-wall'}}, + [6] = {entity = {name = 'stone-wall'}}, + [7] = {entity = {name = 'stone-wall'}}, + [8] = {entity = {name = 'stone-wall'}}, + [9] = {entity = {name = 'stone-wall'}}, + [10] = {entity = {name = 'stone-wall'}}, + [11] = {entity = {name = 'stone-wall'}}, + [12] = {entity = {name = 'stone-wall'}}, + [20] = {entity = {name = 'gun-turret', offset = 3}}, + [22] = {entity = {name = 'gun-turret', offset = 3}} + } diff --git a/map_gen/presets/crash_site/outpost_data/gun_turret_inner_corner.lua b/map_gen/presets/crash_site/outpost_data/gun_turret_inner_corner.lua new file mode 100644 index 00000000..76537438 --- /dev/null +++ b/map_gen/presets/crash_site/outpost_data/gun_turret_inner_corner.lua @@ -0,0 +1,7 @@ +return { + [1] = {entity = {name = 'stone-wall'}}, + [2] = {entity = {name = 'stone-wall'}}, + [7] = {entity = {name = 'stone-wall'}}, + [8] = {entity = {name = 'stone-wall'}}, + [22] = {entity = {name = 'gun-turret', offset = 3}} +}