From 37e218041ce4f65c08eff4a559e09cb4084e8cb5 Mon Sep 17 00:00:00 2001 From: Karel Date: Thu, 11 Apr 2019 21:37:32 +0200 Subject: [PATCH] added tile_picker feature for better dirt generation --- map_gen/maps/diggy/config.lua | 11 +++ map_gen/maps/diggy/feature/diggy_hole.lua | 10 ++- map_gen/maps/diggy/feature/starting_zone.lua | 9 ++- map_gen/maps/diggy/feature/tile_picker.lua | 78 ++++++++++++++++++++ map_gen/maps/diggy/scenario.lua | 7 +- 5 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 map_gen/maps/diggy/feature/tile_picker.lua diff --git a/map_gen/maps/diggy/config.lua b/map_gen/maps/diggy/config.lua index 0fcd13ca1..e9eaea74e 100644 --- a/map_gen/maps/diggy/config.lua +++ b/map_gen/maps/diggy/config.lua @@ -448,6 +448,17 @@ local Config = { ['behemoth-spitter'] = 7, }, }, + -- perlin noise for dirt generation + tile_picker = { + -- uses perlin noise when true, random when false + enabled = true, + + -- tiles to pick from + tiles = {'dirt-1', 'dirt-2', 'dirt-3', 'dirt-4', 'dirt-5', 'dirt-6', 'dirt-7'}, + + -- value between 0 and 1, higher values means smaller areas with same tile + noise_variance = 0.03 + } }, } diff --git a/map_gen/maps/diggy/feature/diggy_hole.lua b/map_gen/maps/diggy/feature/diggy_hole.lua index 8d2affa75..a4f52a0c5 100644 --- a/map_gen/maps/diggy/feature/diggy_hole.lua +++ b/map_gen/maps/diggy/feature/diggy_hole.lua @@ -11,6 +11,7 @@ local ScoreTable = require 'map_gen.maps.diggy.score_table' local Command = require 'utils.command' local CreateParticles = require 'features.create_particles' local Ranks = require 'resources.ranks' +local TilePicker = require 'map_gen.maps.diggy.feature.tile_picker' local random = math.random local tonumber = tonumber @@ -89,7 +90,8 @@ local function diggy_hole(entity) for i = #out_of_map_found, 1, -1 do local void_position = out_of_map_found[i] - tiles[i] = {name = 'dirt-' .. random(1, 7), position = void_position} + local tile_name = TilePicker.get_tile(void_position.x, void_position.y) + tiles[i] = {name = tile_name, position = void_position} local predicted = random() if predicted < 0.2 then rocks[i] = {name = 'rock-huge', position = void_position} @@ -120,7 +122,8 @@ local function on_mined_tile(surface, tiles) for _, tile in pairs(tiles) do if (artificial_tiles[tile.old_tile.name]) then count = count + 1 - new_tiles[count] = {name = 'dirt-' .. random(1, 7), position = tile.position} + local tile_name = TilePicker.get_tile(tile.position.x, tile.position.y) + new_tiles[count] = {name = tile_name, position = tile.position} end end @@ -141,7 +144,8 @@ Command.add('diggy-clear-void', { for x = 0, width do for y = 0, height do count = count + 1 - tiles[count] = {name = 'dirt-' .. random(1, 7), position = {x = x + left_top_x, y = y + left_top_y}} + local tile_name = TilePicker.get_tile(x + left_top_x, y + left_top_y) + tiles[count] = {name = tile_name, position = {x = x + left_top_x, y = y + left_top_y}} end end diff --git a/map_gen/maps/diggy/feature/starting_zone.lua b/map_gen/maps/diggy/feature/starting_zone.lua index bbc3e2036..3309722fa 100644 --- a/map_gen/maps/diggy/feature/starting_zone.lua +++ b/map_gen/maps/diggy/feature/starting_zone.lua @@ -8,9 +8,9 @@ local Template = require 'map_gen.maps.diggy.template' local Retailer = require 'features.retailer' local DiggyCaveCollapse = require 'map_gen.maps.diggy.feature.diggy_cave_collapse' local RS = require 'map_gen.shared.redmew_surface' +local TilePicker = require 'map_gen.maps.diggy.feature.tile_picker' local insert = table.insert -local random = math.random local sqrt = math.sqrt local floor = math.floor local pairs = pairs @@ -51,13 +51,18 @@ function StartingZone.register(config) local rock_range = starting_zone_size - 2 local stress_hack = floor(starting_zone_size * 0.1) + -- init tile picker + local seed = surface.map_gen_settings.seed + surface.index + 300 + TilePicker.set_seed(seed) + for x = -starting_zone_size, starting_zone_size do for y = -starting_zone_size, starting_zone_size do local distance = floor(sqrt(x * x + y * y)) if (distance < starting_zone_size) then if (distance > dirt_range) then - insert(tiles, {name = 'dirt-' .. random(1, 7), position = {x = x, y = y}}) + local tile_name = TilePicker.get_tile(x, y) + insert(tiles, {name = tile_name, position = {x = x, y = y}}) else insert(tiles, {name = 'stone-path', position = {x = x, y = y}}) end diff --git a/map_gen/maps/diggy/feature/tile_picker.lua b/map_gen/maps/diggy/feature/tile_picker.lua new file mode 100644 index 000000000..a1deb8e67 --- /dev/null +++ b/map_gen/maps/diggy/feature/tile_picker.lua @@ -0,0 +1,78 @@ +--[[-- info + Provides nicer tile picking +]] + +-- dependencies +local Event = require 'utils.event' +local perlin_noise = require 'map_gen.shared.perlin_noise'.noise + +-- this +local Picker = {} + +local floor = math.floor +local random = math.random + +local enabled = false +local replacement_tiles +local tile_count +local noise_variance +local seed + +-- should be called once before calling get_tile +function Picker.set_seed(new_seed) + seed = new_seed +end + +-- returns tile generated by perlin noise from coordinates +function Picker.get_tile(x, y) + if not enabled then + return 'dirt-' .. random(1, 7) + end + + -- value in range [-1, 1] + local noise + if seed then + noise = perlin_noise(x * noise_variance, y * noise_variance, seed) + else + noise = perlin_noise(x * noise_variance, y * noise_variance) + end + + -- value in range [0, 1] + local corrected_noise = (noise + 1) / 2 + + -- value in range [1, tile_count] + local tile_number = floor(corrected_noise * tile_count) + 1 + + -- just in case perlin_noise() returns '1', not even sure if it can + if tile_number > tile_count then + tile_number = tile_count + end + + return replacement_tiles[tile_number] +end + +function Picker.register(config) + enabled = true + replacement_tiles = config.tiles or {'dirt-1', 'dirt-2', 'dirt-3', 'dirt-4', 'dirt-5', 'dirt-6', 'dirt-7'} + tile_count = #replacement_tiles + noise_variance = config.noise_variance or 0.03 + + -- add landfill event + Event.add(defines.events.on_player_built_tile, function(event) + local item = event.item + if not item or item.name ~= 'landfill' then + return + end + + local tiles = event.tiles + for i = 1, #tiles do + local tile_name = Picker.get_tile(tiles[i].position.x, tiles[i].position.y) + tiles[i].name = tile_name + end + + local surface = game.surfaces[event.surface_index] + surface.set_tiles(tiles) + end) +end + +return Picker diff --git a/map_gen/maps/diggy/scenario.lua b/map_gen/maps/diggy/scenario.lua index 09ae5dad1..287bbe04b 100644 --- a/map_gen/maps/diggy/scenario.lua +++ b/map_gen/maps/diggy/scenario.lua @@ -73,8 +73,11 @@ function Scenario.register() end ) - local landfill_tiles = {'dirt-1','dirt-2','dirt-3','dirt-4','dirt-5','dirt-6','dirt-7'} - require ('map_gen.shared.change_landfill_tile')(landfill_tiles) + -- tile_picker adds its own landfill event + if not Config.features.tile_picker.enabled then + local landfill_tiles = {'dirt-1','dirt-2','dirt-3','dirt-4','dirt-5','dirt-6','dirt-7'} + require ('map_gen.shared.change_landfill_tile')(landfill_tiles) + end ScenarioInfo.set_map_name('Diggy') ScenarioInfo.set_map_description('Dig your way through!')