diff --git a/map_gen/maps/danger_bobangels_ores.lua b/map_gen/maps/danger_bobangels_ores.lua index 17c2a8b1..58e7ff65 100644 --- a/map_gen/maps/danger_bobangels_ores.lua +++ b/map_gen/maps/danger_bobangels_ores.lua @@ -1,367 +1 @@ -local b = require 'map_gen.shared.builders' -local Generate = require 'map_gen.shared.generate' -local Perlin = require 'map_gen.shared.perlin_noise' -local Event = require 'utils.event' -local Global = require 'utils.global' -local math = require 'utils.math' -local table = require 'utils.table' -local RS = require 'map_gen.shared.redmew_surface' -local MGSP = require 'resources.map_gen_settings' -local ores_init = require 'map_gen.maps.danger_bobangels_ores.ore' -local RocketLaunched = require 'map_gen.maps.danger_bobangels_ores.rocket_launched' -local concat = table.concat -local format = string.format - -local ScenarioInfo = require 'features.gui.info' - -ScenarioInfo.set_map_name('Danger Bobs & Angels Ore Quadrants') -ScenarioInfo.set_map_description( - [[ -Clear the ore to expand the base, -focus mining efforts on specific quadrants to ensure -proper material ratios, expand the map with pollution! -]] -) -ScenarioInfo.add_map_extra_info( - [[ -This map is split in 6 sectors. Each sector has a main resource. - -You may not build the factory on ore patches. Exceptions: - [item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank] - [item=basic-transport-belt] [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=turbo-transport-belt] [item=ultimate-transport-belt] [item=basic-underground-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] [item=turbo-underground-belt] [item=ultimate-underground-belt] - -The map size is restricted to the pollution generated. A significant amount of -pollution must affect a section of the map before it is revealed. Pollution -does not affect biter evolution.]] -) - -ScenarioInfo.set_map_description( - [[ -Clear the ore to expand the base, -focus mining efforts on specific sector to ensure -proper material ratios, expand the map with pollution! -]] -) - -require 'map_gen.maps.danger_bobangels_ores.banned_entities' - -global.config.lazy_bastard.enabled = false - -local ores_names = { - 'angels-ore1', -- Saphirite - 'angels-ore2', -- Jivolite - 'angels-ore3', -- stiratite - 'angels-ore4', -- Crotinium - 'angels-ore5', -- rubyte - 'angels-ore6', -- bobmonium - 'angels-fissure', - 'angels-natural-gas', -- gas well - 'coal', - 'thorium-ore', - 'crude-oil' -} -local ore_oil_none = {} -for _, v in ipairs(ores_names) do - ore_oil_none[v] = { - frequency = 1, - richness = 1, - size = 0 - } -end -ore_oil_none = {autoplace_controls = ore_oil_none} - -RS.set_first_player_position_check_override(true) -RS.set_spawn_island_tile('grass-1') -RS.set_map_gen_settings( - { - MGSP.grass_only, - MGSP.enable_water, - { - terrain_segmentation = 'normal', - water = 'normal' - }, - MGSP.starting_area_very_low, - ore_oil_none, - MGSP.enemy_none, - MGSP.cliff_none - } -) - -Generate.enable_register_events = false - -local perlin_noise = Perlin.noise -local fast_remove = table.fast_remove - -local spawn_circle = b.circle(80) - -local water_scale = 1 / 96 -local water_threshold = 0.5 -local deepwater_threshold = 0.55 -local non_water_zone = b.circle(102) - -local tree_scale = 1 / 64 -local tree_threshold = -0.25 -local tree_chance = 0.125 - -local start_chunks_half_size = 4 - -local start_size = start_chunks_half_size * 64 - -local ores - -local pollution_increment = 2 -global.min_pollution = 300 -global.max_pollution = 10000 - -local enemy_seed -local water_seed -local tree_seed -local chunk_list = {index = 1} -local surface - -Global.register_init( - {chunk_list = chunk_list}, - function(tbl) - local s = RS.get_surface() - tbl.seed = s.map_gen_settings.seed - tbl.surface = s - game.difficulty_settings.technology_price_multiplier = 20 - game.forces.player.technologies['logistics-0'].researched = true - game.forces.player.technologies.automation.researched = true - game.forces.player.technologies['mining-productivity-1'].enabled = false - game.forces.player.technologies['mining-productivity-2'].enabled = false - game.forces.player.technologies['mining-productivity-3'].enabled = false - game.forces.player.technologies['mining-productivity-4'].enabled = false - game.map_settings.enemy_evolution.time_factor = 0.000007 - game.map_settings.enemy_evolution.destroy_factor = 0.000010 - game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution - game.draw_resource_selection = false - - tbl.random = game.create_random_generator(tbl.seed) - end, - function(tbl) - local seed = tbl.seed - enemy_seed = seed * 6 - water_seed = seed * 7 - tree_seed = seed * 8 - - chunk_list = tbl.chunk_list - surface = tbl.surface - - local ores_shapes = ores_init(seed) - - local random = tbl.random - random.re_seed(seed) - table.shuffle_table(ores_shapes, random) - - ores = b.segment_weighted_pattern(ores_shapes) - end -) - -local worm_names = {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret'} -local spawner_names = {'biter-spawner', 'spitter-spawner'} -local factor = 10 / (768 * 32) -local max_chance = 1 / 6 - -local scale_factor = 32 -local sf = 1 / scale_factor -local m = 1 / 850 - -local function enemy(x, y, world) - if global.win_condition_biters_disabled == true then - return nil - end - - local d = math.sqrt(world.x * world.x + world.y * world.y) - - if d < 64 then - return nil - end - - local threshold = 1 - d * m - threshold = math.max(threshold, 0.35) - - x, y = x * sf, y * sf - if perlin_noise(x, y, enemy_seed) <= threshold then - return - end - - if math.random(8) == 1 then - local lvl - if d < 400 then - lvl = 1 - elseif d < 650 then - lvl = 2 - elseif d < 900 then - lvl = 3 - else - lvl = 4 - end - - local chance = math.min(max_chance, d * factor) - - if math.random() < chance then - local worm_id - if d > 1000 then - local power = 1000 / d - worm_id = math.ceil((math.random() ^ power) * lvl) - else - worm_id = math.random(lvl) - end - return {name = worm_names[worm_id]} - end - else - local chance = math.min(max_chance, d * factor) - if math.random() < chance then - local spawner_id = math.random(2) - return {name = spawner_names[spawner_id]} - end - end -end - -local function water_shape(x, y) - if non_water_zone(x, y) then - return false - end - - local water_noise = perlin_noise(x * water_scale, y * water_scale, water_seed) - if water_noise >= deepwater_threshold then - return 'deepwater' - elseif water_noise >= water_threshold then - return 'water' - else - return false - end -end - -local trees = { - 'tree-01', - 'tree-02', - 'tree-02-red', - 'tree-03', - 'tree-04', - 'tree-05', - 'tree-06', - 'tree-06-brown', - 'tree-07', - 'tree-08', - 'tree-08-brown', - 'tree-08-red', - 'tree-09', - 'tree-09-brown', - 'tree-09-red' -} - -local trees_count = #trees - -local function tree_shape(x, y) - local tree_noise = perlin_noise(x * tree_scale, y * tree_scale, tree_seed) - if tree_noise > tree_threshold or math.random() > tree_chance then - return nil - end - - return {name = trees[math.random(trees_count)]} -end - -local water = b.circle(16) -water = b.change_tile(water, true, 'water') -water = b.any {b.rectangle(32, 4), b.rectangle(4, 32), water} - -local start = b.if_else(water, spawn_circle) -start = b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1') - -local function ores_shape(x, y, world) - return ores(x, y, world) -end - -local map = b.any {start, water_shape, ores_shape} -map = b.apply_entity(map, enemy) -map = b.apply_entity(map, tree_shape) -map = b.fish(map, 0.025) - -local bounds = b.rectangle(start_size, start_size) - -local function on_chunk(event) - if surface ~= event.surface then - return - end - - local left_top = event.area.left_top - local x, y = left_top.x, left_top.y - - if bounds(x + 0.5, y + 0.5) then - Generate.do_chunk(event) - else - local tiles = {} - for x1 = x, x + 31 do - for y1 = y, y + 31 do - tiles[#tiles + 1] = {name = 'out-of-map', position = {x1, y1}} - end - end - surface.set_tiles(tiles, true) - - chunk_list[#chunk_list + 1] = {left_top = left_top, id = nil} - end -end - -local function on_tick() - local index = chunk_list.index - - if index > #chunk_list then - chunk_list.index = 1 - return - end - - local data = chunk_list[index] - local pos = data.left_top - local x, y = pos.x, pos.y - local pollution = surface.get_pollution(pos) - - local current_min_pollution = global.min_pollution - - if pollution > current_min_pollution then - fast_remove(chunk_list, index) - - local id = data.id - if id then - rendering.destroy(id) - end - - local area = {left_top = pos, right_bottom = {x + 32, y + 32}} - local event = {surface = surface, area = area} - Generate.schedule_chunk(event) - RocketLaunched.chunk_unlocked(event) - - if current_min_pollution < global.max_pollution then - global.min_pollution = current_min_pollution + pollution_increment - end - - return - else - local text = concat {format('%i', pollution), ' / ', current_min_pollution} - local complete = pollution / current_min_pollution - local color = {r = 1 - complete, g = complete, b = 0} - - local id = data.id - if not id then - data.id = - rendering.draw_text { - text = text, - surface = surface, - target = {x + 16, y + 16}, - color = color, - scale = 5 - } - else - rendering.set_text(id, text) - rendering.set_color(id, color) - end - end - - chunk_list.index = index + 1 -end - -Event.add(defines.events.on_chunk_generated, on_chunk) -Event.on_nth_tick(1, on_tick) - -return map +return require 'map_gen.maps.danger_ores.presets.danger_bobangels_ores' diff --git a/map_gen/maps/danger_bobangels_ores/banned_entities.lua b/map_gen/maps/danger_bobangels_ores/banned_entities.lua deleted file mode 100644 index 5bd8fff9..00000000 --- a/map_gen/maps/danger_bobangels_ores/banned_entities.lua +++ /dev/null @@ -1,85 +0,0 @@ --- This module prevents all but the allowed items from being built on top of resources -local RestrictEntities = require 'map_gen.shared.entity_placement_restriction' -local Event = require 'utils.event' - ---- Items explicitly allowed on ores -RestrictEntities.add_allowed( - { - 'basic-transport-belt', - 'transport-belt', - 'fast-transport-belt', - 'express-transport-belt', - 'turbo-transport-belt', - 'ultimate-transport-belt', - 'basic-underground-belt', - 'underground-belt', - 'fast-underground-belt', - 'express-underground-belt', - 'turbo-underground-belt', - 'ultimate-underground-belt', - 'small-electric-pole', - 'medium-electric-pole', - 'medium-electric-pole-2', - 'medium-electric-pole-3', - 'medium-electric-pole-4', - 'big-electric-pole', - 'big-electric-pole-2', - 'big-electric-pole-3', - 'big-electric-pole-4', - 'substation', - 'substation-2', - 'substation-3', - 'substation-4', - 'electric-mining-drill', - 'bob-mining-drill-1', - 'bob-mining-drill-2', - 'bob-mining-drill-3', - 'bob-mining-drill-4', - 'bob-area-mining-drill-1', - 'bob-area-mining-drill-2', - 'bob-area-mining-drill-3', - 'bob-area-mining-drill-4', - 'burner-mining-drill', - 'pumpjack', - 'bob-pumpjack-1', - 'bob-pumpjack-2', - 'bob-pumpjack-3', - 'bob-pumpjack-4', - 'water-miner-1', - 'water-miner-2', - 'water-miner-3', - 'water-miner-4', - 'water-miner-5', - 'car', - 'tank', - 'bob-tank-2', - 'bob-tank-3', - 'thermal-water-extractor' - } -) - ---- The logic for checking that there are resources under the entity's position -RestrictEntities.set_keep_alive_callback( - function(entity) - -- Some entities have a bounding_box area of zero, eg robots. - local area = entity.bounding_box - local left_top, right_bottom = area.left_top, area.right_bottom - if left_top.x == right_bottom.x and left_top.y == right_bottom.y then - return true - end - local count = entity.surface.count_entities_filtered {area = area, type = 'resource', limit = 1} - if count == 0 then - return true - end - end -) - ---- Warning for players when their entities are destroyed -local function on_destroy(event) - local p = event.player - if p and p.valid then - p.print('You cannot build that on top of ores, only belts, mining drills, and power poles are allowed.') - end -end - -Event.add(RestrictEntities.events.on_restricted_entity_destroyed, on_destroy) diff --git a/map_gen/maps/danger_bobangels_ores/ore.lua b/map_gen/maps/danger_bobangels_ores/ore.lua deleted file mode 100644 index e7a4edb1..00000000 --- a/map_gen/maps/danger_bobangels_ores/ore.lua +++ /dev/null @@ -1,289 +0,0 @@ -local b = require 'map_gen.shared.builders' -local Perlin = require 'map_gen.shared.perlin_noise' -local table = require 'utils.table' -local Debug = require 'utils.debug' - -local random = math.random -local floor = math.floor -local value = b.euclidean_value -local binary_search = table.binary_search -local bnot = bit32.bnot -local perlin_noise = Perlin.noise - -local mixed_ores = true - -local tile_scale = 1 / 64 -local spawn_zone = b.circle(85) - -local density_scale = 1 / 48 -local density_threshold = 0.5 -local density_multiplier = 50 - -local ores = { - ['angels-ore1'] = { -- Saphirite - ['tiles'] = { - [1] = 'grass-1', - [2] = 'grass-2', - [3] = 'grass-3', - [4] = 'grass-4' - }, - ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), - ['weight'] = 15, - ['ratios'] = {} - }, - ['angels-ore2'] = { -- Jivolite - ['tiles'] = { - [1] = 'dirt-1', - [2] = 'dirt-2', - [3] = 'dirt-3' - }, - ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), - ['weight'] = 10, - ['ratios'] = {} - }, - ['angels-ore3'] = { -- Stiratite - ['tiles'] = { - [1] = 'red-desert-0', - [2] = 'red-desert-1', - [3] = 'red-desert-2', - [4] = 'red-desert-3' - }, - ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), - ['weight'] = 10, - ['ratios'] = {} - }, - ['angels-ore4'] = { -- crotinnium - ['tiles'] = { - [1] = 'grass-3', - [2] = 'grass-4' - }, - ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), - ['weight'] = 10, - ['ratios'] = {} - }, - ['angels-ore5'] = { -- rubyte - ['tiles'] = { - [1] = 'grass-1', - [2] = 'grass-2' - }, - ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), - ['weight'] = 10, - ['ratios'] = {} - }, - ['angels-ore6'] = { -- bobmonium-ore - ['tiles'] = { - [1] = 'sand-1', - [2] = 'sand-2', - [3] = 'sand-3' - }, - ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), - ['weight'] = 10, - ['ratios'] = {} - }, - ['coal'] = { - ['tiles'] = { - [1] = 'dirt-5', - [2] = 'dirt-6', - [3] = 'dirt-7' - }, - ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), - ['weight'] = 10, - ['ratios'] = {} - } -} - --- Build ratios based on global weights -local ratio_mixed = 80 -- % purity in the ore - -local oil_scale = 1 / 64 -local oil_threshold = 0.6 -local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7) -local oil_resource = b.resource(oil_shape, 'crude-oil', value(250000, 150)) - -local fissure_scale = 1 / 100 -local fissure_threshold = 0.6 -local fissure_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7) -local fissure_resource = b.resource(fissure_shape, 'angels-fissure', value(25000, 150)) - -local gas_well_scale = 1 / 64 -local gas_well_threshold = 0.6 -local gas_well_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7) -local gas_well_resource = b.resource(gas_well_shape, 'angels-natural-gas', value(25000, 150)) - -local thorium_scale = 1 / 72 -local thorium_threshold = 0.63 -local thorium_resource = b.resource(b.full_shape, 'thorium-ore', value(200, 1)) - -local function init(seed) - local oil_seed = seed * 2 - local uranium_seed = seed * 3 - local density_seed = seed * 4 - local thorium_seed = seed * 5 - local fissure_seed = seed * 6 - local gas_well_seed = seed * 7 - - - local function tile_builder(tiles) - local count = #tiles / 2 - return function(x, y) - x, y = x * tile_scale, y * tile_scale - local v = perlin_noise(x, y, seed) - v = ((v + 1) * count) + 1 - v = floor(v) - return tiles[v] - end - end - - local function ore_builder(ore_name, amount, ratios, weighted) - local start_ore = b.resource(b.full_shape, ore_name, amount) - local total = weighted.total - return function(x, y, world) - if spawn_zone(x, y) then - return start_ore(x, y, world) - end - - local oil_x, oil_y = x * oil_scale, y * oil_scale - local oil_noise = perlin_noise(oil_x, oil_y, oil_seed) - if oil_noise > oil_threshold then - return oil_resource(x, y, world) - end - - local fissure_x, fissure_y = x * fissure_scale, y * fissure_scale - local fissure_noise = perlin_noise(fissure_x, fissure_y, fissure_seed) - if fissure_noise > fissure_threshold then - return fissure_resource(x, y, world) - end - - local gas_well_x, gas_well_y = x * gas_well_scale, y * gas_well_scale - local gas_well_noise = perlin_noise(gas_well_x, gas_well_y, gas_well_seed) - if gas_well_noise > gas_well_threshold then - return gas_well_resource(x, y, world) - end - - local thorium_x, thorium_y = x * thorium_scale, y * thorium_scale - local thorium_noise = perlin_noise(thorium_x, thorium_y, thorium_seed) - if thorium_noise > thorium_threshold then - return thorium_resource(x, y, world) - end - - local i = random() * total - local index = binary_search(weighted, i) - if index < 0 then - index = bnot(index) - end - - local resource = ratios[index].resource - - local entity = resource(x, y, world) - local density_x, density_y = x * density_scale, y * density_scale - local density_noise = perlin_noise(density_x, density_y, density_seed) - - if density_noise > density_threshold then - entity.amount = entity.amount * density_multiplier - end - - entity.enable_tree_removal = false - - return entity - end - end - - local function non_mixed_ore_builder(ore_name, amount) - local resource = b.resource(b.full_shape, ore_name, amount) - return function(x, y, world) - if spawn_zone(x, y) then - return resource(x, y, world) - end - - local oil_x, oil_y = x * oil_scale, y * oil_scale - local oil_noise = perlin_noise(oil_x, oil_y, oil_seed) - if oil_noise > oil_threshold then - return oil_resource(x, y, world) - end - - local fissure_x, fissure_y = x * fissure_scale, y * fissure_scale - local fissure_noise = perlin_noise(fissure_x, fissure_y, fissure_seed) - if fissure_noise > fissure_threshold then - return fissure_resource(x, y, world) - end - - local gas_well_x, gas_well_y = x * gas_well_scale, y * gas_well_scale - local gas_well_noise = perlin_noise(gas_well_x, gas_well_y, gas_well_seed) - if gas_well_noise > gas_well_threshold then - return gas_well_resource(x, y, world) - end - - local thorium_x, thorium_y = x * thorium_scale, y * thorium_scale - local thorium_noise = perlin_noise(thorium_x, thorium_y, thorium_seed) - if thorium_noise > thorium_threshold then - return thorium_resource(x, y, world) - end - - local entity = resource(x, y, world) - local density_x, density_y = x * density_scale, y * density_scale - local density_noise = perlin_noise(density_x, density_y, density_seed) - - if density_noise > density_threshold then - entity.amount = entity.amount * density_multiplier - end - - entity.enable_tree_removal = false - - return entity - end - end - - local shapes = {} - - for ore_name, v in pairs(ores) do - local tiles = v.tiles - local land = tile_builder(tiles) - - local ore - if mixed_ores then - local ratios = { - {resource = b.resource(b.full_shape, ore_name, value(0, 0.5)), weight = ( ratio_mixed ) } - } - local other_ratios = 0 - for ore2_name, v2 in pairs(ores) do - if ore2_name ~= ore_name then - other_ratios = other_ratios + v2.weight - end - end - - local pos = 0 - for ore2_name, v2 in pairs(ores) do - Debug.print('Attempting to add ' .. ore2_name .. ' to ratio') - pos = pos + 1 - if ore2_name ~= ore_name then - table.insert(ratios, {resource = b.resource(b.full_shape, ore2_name, value(0, 0.5)), weight = ( ( 100 - ratio_mixed) * ( v2.weight / other_ratios ) ) }) - end - end - - local weighted = b.prepare_weighted_array(ratios) - local amount = v.start - - Debug.print('Number of mixed ores in ratio ' .. #ratios) - - ore = ore_builder(ore_name, amount, ratios, weighted) - else - local amount = v.non_mixed_value - - ore = non_mixed_ore_builder(ore_name, amount) - end - - local shape = b.apply_entity(land, ore) - shapes[#shapes + 1] = {shape = shape, weight = v.weight} - end - - return shapes -end - -return init diff --git a/map_gen/maps/danger_bobangels_ores/rocket_launched.lua b/map_gen/maps/danger_bobangels_ores/rocket_launched.lua deleted file mode 100644 index ebe2eb3c..00000000 --- a/map_gen/maps/danger_bobangels_ores/rocket_launched.lua +++ /dev/null @@ -1,221 +0,0 @@ -local Event = require 'utils.event' -local Global = require 'utils.global' -local Queue = require 'utils.queue' -local AlienEvolutionProgress = require 'utils.alien_evolution_progress' -local RS = require 'map_gen.shared.redmew_surface' -local Task = require 'utils.task' -local Token = require 'utils.token' - -local recent_chunks = Queue.new() -- Keeps track of recently revealed chunks -local recent_chunks_max = 5 -- Maximum number of chunks to track -local ticks_between_waves = 60 * 30 - recent_chunks_max -local enemy_factor = 5 -local max_enemies_per_wave_per_chunk = 60 - -local Public = {} - -global.win_condition_evolution_rocket_maxed = -1 -global.win_condition_biters_disabled = false -global.win_condition_extra_rockets = 10000 - - -Global.register( - recent_chunks, - function(tbl) - recent_chunks = tbl - end -) - -local function give_command(group, data) - local target = data.target - - if target and target.valid then - local command = { - type = defines.command.attack, - target = target, - distraction = defines.distraction.by_damage - } - group.set_command(command) - group.start_moving() - else - local command = { - type = defines.command.attack_area, - destination = data.position, - radius = 32, - distraction = defines.distraction.by_damage - } - - local members = group.members - for i = 1, #members do - local entitiy = members[i] - entitiy.set_command(command) - end - end -end - -local do_waves -local do_wave - -do_waves = - Token.register( - function(data) - Task.queue_task(do_wave, data, 10) - end -) - -do_wave = - Token.register( - function(data) - local wave = data.wave - local last_wave = data.last_wave - --game.print('wave: ' .. wave .. '/' .. last_wave) - - local chunk_index = data.chunk_index - local chunk = data.chunks[chunk_index] - - if not chunk then - data.wave = wave + 1 - data.chunk_index = 1 - Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data) - return false - end - - local spawner = data.spawner - - local aliens = AlienEvolutionProgress.get_aliens(spawner, game.forces.enemy.evolution_factor) - - local left_top = chunk.area.left_top - local center = {left_top.x + 16, left_top.y + 16} - local surface = chunk.surface - local find_non_colliding_position = surface.find_non_colliding_position - local create_entity = surface.create_entity - - local group = surface.create_unit_group {position = center} - local add_member = group.add_member - - for name, count in pairs(aliens) do - for i = 1, count do - local pos = find_non_colliding_position(name, center, 32, 1) - if pos then - local e = {name = name, position = pos, force = 'enemy', center = center, radius = 16, 1} - local ent = create_entity(e) - - add_member(ent) - end - end - end - - give_command(group, data) - - if chunk_index < recent_chunks_max then - data.chunk_index = chunk_index + 1 - return true - end - - if wave < last_wave then - data.wave = wave + 1 - data.chunk_index = 1 - Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data) - end - - return false - end -) - -local function start_waves(event) - local num_enemies = enemy_factor * game.forces.player.get_item_launched('satellite') - local number_of_waves = math.ceil(num_enemies / max_enemies_per_wave_per_chunk) - local num_enemies_per_wave_per_chunk = math.ceil(num_enemies / number_of_waves) - - local target = event.rocket_silo - local position - if target and target.valid then - position = target.position - else - position = {0, 0} - end - - local data = { - spawner = AlienEvolutionProgress.create_spawner_request(num_enemies_per_wave_per_chunk), - wave = 1, - last_wave = number_of_waves, - chunk_index = 1, - chunks = Queue.to_array(recent_chunks), - target = target, - position = position - } - - Task.set_timeout_in_ticks(1, do_waves, data) - - game.print('Warning incomming biter attack! Number of waves: ' .. number_of_waves) -end - -local function rocket_launched(event) - local entity = event.rocket - - if not entity or not entity.valid or not entity.force == 'player' then - return - end - - local inventory = entity.get_inventory(defines.inventory.rocket) - if not inventory or not inventory.valid then - return - end - - local satellite_count = game.forces.player.get_item_launched('satellite') - if satellite_count == 0 then - return - end - - -- Increase enemy_evolution - local current_evolution = game.forces.enemy.evolution_factor - local message - - if global.win_condition_biters_disabled == false then - if (satellite_count % 5) == 0 and global.win_condition_evolution_rocket_maxed == -1 then - message = - 'Continued launching of satellites has angered the local biter population, evolution increasing...' - game.print(message) - - current_evolution = current_evolution + 0.05 - end - - if current_evolution >= 1 and global.win_condition_evolution_rocket_maxed == -1 then - current_evolution = 1 - global.win_condition_evolution_rocket_maxed = satellite_count - - message = - 'Biters at maximum evolution! Protect the base for an additional ' .. global.win_condition_extra_rockets .. ' rockets to wipe them out forever.' - game.print(message) - end - - game.forces.enemy.evolution_factor = current_evolution - if - global.win_condition_evolution_rocket_maxed > 0 and - satellite_count >= (global.win_condition_evolution_rocket_maxed + global.win_condition_extra_rockets) - then - message = 'Congratulations! Biters have been wiped from the map!' - game.print(message) - - global.win_condition_biters_disabled = true - - for key, enemy_entity in pairs(RS.get_surface().find_entities_filtered({force = 'enemy'})) do - enemy_entity.destroy() - end - else - start_waves(event) - end - end -end - -function Public.chunk_unlocked(chunk) - Queue.push(recent_chunks, chunk) - - while Queue.size(recent_chunks) > 10 do - Queue.pop(recent_chunks) - end -end - -Event.add(defines.events.on_rocket_launched, rocket_launched) - -return Public diff --git a/map_gen/maps/danger_bobs_ores.lua b/map_gen/maps/danger_bobs_ores.lua index 292541ef..6b1b6149 100644 --- a/map_gen/maps/danger_bobs_ores.lua +++ b/map_gen/maps/danger_bobs_ores.lua @@ -1,376 +1 @@ -local b = require 'map_gen.shared.builders' -local Generate = require 'map_gen.shared.generate' -local Perlin = require 'map_gen.shared.perlin_noise' -local Event = require 'utils.event' -local Global = require 'utils.global' -local math = require 'utils.math' -local table = require 'utils.table' -local RS = require 'map_gen.shared.redmew_surface' -local MGSP = require 'resources.map_gen_settings' -local ores_init = require 'map_gen.maps.danger_bobs_ores.ore' -local RocketLaunched = require 'map_gen.maps.danger_bobs_ores.rocket_launched' -local concat = table.concat -local format = string.format - -local ScenarioInfo = require 'features.gui.info' - -ScenarioInfo.set_map_name('Danger Ore Quadrants') -ScenarioInfo.set_map_description( - [[ -Clear the ore to expand the base, -focus mining efforts on specific quadrants to ensure -proper material ratios, expand the map with pollution! -]] -) -ScenarioInfo.add_map_extra_info( - [[ -This map is split in 17 sectors. Each sector has a main resource. - -You may not build the factory on ore patches. Exceptions: - [item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank] - [item=basic-transport-belt] [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=turbo-transport-belt] [item=ultimate-transport-belt] [item=basic-underground-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] [item=turbo-underground-belt] [item=ultimate-underground-belt] - -The map size is restricted to the pollution generated. A significant amount of -pollution must affect a section of the map before it is revealed. Pollution -does not affect biter evolution.]] -) - -ScenarioInfo.set_map_description( - [[ -Clear the ore to expand the base, -focus mining efforts on specific sector to ensure -proper material ratios, expand the map with pollution! -]] -) - -require 'map_gen.maps.danger_bobs_ores.banned_entities' - -global.config.lazy_bastard.enabled = false - -local ores_names = { - 'coal', - 'copper-ore', - 'crude-oil', - 'iron-ore', - 'stone', - 'uranium-ore', - 'bauxite-ore', - 'cobalt-ore', - 'gem-ore', - 'gold-ore', - 'lead-ore', - 'nickel-ore', - 'quartz', - 'rutile-ore', - 'silver-ore', - 'sulfur', - 'tin-ore', - 'tungsten-ore', - 'zinc-ore', - 'thorium-ore' -} -local ore_oil_none = {} -for _, v in ipairs(ores_names) do - ore_oil_none[v] = { - frequency = 1, - richness = 1, - size = 0 - } -end -ore_oil_none = {autoplace_controls = ore_oil_none} - -RS.set_first_player_position_check_override(true) -RS.set_spawn_island_tile('grass-1') -RS.set_map_gen_settings( - { - MGSP.grass_only, - MGSP.enable_water, - { - terrain_segmentation = 'normal', - water = 'normal' - }, - MGSP.starting_area_very_low, - ore_oil_none, - MGSP.enemy_none, - MGSP.cliff_none - } -) - -Generate.enable_register_events = false - -local perlin_noise = Perlin.noise -local fast_remove = table.fast_remove - -local spawn_circle = b.circle(80) - -local water_scale = 1 / 96 -local water_threshold = 0.5 -local deepwater_threshold = 0.55 -local non_water_zone = b.circle(102) - -local tree_scale = 1 / 64 -local tree_threshold = -0.25 -local tree_chance = 0.125 - -local start_chunks_half_size = 4 - -local start_size = start_chunks_half_size * 64 - -local ores - -local pollution_increment = 4 -global.min_pollution = 400 -global.max_pollution = 20000 - -local enemy_seed -local water_seed -local tree_seed -local chunk_list = {index = 1} -local surface - -Global.register_init( - {chunk_list = chunk_list}, - function(tbl) - local s = RS.get_surface() - tbl.seed = s.map_gen_settings.seed - tbl.surface = s - game.difficulty_settings.technology_price_multiplier = 5 - game.forces.player.technologies.logistics.researched = true - game.forces.player.technologies.automation.researched = true - game.forces.player.technologies['mining-productivity-1'].enabled = false - game.forces.player.technologies['mining-productivity-2'].enabled = false - game.forces.player.technologies['mining-productivity-3'].enabled = false - game.forces.player.technologies['mining-productivity-4'].enabled = false - game.map_settings.enemy_evolution.time_factor = 0.000007 - game.map_settings.enemy_evolution.destroy_factor = 0.000010 - game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution - game.draw_resource_selection = false - - tbl.random = game.create_random_generator(tbl.seed) - end, - function(tbl) - local seed = tbl.seed - enemy_seed = seed * 6 - water_seed = seed * 7 - tree_seed = seed * 8 - - chunk_list = tbl.chunk_list - surface = tbl.surface - - local ores_shapes = ores_init(seed) - - local random = tbl.random - random.re_seed(seed) - table.shuffle_table(ores_shapes, random) - - ores = b.segment_weighted_pattern(ores_shapes) - end -) - -local worm_names = {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret'} -local spawner_names = {'biter-spawner', 'spitter-spawner'} -local factor = 10 / (768 * 32) -local max_chance = 1 / 6 - -local scale_factor = 32 -local sf = 1 / scale_factor -local m = 1 / 850 - -local function enemy(x, y, world) - if global.win_condition_biters_disabled == true then - return nil - end - - local d = math.sqrt(world.x * world.x + world.y * world.y) - - if d < 64 then - return nil - end - - local threshold = 1 - d * m - threshold = math.max(threshold, 0.35) - - x, y = x * sf, y * sf - if perlin_noise(x, y, enemy_seed) <= threshold then - return - end - - if math.random(8) == 1 then - local lvl - if d < 400 then - lvl = 1 - elseif d < 650 then - lvl = 2 - elseif d < 900 then - lvl = 3 - else - lvl = 4 - end - - local chance = math.min(max_chance, d * factor) - - if math.random() < chance then - local worm_id - if d > 1000 then - local power = 1000 / d - worm_id = math.ceil((math.random() ^ power) * lvl) - else - worm_id = math.random(lvl) - end - return {name = worm_names[worm_id]} - end - else - local chance = math.min(max_chance, d * factor) - if math.random() < chance then - local spawner_id = math.random(2) - return {name = spawner_names[spawner_id]} - end - end -end - -local function water_shape(x, y) - if non_water_zone(x, y) then - return false - end - - local water_noise = perlin_noise(x * water_scale, y * water_scale, water_seed) - if water_noise >= deepwater_threshold then - return 'deepwater' - elseif water_noise >= water_threshold then - return 'water' - else - return false - end -end - -local trees = { - 'tree-01', - 'tree-02', - 'tree-02-red', - 'tree-03', - 'tree-04', - 'tree-05', - 'tree-06', - 'tree-06-brown', - 'tree-07', - 'tree-08', - 'tree-08-brown', - 'tree-08-red', - 'tree-09', - 'tree-09-brown', - 'tree-09-red' -} - -local trees_count = #trees - -local function tree_shape(x, y) - local tree_noise = perlin_noise(x * tree_scale, y * tree_scale, tree_seed) - if tree_noise > tree_threshold or math.random() > tree_chance then - return nil - end - - return {name = trees[math.random(trees_count)]} -end - -local water = b.circle(16) -water = b.change_tile(water, true, 'water') -water = b.any {b.rectangle(32, 4), b.rectangle(4, 32), water} - -local start = b.if_else(water, spawn_circle) -start = b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1') - -local function ores_shape(x, y, world) - return ores(x, y, world) -end - -local map = b.any {start, water_shape, ores_shape} -map = b.apply_entity(map, enemy) -map = b.apply_entity(map, tree_shape) -map = b.fish(map, 0.025) - -local bounds = b.rectangle(start_size, start_size) - -local function on_chunk(event) - if surface ~= event.surface then - return - end - - local left_top = event.area.left_top - local x, y = left_top.x, left_top.y - - if bounds(x + 0.5, y + 0.5) then - Generate.do_chunk(event) - else - local tiles = {} - for x1 = x, x + 31 do - for y1 = y, y + 31 do - tiles[#tiles + 1] = {name = 'out-of-map', position = {x1, y1}} - end - end - surface.set_tiles(tiles, true) - - chunk_list[#chunk_list + 1] = {left_top = left_top, id = nil} - end -end - -local function on_tick() - local index = chunk_list.index - - if index > #chunk_list then - chunk_list.index = 1 - return - end - - local data = chunk_list[index] - local pos = data.left_top - local x, y = pos.x, pos.y - local pollution = surface.get_pollution(pos) - - local current_min_pollution = global.min_pollution - - if pollution > current_min_pollution then - fast_remove(chunk_list, index) - - local id = data.id - if id then - rendering.destroy(id) - end - - local area = {left_top = pos, right_bottom = {x + 32, y + 32}} - local event = {surface = surface, area = area} - Generate.schedule_chunk(event) - RocketLaunched.chunk_unlocked(event) - - if current_min_pollution < global.max_pollution then - global.min_pollution = current_min_pollution + pollution_increment - end - - return - else - local text = concat {format('%i', pollution), ' / ', current_min_pollution} - local complete = pollution / current_min_pollution - local color = {r = 1 - complete, g = complete, b = 0} - - local id = data.id - if not id then - data.id = - rendering.draw_text { - text = text, - surface = surface, - target = {x + 16, y + 16}, - color = color, - scale = 5 - } - else - rendering.set_text(id, text) - rendering.set_color(id, color) - end - end - - chunk_list.index = index + 1 -end - -Event.add(defines.events.on_chunk_generated, on_chunk) -Event.on_nth_tick(1, on_tick) - -return map +return require 'map_gen.maps.danger_ores.presets.danger_bobs_ores' diff --git a/map_gen/maps/danger_bobs_ores/banned_entities.lua b/map_gen/maps/danger_bobs_ores/banned_entities.lua deleted file mode 100644 index 3a76b2fa..00000000 --- a/map_gen/maps/danger_bobs_ores/banned_entities.lua +++ /dev/null @@ -1,84 +0,0 @@ --- This module prevents all but the allowed items from being built on top of resources -local RestrictEntities = require 'map_gen.shared.entity_placement_restriction' -local Event = require 'utils.event' - ---- Items explicitly allowed on ores -RestrictEntities.add_allowed( - { - 'basic-transport-belt', - 'transport-belt', - 'fast-transport-belt', - 'express-transport-belt', - 'turbo-transport-belt', - 'ultimate-transport-belt', - 'basic-underground-belt', - 'underground-belt', - 'fast-underground-belt', - 'express-underground-belt', - 'turbo-underground-belt', - 'ultimate-underground-belt', - 'small-electric-pole', - 'medium-electric-pole', - 'medium-electric-pole-2', - 'medium-electric-pole-3', - 'medium-electric-pole-4', - 'big-electric-pole', - 'big-electric-pole-2', - 'big-electric-pole-3', - 'big-electric-pole-4', - 'substation', - 'substation-2', - 'substation-3', - 'substation-4', - 'electric-mining-drill', - 'bob-mining-drill-1', - 'bob-mining-drill-2', - 'bob-mining-drill-3', - 'bob-mining-drill-4', - 'bob-area-mining-drill-1', - 'bob-area-mining-drill-2', - 'bob-area-mining-drill-3', - 'bob-area-mining-drill-4', - 'burner-mining-drill', - 'pumpjack', - 'bob-pumpjack-1', - 'bob-pumpjack-2', - 'bob-pumpjack-3', - 'bob-pumpjack-4', - 'water-miner-1', - 'water-miner-2', - 'water-miner-3', - 'water-miner-4', - 'water-miner-5', - 'car', - 'tank', - 'bob-tank-2', - 'bob-tank-3' - } -) - ---- The logic for checking that there are resources under the entity's position -RestrictEntities.set_keep_alive_callback( - function(entity) - -- Some entities have a bounding_box area of zero, eg robots. - local area = entity.bounding_box - local left_top, right_bottom = area.left_top, area.right_bottom - if left_top.x == right_bottom.x and left_top.y == right_bottom.y then - return true - end - local count = entity.surface.count_entities_filtered {area = area, type = 'resource', limit = 1} - if count == 0 then - return true - end - end -) - ---- Warning for players when their entities are destroyed -local function on_destroy(event) - local p = event.player - if p and p.valid then - p.print('You cannot build that on top of ores, only belts, mining drills, and power poles are allowed.') - end -end - -Event.add(RestrictEntities.events.on_restricted_entity_destroyed, on_destroy) diff --git a/map_gen/maps/danger_bobs_ores/rocket_launched.lua b/map_gen/maps/danger_bobs_ores/rocket_launched.lua deleted file mode 100644 index 2b56c87d..00000000 --- a/map_gen/maps/danger_bobs_ores/rocket_launched.lua +++ /dev/null @@ -1,219 +0,0 @@ -local Event = require 'utils.event' -local Global = require 'utils.global' -local Queue = require 'utils.queue' -local AlienEvolutionProgress = require 'utils.alien_evolution_progress' -local RS = require 'map_gen.shared.redmew_surface' -local Task = require 'utils.task' -local Token = require 'utils.token' - -local recent_chunks = Queue.new() -- Keeps track of recently revealed chunks -local recent_chunks_max = 5 -- Maximum number of chunks to track -local ticks_between_waves = 60 * 30 - recent_chunks_max -local enemy_factor = 5 -local max_enemies_per_wave_per_chunk = 60 - -local Public = {} - -global.win_condition_evolution_rocket_maxed = -1 -global.win_condition_biters_disabled = false - -Global.register( - recent_chunks, - function(tbl) - recent_chunks = tbl - end -) - -local function give_command(group, data) - local target = data.target - - if target and target.valid then - local command = { - type = defines.command.attack, - target = target, - distraction = defines.distraction.by_damage - } - group.set_command(command) - group.start_moving() - else - local command = { - type = defines.command.attack_area, - destination = data.position, - radius = 32, - distraction = defines.distraction.by_damage - } - - local members = group.members - for i = 1, #members do - local entitiy = members[i] - entitiy.set_command(command) - end - end -end - -local do_waves -local do_wave - -do_waves = - Token.register( - function(data) - Task.queue_task(do_wave, data, 10) - end -) - -do_wave = - Token.register( - function(data) - local wave = data.wave - local last_wave = data.last_wave - --game.print('wave: ' .. wave .. '/' .. last_wave) - - local chunk_index = data.chunk_index - local chunk = data.chunks[chunk_index] - - if not chunk then - data.wave = wave + 1 - data.chunk_index = 1 - Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data) - return false - end - - local spawner = data.spawner - - local aliens = AlienEvolutionProgress.get_aliens(spawner, game.forces.enemy.evolution_factor) - - local left_top = chunk.area.left_top - local center = {left_top.x + 16, left_top.y + 16} - local surface = chunk.surface - local find_non_colliding_position = surface.find_non_colliding_position - local create_entity = surface.create_entity - - local group = surface.create_unit_group {position = center} - local add_member = group.add_member - - for name, count in pairs(aliens) do - for i = 1, count do - local pos = find_non_colliding_position(name, center, 32, 1) - if pos then - local e = {name = name, position = pos, force = 'enemy', center = center, radius = 16, 1} - local ent = create_entity(e) - - add_member(ent) - end - end - end - - give_command(group, data) - - if chunk_index < recent_chunks_max then - data.chunk_index = chunk_index + 1 - return true - end - - if wave < last_wave then - data.wave = wave + 1 - data.chunk_index = 1 - Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data) - end - - return false - end -) - -local function start_waves(event) - local num_enemies = enemy_factor * game.forces.player.get_item_launched('satellite') - local number_of_waves = math.ceil(num_enemies / max_enemies_per_wave_per_chunk) - local num_enemies_per_wave_per_chunk = math.ceil(num_enemies / number_of_waves) - - local target = event.rocket_silo - local position - if target and target.valid then - position = target.position - else - position = {0, 0} - end - - local data = { - spawner = AlienEvolutionProgress.create_spawner_request(num_enemies_per_wave_per_chunk), - wave = 1, - last_wave = number_of_waves, - chunk_index = 1, - chunks = Queue.to_array(recent_chunks), - target = target, - position = position - } - - Task.set_timeout_in_ticks(1, do_waves, data) - - game.print('Warning incomming biter attack! Number of waves: ' .. number_of_waves) -end - -local function rocket_launched(event) - local entity = event.rocket - - if not entity or not entity.valid or not entity.force == 'player' then - return - end - - local inventory = entity.get_inventory(defines.inventory.rocket) - if not inventory or not inventory.valid then - return - end - - local satellite_count = game.forces.player.get_item_launched('satellite') - if satellite_count == 0 then - return - end - - -- Increase enemy_evolution - local current_evolution = game.forces.enemy.evolution_factor - local message - - if global.win_condition_biters_disabled == false then - if (satellite_count % 5) == 0 and global.win_condition_evolution_rocket_maxed == -1 then - message = - 'Continued launching of satellites has angered the local biter population, evolution increasing...' - game.print(message) - - current_evolution = current_evolution + 0.05 - end - - if current_evolution >= 1 and global.win_condition_evolution_rocket_maxed == -1 then - current_evolution = 1 - global.win_condition_evolution_rocket_maxed = satellite_count - - message = - 'Biters at maximum evolution! Protect the base for an additional 100 rockets to wipe them out forever.' - game.print(message) - end - - game.forces.enemy.evolution_factor = current_evolution - if - global.win_condition_evolution_rocket_maxed > 0 and - satellite_count >= (global.win_condition_evolution_rocket_maxed + 100) - then - message = 'Congratulations! Biters have been wiped from the map!' - game.print(message) - - global.win_condition_biters_disabled = true - - for key, enemy_entity in pairs(RS.get_surface().find_entities_filtered({force = 'enemy'})) do - enemy_entity.destroy() - end - else - start_waves(event) - end - end -end - -function Public.chunk_unlocked(chunk) - Queue.push(recent_chunks, chunk) - - while Queue.size(recent_chunks) > 10 do - Queue.pop(recent_chunks) - end -end - -Event.add(defines.events.on_rocket_launched, rocket_launched) - -return Public diff --git a/map_gen/maps/danger_ores.lua b/map_gen/maps/danger_ores.lua index c39dc1ca..c0ab6f82 100644 --- a/map_gen/maps/danger_ores.lua +++ b/map_gen/maps/danger_ores.lua @@ -1,194 +1 @@ -local b = require 'map_gen.shared.builders' -local Perlin = require 'map_gen.shared.perlin_noise' -local Global = require 'utils.global' -local math = require 'utils.math' -local table = require 'utils.table' -local RS = require 'map_gen.shared.redmew_surface' -local MGSP = require 'resources.map_gen_settings' - -require 'map_gen.shared.danger_ore_banned_entities' - -local ScenarioInfo = require 'features.gui.info' ---setting map info -ScenarioInfo.set_map_name('Danger Ores') -ScenarioInfo.set_map_description( - [[ -Clear the ore to expand the base: -build extensive mining efforts, create large smelting arrays, -use proper material ratios, and defend from enemies! -]] -) -ScenarioInfo.add_map_extra_info( - [[You may not build the factory on ore patches. Exceptions: - [item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank] - [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] ]] -) - -local oil_seed -local uranium_seed -local density_seed - -local oil_scale = 1 / 64 -local oil_threshold = 0.6 - -local uranium_scale = 1 / 128 -local uranium_threshold = 0.65 - -local density_scale = 1 / 48 -local density_threshold = 0.5 -local density_multiplier = 50 - -RS.set_first_player_position_check_override(true) -RS.set_spawn_island_tile('grass-1') -RS.set_map_gen_settings( - { - MGSP.ore_oil_none, - MGSP.cliff_none - } -) - -Global.register_init( - {}, - function(tbl) - tbl.seed = RS.get_surface().map_gen_settings.seed - end, - function(tbl) - local seed = tbl.seed - oil_seed = seed - uranium_seed = seed * 2 - density_seed = seed * 3 - game.map_settings.enemy_evolution.time_factor = 0.000002 - game.map_settings.enemy_evolution.destroy_factor = 0.0009 - game.map_settings.enemy_evolution.pollution_factor = 0.0000015 - end -) - -local value = b.euclidean_value - -local oil_shape = b.throttle_world_xy(b.full_shape, 1, 8, 1, 8) -local oil_resource = b.resource(oil_shape, 'crude-oil', value(150000, 100)) - -local uranium_resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1)) - -local ores = { - {resource = b.resource(b.full_shape, 'iron-ore', value(25, 0.5)), weight = 6}, - {resource = b.resource(b.full_shape, 'copper-ore', value(25, 0.5)), weight = 4}, - {resource = b.resource(b.full_shape, 'stone', value(25, 0.5)), weight = 1}, - {resource = b.resource(b.full_shape, 'coal', value(25, 0.5)), weight = 2} -} - -local weighted_ores = b.prepare_weighted_array(ores) -local total_ores = weighted_ores.total - -local spawn_zone = b.circle(64) - -local ore_circle = b.circle(68) -local start_ores = { - b.resource(ore_circle, 'iron-ore', value(500, 0)), - b.resource(ore_circle, 'copper-ore', value(250, 0)), - b.resource(ore_circle, 'coal', value(500, 0)), - b.resource(ore_circle, 'stone', value(250, 0)) -} - -local start_segment = b.segment_pattern(start_ores) - -local function ore(x, y, world) - if spawn_zone(x, y) then - return - end - - local start_ore = start_segment(x, y, world) - if start_ore then - return start_ore - end - - local oil_x, oil_y = x * oil_scale, y * oil_scale - - local oil_noise = Perlin.noise(oil_x, oil_y, oil_seed) - if oil_noise > oil_threshold then - return oil_resource(x, y, world) - end - - local uranium_x, uranium_y = x * uranium_scale, y * uranium_scale - local uranium_noise = Perlin.noise(uranium_x, uranium_y, uranium_seed) - if uranium_noise > uranium_threshold then - return uranium_resource(x, y, world) - end - - local i = math.random() * total_ores - local index = table.binary_search(weighted_ores, i) - if (index < 0) then - index = bit32.bnot(index) - end - - local resource = ores[index].resource - - local entity = resource(x, y, world) - local density_x, density_y = x * density_scale, y * density_scale - local density_noise = Perlin.noise(density_x, density_y, density_seed) - - if density_noise > density_threshold then - entity.amount = entity.amount * density_multiplier - end - entity.enable_tree_removal = false - return entity -end - -local worms = { - 'small-worm-turret', - 'medium-worm-turret', - 'big-worm-turret', - 'behemoth-worm-turret' -} - -local max_worm_chance = 1 / 384 -local worm_chance_factor = 1 / (192 * 512) - -local function enemy(_, _, world) - local wx, wy = world.x, world.y - local d = math.sqrt(wx * wx + wy * wy) - - local worm_chance = d - 128 - - if worm_chance > 0 then - worm_chance = worm_chance * worm_chance_factor - worm_chance = math.min(worm_chance, max_worm_chance) - - if math.random() < worm_chance then - if d < 384 then - return {name = 'small-worm-turret'} - else - local max_lvl - local min_lvl - if d < 768 then - max_lvl = 2 - min_lvl = 1 - elseif d < 960 then - max_lvl = 3 - min_lvl = 2 - else - max_lvl = 4 - min_lvl = 3 - end - local lvl = math.random() ^ (768 / d) * max_lvl - lvl = math.ceil(lvl) - lvl = math.clamp(lvl, min_lvl, 4) - return {name = worms[lvl]} - end - end - end -end - -local water = b.circle(8) -water = b.change_tile(water, true, 'water') -water = b.any {b.rectangle(16, 4), b.rectangle(4, 16), water} - -local start = b.if_else(water, b.full_shape) -start = b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1') - -local map = b.choose(ore_circle, start, b.full_shape) - -map = b.apply_entity(map, ore) -map = b.apply_entity(map, enemy) - -return map +return require 'map_gen.maps.danger_ores.presets.danger_ores' diff --git a/map_gen/maps/danger_ores/config/bob_allowed_entities.lua b/map_gen/maps/danger_ores/config/bob_allowed_entities.lua new file mode 100644 index 00000000..f12beb26 --- /dev/null +++ b/map_gen/maps/danger_ores/config/bob_allowed_entities.lua @@ -0,0 +1,52 @@ +return { + 'basic-transport-belt', + 'transport-belt', + 'fast-transport-belt', + 'express-transport-belt', + 'turbo-transport-belt', + 'ultimate-transport-belt', + 'basic-underground-belt', + 'underground-belt', + 'fast-underground-belt', + 'express-underground-belt', + 'turbo-underground-belt', + 'ultimate-underground-belt', + 'small-electric-pole', + 'medium-electric-pole', + 'medium-electric-pole-2', + 'medium-electric-pole-3', + 'medium-electric-pole-4', + 'big-electric-pole', + 'big-electric-pole-2', + 'big-electric-pole-3', + 'big-electric-pole-4', + 'substation', + 'substation-2', + 'substation-3', + 'substation-4', + 'electric-mining-drill', + 'bob-mining-drill-1', + 'bob-mining-drill-2', + 'bob-mining-drill-3', + 'bob-mining-drill-4', + 'bob-area-mining-drill-1', + 'bob-area-mining-drill-2', + 'bob-area-mining-drill-3', + 'bob-area-mining-drill-4', + 'burner-mining-drill', + 'pumpjack', + 'bob-pumpjack-1', + 'bob-pumpjack-2', + 'bob-pumpjack-3', + 'bob-pumpjack-4', + 'water-miner-1', + 'water-miner-2', + 'water-miner-3', + 'water-miner-4', + 'water-miner-5', + 'car', + 'tank', + 'bob-tank-2', + 'bob-tank-3', + 'spidertron' +} diff --git a/map_gen/maps/danger_bobs_ores/ore.lua b/map_gen/maps/danger_ores/config/bob_ores.lua similarity index 83% rename from map_gen/maps/danger_bobs_ores/ore.lua rename to map_gen/maps/danger_ores/config/bob_ores.lua index 5434756e..5d4de351 100644 --- a/map_gen/maps/danger_bobs_ores/ore.lua +++ b/map_gen/maps/danger_ores/config/bob_ores.lua @@ -1,33 +1,7 @@ local b = require 'map_gen.shared.builders' -local Perlin = require 'map_gen.shared.perlin_noise' -local table = require 'utils.table' - -local random = math.random -local floor = math.floor local value = b.euclidean_value -local binary_search = table.binary_search -local bnot = bit32.bnot -local perlin_noise = Perlin.noise -local mixed_ores = true - -local tile_scale = 1 / 64 -local spawn_zone = b.circle(85) - -local oil_scale = 1 / 64 -local oil_threshold = 0.6 - -local uranium_scale = 1 / 72 -local uranium_threshold = 0.63 - -local thorium_scale = 1 / 72 -local thorium_threshold = 0.63 - -local density_scale = 1 / 48 -local density_threshold = 0.5 -local density_multiplier = 50 - -local ores = { +return { ['iron-ore'] = { ['tiles'] = { [1] = 'grass-1', @@ -36,7 +10,6 @@ local ores = { [4] = 'grass-4' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 15, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 120}, @@ -66,7 +39,6 @@ local ores = { [4] = 'red-desert-3' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 10, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -99,7 +71,6 @@ local ores = { [7] = 'dirt-7' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 10, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -128,7 +99,6 @@ local ores = { [3] = 'sand-3' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 10, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -158,7 +128,6 @@ local ores = { [4] = 'grass-4' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 2, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -188,7 +157,6 @@ local ores = { [4] = 'red-desert-3' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 0.05, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -221,7 +189,6 @@ local ores = { [7] = 'dirt-7' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 0.05, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -250,7 +217,6 @@ local ores = { [3] = 'sand-3' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 1, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -280,7 +246,6 @@ local ores = { [4] = 'grass-4' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 2, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -310,7 +275,6 @@ local ores = { [4] = 'red-desert-3' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 2, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -343,7 +307,6 @@ local ores = { [7] = 'dirt-7' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 2, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -372,7 +335,6 @@ local ores = { [3] = 'sand-3' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 1, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -402,7 +364,6 @@ local ores = { [4] = 'grass-4' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 1, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -432,7 +393,6 @@ local ores = { [4] = 'red-desert-3' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 1, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -465,7 +425,6 @@ local ores = { [7] = 'dirt-7' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 2, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -494,7 +453,6 @@ local ores = { [3] = 'sand-3' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 1, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -524,7 +482,6 @@ local ores = { [4] = 'grass-4' }, ['start'] = value(125, 0), - ['non_mixed_value'] = value(0, 0.5), ['weight'] = 2, ['ratios'] = { {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, @@ -547,141 +504,3 @@ local ores = { } } } - -local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7) -local oil_resource = b.resource(oil_shape, 'crude-oil', value(250000, 150)) - -local uranium_resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1)) -local thorium_resource = b.resource(b.full_shape, 'thorium-ore', value(200, 1)) - -local function init(seed) - local oil_seed = seed * 2 - local uranium_seed = seed * 3 - local density_seed = seed * 4 - local thorium_seed = seed * 5 - - local function tile_builder(tiles) - local count = #tiles / 2 - return function(x, y) - x, y = x * tile_scale, y * tile_scale - local v = perlin_noise(x, y, seed) - v = ((v + 1) * count) + 1 - v = floor(v) - return tiles[v] - end - end - - local function ore_builder(ore_name, amount, ratios, weighted) - local start_ore = b.resource(b.full_shape, ore_name, amount) - local total = weighted.total - return function(x, y, world) - if spawn_zone(x, y) then - return start_ore(x, y, world) - end - - local oil_x, oil_y = x * oil_scale, y * oil_scale - local oil_noise = perlin_noise(oil_x, oil_y, oil_seed) - if oil_noise > oil_threshold then - return oil_resource(x, y, world) - end - - local uranium_x, uranium_y = x * uranium_scale, y * uranium_scale - local uranium_noise = perlin_noise(uranium_x, uranium_y, uranium_seed) - if uranium_noise > uranium_threshold then - return uranium_resource(x, y, world) - end - - local thorium_x, thorium_y = x * thorium_scale, y * thorium_scale - local thorium_noise = perlin_noise(thorium_x, thorium_y, thorium_seed) - if thorium_noise > thorium_threshold then - return thorium_resource(x, y, world) - end - - local i = random() * total - local index = binary_search(weighted, i) - if index < 0 then - index = bnot(index) - end - - local resource = ratios[index].resource - - local entity = resource(x, y, world) - local density_x, density_y = x * density_scale, y * density_scale - local density_noise = perlin_noise(density_x, density_y, density_seed) - - if density_noise > density_threshold then - entity.amount = entity.amount * density_multiplier - end - - entity.enable_tree_removal = false - - return entity - end - end - - local function non_mixed_ore_builder(ore_name, amount) - local resource = b.resource(b.full_shape, ore_name, amount) - return function(x, y, world) - if spawn_zone(x, y) then - return resource(x, y, world) - end - - local oil_x, oil_y = x * oil_scale, y * oil_scale - local oil_noise = perlin_noise(oil_x, oil_y, oil_seed) - if oil_noise > oil_threshold then - return oil_resource(x, y, world) - end - - local uranium_x, uranium_y = x * uranium_scale, y * uranium_scale - local uranium_noise = perlin_noise(uranium_x, uranium_y, uranium_seed) - if uranium_noise > uranium_threshold then - return uranium_resource(x, y, world) - end - - local thorium_x, thorium_y = x * thorium_scale, y * thorium_scale - local thorium_noise = perlin_noise(thorium_x, thorium_y, thorium_seed) - if thorium_noise > thorium_threshold then - return thorium_resource(x, y, world) - end - - local entity = resource(x, y, world) - local density_x, density_y = x * density_scale, y * density_scale - local density_noise = perlin_noise(density_x, density_y, density_seed) - - if density_noise > density_threshold then - entity.amount = entity.amount * density_multiplier - end - - entity.enable_tree_removal = false - - return entity - end - end - - local shapes = {} - - for ore_name, v in pairs(ores) do - local tiles = v.tiles - local land = tile_builder(tiles) - - local ore - if mixed_ores then - local ratios = v.ratios - local weighted = b.prepare_weighted_array(ratios) - local amount = v.start - - ore = ore_builder(ore_name, amount, ratios, weighted) - else - local amount = v.non_mixed_value - - ore = non_mixed_ore_builder(ore_name, amount) - end - - local shape = b.apply_entity(land, ore) - shapes[#shapes + 1] = {shape = shape, weight = v.weight} - end - - return shapes -end - -return init diff --git a/map_gen/maps/danger_ores/config/bob_ores_unmixed.lua b/map_gen/maps/danger_ores/config/bob_ores_unmixed.lua new file mode 100644 index 00000000..8af3078b --- /dev/null +++ b/map_gen/maps/danger_ores/config/bob_ores_unmixed.lua @@ -0,0 +1,234 @@ +local b = require 'map_gen.shared.builders' +local value = b.euclidean_value + +return { + ['iron-ore'] = { + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 15, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 120} + } + }, + ['copper-ore'] = { + ['tiles'] = { + [1] = 'red-desert-0', + [2] = 'red-desert-1', + [3] = 'red-desert-2', + [4] = 'red-desert-3' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 120} + } + }, + ['coal'] = { + ['tiles'] = { + [1] = 'dirt-1', + [2] = 'dirt-2', + [3] = 'dirt-3', + [4] = 'dirt-4', + [5] = 'dirt-5', + [6] = 'dirt-6', + [7] = 'dirt-7' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 120} + } + }, + ['stone'] = { + ['tiles'] = { + [1] = 'sand-1', + [2] = 'sand-2', + [3] = 'sand-3' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 120} + } + }, + ['bauxite-ore'] = { + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 2, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'bauxite-ore', value(0, 0.5)), weight = 120} + } + }, + ['cobalt-ore'] = { + ['tiles'] = { + [1] = 'red-desert-0', + [2] = 'red-desert-1', + [3] = 'red-desert-2', + [4] = 'red-desert-3' + }, + ['start'] = value(125, 0), + ['weight'] = 0.05, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'cobalt-ore', value(0, 0.5)), weight = 120} + } + }, + ['gem-ore'] = { + ['tiles'] = { + [1] = 'dirt-1', + [2] = 'dirt-2', + [3] = 'dirt-3', + [4] = 'dirt-4', + [5] = 'dirt-5', + [6] = 'dirt-6', + [7] = 'dirt-7' + }, + ['start'] = value(125, 0), + ['weight'] = 0.05, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'gem-ore', value(0, 0.5)), weight = 120} + } + }, + ['gold-ore'] = { + ['tiles'] = { + [1] = 'sand-1', + [2] = 'sand-2', + [3] = 'sand-3' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'gold-ore', value(0, 0.5)), weight = 120} + } + }, + ['lead-ore'] = { + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 2, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'lead-ore', value(0, 0.5)), weight = 120} + } + }, + ['nickel-ore'] = { + ['tiles'] = { + [1] = 'red-desert-0', + [2] = 'red-desert-1', + [3] = 'red-desert-2', + [4] = 'red-desert-3' + }, + ['start'] = value(125, 0), + ['weight'] = 2, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'nickel-ore', value(0, 0.5)), weight = 120} + } + }, + ['quartz'] = { + ['tiles'] = { + [1] = 'dirt-1', + [2] = 'dirt-2', + [3] = 'dirt-3', + [4] = 'dirt-4', + [5] = 'dirt-5', + [6] = 'dirt-6', + [7] = 'dirt-7' + }, + ['start'] = value(125, 0), + ['weight'] = 2, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'quartz', value(0, 0.5)), weight = 120} + } + }, + ['rutile-ore'] = { + ['tiles'] = { + [1] = 'sand-1', + [2] = 'sand-2', + [3] = 'sand-3' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'rutile-ore', value(0, 0.5)), weight = 120} + } + }, + ['silver-ore'] = { + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'silver-ore', value(0, 0.5)), weight = 120} + } + }, + ['sulfur'] = { + ['tiles'] = { + [1] = 'red-desert-0', + [2] = 'red-desert-1', + [3] = 'red-desert-2', + [4] = 'red-desert-3' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'sulfur', value(0, 0.5)), weight = 120} + } + }, + ['tin-ore'] = { + ['tiles'] = { + [1] = 'dirt-1', + [2] = 'dirt-2', + [3] = 'dirt-3', + [4] = 'dirt-4', + [5] = 'dirt-5', + [6] = 'dirt-6', + [7] = 'dirt-7' + }, + ['start'] = value(125, 0), + ['weight'] = 2, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'tin-ore', value(0, 0.5)), weight = 120} + } + }, + ['tungsten-ore'] = { + ['tiles'] = { + [1] = 'sand-1', + [2] = 'sand-2', + [3] = 'sand-3' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'tungsten-ore', value(0, 0.5)), weight = 120} + } + }, + ['zinc-ore'] = { + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 2, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'zinc-ore', value(0, 0.5)), weight = 120} + } + } +} diff --git a/map_gen/maps/danger_ores/config/bob_resource_patches.lua b/map_gen/maps/danger_ores/config/bob_resource_patches.lua new file mode 100644 index 00000000..34c7111a --- /dev/null +++ b/map_gen/maps/danger_ores/config/bob_resource_patches.lua @@ -0,0 +1,22 @@ +local b = require 'map_gen.shared.builders' +local value = b.euclidean_value + +local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7) + +return { + { + scale = 1 / 64, + threshold = 0.6, + resource = b.resource(oil_shape, 'crude-oil', value(250000, 150)) + }, + { + scale = 1 / 72, + threshold = 0.63, + resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1)) + }, + { + scale = 1 / 72, + threshold = 0.63, + resource = b.resource(b.full_shape, 'thorium-ore', value(200, 1)) + } +} diff --git a/map_gen/maps/danger_ores/config/bobangels_allowed_entities.lua b/map_gen/maps/danger_ores/config/bobangels_allowed_entities.lua new file mode 100644 index 00000000..02b940d0 --- /dev/null +++ b/map_gen/maps/danger_ores/config/bobangels_allowed_entities.lua @@ -0,0 +1,53 @@ +return { + 'basic-transport-belt', + 'transport-belt', + 'fast-transport-belt', + 'express-transport-belt', + 'turbo-transport-belt', + 'ultimate-transport-belt', + 'basic-underground-belt', + 'underground-belt', + 'fast-underground-belt', + 'express-underground-belt', + 'turbo-underground-belt', + 'ultimate-underground-belt', + 'small-electric-pole', + 'medium-electric-pole', + 'medium-electric-pole-2', + 'medium-electric-pole-3', + 'medium-electric-pole-4', + 'big-electric-pole', + 'big-electric-pole-2', + 'big-electric-pole-3', + 'big-electric-pole-4', + 'substation', + 'substation-2', + 'substation-3', + 'substation-4', + 'electric-mining-drill', + 'bob-mining-drill-1', + 'bob-mining-drill-2', + 'bob-mining-drill-3', + 'bob-mining-drill-4', + 'bob-area-mining-drill-1', + 'bob-area-mining-drill-2', + 'bob-area-mining-drill-3', + 'bob-area-mining-drill-4', + 'burner-mining-drill', + 'pumpjack', + 'bob-pumpjack-1', + 'bob-pumpjack-2', + 'bob-pumpjack-3', + 'bob-pumpjack-4', + 'water-miner-1', + 'water-miner-2', + 'water-miner-3', + 'water-miner-4', + 'water-miner-5', + 'car', + 'tank', + 'bob-tank-2', + 'bob-tank-3', + 'spidertron', + 'thermal-water-extractor' +} diff --git a/map_gen/maps/danger_ores/config/bobangels_ores.lua b/map_gen/maps/danger_ores/config/bobangels_ores.lua new file mode 100644 index 00000000..48aef477 --- /dev/null +++ b/map_gen/maps/danger_ores/config/bobangels_ores.lua @@ -0,0 +1,107 @@ +local b = require 'map_gen.shared.builders' +local value = b.euclidean_value + +local ratio_mixed = 80 -- % purity in the ore +local main_value = value(0, 0.5) + +local ores = { + ['angels-ore1'] = { + -- Saphirite + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 15, + ['ratios'] = {} + }, + ['angels-ore2'] = { + -- Jivolite + ['tiles'] = { + [1] = 'dirt-1', + [2] = 'dirt-2', + [3] = 'dirt-3' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = {} + }, + ['angels-ore3'] = { + -- Stiratite + ['tiles'] = { + [1] = 'red-desert-0', + [2] = 'red-desert-1', + [3] = 'red-desert-2', + [4] = 'red-desert-3' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = {} + }, + ['angels-ore4'] = { + -- crotinnium + ['tiles'] = { + [1] = 'grass-3', + [2] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = {} + }, + ['angels-ore5'] = { + -- rubyte + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = {} + }, + ['angels-ore6'] = { + -- bobmonium-ore + ['tiles'] = { + [1] = 'sand-1', + [2] = 'sand-2', + [3] = 'sand-3' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = {} + }, + ['coal'] = { + ['tiles'] = { + [1] = 'dirt-5', + [2] = 'dirt-6', + [3] = 'dirt-7' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = {} + } +} + +for ore_name, ore_data in pairs(ores) do + local ratios = { + {resource = b.resource(b.full_shape, ore_name, main_value), weight = ratio_mixed} + } + local sum_other_weights = 0 + for name, data in pairs(ores) do + if name ~= ore_name then + sum_other_weights = sum_other_weights + data.weight + end + end + + for name, data in pairs(ores) do + if name ~= ore_name then + local weight = (100 - ratio_mixed) * (data.weight / sum_other_weights) + ratios[#ratios + 1] = {resource = b.resource(b.full_shape, name, value(0, 0.5)), weight = weight} + end + end + + ore_data.ratios = ratios +end + +return ores diff --git a/map_gen/maps/danger_ores/config/bobangels_ores_unmixed.lua b/map_gen/maps/danger_ores/config/bobangels_ores_unmixed.lua new file mode 100644 index 00000000..aaaf330f --- /dev/null +++ b/map_gen/maps/danger_ores/config/bobangels_ores_unmixed.lua @@ -0,0 +1,95 @@ +local b = require 'map_gen.shared.builders' +local value = b.euclidean_value + +return { + ['angels-ore1'] = { + -- Saphirite + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 15, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'angels-ore1', value(0, 0.5)), weight = 1} + } + }, + ['angels-ore2'] = { + -- Jivolite + ['tiles'] = { + [1] = 'dirt-1', + [2] = 'dirt-2', + [3] = 'dirt-3' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'angels-ore2', value(0, 0.5)), weight = 1} + } + }, + ['angels-ore3'] = { + -- Stiratite + ['tiles'] = { + [1] = 'red-desert-0', + [2] = 'red-desert-1', + [3] = 'red-desert-2', + [4] = 'red-desert-3' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'angels-ore3', value(0, 0.5)), weight = 1} + } + }, + ['angels-ore4'] = { + -- crotinnium + ['tiles'] = { + [1] = 'grass-3', + [2] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'angels-ore4', value(0, 0.5)), weight = 1} + } + }, + ['angels-ore5'] = { + -- rubyte + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'angels-ore5', value(0, 0.5)), weight = 1} + } + }, + ['angels-ore6'] = { + -- bobmonium-ore + ['tiles'] = { + [1] = 'sand-1', + [2] = 'sand-2', + [3] = 'sand-3' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'angels-ore6', value(0, 0.5)), weight = 1} + } + }, + ['coal'] = { + ['tiles'] = { + [1] = 'dirt-5', + [2] = 'dirt-6', + [3] = 'dirt-7' + }, + ['start'] = value(125, 0), + ['weight'] = 10, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 1} + } + } +} diff --git a/map_gen/maps/danger_ores/config/bobangels_resource_patches.lua b/map_gen/maps/danger_ores/config/bobangels_resource_patches.lua new file mode 100644 index 00000000..bcc5a999 --- /dev/null +++ b/map_gen/maps/danger_ores/config/bobangels_resource_patches.lua @@ -0,0 +1,22 @@ +local b = require 'map_gen.shared.builders' +local value = b.euclidean_value + +local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7) + +return { + { + scale = 1 / 64, + threshold = 0.6, + resource = b.resource(oil_shape, 'crude-oil', value(250000, 150)) + }, + { + scale = 1 / 100, + threshold = 0.6, + resource = b.resource(oil_shape, 'angels-fissure', value(1250, 1)) + }, + { + scale = 1 / 64, + threshold = 0.6, + resource = b.resource(oil_shape, 'angels-natural-gas', value(1250, 1)) + } +} diff --git a/map_gen/maps/danger_ores/config/vanilla_allowed_entities.lua b/map_gen/maps/danger_ores/config/vanilla_allowed_entities.lua new file mode 100644 index 00000000..2c0dcc6d --- /dev/null +++ b/map_gen/maps/danger_ores/config/vanilla_allowed_entities.lua @@ -0,0 +1,18 @@ +return { + 'transport-belt', + 'fast-transport-belt', + 'express-transport-belt', + 'underground-belt', + 'fast-underground-belt', + 'express-underground-belt', + 'small-electric-pole', + 'medium-electric-pole', + 'big-electric-pole', + 'substation', + 'electric-mining-drill', + 'burner-mining-drill', + 'pumpjack', + 'car', + 'tank', + 'spidertron' +} diff --git a/map_gen/maps/danger_ores/config/vanilla_ores.lua b/map_gen/maps/danger_ores/config/vanilla_ores.lua new file mode 100644 index 00000000..7b437756 --- /dev/null +++ b/map_gen/maps/danger_ores/config/vanilla_ores.lua @@ -0,0 +1,71 @@ +local b = require 'map_gen.shared.builders' +local value = b.euclidean_value + +return { + ['copper-ore'] = { + ['tiles'] = { + [1] = 'red-desert-0', + [2] = 'red-desert-1', + [3] = 'red-desert-2', + [4] = 'red-desert-3' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, + {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 60}, + {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2}, + {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20} + } + }, + ['coal'] = { + ['tiles'] = { + [1] = 'dirt-1', + [2] = 'dirt-2', + [3] = 'dirt-3', + [4] = 'dirt-4', + [5] = 'dirt-5', + [6] = 'dirt-6', + [7] = 'dirt-7' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, + {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20}, + {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2}, + {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 40} + } + }, + ['iron-ore'] = { + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 60}, + {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20}, + {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2}, + {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20} + } + }, + ['stone'] = { + ['tiles'] = { + [1] = 'sand-1', + [2] = 'sand-2', + [3] = 'sand-3' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, + {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20}, + {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 30}, + {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20} + } + } +} diff --git a/map_gen/maps/danger_ores/config/vanilla_ores_unmixed.lua b/map_gen/maps/danger_ores/config/vanilla_ores_unmixed.lua new file mode 100644 index 00000000..0954df7d --- /dev/null +++ b/map_gen/maps/danger_ores/config/vanilla_ores_unmixed.lua @@ -0,0 +1,59 @@ +local b = require 'map_gen.shared.builders' +local value = b.euclidean_value + +return { + ['copper-ore'] = { + ['tiles'] = { + [1] = 'red-desert-0', + [2] = 'red-desert-1', + [3] = 'red-desert-2', + [4] = 'red-desert-3' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 1} + } + }, + ['coal'] = { + ['tiles'] = { + [1] = 'dirt-1', + [2] = 'dirt-2', + [3] = 'dirt-3', + [4] = 'dirt-4', + [5] = 'dirt-5', + [6] = 'dirt-6', + [7] = 'dirt-7' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 1} + } + }, + ['iron-ore'] = { + ['tiles'] = { + [1] = 'grass-1', + [2] = 'grass-2', + [3] = 'grass-3', + [4] = 'grass-4' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 1} + } + }, + ['stone'] = { + ['tiles'] = { + [1] = 'sand-1', + [2] = 'sand-2', + [3] = 'sand-3' + }, + ['start'] = value(125, 0), + ['weight'] = 1, + ['ratios'] = { + {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 1} + } + } +} diff --git a/map_gen/maps/danger_ores/config/vanilla_resource_patches.lua b/map_gen/maps/danger_ores/config/vanilla_resource_patches.lua new file mode 100644 index 00000000..9bc676b9 --- /dev/null +++ b/map_gen/maps/danger_ores/config/vanilla_resource_patches.lua @@ -0,0 +1,17 @@ +local b = require 'map_gen.shared.builders' +local value = b.euclidean_value + +local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7) + +return { + { + scale = 1 / 64, + threshold = 0.6, + resource = b.resource(oil_shape, 'crude-oil', value(250000, 150)) + }, + { + scale = 1 / 72, + threshold = 0.63, + resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1)) + } +} diff --git a/map_gen/maps/danger_ores/modules/banned_entities.lua b/map_gen/maps/danger_ores/modules/banned_entities.lua new file mode 100644 index 00000000..8da7b168 --- /dev/null +++ b/map_gen/maps/danger_ores/modules/banned_entities.lua @@ -0,0 +1,37 @@ +-- This module prevents all but the allowed items from being built on top of resources +local RestrictEntities = require 'map_gen.shared.entity_placement_restriction' +local Event = require 'utils.event' +local Token = require 'utils.token' + +return function(allowed_entities) + --- Items explicitly allowed on ores + RestrictEntities.add_allowed(allowed_entities) + + --- The logic for checking that there are resources under the entity's position + RestrictEntities.set_keep_alive_callback( + Token.register( + function(entity) + -- Some entities have a bounding_box area of zero, eg robots. + local area = entity.bounding_box + local left_top, right_bottom = area.left_top, area.right_bottom + if left_top.x == right_bottom.x and left_top.y == right_bottom.y then + return true + end + local count = entity.surface.count_entities_filtered {area = area, type = 'resource', limit = 1} + if count == 0 then + return true + end + end + ) + ) + + --- Warning for players when their entities are destroyed + local function on_destroy(event) + local p = event.player + if p and p.valid then + p.print('You cannot build that on top of ores, only belts, mining drills, and power poles are allowed.') + end + end + + Event.add(RestrictEntities.events.on_restricted_entity_destroyed, on_destroy) +end diff --git a/map_gen/maps/danger_ores/modules/dense_patches.lua b/map_gen/maps/danger_ores/modules/dense_patches.lua new file mode 100644 index 00000000..b5532b12 --- /dev/null +++ b/map_gen/maps/danger_ores/modules/dense_patches.lua @@ -0,0 +1,19 @@ +local Perlin = require 'map_gen.shared.perlin_noise' +local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider' + +local perlin_noise = Perlin.noise + +return function(config) + local scale = config.dense_patches_scale or 1 / 48 + local threshold = config.dense_patches_threshold or 0.5 + local multiplier = config.dense_patches_multiplier or 50 + local seed = config.dense_patches_seed or seed_provider() + + return function(x, y, entity) + x, y = x * scale, y * scale + local noise = perlin_noise(x, y, seed) + if noise > threshold then + entity.amount = entity.amount * multiplier + end + end +end diff --git a/map_gen/maps/danger_ores/modules/enemy.lua b/map_gen/maps/danger_ores/modules/enemy.lua new file mode 100644 index 00000000..2fa814e3 --- /dev/null +++ b/map_gen/maps/danger_ores/modules/enemy.lua @@ -0,0 +1,75 @@ +local Perlin = require 'map_gen.shared.perlin_noise' +local math = require 'utils.math' +local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider' + +local sqrt = math.sqrt +local max = math.max +local min = math.min +local ceil = math.ceil +local perlin_noise = Perlin.noise +local random = math.random + +return function(config, shared_globals) + local worm_names = + config.worm_names or {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret'} + local spawner_names = config.spawner_names or {'biter-spawner', 'spitter-spawner'} + local factor = config.enemy_factor or 10 / (768 * 32) + local max_chance = config.enemy_max_chance or 1 / 6 + local scale_factor = config.enemy_scale_factor or 32 + local seed = config.enemy_seed or seed_provider() + + local sf = 1 / scale_factor + local m = 1 / 850 + + return function(x, y, world) + if shared_globals.biters_disabled then + return nil + end + + local d = sqrt(world.x * world.x + world.y * world.y) + + if d < 64 then + return nil + end + + local threshold = 1 - d * m + threshold = max(threshold, 0.35) + + x, y = x * sf, y * sf + if perlin_noise(x, y, seed) <= threshold then + return + end + + if random(8) == 1 then + local lvl + if d < 400 then + lvl = 1 + elseif d < 650 then + lvl = 2 + elseif d < 900 then + lvl = 3 + else + lvl = 4 + end + + local chance = min(max_chance, d * factor) + + if random() < chance then + local worm_id + if d > 1000 then + local power = 1000 / d + worm_id = ceil((random() ^ power) * lvl) + else + worm_id = random(lvl) + end + return {name = worm_names[worm_id]} + end + else + local chance = min(max_chance, d * factor) + if random() < chance then + local spawner_id = random(2) + return {name = spawner_names[spawner_id]} + end + end + end +end diff --git a/map_gen/maps/danger_ores/modules/map.lua b/map_gen/maps/danger_ores/modules/map.lua new file mode 100644 index 00000000..fefc517a --- /dev/null +++ b/map_gen/maps/danger_ores/modules/map.lua @@ -0,0 +1,147 @@ +local Global = require 'utils.global' +local b = require 'map_gen.shared.builders' +local Perlin = require 'map_gen.shared.perlin_noise' +local table = require 'utils.table' +local math = require 'utils.math' +local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider' + +local binary_search = table.binary_search +local perlin_noise = Perlin.noise +local floor = math.floor +local random = math.random +local bnot = bit32.bnot + +local function spawn_builder(config) + local spawn_circle = config.spawn_shape or b.circle(64) + + local water = b.circle(16) + water = b.change_tile(water, true, 'water') + water = b.any {b.rectangle(32, 4), b.rectangle(4, 32), water} + + local start = b.if_else(water, spawn_circle) + return b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1') +end + +local function tile_builder_factory(config) + local tile_builder_scale = config.tile_builder_scale or 1 / 64 + local seed = seed_provider() + + return function(tiles) + local half = #tiles / 2 + + return function(x, y) + x, y = x * tile_builder_scale, y * tile_builder_scale + local v = perlin_noise(x, y, seed) + v = (v + 1) * half + 1 + v = floor(v) + return tiles[v] + end + end +end + +local function no_op() +end + +local function empty_builder() + return b.empty_shape +end + +return function(config, shared_globals) + local start_ore_shape + local resource_patches + local dense_patches + + local function ore_builder(ore_name, amount, ratios, weighted) + local start_ore = b.resource(b.full_shape, ore_name, amount) + local total = weighted.total + + return function(x, y, world) + if start_ore_shape(x, y) then + return start_ore(x, y, world) + end + + local resource_patches_entity = resource_patches(x, y, world) + if resource_patches_entity ~= false then + return resource_patches_entity + end + + local i = random() * total + local index = binary_search(weighted, i) + if index < 0 then + index = bnot(index) + end + + local resource = ratios[index].resource + local entity = resource(x, y, world) + + dense_patches(x, y, entity) + entity.enable_tree_removal = false + + return entity + end + end + + local map + Global.register_init( + {}, + function(tbl) + tbl.seed = seed_provider() + tbl.random = game.create_random_generator(tbl.seed) + end, + function(tbl) + local spawn_shape = spawn_builder(config) + local water_shape = (config.water or empty_builder)(config) + local tile_builder = tile_builder_factory(config) + local trees_shape = (config.trees or no_op)(config) + local enemy_shape = (config.enemy or no_op)(config, shared_globals) + local fish_spawn_rate = config.fish_spawn_rate + local main_ores = config.main_ores + + start_ore_shape = config.start_ore_shape or b.circle(68) + resource_patches = (config.resource_patches or no_op)(config) or b.empty_shape + dense_patches = (config.dense_patches or no_op)(config) or no_op + + local shapes = {} + + for ore_name, ore_data in pairs(main_ores) do + local tiles = ore_data.tiles + local land = tile_builder(tiles) + + local ratios = ore_data.ratios + local weighted = b.prepare_weighted_array(ratios) + local amount = ore_data.start + + local ore = ore_builder(ore_name, amount, ratios, weighted) + + local shape = b.apply_entity(land, ore) + shapes[#shapes + 1] = {shape = shape, weight = ore_data.weight} + end + + if config.main_ores_shuffle_order then + local random_gen = tbl.random + random_gen.re_seed(tbl.seed) + table.shuffle_table(shapes, random_gen) + end + + local ores = b.segment_weighted_pattern(shapes) + + map = b.any {spawn_shape, water_shape, ores} + + if enemy_shape then + map = b.apply_entity(map, enemy_shape) + end + + if trees_shape then + map = b.apply_entity(map, trees_shape) + end + + if fish_spawn_rate then + map = b.fish(map, fish_spawn_rate) + end + end + ) + + return function(x, y, world) + return map(x, y, world) + end +end diff --git a/map_gen/maps/danger_ores/modules/resource_patches.lua b/map_gen/maps/danger_ores/modules/resource_patches.lua new file mode 100644 index 00000000..b63844a7 --- /dev/null +++ b/map_gen/maps/danger_ores/modules/resource_patches.lua @@ -0,0 +1,41 @@ +local Perlin = require 'map_gen.shared.perlin_noise' +local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider' + +local perlin_noise = Perlin.noise + +return function(config) + local resource_patches = config.resource_patches_config + + local entities = {} + + for _, data in pairs(resource_patches) do + local scale = data.scale + local threshold = data.threshold + local resource = data.resource + local seed = data.seed or seed_provider() + + local function entity_shape(x, y, world) + x, y = x * scale, y * scale + local noise = perlin_noise(x, y, seed) + + if noise > threshold then + return resource(x, y, world) + end + + return false + end + + entities[#entities + 1] = entity_shape + end + + return function(x, y, world) + for i = 1, #entities do + local e = entities[i](x, y, world) + if e ~= false then + return e + end + end + + return false + end +end diff --git a/map_gen/maps/danger_ores/modules/rocket_launched.lua b/map_gen/maps/danger_ores/modules/rocket_launched.lua new file mode 100644 index 00000000..04bfe361 --- /dev/null +++ b/map_gen/maps/danger_ores/modules/rocket_launched.lua @@ -0,0 +1,239 @@ +local Event = require 'utils.event' +local Generate = require 'map_gen.shared.generate' +local Global = require 'utils.global' +local Queue = require 'utils.queue' +local AlienEvolutionProgress = require 'utils.alien_evolution_progress' +local RS = require 'map_gen.shared.redmew_surface' +local Task = require 'utils.task' +local Token = require 'utils.token' +local Server = require 'features.server' + +return function(config, shared_globals) + local recent_chunks = Queue.new() -- Keeps track of recently revealed chunks + local recent_chunks_max = config.recent_chunks_max or 10 -- Maximum number of chunks to track + local ticks_between_waves = config.ticks_between_waves or 60 * 30 + local enemy_factor = config.enemy_factor or 5 + local max_enemies_per_wave_per_chunk = config.max_enemies_per_wave_per_chunk or 60 + + local win_data = { + evolution_rocket_maxed = -1, + extra_rockets = config.extra_rockets or 100 + } + + shared_globals.biters_disabled = false + + _G.rocket_launched_win_data = win_data + + Global.register( + {recent_chunks = recent_chunks, win_data = win_data}, + function(tbl) + recent_chunks = tbl.recent_chunks + win_data = tbl.win_data + end + ) + + local function give_command(group, data) + local target = data.target + + if target and target.valid then + local command = { + type = defines.command.attack, + target = target, + distraction = defines.distraction.by_damage + } + group.set_command(command) + group.start_moving() + else + local command = { + type = defines.command.attack_area, + destination = data.position, + radius = 32, + distraction = defines.distraction.by_damage + } + + local members = group.members + for i = 1, #members do + local entitiy = members[i] + entitiy.set_command(command) + end + end + end + + local do_waves + local do_wave + + do_waves = + Token.register( + function(data) + Task.queue_task(do_wave, data, 10) + end + ) + + do_wave = + Token.register( + function(data) + if shared_globals.biters_disabled then + return false + end + + local wave = data.wave + local last_wave = data.last_wave + --game.print('wave: ' .. wave .. '/' .. last_wave) + + local chunk_index = data.chunk_index + local chunk = data.chunks[chunk_index] + + if not chunk then + data.wave = wave + 1 + data.chunk_index = 1 + Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data) + return false + end + + local spawner = data.spawner + + local aliens = AlienEvolutionProgress.get_aliens(spawner, game.forces.enemy.evolution_factor) + + local left_top = chunk.area.left_top + local center = {left_top.x + 16, left_top.y + 16} + local surface = chunk.surface + local find_non_colliding_position = surface.find_non_colliding_position + local create_entity = surface.create_entity + + local group = surface.create_unit_group {position = center} + local add_member = group.add_member + + for name, count in pairs(aliens) do + for i = 1, count do + local pos = find_non_colliding_position(name, center, 32, 1) + if pos then + local e = {name = name, position = pos, force = 'enemy', center = center, radius = 16, 1} + local ent = create_entity(e) + + add_member(ent) + end + end + end + + give_command(group, data) + + if chunk_index < recent_chunks_max then + data.chunk_index = chunk_index + 1 + return true + end + + if wave < last_wave then + data.wave = wave + 1 + data.chunk_index = 1 + Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data) + end + + return false + end + ) + + local function start_waves(event) + local num_enemies = enemy_factor * game.forces.player.get_item_launched('satellite') + local number_of_waves = math.ceil(num_enemies / max_enemies_per_wave_per_chunk) + local num_enemies_per_wave_per_chunk = math.ceil(num_enemies / number_of_waves) + + local target = event.rocket_silo + local position + if target and target.valid then + position = target.position + else + position = {0, 0} + end + + local data = { + spawner = AlienEvolutionProgress.create_spawner_request(num_enemies_per_wave_per_chunk), + wave = 1, + last_wave = number_of_waves, + chunk_index = 1, + chunks = Queue.to_array(recent_chunks), + target = target, + position = position + } + + Task.set_timeout_in_ticks(1, do_waves, data) + + game.print('Warning incomming biter attack! Number of waves: ' .. number_of_waves) + end + + local function rocket_launched(event) + local entity = event.rocket + + if not entity or not entity.valid or not entity.force == 'player' then + return + end + + local inventory = entity.get_inventory(defines.inventory.rocket) + if not inventory or not inventory.valid then + return + end + + local satellite_count = game.forces.player.get_item_launched('satellite') + if satellite_count == 0 then + return + end + + if shared_globals.biters_disabled then + return + end + + -- Increase enemy_evolution + local current_evolution = game.forces.enemy.evolution_factor + + if (satellite_count % 5) == 0 and win_data.evolution_rocket_maxed == -1 then + local message = + 'Continued launching of satellites has angered the local biter population, evolution increasing...' + game.print(message) + Server.to_discord_bold(message) + + current_evolution = current_evolution + 0.05 + game.forces.enemy.evolution_factor = current_evolution + end + + if current_evolution < 1 then + start_waves(event) + return + end + + if win_data.evolution_rocket_maxed == -1 then + win_data.evolution_rocket_maxed = satellite_count + end + + local remaining_satellites = win_data.evolution_rocket_maxed + win_data.extra_rockets - satellite_count + if remaining_satellites > 0 then + local message = + 'Biters at maximum evolution! Protect the base for an additional ' .. + remaining_satellites .. ' rockets to wipe them out forever.' + game.print(message) + Server.to_discord_bold(message) + + start_waves(event) + return + end + + local win_message = 'Congratulations! Biters have been wiped from the map!' + game.print(win_message) + Server.to_discord_bold(win_message) + + shared_globals.biters_disabled = true + + for key, enemy_entity in pairs(RS.get_surface().find_entities_filtered({force = 'enemy'})) do + enemy_entity.destroy() + end + end + + local function chunk_unlocked(chunk) + Queue.push(recent_chunks, chunk) + + while Queue.size(recent_chunks) > recent_chunks_max do + Queue.pop(recent_chunks) + end + end + + Event.add(defines.events.on_rocket_launched, rocket_launched) + Event.add(Generate.events.on_chunk_generated, chunk_unlocked) +end diff --git a/map_gen/maps/danger_ores/modules/seed_provider.lua b/map_gen/maps/danger_ores/modules/seed_provider.lua new file mode 100644 index 00000000..07267cb0 --- /dev/null +++ b/map_gen/maps/danger_ores/modules/seed_provider.lua @@ -0,0 +1,13 @@ +local RS = require 'map_gen.shared.redmew_surface' + +local seed = nil +local count = 0 + +return function() + if seed == nil then + seed = RS.get_surface().map_gen_settings.seed + end + + count = count + 1 + return seed * count +end diff --git a/map_gen/maps/danger_ores/modules/terraforming.lua b/map_gen/maps/danger_ores/modules/terraforming.lua new file mode 100644 index 00000000..e0f424a4 --- /dev/null +++ b/map_gen/maps/danger_ores/modules/terraforming.lua @@ -0,0 +1,124 @@ +local b = require 'map_gen.shared.builders' +local Generate = require 'map_gen.shared.generate' +local Event = require 'utils.event' +local Global = require 'utils.global' +local RS = require 'map_gen.shared.redmew_surface' +local table = require 'utils.table' + +local fast_remove = table.fast_remove +local concat = table.concat +local format = string.format +local rendering = rendering + +return function(config) + Generate.enable_register_events = false + + local start_size = config.start_size + + local pollution_data = { + min_pollution = config.min_pollution or 400, + max_pollution = config.max_pollution or 3500, + pollution_increment = config.pollution_increment or 2.5 + } + + _G.terraforming_pollution_data = pollution_data + + local chunk_list = {index = 1} + local surface + + Global.register_init( + {chunk_list = chunk_list, pollution_data = pollution_data}, + function(tbl) + tbl.surface = RS.get_surface() + end, + function(tbl) + chunk_list = tbl.chunk_list + pollution_data = tbl.pollution_data + surface = tbl.surface + end + ) + + local bounds = b.rectangle(start_size, start_size) + + local function on_chunk(event) + if surface ~= event.surface then + return + end + + local left_top = event.area.left_top + local x, y = left_top.x, left_top.y + + if bounds(x + 0.5, y + 0.5) then + Generate.do_chunk(event) + else + local tiles = {} + for x1 = x, x + 31 do + for y1 = y, y + 31 do + tiles[#tiles + 1] = {name = 'out-of-map', position = {x1, y1}} + end + end + surface.set_tiles(tiles, true) + + chunk_list[#chunk_list + 1] = {left_top = left_top, id = nil} + end + end + + local function on_tick() + local index = chunk_list.index + + if index > #chunk_list then + chunk_list.index = 1 + return + end + + local data = chunk_list[index] + local pos = data.left_top + local x, y = pos.x, pos.y + local pollution = surface.get_pollution(pos) + + local current_min_pollution = pollution_data.min_pollution + + if pollution > current_min_pollution then + fast_remove(chunk_list, index) + + local id = data.id + if id then + rendering.destroy(id) + end + + local area = {left_top = pos, right_bottom = {x + 32, y + 32}} + local event = {surface = surface, area = area} + Generate.schedule_chunk(event) + + if current_min_pollution < pollution_data.max_pollution then + pollution_data.min_pollution = current_min_pollution + pollution_data.pollution_increment + end + + return + else + local text = concat {format('%i', pollution), ' / ', current_min_pollution} + local complete = pollution / current_min_pollution + local color = {r = 1 - complete, g = complete, b = 0} + + local id = data.id + if not id then + data.id = + rendering.draw_text { + text = text, + surface = surface, + target = {x + 16, y + 16}, + color = color, + scale = 5 + } + else + rendering.set_text(id, text) + rendering.set_color(id, color) + end + end + + chunk_list.index = index + 1 + end + + Event.add(defines.events.on_chunk_generated, on_chunk) + Event.on_nth_tick(1, on_tick) +end diff --git a/map_gen/maps/danger_ores/modules/trees.lua b/map_gen/maps/danger_ores/modules/trees.lua new file mode 100644 index 00000000..5ee284cf --- /dev/null +++ b/map_gen/maps/danger_ores/modules/trees.lua @@ -0,0 +1,42 @@ +local Perlin = require 'map_gen.shared.perlin_noise' +local math = require 'utils.math' +local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider' + +local perlin_noise = Perlin.noise +local random = math.random + +local trees = { + 'tree-01', + 'tree-02', + 'tree-02-red', + 'tree-03', + 'tree-04', + 'tree-05', + 'tree-06', + 'tree-06-brown', + 'tree-07', + 'tree-08', + 'tree-08-brown', + 'tree-08-red', + 'tree-09', + 'tree-09-brown', + 'tree-09-red' +} + +local trees_count = #trees + +return function(config) + local scale = config.trees_scale or 1 / 64 + local threshold = config.trees_threshold or -0.25 + local chance = config.trees_chance or 0.125 + local seed = config.trees_seed or seed_provider() + + return function(x, y) + local tree_noise = perlin_noise(x * scale, y * scale, seed) + if tree_noise > threshold or random() > chance then + return nil + end + + return {name = trees[random(trees_count)]} + end +end diff --git a/map_gen/maps/danger_ores/modules/water.lua b/map_gen/maps/danger_ores/modules/water.lua new file mode 100644 index 00000000..d224cdd4 --- /dev/null +++ b/map_gen/maps/danger_ores/modules/water.lua @@ -0,0 +1,28 @@ +local Perlin = require 'map_gen.shared.perlin_noise' +local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider' +local b = require 'map_gen.shared.builders' + +local perlin_noise = Perlin.noise + +return function(config) + local scale = config.water_scale or 1 / 96 + local water_threshold = config.water_threshold or 0.5 + local deepwater_threshold = config.deepwater_threshold or 0.55 + local no_water_shape = config.no_water_shape or b.circle(96) + local seed = config.water_seed or seed_provider() + + return function(x, y) + if no_water_shape(x, y) then + return false + end + + local water_noise = perlin_noise(x * scale, y * scale, seed) + if water_noise >= deepwater_threshold then + return 'deepwater' + elseif water_noise >= water_threshold then + return 'water' + end + + return false + end +end diff --git a/map_gen/maps/danger_ores/presets/danger_bobangels_ores.lua b/map_gen/maps/danger_ores/presets/danger_bobangels_ores.lua new file mode 100644 index 00000000..d3a6bcab --- /dev/null +++ b/map_gen/maps/danger_ores/presets/danger_bobangels_ores.lua @@ -0,0 +1,158 @@ +local RS = require 'map_gen.shared.redmew_surface' +local MGSP = require 'resources.map_gen_settings' +local Event = require 'utils.event' +local b = require 'map_gen.shared.builders' +local Token = require 'utils.token' + +local ScenarioInfo = require 'features.gui.info' +ScenarioInfo.set_map_name('Danger Bobs & Angels Ore Quadrants') +ScenarioInfo.set_map_description( + [[ +Clear the ore to expand the base, +focus mining efforts on specific quadrants to ensure +proper material ratios, expand the map with pollution! +]] +) +ScenarioInfo.add_map_extra_info( + [[ +This map is split in 6 sectors. Each sector has a main resource. + +You may not build the factory on ore patches. Exceptions: + [item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank] + [item=basic-transport-belt] [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=turbo-transport-belt] [item=ultimate-transport-belt] [item=basic-underground-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] [item=turbo-underground-belt] [item=ultimate-underground-belt] + +The map size is restricted to the pollution generated. A significant amount of +pollution must affect a section of the map before it is revealed. Pollution +does not affect biter evolution.]] +) + +ScenarioInfo.set_map_description( + [[ +Clear the ore to expand the base, +focus mining efforts on specific sector to ensure +proper material ratios, expand the map with pollution! +]] +) + +local shared_globals = {} +Token.register_global(shared_globals) +_G.danger_ore_shared_globals = shared_globals + +local map = require 'map_gen.maps.danger_ores.modules.map' +local main_ores_config = require 'map_gen.maps.danger_ores.config.bobangels_ores' +local resource_patches = require 'map_gen.maps.danger_ores.modules.resource_patches' +local resource_patches_config = require 'map_gen.maps.danger_ores.config.bobangels_resource_patches' +local water = require 'map_gen.maps.danger_ores.modules.water' +local trees = require 'map_gen.maps.danger_ores.modules.trees' +local enemy = require 'map_gen.maps.danger_ores.modules.enemy' +local dense_patches = require 'map_gen.maps.danger_ores.modules.dense_patches' + +local banned_entities = require 'map_gen.maps.danger_ores.modules.banned_entities' +local allowed_entities = require 'map_gen.maps.danger_ores.config.bobangels_allowed_entities' +banned_entities(allowed_entities) + +local ores_names = { + 'angels-ore1', -- Saphirite + 'angels-ore2', -- Jivolite + 'angels-ore3', -- stiratite + 'angels-ore4', -- Crotinium + 'angels-ore5', -- rubyte + 'angels-ore6', -- bobmonium + 'angels-fissure', + 'angels-natural-gas', -- gas well + 'coal', + 'crude-oil' + } +local ore_oil_none = {} +for _, v in pairs(ores_names) do + ore_oil_none[v] = { + frequency = 1, + richness = 1, + size = 0 + } +end +ore_oil_none = {autoplace_controls = ore_oil_none} + +RS.set_map_gen_settings( + { + MGSP.grass_only, + MGSP.enable_water, + { + terrain_segmentation = 'normal', + water = 'normal' + }, + MGSP.starting_area_very_low, + ore_oil_none, + MGSP.enemy_none, + MGSP.cliff_none + } +) + +Event.on_init( + function() + game.draw_resource_selection = false + game.forces.player.technologies['mining-productivity-1'].enabled = false + game.forces.player.technologies['mining-productivity-2'].enabled = false + game.forces.player.technologies['mining-productivity-3'].enabled = false + game.forces.player.technologies['mining-productivity-4'].enabled = false + + game.difficulty_settings.technology_price_multiplier = 5 + game.forces.player.technologies.logistics.researched = true + game.forces.player.technologies.automation.researched = true + + game.map_settings.enemy_evolution.time_factor = 0.000007 -- default 0.000004 + game.map_settings.enemy_evolution.destroy_factor = 0.000010 -- default 0.002 + game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution default 0.0000009 + end +) + +local terraforming = require 'map_gen.maps.danger_ores.modules.terraforming' +terraforming( + { + start_size = 8 * 32, + min_pollution = 400, + max_pollution = 20000, + pollution_increment = 4 + } +) + +local rocket_launched = require 'map_gen.maps.danger_ores.modules.rocket_launched' +rocket_launched( + { + recent_chunks_max = 10, + ticks_between_waves = 60 * 30, + enemy_factor = 5, + max_enemies_per_wave_per_chunk = 60, + extra_rockets = 100 + }, + shared_globals +) + +local config = { + spawn_shape = b.circle(80), + start_ore_shape = b.circle(86), + main_ores = main_ores_config, + main_ores_shuffle_order = true, + resource_patches = resource_patches, + resource_patches_config = resource_patches_config, + water = water, + water_scale = 1 / 96, + water_threshold = 0.5, + deepwater_threshold = 0.55, + no_water_shape = b.circle(102), + trees = trees, + trees_scale = 1 / 64, + trees_threshold = -0.25, + trees_chance = 0.125, + enemy = enemy, + enemy_factor = 10 / (768 * 32), + enemy_max_chance = 1 / 6, + enemy_scale_factor = 32, + fish_spawn_rate = 0.025, + dense_patches = dense_patches, + dense_patches_scale = 1 / 48, + dense_patches_threshold = 0.5, + dense_patches_multiplier = 50 +} + +return map(config, shared_globals) diff --git a/map_gen/maps/danger_ores/presets/danger_bobs_ores.lua b/map_gen/maps/danger_ores/presets/danger_bobs_ores.lua new file mode 100644 index 00000000..799231e1 --- /dev/null +++ b/map_gen/maps/danger_ores/presets/danger_bobs_ores.lua @@ -0,0 +1,169 @@ +local RS = require 'map_gen.shared.redmew_surface' +local MGSP = require 'resources.map_gen_settings' +local Event = require 'utils.event' +local b = require 'map_gen.shared.builders' +local Token = require 'utils.token' + +local ScenarioInfo = require 'features.gui.info' +ScenarioInfo.set_map_name('Terraforming Danger Ore') +ScenarioInfo.set_map_description( + [[ +Clear the ore to expand the base, +focus mining efforts on specific quadrants to ensure +proper material ratios, expand the map with pollution! +]] +) +ScenarioInfo.add_map_extra_info( + [[ +This map is split in four quadrants. Each quadrant has a main resource. + [item=iron-ore] north east, [item=copper-ore] south west, [item=coal] north west, [item=stone] south east + +You may not build the factory on ore patches. Exceptions: + [item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank] + [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] + +The map size is restricted to the pollution generated. A significant amount of +pollution must affect a section of the map before it is revealed. Pollution +does not affect biter evolution.]] +) + +ScenarioInfo.set_map_description( + [[ +Clear the ore to expand the base, +focus mining efforts on specific quadrants to ensure +proper material ratios, expand the map with pollution! +]] +) + +local shared_globals = {} +Token.register_global(shared_globals) +_G.danger_ore_shared_globals = shared_globals + +local map = require 'map_gen.maps.danger_ores.modules.map' +local main_ores_config = require 'map_gen.maps.danger_ores.config.bob_ores' +local resource_patches = require 'map_gen.maps.danger_ores.modules.resource_patches' +local resource_patches_config = require 'map_gen.maps.danger_ores.config.bob_resource_patches' +local water = require 'map_gen.maps.danger_ores.modules.water' +local trees = require 'map_gen.maps.danger_ores.modules.trees' +local enemy = require 'map_gen.maps.danger_ores.modules.enemy' +local dense_patches = require 'map_gen.maps.danger_ores.modules.dense_patches' + +local banned_entities = require 'map_gen.maps.danger_ores.modules.banned_entities' +local allowed_entities = require 'map_gen.maps.danger_ores.config.bob_allowed_entities' +banned_entities(allowed_entities) + +local ores_names = { + 'coal', + 'copper-ore', + 'crude-oil', + 'iron-ore', + 'stone', + 'uranium-ore', + 'bauxite-ore', + 'cobalt-ore', + 'gem-ore', + 'gold-ore', + 'lead-ore', + 'nickel-ore', + 'quartz', + 'rutile-ore', + 'silver-ore', + 'sulfur', + 'tin-ore', + 'tungsten-ore', + 'zinc-ore', + 'thorium-ore' +} +local ore_oil_none = {} +for _, v in pairs(ores_names) do + ore_oil_none[v] = { + frequency = 1, + richness = 1, + size = 0 + } +end +ore_oil_none = {autoplace_controls = ore_oil_none} + +RS.set_map_gen_settings( + { + MGSP.grass_only, + MGSP.enable_water, + { + terrain_segmentation = 'normal', + water = 'normal' + }, + MGSP.starting_area_very_low, + ore_oil_none, + MGSP.enemy_none, + MGSP.cliff_none + } +) + +Event.on_init( + function() + game.draw_resource_selection = false + game.forces.player.technologies['mining-productivity-1'].enabled = false + game.forces.player.technologies['mining-productivity-2'].enabled = false + game.forces.player.technologies['mining-productivity-3'].enabled = false + game.forces.player.technologies['mining-productivity-4'].enabled = false + + game.difficulty_settings.technology_price_multiplier = 5 + game.forces.player.technologies.logistics.researched = true + game.forces.player.technologies.automation.researched = true + + game.map_settings.enemy_evolution.time_factor = 0.000007 -- default 0.000004 + game.map_settings.enemy_evolution.destroy_factor = 0.000010 -- default 0.002 + game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution default 0.0000009 + end +) + +local terraforming = require 'map_gen.maps.danger_ores.modules.terraforming' +terraforming( + { + start_size = 8 * 32, + min_pollution = 400, + max_pollution = 20000, + pollution_increment = 4 + } +) + +local rocket_launched = require 'map_gen.maps.danger_ores.modules.rocket_launched' +rocket_launched( + { + recent_chunks_max = 10, + ticks_between_waves = 60 * 30, + enemy_factor = 5, + max_enemies_per_wave_per_chunk = 60, + extra_rockets = 100 + }, + shared_globals +) + +local config = { + spawn_shape = b.circle(80), + start_ore_shape = b.circle(86), + main_ores = main_ores_config, + main_ores_shuffle_order = true, + resource_patches = resource_patches, + resource_patches_config = resource_patches_config, + water = water, + water_scale = 1 / 96, + water_threshold = 0.5, + deepwater_threshold = 0.55, + no_water_shape = b.circle(102), + trees = trees, + trees_scale = 1 / 64, + trees_threshold = -0.25, + trees_chance = 0.125, + enemy = enemy, + enemy_factor = 10 / (768 * 32), + enemy_max_chance = 1 / 6, + enemy_scale_factor = 32, + fish_spawn_rate = 0.025, + dense_patches = dense_patches, + dense_patches_scale = 1 / 48, + dense_patches_threshold = 0.5, + dense_patches_multiplier = 50 +} + +return map(config, shared_globals) diff --git a/map_gen/maps/danger_ores/presets/danger_ores.lua b/map_gen/maps/danger_ores/presets/danger_ores.lua new file mode 100644 index 00000000..3770a0b4 --- /dev/null +++ b/map_gen/maps/danger_ores/presets/danger_ores.lua @@ -0,0 +1,74 @@ +local RS = require 'map_gen.shared.redmew_surface' +local MGSP = require 'resources.map_gen_settings' +local Event = require 'utils.event' +local b = require 'map_gen.shared.builders' +local Token = require 'utils.token' + +local ScenarioInfo = require 'features.gui.info' +ScenarioInfo.set_map_name('Danger Ores') +ScenarioInfo.set_map_description( + [[ +Clear the ore to expand the base: +build extensive mining efforts, create large smelting arrays, +use proper material ratios, and defend from enemies! +]] +) +ScenarioInfo.add_map_extra_info( + [[You may not build the factory on ore patches. Exceptions: + [item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank] + [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] ]] +) + +local shared_globals = {} +Token.register_global(shared_globals) +_G.danger_ore_shared_globals = shared_globals + +local map = require 'map_gen.maps.danger_ores.modules.map' +local main_ores_config = require 'map_gen.maps.danger_ores.config.vanilla_ores' +local resource_patches = require 'map_gen.maps.danger_ores.modules.resource_patches' +local resource_patches_config = require 'map_gen.maps.danger_ores.config.vanilla_resource_patches' +local dense_patches = require 'map_gen.maps.danger_ores.modules.dense_patches' + +local banned_entities = require 'map_gen.maps.danger_ores.modules.banned_entities' +local allowed_entities = require 'map_gen.maps.danger_ores.config.vanilla_allowed_entities' +banned_entities(allowed_entities) + +RS.set_map_gen_settings( + { + MGSP.ore_oil_none, + MGSP.cliff_none + } +) + +Event.on_init( + function() + game.draw_resource_selection = false + game.forces.player.technologies['mining-productivity-1'].enabled = false + game.forces.player.technologies['mining-productivity-2'].enabled = false + game.forces.player.technologies['mining-productivity-3'].enabled = false + game.forces.player.technologies['mining-productivity-4'].enabled = false + + game.difficulty_settings.technology_price_multiplier = 20 + game.forces.player.technologies.logistics.researched = true + game.forces.player.technologies.automation.researched = true + + game.map_settings.enemy_evolution.time_factor = 0.000002 -- default 0.000004 + game.map_settings.enemy_evolution.destroy_factor = 0.0009 -- default 0.002 + game.map_settings.enemy_evolution.pollution_factor = 0.0000015 -- default 0.0000009 + end +) + +local config = { + spawn_shape = b.circle(64), + start_ore_shape = b.circle(68), + main_ores = main_ores_config, + --main_ores_shuffle_order = true, + resource_patches = resource_patches, + resource_patches_config = resource_patches_config, + dense_patches = dense_patches, + dense_patches_scale = 1 / 48, + dense_patches_threshold = 0.5, + dense_patches_multiplier = 50 +} + +return map(config, shared_globals) diff --git a/map_gen/maps/danger_ores/presets/terraforming_danger_ore.lua b/map_gen/maps/danger_ores/presets/terraforming_danger_ore.lua new file mode 100644 index 00000000..4d3c5a7c --- /dev/null +++ b/map_gen/maps/danger_ores/presets/terraforming_danger_ore.lua @@ -0,0 +1,156 @@ +local RS = require 'map_gen.shared.redmew_surface' +local MGSP = require 'resources.map_gen_settings' +local Event = require 'utils.event' +local b = require 'map_gen.shared.builders' +local Token = require 'utils.token' + +local ScenarioInfo = require 'features.gui.info' +ScenarioInfo.set_map_name('Terraforming Danger Ore') +ScenarioInfo.set_map_description( + [[ +Clear the ore to expand the base, +focus mining efforts on specific quadrants to ensure +proper material ratios, expand the map with pollution! +]] +) +ScenarioInfo.add_map_extra_info( + [[ +This map is split in four quadrants. Each quadrant has a main resource. + [item=iron-ore] north east, [item=copper-ore] south west, [item=coal] north west, [item=stone] south east + +You may not build the factory on ore patches. Exceptions: + [item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank] + [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] + +The map size is restricted to the pollution generated. A significant amount of +pollution must affect a section of the map before it is revealed. Pollution +does not affect biter evolution.]] +) + +ScenarioInfo.set_map_description( + [[ +Clear the ore to expand the base, +focus mining efforts on specific quadrants to ensure +proper material ratios, expand the map with pollution! +]] +) +ScenarioInfo.set_new_info( + [[ +2019-04-24: + - Stone ore density reduced by 1/2 + - Ore quadrants randomized + - Increased time factor of biter evolution from 5 to 7 + - Added win conditions (+5% evolution every 5 rockets until 100%, +100 rockets until biters are wiped) + +2019-03-30: + - Uranium ore patch threshold increased slightly + - Bug fix: Cars and tanks can now be placed onto ore! + - Starting minimum pollution to expand map set to 650 + View current pollution via Debug Settings [F4] show-pollution-values, + then open map and turn on pollution via the red box. + - Starting water at spawn increased from radius 8 to radius 16 circle. + +2019-03-27: + - Ore arranged into quadrants to allow for more controlled resource gathering. +]] +) + +local shared_globals = {} +Token.register_global(shared_globals) +_G.danger_ore_shared_globals = shared_globals + +local map = require 'map_gen.maps.danger_ores.modules.map' +local main_ores_config = require 'map_gen.maps.danger_ores.config.vanilla_ores' +local resource_patches = require 'map_gen.maps.danger_ores.modules.resource_patches' +local resource_patches_config = require 'map_gen.maps.danger_ores.config.vanilla_resource_patches' +local water = require 'map_gen.maps.danger_ores.modules.water' +local trees = require 'map_gen.maps.danger_ores.modules.trees' +local enemy = require 'map_gen.maps.danger_ores.modules.enemy' +local dense_patches = require 'map_gen.maps.danger_ores.modules.dense_patches' + +local banned_entities = require 'map_gen.maps.danger_ores.modules.banned_entities' +local allowed_entities = require 'map_gen.maps.danger_ores.config.vanilla_allowed_entities' +banned_entities(allowed_entities) + +RS.set_map_gen_settings( + { + MGSP.grass_only, + MGSP.enable_water, + { + terrain_segmentation = 'normal', + water = 'normal' + }, + MGSP.starting_area_very_low, + MGSP.ore_oil_none, + MGSP.enemy_none, + MGSP.cliff_none + } +) + +Event.on_init( + function() + game.draw_resource_selection = false + game.forces.player.technologies['mining-productivity-1'].enabled = false + game.forces.player.technologies['mining-productivity-2'].enabled = false + game.forces.player.technologies['mining-productivity-3'].enabled = false + game.forces.player.technologies['mining-productivity-4'].enabled = false + + game.difficulty_settings.technology_price_multiplier = 20 + game.forces.player.technologies.logistics.researched = true + game.forces.player.technologies.automation.researched = true + + game.map_settings.enemy_evolution.time_factor = 0.000007 -- default 0.000004 + game.map_settings.enemy_evolution.destroy_factor = 0.000010 -- default 0.002 + game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution default 0.0000009 + end +) + +local terraforming = require 'map_gen.maps.danger_ores.modules.terraforming' +terraforming( + { + start_size = 8 * 32, + min_pollution = 400, + max_pollution = 3500, + pollution_increment = 2.5 + } +) + +local rocket_launched = require 'map_gen.maps.danger_ores.modules.rocket_launched' +rocket_launched( + { + recent_chunks_max = 10, + ticks_between_waves = 60 * 30, + enemy_factor = 2, + max_enemies_per_wave_per_chunk = 60, + extra_rockets = 100 + }, + shared_globals +) + +local config = { + spawn_shape = b.circle(64), + start_ore_shape = b.circle(68), + main_ores = main_ores_config, + --main_ores_shuffle_order = true, + resource_patches = resource_patches, + resource_patches_config = resource_patches_config, + water = water, + water_scale = 1 / 96, + water_threshold = 0.5, + deepwater_threshold = 0.55, + trees = trees, + trees_scale = 1 / 64, + trees_threshold = -0.25, + trees_chance = 0.125, + enemy = enemy, + enemy_factor = 10 / (768 * 32), + enemy_max_chance = 1 / 6, + enemy_scale_factor = 32, + fish_spawn_rate = 0.025, + dense_patches = dense_patches, + dense_patches_scale = 1 / 48, + dense_patches_threshold = 0.5, + dense_patches_multiplier = 50 +} + +return map(config, shared_globals) diff --git a/map_gen/maps/terraforming_danger_ores.lua b/map_gen/maps/terraforming_danger_ores.lua index 3942bd42..9e76c59e 100644 --- a/map_gen/maps/terraforming_danger_ores.lua +++ b/map_gen/maps/terraforming_danger_ores.lua @@ -1,669 +1 @@ -local b = require 'map_gen.shared.builders' -local Generate = require 'map_gen.shared.generate' -local Perlin = require 'map_gen.shared.perlin_noise' -local Event = require 'utils.event' -local Global = require 'utils.global' -local math = require 'utils.math' -local table = require 'utils.table' -local RS = require 'map_gen.shared.redmew_surface' -local MGSP = require 'resources.map_gen_settings' - -local ScenarioInfo = require 'features.gui.info' - -ScenarioInfo.set_map_name('Danger Ore Quadrants') -ScenarioInfo.set_map_description( - [[ -Clear the ore to expand the base, -focus mining efforts on specific quadrants to ensure -proper material ratios, expand the map with pollution! -]] -) -ScenarioInfo.add_map_extra_info( - [[ -This map is split in four quadrants. Each quadrant has a main resource. - [item=iron-ore] north east, [item=copper-ore] south west, [item=coal] north west, [item=stone] south east - -You may not build the factory on ore patches. Exceptions: - [item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank] - [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] - -The map size is restricted to the pollution generated. A significant amount of -pollution must affect a section of the map before it is revealed. Pollution -does not affect biter evolution.]] -) - -ScenarioInfo.set_map_description( - [[ -Clear the ore to expand the base, -focus mining efforts on specific quadrants to ensure -proper material ratios, expand the map with pollution! -]] -) -ScenarioInfo.set_new_info( - [[ -2019-04-24: - - Stone ore density reduced by 1/2 - - Ore quadrants randomized - - Increased time factor of biter evolution from 5 to 7 - - Added win conditions (+5% evolution every 5 rockets until 100%, +100 rockets until biters are wiped) - -2019-03-30: - - Uranium ore patch threshold increased slightly - - Bug fix: Cars and tanks can now be placed onto ore! - - Starting minimum pollution to expand map set to 650 - View current pollution via Debug Settings [F4] show-pollution-values, - then open map and turn on pollution via the red box. - - Starting water at spawn increased from radius 8 to radius 16 circle. - -2019-03-27: - - Ore arranged into quadrants to allow for more controlled resource gathering. -]] -) - -require 'map_gen.shared.danger_ore_banned_entities' - -global.config.lazy_bastard.enabled = false - -RS.set_first_player_position_check_override(true) -RS.set_spawn_island_tile('grass-1') -RS.set_map_gen_settings( - { - MGSP.grass_only, - MGSP.enable_water, - { - terrain_segmentation = 'normal', - water = 'normal' - }, - MGSP.starting_area_very_low, - MGSP.ore_oil_none, - MGSP.enemy_none, - MGSP.cliff_none - } -) - -local perlin_noise = Perlin.noise -local fast_remove = table.fast_remove - -Generate.enable_register_events = false - -local oil_seed -local uranium_seed -local density_seed -local enemy_seed -local water_seed -local tree_seed - -local oil_scale = 1 / 64 -local oil_threshold = 0.6 - -local uranium_scale = 1 / 72 -local uranium_threshold = 0.63 - -local density_scale = 1 / 48 -local density_threshold = 0.5 -local density_multiplier = 50 - -local water_scale = 1 / 96 -local water_threshold = 0.5 -local deepwater_threshold = 0.55 - -local tree_scale = 1 / 64 -local tree_threshold = -0.25 -local tree_chance = 0.125 - -local start_chunks_half_size = 3 - -local max_pollution = 2500 -local pollution_increment = 2 -global.min_pollution = 300 - -local chunk_list = {index = 1} -local surface - -local start_size = start_chunks_half_size * 64 - -local value = b.euclidean_value - -local quadrant_config = { - ['iron-ore'] = { - ['tiles'] = { - [1] = 'grass-1', - [2] = 'grass-2', - [3] = 'grass-3', - [4] = 'grass-4' - }, - ['ratios'] = { - {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 60}, - {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20}, - {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2}, - {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20} - } - }, - ['copper-ore'] = { - ['tiles'] = { - [1] = 'red-desert-0', - [2] = 'red-desert-1', - [3] = 'red-desert-2', - [4] = 'red-desert-3' - }, - ['ratios'] = { - {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, - {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 60}, - {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2}, - {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20} - } - }, - ['coal'] = { - ['tiles'] = { - [1] = 'dirt-1', - [2] = 'dirt-2', - [3] = 'dirt-3', - [4] = 'dirt-4', - [5] = 'dirt-5', - [6] = 'dirt-6', - [7] = 'dirt-7' - }, - ['ratios'] = { - {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, - {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20}, - {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2}, - {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 40} - } - }, - ['stone'] = { - ['tiles'] = { - [1] = 'sand-1', - [2] = 'sand-2', - [3] = 'sand-3' - }, - ['ratios'] = { - {resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20}, - {resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20}, - {resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 30}, - {resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20} - } - } -} - -local tile_quadrants = { - [1] = 'stone', - [2] = 'iron-ore', - [3] = 'copper-ore', - [4] = 'coal' -} - -local tiles_pos_x_pos_y -local tiles_pos_x_pos_y_count -local tiles_pos_x_neg_y -local tiles_pos_x_neg_y_count -local tiles_neg_x_pos_y -local tiles_neg_x_pos_y_count -local tiles_neg_x_neg_y -local tiles_neg_x_neg_y_count - -local ores_pos_x_pos_y -local ores_pos_x_neg_y -local ores_neg_x_pos_y -local ores_neg_x_neg_y - -local weighted_ores_pos_x_pos_y -local weighted_ores_pos_x_neg_y -local weighted_ores_neg_x_pos_y -local weighted_ores_neg_x_neg_y - -local total_ores_pos_x_pos_y -local total_ores_pos_x_neg_y -local total_ores_neg_x_pos_y -local total_ores_neg_x_neg_y - -local ore_circle = b.circle(68) -local start_ores -local start_segment - -Global.register_init( - {chunk_list = chunk_list}, - function(tbl) - local s = RS.get_surface() - tbl.seed = s.map_gen_settings.seed - tbl.surface = s - game.difficulty_settings.technology_price_multiplier = 20 - game.forces.player.technologies.logistics.researched = true - game.forces.player.technologies.automation.researched = true - game.forces.player.technologies['mining-productivity-1'].enabled = false - game.forces.player.technologies['mining-productivity-2'].enabled = false - game.forces.player.technologies['mining-productivity-3'].enabled = false - game.forces.player.technologies['mining-productivity-4'].enabled = false - game.map_settings.enemy_evolution.time_factor = 0.000007 - game.map_settings.enemy_evolution.destroy_factor = 0.000010 - game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution - game.draw_resource_selection = false - - tbl.random = game.create_random_generator(tbl.seed) - end, - function(tbl) - local seed = tbl.seed - oil_seed = seed - uranium_seed = seed * 2 - density_seed = seed * 3 - enemy_seed = seed * 4 - water_seed = seed * 5 - tree_seed = seed * 6 - - chunk_list = tbl.chunk_list - surface = tbl.surface - - local random = tbl.random - random.re_seed(seed) - table.shuffle_table(tile_quadrants, random) - - tiles_pos_x_pos_y = quadrant_config[tile_quadrants[1]]['tiles'] - tiles_pos_x_pos_y_count = #quadrant_config[tile_quadrants[1]]['tiles'] - tiles_pos_x_neg_y = quadrant_config[tile_quadrants[2]]['tiles'] - tiles_pos_x_neg_y_count = #quadrant_config[tile_quadrants[2]]['tiles'] - tiles_neg_x_pos_y = quadrant_config[tile_quadrants[3]]['tiles'] - tiles_neg_x_pos_y_count = #quadrant_config[tile_quadrants[3]]['tiles'] - tiles_neg_x_neg_y = quadrant_config[tile_quadrants[4]]['tiles'] - tiles_neg_x_neg_y_count = #quadrant_config[tile_quadrants[4]]['tiles'] - - ores_pos_x_pos_y = quadrant_config[tile_quadrants[1]]['ratios'] - ores_pos_x_neg_y = quadrant_config[tile_quadrants[2]]['ratios'] - ores_neg_x_pos_y = quadrant_config[tile_quadrants[3]]['ratios'] - ores_neg_x_neg_y = quadrant_config[tile_quadrants[4]]['ratios'] - - weighted_ores_pos_x_pos_y = b.prepare_weighted_array(ores_pos_x_pos_y) - weighted_ores_pos_x_neg_y = b.prepare_weighted_array(ores_pos_x_neg_y) - weighted_ores_neg_x_pos_y = b.prepare_weighted_array(ores_neg_x_pos_y) - weighted_ores_neg_x_neg_y = b.prepare_weighted_array(ores_neg_x_neg_y) - - total_ores_pos_x_pos_y = weighted_ores_pos_x_pos_y.total - total_ores_pos_x_neg_y = weighted_ores_pos_x_neg_y.total - total_ores_neg_x_pos_y = weighted_ores_neg_x_pos_y.total - total_ores_neg_x_neg_y = weighted_ores_neg_x_neg_y.total - - start_ores = { - b.resource(ore_circle, tile_quadrants[2], value(125, 0)), - b.resource(ore_circle, tile_quadrants[4], value(125, 0)), - b.resource(ore_circle, tile_quadrants[3], value(125, 0)), - b.resource(ore_circle, tile_quadrants[1], value(125, 0)) - } - - start_segment = b.segment_pattern(start_ores) - end -) - -local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7) -local oil_resource = b.resource(oil_shape, 'crude-oil', value(250000, 150)) - -local uranium_resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1)) - -local spawn_zone = b.circle(64) - -local function ore(x, y, world) - if spawn_zone(x, y) then - return - end - - local start_ore = start_segment(x, y, world) - if start_ore then - return start_ore - end - - local oil_x, oil_y = x * oil_scale, y * oil_scale - local oil_noise = perlin_noise(oil_x, oil_y, oil_seed) - if oil_noise > oil_threshold then - return oil_resource(x, y, world) - end - - local uranium_x, uranium_y = x * uranium_scale, y * uranium_scale - local uranium_noise = perlin_noise(uranium_x, uranium_y, uranium_seed) - if uranium_noise > uranium_threshold then - return uranium_resource(x, y, world) - end - - local i - local index - local resource - - if x > 0 and y > 0 then - i = math.random() * total_ores_pos_x_pos_y - index = table.binary_search(weighted_ores_pos_x_pos_y, i) - if (index < 0) then - index = bit32.bnot(index) - end - - resource = ores_pos_x_pos_y[index].resource - elseif x > 0 and y < 0 then - i = math.random() * total_ores_pos_x_neg_y - index = table.binary_search(weighted_ores_pos_x_neg_y, i) - if (index < 0) then - index = bit32.bnot(index) - end - resource = ores_pos_x_neg_y[index].resource - elseif x < 0 and y > 0 then - i = math.random() * total_ores_neg_x_pos_y - index = table.binary_search(weighted_ores_neg_x_pos_y, i) - if (index < 0) then - index = bit32.bnot(index) - end - resource = ores_neg_x_pos_y[index].resource - else - i = math.random() * total_ores_neg_x_neg_y - index = table.binary_search(weighted_ores_neg_x_neg_y, i) - if (index < 0) then - index = bit32.bnot(index) - end - - resource = ores_neg_x_neg_y[index].resource - end - - local entity = resource(x, y, world) - local density_x, density_y = x * density_scale, y * density_scale - local density_noise = perlin_noise(density_x, density_y, density_seed) - - if density_noise > density_threshold then - entity.amount = entity.amount * density_multiplier - end - entity.enable_tree_removal = false - return entity -end - -local worm_names = {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret'} -local spawner_names = {'biter-spawner', 'spitter-spawner'} -local factor = 10 / (768 * 32) -local max_chance = 1 / 6 - -local scale_factor = 32 -local sf = 1 / scale_factor -local m = 1 / 850 - -global.win_condition_evolution_rocket_maxed = -1 -global.win_condition_biters_disabled = false - -local function enemy(x, y, world) - if global.win_condition_biters_disabled == true then - return nil - end - - local d = math.sqrt(world.x * world.x + world.y * world.y) - - if d < 64 then - return nil - end - - local threshold = 1 - d * m - threshold = math.max(threshold, 0.35) - - x, y = x * sf, y * sf - if perlin_noise(x, y, enemy_seed) <= threshold then - return - end - - if math.random(8) == 1 then - local lvl - if d < 400 then - lvl = 1 - elseif d < 650 then - lvl = 2 - elseif d < 900 then - lvl = 3 - else - lvl = 4 - end - - local chance = math.min(max_chance, d * factor) - - if math.random() < chance then - local worm_id - if d > 1000 then - local power = 1000 / d - worm_id = math.ceil((math.random() ^ power) * lvl) - else - worm_id = math.random(lvl) - end - return {name = worm_names[worm_id]} - end - else - local chance = math.min(max_chance, d * factor) - if math.random() < chance then - local spawner_id = math.random(2) - return {name = spawner_names[spawner_id]} - end - end -end - -local function water_shape(x, y) - local water_noise = perlin_noise(x * water_scale, y * water_scale, water_seed) - if water_noise >= deepwater_threshold then - return 'deepwater' - elseif water_noise >= water_threshold then - return 'water' - else - -- Control the tiles at X quadrant - if x > 31 and y > 31 then - -- southeast - return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))] - elseif x > 0 and y < 31 and y > 0 then - -- southeast to northeast - if math.random(100) < 50 + y * 2 then - return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))] - else - return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))] - end - elseif x > 0 and y >= 0 then - -- southeast to southwest - if math.random(100) < 50 + x * 2 then - return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))] - else - return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))] - end - elseif x > 31 and y < -31 then - -- northeast - return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))] - elseif x > 0 and x < 31 and y <= 0 then - -- northeast to northwest - if math.random(100) < 50 + x * 2 then - return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))] - else - return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))] - end - elseif x > 0 and y < 0 then - -- northeast to southeast - if math.random(100) < 50 - y * 2 then - return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))] - else - return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))] - end - elseif x < -31 and y < -31 then - -- northwest - return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))] - elseif x > -31 and x < 0 and y <= 0 then - -- northwest to northeast - if math.random(100) < 50 - x * 2 then - return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))] - else - return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))] - end - elseif x < 0 and y > -31 and y < 0 then - -- northwest to southwest - if math.random(100) < (50 - y * 2) then - return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))] - else - return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))] - end - elseif x < -31 and y > 31 then - -- southwest - return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))] - elseif x < 0 and y > 0 and y < 32 then - -- southwest to northwest - if math.random(100) < (50 + y * 2) then - return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))] - else - return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))] - end - elseif x < 0 and y > 0 then - -- southwest to southeast - if math.random(100) < 50 - x * 2 then - return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))] - else - return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))] - end - end - end -end - -local trees = { - 'tree-01', - 'tree-02', - 'tree-02-red', - 'tree-03', - 'tree-04', - 'tree-05', - 'tree-06', - 'tree-06-brown', - 'tree-07', - 'tree-08', - 'tree-08-brown', - 'tree-08-red', - 'tree-09', - 'tree-09-brown', - 'tree-09-red' -} - -local trees_count = #trees - -local function tree_shape(x, y) - local tree_noise = perlin_noise(x * tree_scale, y * tree_scale, tree_seed) - if tree_noise > tree_threshold or math.random() > tree_chance then - return nil - end - - return {name = trees[math.random(trees_count)]} -end - -local water = b.circle(16) -water = b.change_tile(water, true, 'water') -water = b.any {b.rectangle(32, 4), b.rectangle(4, 32), water} - -local start = b.if_else(water, b.full_shape) -start = b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1') - -local map = b.choose(ore_circle, start, water_shape) - -map = b.apply_entity(map, ore) -map = b.apply_entity(map, enemy) -map = b.apply_entity(map, tree_shape) -map = b.fish(map, 0.025) - -local bounds = b.rectangle(start_size, start_size) - -local function rocket_launched(event) - local entity = event.rocket - - if not entity or not entity.valid or not entity.force == 'player' then - return - end - - local inventory = entity.get_inventory(defines.inventory.rocket) - if not inventory or not inventory.valid then - return - end - - local satellite_count = game.forces.player.get_item_launched('satellite') - if satellite_count == 0 then - return - end - - -- Increase enemy_evolution - local current_evolution = game.forces.enemy.evolution_factor - local message - - if global.win_condition_biters_disabled == false then - if (satellite_count % 5) == 0 and global.win_condition_evolution_rocket_maxed == -1 then - message = - 'Continued launching of satellites has angered the local biter population, evolution increasing...' - game.print(message) - - current_evolution = current_evolution + 0.05 - end - - if current_evolution >= 1 and global.win_condition_evolution_rocket_maxed == -1 then - current_evolution = 1 - global.win_condition_evolution_rocket_maxed = satellite_count - - message = - 'Biters at maximum evolution! Protect the base for an additional 100 rockets to wipe them out forever.' - game.print(message) - end - - game.forces.enemy.evolution_factor = current_evolution - if global.win_condition_evolution_rocket_maxed > 0 and satellite_count >= (global.win_condition_evolution_rocket_maxed + 100) then - message = 'Congratulations! Biters have been wiped from the map!' - game.print(message) - - global.win_condition_biters_disabled = true - - for key, enemy_entity in pairs(surface.find_entities_filtered({force = 'enemy'})) do - enemy_entity.destroy() - end - end - end -end - -local function on_chunk(event) - if surface ~= event.surface then - return - end - - local left_top = event.area.left_top - local x, y = left_top.x, left_top.y - - if bounds(x + 0.5, y + 0.5) then - Generate.do_chunk(event) - else - local tiles = {} - for x1 = x, x + 31 do - for y1 = y, y + 31 do - tiles[#tiles + 1] = {name = 'out-of-map', position = {x1, y1}} - end - end - surface.set_tiles(tiles, true) - - chunk_list[#chunk_list + 1] = left_top - end -end - -local function on_tick() - local index = chunk_list.index - - if index > #chunk_list then - chunk_list.index = 1 - return - end - - local pos = chunk_list[index] - local pollution = surface.get_pollution(pos) - - local current_min_pollution = global.min_pollution - - if pollution > current_min_pollution then - fast_remove(chunk_list, index) - - local area = {left_top = pos, right_bottom = {pos.x + 32, pos.y + 32}} - local event = {surface = surface, area = area} - Generate.schedule_chunk(event) - - if current_min_pollution < max_pollution then - global.min_pollution = current_min_pollution + pollution_increment - end - - return - end - - chunk_list.index = index + 1 -end - -Event.add(defines.events.on_chunk_generated, on_chunk) -Event.add(defines.events.on_rocket_launched, rocket_launched) -Event.on_nth_tick(1, on_tick) - -return map +return require 'map_gen.maps.danger_ores.presets.terraforming_danger_ore' diff --git a/map_gen/shared/generate.lua b/map_gen/shared/generate.lua index e64fe4b2..7a195988 100644 --- a/map_gen/shared/generate.lua +++ b/map_gen/shared/generate.lua @@ -3,6 +3,7 @@ local Token = require 'utils.token' local Event = require 'utils.event' local insert = table.insert +local raise_event = script.raise_event local tiles_per_tick local regen_decoratives @@ -15,6 +16,12 @@ local Public = {} -- Set to false by modules that want to control the on_chunk_generated event themselves. Public.enable_register_events = true +local on_chunk_generated = Event.generate_event_name('generate_on_chunk_generated') + +Public.events = { + on_chunk_generated = on_chunk_generated +} + local function do_tile_inner(tiles, tile, pos) if not tile then insert(tiles, {name = 'out-of-map', position = pos}) @@ -210,6 +217,7 @@ local function map_gen_action(data) return true elseif state == 36 then run_chart_update(data) + raise_event(on_chunk_generated, data) return false end end @@ -234,6 +242,7 @@ function Public.schedule_chunk(event) area = area, top_x = area.left_top.x, top_y = area.left_top.y, + position = event.position, surface = surface, tiles = {}, hidden_tiles = {}, @@ -260,6 +269,7 @@ function Public.do_chunk(event) area = area, top_x = area.left_top.x, top_y = area.left_top.y, + position = event.position, surface = surface, tiles = {}, hidden_tiles = {}, @@ -275,6 +285,8 @@ function Public.do_chunk(event) do_place_hidden_tiles(data) do_place_entities(data) do_place_decoratives(data) + + raise_event(on_chunk_generated, data) end --- Sets the variables for the generate functions, should only be called from map_loader