mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-16 10:19:27 +02:00
6aed6d6317
Add map loader
191 lines
4.8 KiB
Lua
191 lines
4.8 KiB
Lua
local Event = require 'utils.event'
|
|
local RS = require 'map_gen.shared.redmew_surface'
|
|
local Global = require 'utils.global'
|
|
|
|
local wall_thickness = 1
|
|
local cell_size = 3 --must be an uneven number
|
|
local wall_delta = math.floor((cell_size - wall_thickness) / 2)
|
|
|
|
local pixels = {}
|
|
local cells = {}
|
|
|
|
local primitives = {
|
|
max = 0,
|
|
rnd_p = 1,
|
|
walk_seed_w = 0,
|
|
walk_seed_h = 0
|
|
}
|
|
local rects = {}
|
|
local shuffle_pool = {}
|
|
|
|
Global.register(
|
|
{
|
|
primitives = primitives,
|
|
rects = rects,
|
|
shuffle_pool = shuffle_pool
|
|
},
|
|
function(tbl)
|
|
primitives = tbl.primitives
|
|
rects = tbl.rects
|
|
end
|
|
)
|
|
|
|
local function add_tile(x, y, width, height, add_cell)
|
|
if add_cell then
|
|
if cells[x] == nil then
|
|
cells[x] = {}
|
|
end
|
|
cells[x][y] = 1
|
|
end
|
|
for xpos = x, x + width - 1 do
|
|
for ypos = y, y + height - 1 do
|
|
if pixels[xpos] == nil then
|
|
pixels[xpos] = {}
|
|
end
|
|
pixels[xpos][ypos] = 1
|
|
end
|
|
end
|
|
end
|
|
|
|
primitives.max = 0
|
|
local function render()
|
|
for x, _ in pairs(pixels) do
|
|
for y, _ in pairs(pixels[x]) do
|
|
if y * 32 > primitives.max and y % 2 == 0 then
|
|
primitives.max = y * 32
|
|
end
|
|
rects[x * 32 .. '/' .. y * 32] = 1
|
|
end
|
|
end
|
|
end
|
|
|
|
primitives.rnd_p = 1
|
|
local function psd_rnd(l)
|
|
while shuffle_pool[primitives.rnd_p] < l do
|
|
primitives.rnd_p = primitives.rnd_p + 1
|
|
end
|
|
local res = shuffle_pool[primitives.rnd_p]
|
|
primitives.rnd_p = primitives.rnd_p + 1
|
|
return res
|
|
end
|
|
|
|
local function shuffle(t)
|
|
for i = 1, #t - 1 do
|
|
local r = psd_rnd(i, #t)
|
|
t[i], t[r] = t[r], t[i]
|
|
end
|
|
end
|
|
|
|
-- builds a width-by-height grid of trues
|
|
local function initialize_grid(w, h)
|
|
local a = {}
|
|
for i = 1, h do
|
|
table.insert(a, {})
|
|
for j = 1, w do
|
|
table.insert(a[i], true)
|
|
end
|
|
end
|
|
return a
|
|
end
|
|
|
|
-- average of a and b
|
|
local function avg(a, b)
|
|
return (a + b) / 2
|
|
end
|
|
|
|
local dirs = {
|
|
{x = 0, y = -2}, -- north
|
|
{x = 2, y = 0}, -- east
|
|
{x = -2, y = 0}, -- west
|
|
{x = 0, y = 2} -- south
|
|
}
|
|
|
|
local function make_maze(w, h)
|
|
local map = initialize_grid(w * 2 + 1, h * 2 + 1)
|
|
|
|
local walk
|
|
walk = function(x, y)
|
|
map[y][x] = false
|
|
|
|
local d = {1, 2, 3, 4}
|
|
shuffle(d)
|
|
for i, dirnum in pairs(d) do
|
|
local xx = x + dirs[dirnum].x
|
|
local yy = y + dirs[dirnum].y
|
|
if map[yy] and map[yy][xx] then
|
|
map[avg(y, yy)][avg(x, xx)] = false
|
|
walk(xx, yy)
|
|
end
|
|
end
|
|
end
|
|
walk(primitives.walk_seed_w, primitives.walk_seed_h)
|
|
|
|
local s = {}
|
|
for i = 1, h * 2 + 1 do
|
|
for j = 1, w * 2 + 1 do
|
|
if map[i][j] then
|
|
add_tile(i * cell_size, j * cell_size, cell_size, cell_size, true)
|
|
end
|
|
end
|
|
end
|
|
return table.concat(s)
|
|
end
|
|
|
|
local function reduce_walls()
|
|
for x, _ in pairs(cells) do
|
|
for y, _ in pairs(cells[x]) do
|
|
if cells[x - cell_size] ~= nil and cells[x - cell_size][y] ~= 1 then
|
|
add_tile(x - wall_delta, y, wall_delta, cell_size, false)
|
|
end
|
|
if cells[x + cell_size] ~= nil and cells[x + cell_size][y] ~= 1 then
|
|
add_tile(x + cell_size, y, wall_delta, cell_size, false)
|
|
end
|
|
if cells[x] ~= nil and cells[x][y - cell_size] ~= 1 then
|
|
add_tile(x - wall_delta, y - wall_delta, cell_size + 2 * wall_delta, wall_delta, false)
|
|
end
|
|
if cells[x] ~= nil and cells[x][y + cell_size] ~= 1 then
|
|
add_tile(x - wall_delta, y + cell_size, cell_size + 2 * wall_delta, wall_delta, false)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function remove_chunk(event)
|
|
local surface = event.surface
|
|
local tiles = {}
|
|
for x = event.area.left_top.x, event.area.right_bottom.x do
|
|
for y = event.area.left_top.y, event.area.right_bottom.y do
|
|
table.insert(tiles, {name = 'out-of-map', position = {x, y}})
|
|
end
|
|
end
|
|
surface.set_tiles(tiles)
|
|
end
|
|
|
|
Event.on_init(
|
|
function()
|
|
primitives.walk_seed_w = math.random(1, 50) * 2
|
|
primitives.walk_seed_h = math.random(1, 50) * 2
|
|
for i = 1, 20000 do
|
|
shuffle_pool[i] = math.random(1, 4)
|
|
end
|
|
make_maze(50, 50)
|
|
reduce_walls()
|
|
render()
|
|
end
|
|
)
|
|
|
|
Event.add(
|
|
defines.events.on_chunk_generated,
|
|
function(event)
|
|
if event.surface == RS.get_surface() then
|
|
local pos = event.area.left_top
|
|
if
|
|
math.abs(pos.x) > 10000 or math.abs(pos.y) > 10000 or
|
|
(rects[pos.x + primitives.max / 2 .. '/' .. pos.y + primitives.max / 2] == nil)
|
|
then
|
|
remove_chunk(event)
|
|
end
|
|
end
|
|
end
|
|
)
|