local Event = require('__stdlib__/stdlib/event/event').set_protected_mode(true) local Area = require('__stdlib__/stdlib/area/area') local Position = require('__stdlib__/stdlib/area/position') local Color = require('__stdlib__/stdlib/utils/color') local config = require('__PickerAtheneum__/scenarios/testing/config') local map_area = Area():adjust({config.width / 2, config.height / 2}) local center_chunk_position = Position() local initial_area = Area() local initial_chunks = Area() local water_chunks = {Position(-1, 2), Position(0, 2)} local rolling_stock = { ['locomotive'] = true, ['cargo-wagon'] = true, ['artillery-wagon'] = true, ['fluid-wagon'] = true } local color = {r = 1, g = 1, b = 1} local function set_map_gen_settings(surface) local mgs = surface.map_gen_settings local _, width, height = map_area:size() -- width :: uint: Width in tiles. If 0, the map has infinite width. -- height :: uint: Height in tiles. If 0, the map has infinite height. -- starting_area :: MapGenSize: Size of the starting area. -- peaceful_mode :: boolean: Whether peaceful mode is enabled for this map. initial_area = initial_area:adjust({mgs.width / 2, mgs.height / 2}) initial_chunks = initial_area:to_chunk_coords():expand(1) global.initial_chunk_count = #initial_chunks:positions() global.water_count = #water_chunks mgs.width = width mgs.height = height mgs.default_enable_all_autoplace_controls = false for _, resource in pairs(mgs.autoplace_controls) do resource.frequency = 0 resource.size = 0 resource.richness = 0 end mgs.cliff_settings.richness = 0 surface.map_gen_settings = mgs surface.generate_with_lab_tiles = true surface.always_day = true surface.force_generate_chunk_requests() end local function create_bp_from_string(surface, force) -- Create proxy blueprint from string, read in the entities and remove it. local bp = surface.create_entity{name = 'item-on-ground', position = {0, 0}, force = force, stack = 'blueprint'} bp.stack.import_stack(config.bpstring) local revive = bp.stack.build_blueprint{ surface = surface, force = force, position = {0, 0}, force_build = true, skip_fog_of_war = false } local count = #revive for i, ent in ipairs(revive) do -- put rolling stock at the end. if i < count and rolling_stock[ent.ghost_type] then revive[#revive + 1] = ent else if ent.ghost_type == 'locomotive' then local _, loco = ent.revive() if loco then loco.burner.currently_burning = 'rocket-fuel' loco.burner.remaining_burning_fuel = 222222222 end else ent.revive() end end end bp.destroy() if game.entity_prototypes['debug-energy-interface'] then local es = surface.create_entity{ name = 'debug-energy-interface', position = {0, 0}, force = force, raise_built = true } es.destructible = false end if game.entity_prototypes['debug-substation'] then local sb = surface.create_entity{ name = 'debug-substation', position = {0, 0}, force = force, raise_built = true } sb.destructible = false end end local function generate_lab_tile_grid(surface, chunk_area) local tiles = {} local floor_tile = 'lab-dark-1' local floor_tile_alt = 'lab-dark-2' for x = chunk_area.left_top.x, chunk_area.right_bottom.x - 1 do for y = chunk_area.left_top.y, chunk_area.right_bottom.y - 1 do if y % 2 == 0 then if x % 2 == 0 then tiles[#tiles + 1] = {name = floor_tile, position = {x = x, y = y}} else tiles[#tiles + 1] = {name = floor_tile_alt, position = {x = x, y = y}} end else if x % 2 ~= 0 then tiles[#tiles + 1] = {name = floor_tile, position = {x = x, y = y}} else tiles[#tiles + 1] = {name = floor_tile_alt, position = {x = x, y = y}} end end end end surface.set_tiles(tiles, false) end local function render_center_point(surface) rendering.draw_circle{ width = 2, color = color, surface = surface, radius = 1, filled = false, target = {x = 0, y = 0}, only_in_alt_mode = true } end local function render_chunk_grid(surface, chunk_area, chunk_position) local left_top = chunk_area.left_top local right_bottom = chunk_area.right_bottom local function render_chunk_boundries(from, to) rendering.draw_line{width = 2, color = color, from = from, to = to, surface = surface, only_in_alt_mode = true} end render_chunk_boundries({left_top.x, left_top.y}, {right_bottom.x, left_top.y}) render_chunk_boundries({left_top.x, right_bottom.y}, {right_bottom.x, right_bottom.y}) render_chunk_boundries({left_top.x, left_top.y}, {left_top.x, right_bottom.y}) render_chunk_boundries({right_bottom.x, left_top.y}, {right_bottom.x, right_bottom.y}) rendering.draw_text{ text = chunk_position.x .. ', ' .. chunk_position.y, surface = surface, target = left_top, color = Color.color.white, scale = 1.25, draw_on_ground = true, orientation = 0, scale_with_zoom = true, only_in_alt_mode = true -- target_offset=, -- font=, -- alignment=, -- time_to_live=, -- forces=, -- players=, -- visible=, } end local function generate_starting_resources(surface) -- Top left for pos in Area{{-37.5, -27.5}, {-32.5, -4.5}}:iterate(true) do surface.create_entity{name = 'coal', position = pos, amount = 2500} end -- Top Right for pos in Area{{32.5, -27.5}, {37.5, -4.5}}:iterate(true) do surface.create_entity{name = 'iron-ore', position = pos, amount = 2500} end -- Top Middle left for pos in Area{{-27.5, -37.5}, {-4.5, -32.5}}:iterate(true) do surface.create_entity{name = 'uranium-ore', position = pos, amount = 2500} end -- Top middle right for pos in Area{{4.5, -37.5}, {27.5, -32.5}}:iterate(true) do surface.create_entity{name = 'uranium-ore', position = pos, amount = 2500} end -- Bottom Right for pos in Area{{32.5, 4.5}, {37.5, 27.5}}:iterate(true) do surface.create_entity{name = 'copper-ore', position = pos, amount = 2500} end -- Bottom Left for pos in Area{{-37.5, 4.5}, {-32.5, 27.5}}:iterate(true) do surface.create_entity{name = 'stone', position = pos, amount = 2500} end surface.create_entity{name = 'crude-oil', position = {-35.5, 1.5}, amount = 32000} surface.create_entity{name = 'crude-oil', position = {-35.5, -1.5}, amount = 32000} surface.create_entity{name = 'crude-oil', position = {35.5, 1.5}, amount = 32000} surface.create_entity{name = 'crude-oil', position = {35.5, -1.5}, amount = 32000} end local function chart_area(surface, force) local chart = map_area() chart.right_bottom.x = chart.right_bottom.x - 32 chart.right_bottom.y = chart.right_bottom.y - 32 force.chart(surface, chart) end local function generate_water(surface, chunk_area) local water_tiles = {} for pos in chunk_area:shrink(1):iterate(true, true) do water_tiles[#water_tiles + 1] = {name = 'water', position = pos} end surface.set_tiles(water_tiles, false) end local function on_init() local force = game.forces['player'] local surface = game.surfaces['nauvis'] set_map_gen_settings(surface) generate_starting_resources(surface) create_bp_from_string(surface, force) chart_area(surface, force) end Event.on_init(on_init) local function on_chunk_generated(event) local surface = event.surface local chunk_area = Area.load(event.area) local chunk_position = Position.load(event.position) surface.destroy_decoratives(chunk_area) for _, entity in pairs(surface.find_entities_filtered{area = chunk_area, type = 'character', invert = true}) do entity.destroy() end -- Generate water if global.water_count > 0 then for _, pos in pairs(water_chunks) do if pos == chunk_position then generate_water(surface, chunk_area) end end end -- Generate initial grid tiles if global.initial_chunk_count > 0 and chunk_position:inside(initial_chunks) then generate_lab_tile_grid(surface, chunk_area) global.initial_chunk_count = global.initial_chunk_count - 1 end -- Generate resources if global.initial_chunk_count == 0 and not global.resources_generated then generate_starting_resources(surface) create_bp_from_string(surface, game.forces['player']) global.resources_generated = true end -- Renderings if chunk_position == center_chunk_position then render_center_point(surface) end render_chunk_grid(surface, chunk_area, chunk_position) end Event.on_event(defines.events.on_chunk_generated, on_chunk_generated) local function on_player_created(event) local player = game.get_player(event.player_index) player.cheat_mode = true local main_inv = player.get_main_inventory() main_inv.clear() for name, count in pairs(config.items) do if game.item_prototypes[name] then main_inv.insert({name = name, count = count}) end end if player.character then local gun_inv = player.get_inventory(defines.inventory.character_guns) gun_inv.clear() for name, count in pairs(config.weapons) do if game.item_prototypes[name] then gun_inv.insert({name = name, count = count}) end end if game.item_prototypes['power-armor-mk2'] then player.get_inventory(defines.inventory.character_armor).insert('power-armor-mk2') local grid = player.character.grid if grid then for _, eq in pairs(config.equipment) do if game.equipment_prototypes[eq] then grid.put{name = eq} end end end end end end Event.on_event(defines.events.on_player_created, on_player_created) local function on_player_cheat_mode_enabled(event) local player = game.get_player(event.player_index) player.force.research_all_technologies() player.clear_recipe_notifications() local character = player.character if character then player.character_running_speed_modifier = 2 player.character_reach_distance_bonus = 200 player.character_build_distance_bonus = 200 end end Event.on_event(defines.events.on_player_cheat_mode_enabled, on_player_cheat_mode_enabled) local function on_player_promoted(event) local player = game.get_player(event.player_index) player.clear_recipe_notifications() end Event.on_event(defines.events.on_player_promoted, on_player_promoted)