mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-12 10:04:40 +02:00
updates
This commit is contained in:
parent
7199cfa497
commit
e4cf31a6fb
@ -4,6 +4,45 @@ local Token = require 'utils.global_token'
|
||||
local direction_bit_mask = 0xc0000000
|
||||
local section_bit_mask = 0x30000000
|
||||
local level_bit_mask = 0x0fffffff
|
||||
local not_level_bit_mask = 0xf0000000
|
||||
local direction_bit_shift = 30
|
||||
local section_bit_shift = 28
|
||||
|
||||
local section_straight = 0
|
||||
local section_outer_corner = 1
|
||||
local section_inner_corner = 2
|
||||
|
||||
local wall_north_straight = 0x00000001
|
||||
local wall_east_straight = 0x40000001
|
||||
local wall_south_straight = 0x80000001
|
||||
local wall_west_straight = 0xc0000001
|
||||
local wall_north_outer = 0x10000001
|
||||
local wall_east_outer = 0x50000001
|
||||
local wall_south_outer = 0x90000001
|
||||
local wall_west_outer = 0xd0000001
|
||||
local wall_north_inner = 0x20000001
|
||||
local wall_east_inner = 0x60000001
|
||||
local wall_south_inner = 0xa0000001
|
||||
local wall_west_inner = 0xe0000001
|
||||
|
||||
local function get_direction(part)
|
||||
local dir = bit32.band(part, direction_bit_mask)
|
||||
return bit32.rshift(dir, direction_bit_shift - 1)
|
||||
end
|
||||
|
||||
local function get_section(part)
|
||||
local sec = bit32.band(part, section_bit_mask)
|
||||
return bit32.rshift(sec, section_bit_shift)
|
||||
end
|
||||
|
||||
local function get_level(part)
|
||||
return bit32.band(part, level_bit_mask)
|
||||
end
|
||||
|
||||
local function set_level(part, level)
|
||||
local not_level = bit32.band(part)
|
||||
return not_level + level
|
||||
end
|
||||
|
||||
local function set_block(tbl, x, y, value)
|
||||
tbl[(y - 1) * tbl.size + x] = value
|
||||
@ -26,79 +65,6 @@ function Public.new(seed)
|
||||
return setmetatable(obj, Public)
|
||||
end
|
||||
|
||||
local function set_wall_block(blocks, x, y)
|
||||
set_block(blocks, x, y, 1)
|
||||
table.insert(blocks.stack, {x = x, y = y})
|
||||
end
|
||||
|
||||
local function goto_point_top(blocks, x, y, tx, ty)
|
||||
while x < tx do
|
||||
x = x + 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
|
||||
while y > ty do
|
||||
y = y - 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
|
||||
while y < ty do
|
||||
y = y + 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
local function goto_point_bottom(blocks, x, y, tx, ty)
|
||||
while x > tx do
|
||||
x = x - 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
|
||||
while y > ty do
|
||||
y = y - 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
|
||||
while y < ty do
|
||||
y = y + 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
local function goto_point_left(blocks, x, y, tx, ty)
|
||||
while y > ty do
|
||||
y = y - 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
|
||||
while x > tx do
|
||||
x = x - 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
|
||||
while x < tx do
|
||||
x = x + 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
local function goto_point_right(blocks, x, y, tx, ty)
|
||||
while y < ty do
|
||||
y = y + 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
|
||||
while x > tx do
|
||||
x = x - 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
|
||||
while x < tx do
|
||||
x = x + 1
|
||||
set_wall_block(blocks, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
local function do_walls(self, blocks, outpost_variance, outpost_min_step)
|
||||
local size = blocks.size
|
||||
local random = self.random
|
||||
@ -109,86 +75,282 @@ local function do_walls(self, blocks, outpost_variance, outpost_min_step)
|
||||
local x = random:next_int(1, outpost_variance)
|
||||
local y = random:next_int(1, outpost_variance)
|
||||
|
||||
set_block(blocks, x, y, 1)
|
||||
table.insert(blocks.stack, {x = x, y = y})
|
||||
local start_x, start_y = x, y
|
||||
|
||||
local i = (y - 1) * size + x
|
||||
|
||||
local pv = -1
|
||||
|
||||
-- top
|
||||
while x < size do
|
||||
local tx = x + random:next_int(outpost_min_step, variance_step)
|
||||
tx = math.min(size, tx)
|
||||
local ty = random:next_int(1, outpost_variance)
|
||||
tx = math.min(tx, size)
|
||||
|
||||
goto_point_top(blocks, x, y, tx, ty)
|
||||
if pv == 0 then
|
||||
blocks[i] = wall_north_straight
|
||||
elseif pv == -1 then
|
||||
blocks[i] = wall_north_outer
|
||||
else
|
||||
blocks[i] = wall_north_inner
|
||||
end
|
||||
|
||||
x, y = tx, ty
|
||||
x = x + 1
|
||||
i = i + 1
|
||||
|
||||
while x < tx do
|
||||
blocks[i] = wall_north_straight
|
||||
x = x + 1
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
if x < size - outpost_min_step then
|
||||
local ty = random:next_int(1, outpost_variance)
|
||||
|
||||
if y == ty then
|
||||
pv = 0
|
||||
elseif y < ty then
|
||||
pv = 1
|
||||
blocks[i] = wall_north_outer
|
||||
y = y + 1
|
||||
i = i + size
|
||||
while y < ty do
|
||||
blocks[i] = wall_east_straight
|
||||
y = y + 1
|
||||
i = i + size
|
||||
end
|
||||
else
|
||||
pv = -1
|
||||
blocks[i] = wall_north_inner
|
||||
y = y - 1
|
||||
i = i - size
|
||||
while y > ty do
|
||||
blocks[i] = wall_west_straight
|
||||
y = y - 1
|
||||
i = i - size
|
||||
end
|
||||
end
|
||||
else
|
||||
pv = 0
|
||||
end
|
||||
end
|
||||
|
||||
pv = 1
|
||||
-- right
|
||||
while y < size do
|
||||
local tx = random:next_int(max_variance, size)
|
||||
local ty = y + random:next_int(outpost_min_step, variance_step)
|
||||
ty = math.min(size, ty)
|
||||
ty = math.min(ty, size)
|
||||
|
||||
goto_point_right(blocks, x, y, tx, ty)
|
||||
if pv == 0 then
|
||||
blocks[i] = wall_east_straight
|
||||
elseif pv == -1 then
|
||||
blocks[i] = wall_east_inner
|
||||
else
|
||||
blocks[i] = wall_east_outer
|
||||
end
|
||||
|
||||
x, y = tx, ty
|
||||
y = y + 1
|
||||
i = i + size
|
||||
|
||||
while y < ty do
|
||||
blocks[i] = wall_east_straight
|
||||
y = y + 1
|
||||
i = i + size
|
||||
end
|
||||
|
||||
if y < size - outpost_min_step then
|
||||
local tx = random:next_int(max_variance, size)
|
||||
|
||||
if x == tx then
|
||||
pv = 0
|
||||
elseif x < tx then
|
||||
pv = 1
|
||||
blocks[i] = wall_east_inner
|
||||
x = x + 1
|
||||
i = i + 1
|
||||
while x < tx do
|
||||
blocks[i] = wall_north_straight
|
||||
x = x + 1
|
||||
i = i + 1
|
||||
end
|
||||
else
|
||||
pv = -1
|
||||
blocks[i] = wall_east_outer
|
||||
x = x - 1
|
||||
i = i - 1
|
||||
while x > tx do
|
||||
blocks[i] = wall_south_straight
|
||||
x = x - 1
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
else
|
||||
pv = 0
|
||||
end
|
||||
end
|
||||
|
||||
pv = 1
|
||||
|
||||
-- bottom
|
||||
while x > 1 do
|
||||
local tx = x - random:next_int(outpost_min_step, variance_step)
|
||||
tx = math.max(1, tx)
|
||||
local ty = random:next_int(max_variance, size)
|
||||
tx = math.max(tx, 1)
|
||||
|
||||
goto_point_bottom(blocks, x, y, tx, ty)
|
||||
if pv == 0 then
|
||||
blocks[i] = wall_south_straight
|
||||
elseif pv == -1 then
|
||||
blocks[i] = wall_south_inner
|
||||
else
|
||||
blocks[i] = wall_south_outer
|
||||
end
|
||||
|
||||
x, y = tx, ty
|
||||
x = x - 1
|
||||
i = i - 1
|
||||
|
||||
while x > tx do
|
||||
blocks[i] = wall_south_straight
|
||||
x = x - 1
|
||||
i = i - 1
|
||||
end
|
||||
|
||||
if x > outpost_min_step + 1 then
|
||||
local ty = random:next_int(max_variance, size)
|
||||
|
||||
if y == ty then
|
||||
pv = 0
|
||||
elseif y < ty then
|
||||
pv = 1
|
||||
blocks[i] = wall_south_inner
|
||||
y = y + 1
|
||||
i = i + size
|
||||
while y < ty do
|
||||
blocks[i] = wall_east_straight
|
||||
y = y + 1
|
||||
i = i + size
|
||||
end
|
||||
else
|
||||
pv = -1
|
||||
blocks[i] = wall_south_outer
|
||||
y = y - 1
|
||||
i = i - size
|
||||
while y > ty do
|
||||
blocks[i] = wall_west_straight
|
||||
y = y - 1
|
||||
i = i - size
|
||||
end
|
||||
end
|
||||
else
|
||||
pv = 0
|
||||
end
|
||||
end
|
||||
|
||||
pv = -1
|
||||
-- left
|
||||
local bottom_left_y = y
|
||||
while y > start_y + variance_step do
|
||||
local ty = y - random:next_int(outpost_min_step, variance_step)
|
||||
ty = math.max(ty, start_y)
|
||||
|
||||
if pv == 0 then
|
||||
blocks[i] = wall_west_straight
|
||||
elseif pv == -1 then
|
||||
blocks[i] = wall_west_outer
|
||||
else
|
||||
blocks[i] = wall_west_inner
|
||||
end
|
||||
|
||||
y = y - 1
|
||||
i = i - size
|
||||
|
||||
while y > ty do
|
||||
blocks[i] = wall_west_straight
|
||||
y = y - 1
|
||||
i = i - size
|
||||
end
|
||||
|
||||
if y > start_y + variance_step + outpost_min_step then
|
||||
local tx = random:next_int(1, outpost_variance)
|
||||
|
||||
if x == tx then
|
||||
pv = 0
|
||||
elseif x < tx then
|
||||
pv = 1
|
||||
blocks[i] = wall_west_outer
|
||||
x = x + 1
|
||||
i = i + 1
|
||||
while x < tx do
|
||||
blocks[i] = wall_north_straight
|
||||
x = x + 1
|
||||
i = i + 1
|
||||
end
|
||||
else
|
||||
pv = -1
|
||||
blocks[i] = wall_west_inner
|
||||
x = x - 1
|
||||
i = i - 1
|
||||
while x > tx do
|
||||
blocks[i] = wall_south_straight
|
||||
x = x - 1
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
else
|
||||
pv = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- final connection
|
||||
if y == bottom_left_y then
|
||||
blocks[i] = wall_west_outer
|
||||
|
||||
y = y - 1
|
||||
i = i - size
|
||||
|
||||
while y > bottom_left_y - outpost_min_step do
|
||||
blocks[i] = wall_west_straight
|
||||
y = y - 1
|
||||
i = i - size
|
||||
end
|
||||
end
|
||||
|
||||
if x == start_x then
|
||||
pv = 0
|
||||
elseif x < start_x then
|
||||
pv = 1
|
||||
blocks[i] = wall_west_outer
|
||||
x = x + 1
|
||||
i = i + 1
|
||||
while x < start_x do
|
||||
blocks[i] = wall_north_straight
|
||||
x = x + 1
|
||||
i = i + 1
|
||||
end
|
||||
else
|
||||
pv = -1
|
||||
blocks[i] = wall_west_inner
|
||||
x = x - 1
|
||||
i = i - 1
|
||||
while x > start_x do
|
||||
blocks[i] = wall_south_straight
|
||||
x = x - 1
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
|
||||
if pv == 0 then
|
||||
blocks[i] = wall_west_straight
|
||||
elseif pv == -1 then
|
||||
blocks[i] = wall_west_outer
|
||||
else
|
||||
blocks[i] = wall_west_inner
|
||||
end
|
||||
|
||||
y = y - 1
|
||||
i = i - size
|
||||
|
||||
while y > start_y do
|
||||
local tx = random:next_int(1, outpost_variance)
|
||||
local ty = y - random:next_int(outpost_min_step, variance_step)
|
||||
|
||||
if ty <= start_y then
|
||||
ty = start_y
|
||||
tx = start_x
|
||||
end
|
||||
|
||||
goto_point_left(blocks, x, y, tx, ty)
|
||||
|
||||
x, y = tx, ty
|
||||
end
|
||||
end
|
||||
|
||||
local function remove_surplus_walls(blocks)
|
||||
local stack = blocks.stack
|
||||
local size = blocks.size
|
||||
|
||||
while #stack > 0 do
|
||||
local count = 0
|
||||
local nx, ny
|
||||
local point = table.remove(stack)
|
||||
local x, y = point.x, point.y
|
||||
|
||||
if x > 1 and get_block(blocks, x - 1, y) == 1 then
|
||||
nx, ny = x - 1, y
|
||||
count = count + 1
|
||||
end
|
||||
if x < size and get_block(blocks, x + 1, y) == 1 then
|
||||
nx, ny = x + 1, y
|
||||
count = count + 1
|
||||
end
|
||||
if y > 1 and get_block(blocks, x, y - 1) == 1 then
|
||||
nx, ny = x, y - 1
|
||||
count = count + 1
|
||||
end
|
||||
if y < size and get_block(blocks, x, y + 1) == 1 then
|
||||
nx, ny = x, y + 1
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
if count == 1 then
|
||||
set_block(blocks, x, y, 0)
|
||||
table.insert(stack, {x = nx, y = ny})
|
||||
end
|
||||
blocks[i] = wall_west_straight
|
||||
y = y - 1
|
||||
i = i - size
|
||||
end
|
||||
end
|
||||
|
||||
@ -199,22 +361,22 @@ local function fill(blocks)
|
||||
|
||||
local y_offset = (size - 1) * size
|
||||
for x = 1, size do
|
||||
if blocks[x] ~= 1 then
|
||||
if blocks[x] == nil then
|
||||
table.insert(anti_stack, {x = x, y = 1})
|
||||
end
|
||||
|
||||
if blocks[x + y_offset] ~= 1 then
|
||||
if blocks[x + y_offset] == nil then
|
||||
table.insert(anti_stack, {x = x, y = size})
|
||||
end
|
||||
end
|
||||
|
||||
for y = 2, size do
|
||||
y_offset = (y - 1) * size
|
||||
if blocks[y_offset + 1] ~= 1 then
|
||||
if blocks[y_offset + 1] == nil then
|
||||
table.insert(anti_stack, {x = 1, y = y})
|
||||
end
|
||||
|
||||
if blocks[y_offset + size] ~= 1 then
|
||||
if blocks[y_offset + size] == nil then
|
||||
table.insert(anti_stack, {x = size, y = y})
|
||||
end
|
||||
end
|
||||
@ -225,13 +387,13 @@ local function fill(blocks)
|
||||
|
||||
local offset = (y - 1) * size + x
|
||||
|
||||
anti_set[offset] = 1
|
||||
anti_set[offset] = true
|
||||
|
||||
if x > 1 then
|
||||
local x2 = x - 1
|
||||
local offset2 = offset - 1
|
||||
|
||||
if anti_set[offset2] ~= 1 and blocks[offset2] ~= 1 then
|
||||
if not anti_set[offset2] and not blocks[offset2] then
|
||||
table.insert(anti_stack, {x = x2, y = y})
|
||||
end
|
||||
end
|
||||
@ -239,7 +401,7 @@ local function fill(blocks)
|
||||
local x2 = x + 1
|
||||
local offset2 = offset + 1
|
||||
|
||||
if anti_set[offset2] ~= 1 and blocks[offset2] ~= 1 then
|
||||
if not anti_set[offset2] and not blocks[offset2] then
|
||||
table.insert(anti_stack, {x = x2, y = y})
|
||||
end
|
||||
end
|
||||
@ -247,7 +409,7 @@ local function fill(blocks)
|
||||
local y2 = y - 1
|
||||
local offset2 = offset - size
|
||||
|
||||
if anti_set[offset2] ~= 1 and blocks[offset2] ~= 1 then
|
||||
if not anti_set[offset2] and not blocks[offset2] then
|
||||
table.insert(anti_stack, {x = x, y = y2})
|
||||
end
|
||||
end
|
||||
@ -255,7 +417,7 @@ local function fill(blocks)
|
||||
local y2 = y + 1
|
||||
local offset2 = offset + size
|
||||
|
||||
if anti_set[offset2] ~= 1 and blocks[offset2] ~= 1 then
|
||||
if not anti_set[offset2] and not blocks[offset2] then
|
||||
table.insert(anti_stack, {x = x, y = y2})
|
||||
end
|
||||
end
|
||||
@ -265,49 +427,41 @@ local function fill(blocks)
|
||||
local offset = (y - 1) * size
|
||||
for x = 1, size do
|
||||
local i = offset + x
|
||||
if anti_set[i] ~= 1 then
|
||||
blocks[i] = 1
|
||||
if not anti_set[i] and not blocks[i] then
|
||||
blocks[i] = 2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function do_levels(blocks, max_level)
|
||||
if max_level < 2 then
|
||||
if max_level < 3 then
|
||||
return
|
||||
end
|
||||
|
||||
local size = blocks.size
|
||||
|
||||
--[[ for y = 1, size do
|
||||
local offset = (y - 1) * size
|
||||
for x = 1, size do
|
||||
local i = offset + x
|
||||
end
|
||||
end ]]
|
||||
|
||||
local level = 1
|
||||
local next_level = 2
|
||||
local level = 2
|
||||
|
||||
repeat
|
||||
local next_level = level + 1
|
||||
for y = 1, size do
|
||||
local offset = (y - 1) * size
|
||||
for x = 1, size do
|
||||
local i = offset + x
|
||||
|
||||
if (blocks[i] or 0) >= level then
|
||||
if get_level(blocks[i] or 0) >= level then
|
||||
local count = 0
|
||||
|
||||
if x > 1 and (blocks[i - 1] or 0) >= level then
|
||||
if x > 1 and get_level(blocks[i - 1] or 0) >= level then
|
||||
count = count + 1
|
||||
end
|
||||
if x < size and (blocks[i + 1] or 0) >= level then
|
||||
if x < size and get_level(blocks[i + 1] or 0) >= level then
|
||||
count = count + 1
|
||||
end
|
||||
if y > 1 and (blocks[i - size] or 0) >= level then
|
||||
if y > 1 and get_level(blocks[i - size] or 0) >= level then
|
||||
count = count + 1
|
||||
end
|
||||
if y < size and (blocks[i + size] or 0) >= level then
|
||||
if y < size and get_level(blocks[i + size] or 0) >= level then
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
@ -319,8 +473,7 @@ local function do_levels(blocks, max_level)
|
||||
end
|
||||
|
||||
level = level + 1
|
||||
next_level = next_level + 1
|
||||
until next_level == max_level + 1
|
||||
until level == max_level
|
||||
end
|
||||
|
||||
local callback =
|
||||
@ -331,25 +484,50 @@ local callback =
|
||||
)
|
||||
|
||||
function Public:do_outpost(outpost_blocks, outpost_variance, outpost_min_step, max_level)
|
||||
local blocks = {size = outpost_blocks, stack = {}}
|
||||
local blocks = {size = outpost_blocks}
|
||||
|
||||
do_walls(self, blocks, outpost_variance, outpost_min_step)
|
||||
remove_surplus_walls(blocks)
|
||||
fill(blocks)
|
||||
do_levels(blocks, max_level)
|
||||
|
||||
local size = blocks.size
|
||||
|
||||
return function(x, y)
|
||||
x, y = math.floor(x), math.floor(y)
|
||||
local level = get_block(blocks, x, y)
|
||||
if x < 1 or x > size or y < 1 or y > size then
|
||||
return
|
||||
end
|
||||
|
||||
if level == 1 then
|
||||
return {name = 'stone-wall', force = 'player'}
|
||||
elseif level == 2 then
|
||||
return {name = 'transport-belt', force = 'player'}
|
||||
elseif level == 3 then
|
||||
return {name = 'pipe', force = 'player', callback = callback}
|
||||
elseif level == 4 then
|
||||
return {name = 'iron-chest', force = 'player'}
|
||||
local part = blocks[(y - 1) * blocks.size + x]
|
||||
|
||||
if part then
|
||||
local direction = get_direction(part)
|
||||
local section = get_section(part)
|
||||
local level = get_level(part)
|
||||
|
||||
local name
|
||||
if level == 2 then
|
||||
name = 'wooden-chest'
|
||||
elseif level == 3 then
|
||||
name = 'iron-chest'
|
||||
elseif level == 4 then
|
||||
name = 'steel-chest'
|
||||
elseif level > 4 then
|
||||
name = 'pipe'
|
||||
elseif level < 1 then
|
||||
name = 'small-electric-pole'
|
||||
else
|
||||
if section == section_straight then
|
||||
name = 'stone-wall'
|
||||
elseif section == section_outer_corner then
|
||||
name = 'inserter'
|
||||
elseif section == section_inner_corner then
|
||||
name = 'transport-belt'
|
||||
else
|
||||
name = 'pipe'
|
||||
end
|
||||
end
|
||||
return {name = name, force = 'player', direction = direction, callback = callback}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user