1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2024-12-12 10:04:40 +02:00

Merge pull request #1216 from Soggs/master

Fix the desync on Danger Ores Circles.
This commit is contained in:
grilledham 2021-05-23 13:27:23 +01:00 committed by GitHub
commit e86ddf5394
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 52 deletions

View File

@ -2,67 +2,50 @@ local Helper = require 'map_gen.maps.danger_ores.modules.helper'
local b = require 'map_gen.shared.builders'
local table = require 'utils.table'
local binary_search = table.binary_search
local bnot = bit32.bnot
local sqrt = math.sqrt
local floor = math.floor
local value = b.manhattan_value
return function(config)
local main_ores = config.main_ores
local main_ores_split_count = config.main_ores_split_count or 1
local main_ores_rotate = config.main_ores_rotate or 0
local start_ore_shape = config.start_ore_shape
local circle_thickenss = config.circle_thickness or 16
main_ores = Helper.split_ore(main_ores, main_ores_split_count)
if config.main_ores_shuffle_order then
table.shuffle_table(main_ores)
end
return function(tile_builder, ore_builder, spawn_shape, water_shape, random_gen)
local starting_ores_list = {}
local shapes = {}
local function condition_factory(ore_name)
local scale = config.circle_scale or 1
--local randomize_scale = config.randomize_scale or false
local ore_table = {}
for _, ore_data in pairs(main_ores) do
table.insert(ore_table, {name = ore_data.name, weight = ore_data.weight})
end
local weighted = b.prepare_weighted_array(ore_table)
return function(x, y, _)
local i = floor(sqrt(x * x + y * y) * scale) % weighted.total + 1
local index = binary_search(weighted, i)
if index < 0 then
index = bnot(index)
for _, ore_data in pairs(main_ores) do
local ore_name = ore_data.name
local tiles = ore_data.tiles
local start_amount = ore_data.start
local ratios = ore_data.ratios
local ore_weight = ore_data.weight
local weighted = b.prepare_weighted_array(ratios)
local land = tile_builder(tiles)
local start_ore = b.apply_entity(land, b.resource(b.full_shape, ore_name, start_amount))
start_ore = b.choose(start_ore_shape, start_ore, b.empty_shape)
starting_ores_list[#starting_ores_list + 1] = {shape = start_ore, weight = ore_weight}
local ore = ore_builder(ore_name, start_amount, ratios, weighted)
local shape = b.apply_entity(land, ore)
shapes[#shapes + 1] = {shape = shape, weight = ore_weight}
end
return ore_table[index].name == ore_name
end
end
return function(tile_builder, ore_builder, spawn_shape, water_shape, _)
if config.main_ores_shuffle_order then
table.shuffle_table(starting_ores_list, random_gen)
table.shuffle_table(shapes, random_gen)
end
local shapes = {}
local starting_ores_list = {}
for _, ore_data in pairs(main_ores) do
local ore_name = ore_data.name
local tiles = ore_data.tiles
local land = tile_builder(tiles)
local starting_ores = b.segment_weighted_pattern(starting_ores_list)
local ores = b.ring_weighted_pattern(shapes, circle_thickenss)
table.insert(starting_ores_list, b.resource(start_ore_shape, ore_name, value(100, 0)))
if main_ores_rotate ~= 0 then
-- Only makes sense to rotate starting ores as the main ores are a circle.
starting_ores = b.rotate(starting_ores, math.rad(main_ores_rotate))
end
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 condition = condition_factory(ore_name)
local shape = b.choose(condition, b.apply_entity(land, ore), b.empty_shape)
table.insert(shapes, shape)
end
local ores = b.any(shapes)
local starting_ores = b.change_map_gen_collision_tile(start_ore_shape, 'water-tile', 'grass-1')
starting_ores = b.apply_entity(starting_ores, b.segment_pattern(starting_ores_list))
return b.any {spawn_shape, starting_ores ,water_shape, ores}
return b.any {spawn_shape, water_shape, starting_ores, ores}
end
end

View File

@ -109,7 +109,7 @@ local rocket_launched = require 'map_gen.maps.danger_ores.modules.rocket_launche
rocket_launched({win_satellite_count = 500})
local restart_command = require 'map_gen.maps.danger_ores.modules.restart_command'
restart_command({scenario_name = 'danger-ore-gradient'})
restart_command({scenario_name = 'danger-ore-circles'})
local container_dump = require 'map_gen.maps.danger_ores.modules.container_dump'
container_dump({entity_name = 'coal'})
@ -125,7 +125,7 @@ local config = {
main_ores_builder = main_ores_builder,
main_ores = main_ores_config,
main_ores_shuffle_order = true,
main_ores_rotate = 0,
main_ores_rotate = 30,
resource_patches = resource_patches,
resource_patches_config = resource_patches_config,
water = water,
@ -145,7 +145,7 @@ local config = {
dense_patches_scale = 1 / 48,
dense_patches_threshold = 0.55,
dense_patches_multiplier = 25,
circle_scale = 1/16 -- regulates the width of each circle
circle_thickness = 16 -- Thickness of the rings at weight 1
}
return map(config)

View File

@ -1517,6 +1517,43 @@ function Builders.segment_weighted_pattern(pattern)
end
end
function Builders.ring_pattern(pattern, thickness)
local count = #pattern
local scale = 1 / thickness
return function(x, y, world)
local d = sqrt(x * x + y * y)
local index = floor(d * scale) % count + 1
local shape = pattern[index] or Builders.empty_shape
return shape(x, y, world)
end
end
function Builders.ring_weighted_pattern(pattern, thickness)
local weights = Builders.prepare_weighted_array(pattern)
local total = weights.total
local scale = 1 / thickness
return function(x, y, world)
local d = sqrt(x * x + y * y)
local i = (d * scale) % total
local index = binary_search(weights, i)
if index < 0 then
index = bnot(index)
end
local data = pattern[index]
local shape
if data then
shape = data.shape
end
shape = shape or Builders.empty_shape
return shape(x, y, world)
end
end
local function rotate_cords(angle)
local qx = cos(angle)
local qy = sin(angle)