1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-10 00:43:27 +02:00
ComfyFactorio/maps/mountain_fortress_v2/collapse.lua

224 lines
6.6 KiB
Lua
Raw Normal View History

2019-11-14 17:44:08 +02:00
local Public = {}
local simplex_noise = require "utils.simplex_noise".d2
local math_random = math.random
local math_abs = math.abs
local math_sqrt = math.sqrt
local math_floor = math.floor
local table_remove = table.remove
local table_insert = table.insert
2019-11-15 00:06:15 +02:00
local table_shuffle_table = table.shuffle_table
2019-11-14 19:06:59 +02:00
local chart_radius = 30
2019-11-15 00:06:15 +02:00
local start_chunk_y = 5
2019-11-14 18:54:28 +02:00
local tile_conversion = {
["concrete"] = "stone-path",
["hazard-concrete-left"] = "stone-path",
["hazard-concrete-right"] = "stone-path",
["refined-concrete"] = "concrete",
["refined-hazard-concrete-left"] = "hazard-concrete-left",
["refined-hazard-concrete-right"] = "hazard-concrete-right",
["stone-path"] = "landfill",
}
2019-11-14 17:44:08 +02:00
local size_of_vector_list = 64
2019-11-15 00:06:15 +02:00
local function get_collapse_vectors(radius, seed)
2019-11-14 17:44:08 +02:00
local vectors = {}
local i = 1
local m = 1 / (radius * 2)
for x = radius * -1, radius, 1 do
for y = radius * -1, radius, 1 do
2019-11-15 00:06:15 +02:00
local noise = math_abs(simplex_noise(x * m, y * m, seed) * radius * 1.2)
2019-11-14 17:44:08 +02:00
local d = math_sqrt(x ^ 2 + y ^ 2)
if d + noise < radius then
vectors[i] = {x, y}
i = i + 1
end
end
end
2020-04-08 20:28:02 +02:00
2019-11-15 00:06:15 +02:00
local sorted_vectors = {}
for _, vector in pairs(vectors) do
local index = math_floor(math_sqrt(vector[1] ^ 2 + vector[2] ^ 2)) + 1
if not sorted_vectors[index] then sorted_vectors[index] = {} end
2020-04-08 20:28:02 +02:00
sorted_vectors[index][#sorted_vectors[index] + 1] = vector
2019-11-14 18:54:28 +02:00
end
2020-04-08 20:28:02 +02:00
local final_list = {}
2019-11-15 00:06:15 +02:00
for _, row in pairs(sorted_vectors) do
table_shuffle_table(row)
for _, tile in pairs(row) do
table_insert(final_list, tile)
end
end
2020-04-08 20:28:02 +02:00
2019-11-15 00:06:15 +02:00
return final_list
2019-11-14 18:54:28 +02:00
end
2019-11-16 21:50:34 +02:00
local function set_y(surface)
2019-11-15 00:06:15 +02:00
local level_width = surface.map_gen_settings.width
2019-11-16 21:50:34 +02:00
local map_collapse = global.map_collapse
local x_left = surface.map_gen_settings.width * -0.5
local x_right = surface.map_gen_settings.width * 0.5
for _ = 1, 16, 1 do
local area = {{x_left, map_collapse.last_position.y},{x_right, map_collapse.last_position.y + 1}}
if surface.count_tiles_filtered({name = "out-of-map", area = area}) < level_width then
2020-04-08 20:28:02 +02:00
return area
2019-11-15 00:06:15 +02:00
end
2019-11-16 21:50:34 +02:00
map_collapse.last_position.y = map_collapse.last_position.y - 1
2019-11-14 18:54:28 +02:00
end
2019-11-16 21:50:34 +02:00
end
local function set_positions(surface)
local area = set_y(surface)
2019-11-15 00:06:15 +02:00
if not area then return end
2019-11-14 17:44:08 +02:00
2019-11-16 21:50:34 +02:00
local map_collapse = global.map_collapse
map_collapse.positions = {}
2020-04-08 20:28:02 +02:00
2019-11-15 00:06:15 +02:00
local i = 1
for _, tile in pairs(surface.find_tiles_filtered({area = area})) do
if tile.valid then
if tile.name ~= "out-of-map" then
2019-11-16 21:50:34 +02:00
map_collapse.positions[i] = tile
2019-11-15 00:06:15 +02:00
i = i + 1
end
2019-11-14 17:44:08 +02:00
end
end
2020-04-08 20:28:02 +02:00
2019-11-16 21:50:34 +02:00
if i == 1 then
map_collapse.positions = nil
return
2019-11-15 00:06:15 +02:00
end
2019-11-16 21:50:34 +02:00
if i > 1 then table_shuffle_table(map_collapse.positions) end
2019-11-14 17:44:08 +02:00
end
local function set_collapse_tiles(surface, position, vectors)
2019-11-16 21:50:34 +02:00
local map_collapse = global.map_collapse
map_collapse.processing = {}
2019-11-14 17:44:08 +02:00
local i = 1
for _, vector in pairs(vectors) do
2020-04-08 20:28:02 +02:00
local shifted_position = {x = position[1] + vector[1], y = position[2] + vector[2] - 60}
2019-11-15 00:06:15 +02:00
local position = {x = position[1] + vector[1], y = position[2] + vector[2]}
2020-04-08 20:28:02 +02:00
local rocks = surface.find_entities_filtered{position = shifted_position, radius = 2, type = {"simple-entity", "tree"}}
if #rocks > 0 then
for i = 1, #rocks, 1 do
if rocks[i].valid then
rocks[i].destroy()
end
end
end
2019-11-14 17:44:08 +02:00
local tile = surface.get_tile(position)
2019-11-16 21:50:34 +02:00
if tile.valid and tile.name ~= "out-of-map" then
map_collapse.processing[i] = tile
2019-11-14 17:44:08 +02:00
i = i + 1
end
end
2019-11-16 21:50:34 +02:00
map_collapse.processing_index = 1
map_collapse.size_of_processing = #map_collapse.processing
end
local function clean_positions(tbl)
for k, tile in pairs(tbl) do
2020-04-08 20:28:02 +02:00
if not tile.valid then
2019-11-16 21:50:34 +02:00
table_remove(tbl, k)
else
2020-04-08 20:28:02 +02:00
if tile.name == "out-of-map" then
2019-11-16 21:50:34 +02:00
table_remove(tbl, k)
end
2020-04-08 20:28:02 +02:00
end
end
2019-11-14 17:44:08 +02:00
end
2019-11-15 00:06:15 +02:00
local function setup_next_collapse()
2019-11-14 18:54:28 +02:00
local surface = game.surfaces[global.active_surface_index]
2020-04-08 20:28:02 +02:00
local map_collapse = global.map_collapse
2019-11-15 00:06:15 +02:00
if not map_collapse.vector_list then
2020-04-08 20:28:02 +02:00
map_collapse.vector_list = {}
2019-11-15 00:06:15 +02:00
for _ = 1, size_of_vector_list, 1 do
table_insert(global.map_collapse.vector_list, get_collapse_vectors(math_random(24, 48), math_random(1, 9999999)))
2019-11-15 00:06:15 +02:00
end
end
2019-11-16 21:50:34 +02:00
if not map_collapse.positions then
2020-04-17 23:01:34 +02:00
--if math_random(1, 64) == 1 then map_collapse.last_position = {x = 0, y = 128} end
2019-11-16 21:50:34 +02:00
set_positions(surface)
return
2019-11-15 00:06:15 +02:00
end
2019-11-15 01:03:38 +02:00
2019-11-16 21:50:34 +02:00
local tile = map_collapse.positions[#map_collapse.positions]
if not tile then map_collapse.positions = nil return end
if not tile.valid then clean_positions(map_collapse.positions) return end
if tile.name == "out-of-map" then clean_positions(map_collapse.positions) return end
local position = {tile.position.x, tile.position.y}
2020-04-08 20:28:02 +02:00
2019-11-15 01:03:38 +02:00
local vectors = map_collapse.vector_list[math_random(1, size_of_vector_list)]
2019-11-16 21:50:34 +02:00
set_collapse_tiles(surface, position, vectors)
2020-04-08 20:28:02 +02:00
2019-11-15 00:06:15 +02:00
local last_position = global.map_collapse.last_position
game.forces.player.chart(surface, {{last_position.x - chart_radius, last_position.y - chart_radius},{last_position.x + chart_radius, last_position.y + chart_radius}})
global.map_collapse.last_position = {x = position[1], y = position[2]}
game.forces.player.chart(surface, {{position[1] - chart_radius, position[2] - chart_radius},{position[1] + chart_radius, position[2] + chart_radius}})
2019-11-14 18:54:28 +02:00
end
function Public.delete_out_of_map_chunks(surface)
local count = 0
for chunk in surface.get_chunks() do
if surface.count_tiles_filtered({name = "out-of-map", area = chunk.area}) == 1024 then
surface.delete_chunk({chunk.x, chunk.y})
count = count + 1
end
end
end
2019-11-16 21:50:34 +02:00
local function process_tile(surface, tile, tiles_to_set)
if not tile then return end
if not tile.valid then return end
2020-04-08 20:28:02 +02:00
local conversion_tile = tile_conversion[tile.name]
2019-11-16 21:50:34 +02:00
if conversion_tile then
table_insert(tiles_to_set, {name = conversion_tile, position = tile.position})
2020-04-08 20:28:02 +02:00
surface.create_trivial_smoke({name="train-smoke", position = tile.position})
2019-11-16 21:50:34 +02:00
else
table_insert(tiles_to_set, {name = "out-of-map", position = tile.position})
end
return true
end
2019-11-14 17:44:08 +02:00
function Public.process()
local surface = game.surfaces[global.active_surface_index]
2019-11-15 01:03:38 +02:00
local map_collapse = global.map_collapse
2020-04-08 20:28:02 +02:00
2019-11-16 21:50:34 +02:00
if map_collapse.processing_index >= map_collapse.size_of_processing then
setup_next_collapse()
2019-11-15 01:03:38 +02:00
return
2019-11-14 17:44:08 +02:00
end
2020-04-08 20:28:02 +02:00
2019-11-16 21:50:34 +02:00
local count = 0
local tiles_to_set = {}
for i = map_collapse.processing_index, map_collapse.size_of_processing, 1 do
if process_tile(surface, map_collapse.processing[i], tiles_to_set) then
count = count + 1
if count >= map_collapse.speed then break end
end
map_collapse.processing_index = map_collapse.processing_index + 1
end
2020-04-08 20:28:02 +02:00
2019-11-16 21:50:34 +02:00
if count > 1 then surface.set_tiles(tiles_to_set, true) end
2019-11-14 17:44:08 +02:00
end
function Public.init()
2019-11-16 21:50:34 +02:00
global.map_collapse = {
["processing_index"] = 0,
["size_of_processing"] = 0,
["processing"] = {},
["last_position"] = {x = 0, y = 128},
2020-04-08 20:28:02 +02:00
["speed"] = 3,
2019-11-16 21:50:34 +02:00
}
2019-11-14 17:44:08 +02:00
end
local event = require 'utils.event'
event.on_init(Public.init())
2020-04-08 20:28:02 +02:00
return Public