Attached Files |
concentric_octagon_layouts.png [^] (26,357 bytes) 2014-03-12 19:27
layout_concentric_octagons.des [^] (10,248 bytes) 2014-03-12 19:28 [Show Content] [Hide Content]###############################################################################
# layout_concentric_octagons.des:
###############################################################################
# This is properly called a labyrinth, but that name is already taken
# Idea by Vivificient, code by infiniplex
NAME: layout_concentric_octagons
DEPTH: D
WEIGHT: 10
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand no_rotate no_hmirror no_vmirror
TAGS: no_primary_vault layout_type_halls
{{
-- xx
-- xxxx
-- xxxx
-- xx
function draw_plug (x, y, fill)
for x1 = x - 1, x + 2 do
for y1 = y - 1, y + 2 do
if ( (x1 ~= x - 1 and x1 ~= x + 2)
or (y1 ~= y - 1 and y1 ~= y + 2)) then
mapgrd[x1][y1] = fill
end
end
end
end
function is_plug (x, y, check)
for x1 = x - 1, x + 2 do
for y1 = y - 1, y + 2 do
if ( (x1 ~= x - 1 and x1 ~= x + 2)
or (y1 ~= y - 1 and y1 ~= y + 2)) then
if (mapgrd[x1][y1] == check) then
return true
end
end
end
end
return false
end
function sign (n)
if (n > 0) then
return 1
elseif (n < 0) then
return -1
else
return 0
end
end
function resolve_position (layer, position, out_straight, out_diagonal)
local x
local y
if (position < layer.side_start[1]) then
-- north
local offset = position - layer.side_start[0]
x = layer.x2 + offset
y = layer.y1 - out_straight
elseif (position < layer.side_start[2]) then
-- northeast
local offset = position - layer.side_start[1]
out_diagonal = math.floor(out_diagonal)
x = layer.x3 + offset + out_diagonal
y = layer.y1 + offset - out_diagonal + 1
elseif (position < layer.side_start[3]) then
-- east
local offset = position - layer.side_start[2]
x = layer.x4 + out_straight - 1
y = layer.y2 + offset
elseif (position < layer.side_start[4]) then
-- southeast
local offset = position - layer.side_start[3]
out_diagonal = math.floor(out_diagonal)
x = layer.x4 - offset + out_diagonal - 1
y = layer.y3 + offset + out_diagonal
elseif (position < layer.side_start[5]) then
-- south
local offset = position - layer.side_start[4]
x = layer.x3 - offset - 1
y = layer.y4 + out_straight - 1
elseif (position < layer.side_start[6]) then
-- southwest
local offset = position - layer.side_start[5]
out_diagonal = math.floor(out_diagonal)
x = layer.x2 - offset - out_diagonal
y = layer.y4 - offset + out_diagonal - 1
elseif (position < layer.side_start[7]) then
-- west
local offset = position - layer.side_start[6]
x = layer.x1 - out_straight
y = layer.y3 - offset - 1
else
-- northwest
local offset = position - layer.side_start[7]
out_diagonal = math.ceil(out_diagonal) -- otherwise blocks miss hallway
x = layer.x1 + offset - out_diagonal + 1
y = layer.y2 - offset - out_diagonal
end
return x, y
end
-- draw hallways of the correct width, length, and direction
function draw_hallway_s_n (x, y, length, fill)
local sign_val = sign(length)
for y1 = y, y + length, sign(length) do
mapgrd[x ][y1] = fill
mapgrd[x + 1][y1] = fill
end
end
function draw_hallway_e_w (x, y, length, fill)
local sign_val = sign(length)
for x1 = x, x + length, sign(length) do
mapgrd[x1][y ] = fill
mapgrd[x1][y + 1] = fill
end
end
function draw_hallway_se_nw (x, y, length, fill)
local sign_val = sign(length)
for i = 0, length, sign_val do
local x1 = x + i
local y1 = y + i
mapgrd[x1][y1] = fill
if (i ~= 0) then
mapgrd[x1 - sign_val][y1 ] = fill
mapgrd[x1 ][y1 - sign_val] = fill
end
end
end
function draw_hallway_sw_ne (x, y, length, fill)
local sign_val = sign(length)
for i = 0, length, sign_val do
local x1 = x - i
local y1 = y + i
mapgrd[x1][y1] = fill
if (i ~= 0) then
mapgrd[x1 + sign_val][y1 ] = fill
mapgrd[x1 ][y1 - sign_val] = fill
end
end
end
local GXM, GYM = dgn.max_bounds()
extend_map{width = GXM, height = GYM}
fill_area{fill="x"}
local CENTER_X = GXM / 2
local CENTER_Y = GYM / 2
local HALLWAY_SIZE = 2
local layer_size = 2 * crawl.random_range(2, 4)
local center_radius = 2 * crawl.random_range(2, 3)
local layer_size_diagonal = layer_size * 3 / 4 -- can have a .5 on it
local border = crawl.random_range(2, 8 - (layer_size - 4))
local max_radius = math.min(CENTER_X, CENTER_Y) - border
local layer_count = math.floor((max_radius - center_radius) / layer_size)
local radial_seperation_min = crawl.random_range(4, 8)
local radial_seperation_max = crawl.random_range(radial_seperation_min+4, 20)
local plug_percent = crawl.random_range(0, 100)
-- make the octagon layers
local layer = {}
for i = layer_count, 0, -1 do
-- calculate octagon properties
--
-- .... y1
-- ......
-- ... ... y2
-- .. ..
-- .. ..
-- ... ... y3
-- ......
-- .... y4
--
layer[i] = {}
layer[i].radius = center_radius + layer_size * i
layer[i].oblique = layer[i].radius / 2
layer[i].x1 = CENTER_X - layer[i].radius
layer[i].x4 = CENTER_X + layer[i].radius - 1
layer[i].x2 = layer[i].x1 + layer[i].oblique
layer[i].x3 = layer[i].x4 - layer[i].oblique
layer[i].y1 = CENTER_Y - layer[i].radius
layer[i].y4 = CENTER_Y + layer[i].radius - 1
layer[i].y2 = layer[i].y1 + layer[i].oblique
layer[i].y3 = layer[i].y4 - layer[i].oblique
-- where each of the 8 sides start
-- -> needed for placing connections between rings
layer[i].side_straight = layer[i].x3 - layer[i].x2 - 1
layer[i].side_diagonal = layer[i].x4 - layer[i].x3 - 1
layer[i].side_start = {}
layer[i].side_start[0] = 0
for j = 1, 8 do
if (j % 2 == 0) then
layer[i].side_start[j]=layer[i].side_start[j-1]+layer[i].side_diagonal
else
layer[i].side_start[j]=layer[i].side_start[j-1]+layer[i].side_straight
end
end
-- draw the octagons
-- -> inner room has chance of being open
octa_room{ x1 = layer[i].x1, y1 = layer[i].y1,
x2 = layer[i].x4, y2 = layer[i].y4,
oblique = layer[i].oblique,
replace = 'x', inside = '.', outside = 'x' }
if (i > 0 or (crawl.one_chance_in(3) and layer[i].radius >= 3)) then
octa_room{ x1 = layer[i].x1 + HALLWAY_SIZE,
y1 = layer[i].y1 + HALLWAY_SIZE,
x2 = layer[i].x4 - HALLWAY_SIZE,
y2 = layer[i].y4 - HALLWAY_SIZE,
oblique = layer[i].oblique - HALLWAY_SIZE / 2,
replace = '.', inside = 'x', outside = '.' }
end
end
-- connect the layers
for i = 0, layer_count - 1 do
local total_distance = layer[i].side_start[8]
local hallway_pos = crawl.random2(total_distance)
local hallway_pos_end = hallway_pos + total_distance-radial_seperation_min
local is_next_plug = false
while (hallway_pos < hallway_pos_end) do
-- find a spot for the hallway
local hallway_pos_fixed = hallway_pos % total_distance
local good_spot = false
while (not good_spot and hallway_pos < hallway_pos_end) do
local x, y = resolve_position(layer[i], hallway_pos_fixed, 0, 0)
if (not is_plug(x, y, 'c')) then
good_spot = true
else
hallway_pos = hallway_pos + crawl.random_range(1, 4)
hallway_pos_fixed = hallway_pos % total_distance
end
end
if (good_spot) then
if (is_next_plug) then
-- draw a plug
local x, y = resolve_position(layer[i], hallway_pos_fixed,
layer_size, layer_size_diagonal)
is_next_plug = false -- 2 blocks in a row can disconnect map
draw_plug(x, y, 'c')
else
-- draw a hallway
local x, y = resolve_position(layer[i], hallway_pos_fixed, 0, 0)
is_next_plug = crawl.x_chance_in_y(plug_percent, 100)
if (hallway_pos_fixed < layer[i].side_start[1]) then
draw_hallway_s_n (x, y, -layer_size, '.') -- north
elseif (hallway_pos_fixed < layer[i].side_start[2]) then
draw_hallway_sw_ne(x, y, -layer_size_diagonal, '.') -- northeast
elseif (hallway_pos_fixed < layer[i].side_start[3]) then
draw_hallway_e_w (x, y, layer_size, '.') -- east
elseif (hallway_pos_fixed < layer[i].side_start[4]) then
draw_hallway_se_nw(x, y, layer_size_diagonal, '.') -- southeast
elseif (hallway_pos_fixed < layer[i].side_start[5]) then
draw_hallway_s_n (x, y, layer_size, '.') -- south
elseif (hallway_pos_fixed < layer[i].side_start[6]) then
draw_hallway_sw_ne(x, y, layer_size_diagonal, '.') -- southwest
elseif (hallway_pos_fixed < layer[i].side_start[7]) then
draw_hallway_e_w (x, y, -layer_size, '.') -- west
else
draw_hallway_se_nw(x, y, -layer_size_diagonal, '.') -- northwest
end
end
end
hallway_pos = hallway_pos + crawl.random_range(radial_seperation_min,
radial_seperation_max)
end
end
--print("MAP") <|>
--for y = 0, GYM - 1 do
-- local line_output = ""
-- for x = 0, GXM - 2 do
-- line_output = line_output .. mapgrd[x][y]
-- end
-- print(line_output)
--end
-- turn the plugs into ordinary walls and floor
subst("c = x")
}}
|