1############################################################################### 2# layout_geoelf.des: Layouts for Elf with geometric rooms 3# These are not the only Elf layouts 4# These layouts will build around primary vaults correctly. 5# There is another geoelf layout in layout_geoelf_castle.des. 6############################################################################### 7 8# Required file contains overview 9: crawl_require("dlua/layout/geoelf.lua") 10 11############################################################## 12# layout_geoelf_grid 13# 14# A grid of rooms, inspired by layout_roguey. There are no 15# missing rooms because they mess up the corridors between 16# rooms and can disconnect the map (or connect it through a 17# primary vault and have the connection be overwritten). 18# 19# These 3 layouts could be combined into 1 big layout, but it 20# would be as long as the three combined, so it would just make 21# them harder to read. 22# 23# O-O-O-O-O 24# |X|X|X|X| O-O-O-O 25# O-O-O-O-O |X|X|X| 26# |X|X|X|X| O-O-O-O 27# O-O-O-O-O |X|X|X| 28# |X|X|X|X| OR O-O-O-O 29# O-O-O-O-O |X|X|X| 30# |X|X|X|X| O-O-O-O 31# O-O-O-O-O |X|X|X| 32# |X|X|X|X| O-O-O-O 33# O-O-O-O-O 16 Rooms 34# 25 Rooms 35# 36NAME: layout_geoelf_grid 37DEPTH: Elf 38WEIGHT: 10 39ORIENT: encompass 40TAGS: overwritable layout allow_dup unrand layout_type_rooms 41TAGS: no_rotate no_vmirror no_hmirror 42{{ 43 local gxm, gym = dgn.max_bounds() 44 extend_map{width = gxm, height = gym, fill = 'x'} 45 46 local depth_fraction = you.depth_fraction() 47 48 -- some paramters 49 local rooms_across = 5 50 local room_spacing = 13 51 local offset_max = 1 52 local radius_min = math.floor(2 + depth_fraction + crawl.random_real()) 53 local radius_max = math.floor(4 + depth_fraction + crawl.random_real()) 54 local extra_corridor_fraction = 0.7 - depth_fraction * 0.2 55 local fancy_room_fraction = 0.1 + depth_fraction * 0.1 56 57 if (depth_fraction * 2 + crawl.random_real() * 4 >= 3) then 58 rooms_across = 4 59 room_spacing = crawl.random_range(13, 17) 60 offset_max = math.floor(1 + depth_fraction + crawl.random_real()) 61 radius_min = math.floor(offset_max + 1 + crawl.random_real()) 62 radius_max = math.floor(4 + depth_fraction + crawl.random_real() * 2) 63 fancy_room_fraction = 0.15 + depth_fraction * 0.1 64 end 65 66 -- create the arrays 67 local room_data = { count = 0 } 68 local corridor_data = { count = 0 } 69 local rooms_by_position = {} 70 71 -- choose the room positions 72 for y = 0, rooms_across - 1 do 73 rooms_by_position[y] = {} 74 for x = 0, rooms_across - 1 do 75 local x_pos = gxm / 2 + 76 math.floor(room_spacing * (x - (rooms_across - 1) / 2)) + 77 crawl.random_range(-offset_max, offset_max) 78 local y_pos = gym / 2 + 79 math.floor(room_spacing * (y - (rooms_across - 1) / 2)) + 80 crawl.random_range(-offset_max, offset_max) 81 local radius = crawl.random_range(radius_min, radius_max) 82 83 -- we are only actually checking for vaults 84 if (not find_in_area {x1 = x_pos - radius, y1 = y_pos - radius, 85 x2 = x_pos + radius, y2 = y_pos + radius, 86 find = "", find_vault = true }) then 87 rooms_by_position[y][x] = geoelf.add_room(room_data, 88 x_pos, y_pos, radius) 89 else 90 rooms_by_position[y][x] = nil 91 end 92 end 93 end 94 95 -- add potential corridors 96 for y = 0, rooms_across - 1 do 97 for x = 0, rooms_across - 1 do 98 if (rooms_by_position[y][x] ~= nil) then 99 local index = rooms_by_position[y][x] 100 101 -- east-west 102 if (x >= 1 and rooms_by_position[y][x - 1] ~= nil) then 103 local other_index = rooms_by_position[y][x - 1] 104 geoelf.add_corridor(room_data, corridor_data, 105 other_index, index, 106 geoelf.directions.E, nil) 107 end 108 109 -- south-north 110 if (y >= 1 and rooms_by_position[y - 1][x] ~= nil) then 111 local other_index = rooms_by_position[y - 1][x] 112 geoelf.add_corridor(room_data, corridor_data, 113 other_index, index, 114 geoelf.directions.S, nil) 115 end 116 117 -- southeast-northwest 118 if (x >= 1 and y >= 1 and 119 rooms_by_position[y - 1][x - 1] ~= nil) then 120 local other_index = rooms_by_position[y - 1][x - 1] 121 122 -- determine if there is another corridor that would 123 -- block this one (i.e. an NE-SW one) 124 local block_index = nil 125 if (rooms_by_position[y][x - 1] ~= nil) then 126 local old_index = rooms_by_position[y][x - 1] 127 block_index = room_data[old_index].corridor[geoelf.directions.NE] 128 end 129 130 geoelf.add_corridor(room_data, corridor_data, 131 other_index, index, 132 geoelf.directions.SE, block_index) 133 end 134 135 -- southwest-northeast 136 if (x + 1 < rooms_across and y >= 1 and 137 rooms_by_position[y - 1][x + 1] ~= nil) then 138 local other_index = rooms_by_position[y - 1][x + 1] 139 geoelf.add_corridor(room_data, corridor_data, 140 other_index, index, 141 geoelf.directions.SW, nil) 142 end 143 end 144 end 145 end 146 147 -- generate the layout 148 geoelf.generate(_G, room_data, corridor_data, extra_corridor_fraction, 149 fancy_room_fraction, false, false) 150}} 151MAP 152ENDMAP 153 154############################################################## 155# layout_geoelf_diagonals 156# 157# A grid of rooms, with most connection along the diagonals. 158# 159# O---O---O 160# /|\ /|\ /|\ O---O---O 161# O-+-O-+-O-+-O /|\ /|\ /| 162# |\|/|\|/|\|/| O-+-O-+-O | 163# | O-+-O-+-O | |\|/|\|/|\| 164# |/|\|/|\|/|\| | O-+-O-+-O Note that the grid actually is 7x7 165# O-+-O-+-O-+-O OR |/|\|/|\|/| (or 6x6), but only half the cells 166# |\|/|\|/|\|/| O-+-O-+-O | are used (in a checkerboard pattern). 167# | O-+-O-+-O | |\|/|\|/|\| 168# |/|\|/|\|/|\| | O-+-O-+-O 169# O-+-O-+-O-+-O |/ \|/ \|/ 170# \|/ \|/ \|/ O---O---O 171# O---O---O 18 Rooms 172# 24 Rooms 173# 174NAME: layout_geoelf_diagonals 175DEPTH: Elf 176WEIGHT: 10 177ORIENT: encompass 178TAGS: overwritable layout allow_dup unrand layout_type_rooms 179TAGS: no_rotate no_vmirror no_hmirror 180{{ 181 local gxm, gym = dgn.max_bounds() 182 extend_map{width = gxm, height = gym, fill = 'x'} 183 184 local depth_fraction = you.depth_fraction() 185 186 -- some paramters 187 local rooms_across = 7 188 local room_spacing = 9 189 local offset_max = 1 190 local radius_min = 2 191 local radius_max = math.floor(4 + depth_fraction + crawl.random_real()) 192 local extra_corridor_fraction = 0.7 - depth_fraction * 0.2 193 local fancy_room_fraction = 0.1 + depth_fraction * 0.1 194 195 if (depth_fraction * 2 + crawl.random_real() * 4 >= 3) then 196 rooms_across = 6 197 room_spacing = crawl.random_range(9, 11) 198 radius_min = math.floor(2 + depth_fraction + crawl.random_real()) 199 radius_max = math.floor(4 + depth_fraction + crawl.random_real() * 2) 200 fancy_room_fraction = 0.15 + depth_fraction * 0.1 201 end 202 203 -- create the arrays 204 local room_data = { count = 0 } 205 local corridor_data = { count = 0 } 206 local rooms_by_position = {} 207 208 -- choose the room positions 209 for y = 0, rooms_across - 1 do 210 rooms_by_position[y] = {} 211 for x = 0, rooms_across - 1 do -- checkerboard test 212 if ((x + y) % 2 == 1) then 213 local x_pos = gxm / 2 + 214 math.floor(room_spacing * (x - (rooms_across - 1) / 2)) + 215 crawl.random_range(-offset_max, offset_max) 216 local y_pos = gym / 2 + 217 math.floor(room_spacing * (y - (rooms_across - 1) / 2)) + 218 crawl.random_range(-offset_max, offset_max) 219 local radius = crawl.random_range(radius_min, radius_max) 220 221 -- we are only actually checking for vaults 222 if (not find_in_area {x1 = x_pos - radius, y1 = y_pos - radius, 223 x2 = x_pos + radius, y2 = y_pos + radius, 224 find = "", find_vault = true }) then 225 rooms_by_position[y][x] = geoelf.add_room(room_data, 226 x_pos, y_pos, radius) 227 else 228 rooms_by_position[y][x] = nil 229 end 230 else 231 rooms_by_position[y][x] = nil 232 end 233 end 234 end 235 236 -- add potential corridors 237 for y = 0, rooms_across - 1 do 238 for x = 0, rooms_across - 1 do 239 if (rooms_by_position[y][x] ~= nil) then 240 -- we have impliclitly passed the checkerboard test if we gwt here 241 242 local index = rooms_by_position[y][x] 243 244 -- east-west 245 if (x >= 2 and rooms_by_position[y][x - 2] ~= nil) then 246 local other_index = rooms_by_position[y][x - 2] 247 geoelf.add_corridor(room_data, corridor_data, 248 other_index, index, 249 geoelf.directions.E, nil) 250 end 251 252 -- south-north 253 if (y >= 2 and rooms_by_position[y - 2][x] ~= nil) then 254 local other_index = rooms_by_position[y - 2][x] 255 256 -- determine if there is another corridor that would 257 -- block this one (i.e. an E-W one) 258 local block_index = nil 259 if (x >= 1 and rooms_by_position[y - 1][x - 1] ~= nil) then 260 local old_index = rooms_by_position[y - 1][x - 1] 261 block_index = room_data[old_index].corridor[geoelf.directions.E] 262 end 263 264 geoelf.add_corridor(room_data, corridor_data, 265 other_index, index, 266 geoelf.directions.S, block_index) 267 end 268 269 -- southeast-northwest 270 if (x >= 1 and y >= 1 and 271 rooms_by_position[y - 1][x - 1] ~= nil) then 272 local other_index = rooms_by_position[y - 1][x - 1] 273 geoelf.add_corridor(room_data, corridor_data, 274 other_index, index, 275 geoelf.directions.SE, nil) 276 end 277 278 -- southwest-northeast 279 if (x + 1 < rooms_across and y >= 1 and 280 rooms_by_position[y - 1][x + 1] ~= nil) then 281 local other_index = rooms_by_position[y - 1][x + 1] 282 geoelf.add_corridor(room_data, corridor_data, 283 other_index, index, 284 geoelf.directions.SW, nil) 285 end 286 end 287 end 288 end 289 290 -- generate the layout 291 geoelf.generate(_G, room_data, corridor_data, extra_corridor_fraction, 292 fancy_room_fraction, false, false) 293}} 294MAP 295ENDMAP 296 297############################################################## 298# layout_geoelf_octagon 299# 300# A large central room, with 2 rings of other rooms around it. 301# There is no simple formula for this one, so the code is a bit 302# confusing. Basically the rooms all start in an array. 303# 304# O--O--O O 305# / /|\ \ /|\ 306# O--O-+-O--O O--O-+-O--O O---O 307# /|\/|\|/|\/|\ |\/|\|/|\/| /|\ /|\ 308# O |/\| O |/\| O |/\| O |/\| / | O | \ 309# | O--O | O--O | O--O | O--O O--O | O--O 310# |/|\ \|/ /|\| /|\ \|/ /|\ |\ \|/ /| 311# O-+-O--O--O-+-O O-+-O--O--O-+-O | O--O--O | 312# |\|/ /|\ \|/| \|/ /|\ \|/ |/ /|\ \| 313# | O--O | O--O | O--O | O--O O--O | O--O 314# O |\/| O |\/| O |\/| O |\/| \ | O | / 315# \|/\|/|\|/\|/ |/\|/|\|/\| \|/ \|/ 316# O--O-+-O--O O--O-+-O--O O---O 317# \ \|/ / \|/ 17 Rooms 318# O--O--O O 319# 33 Rooms 25 Rooms 320# 321# 322# 29--21-28 323# / /|\ \ 324# 22-13-+-12-2O 325# / |\/|\|/|\/| \ 326# 3O |/\| 5 |/\| 27 327# | 14-6 | 4--11 | 328# | /|\ \|/ /| \| Room Indexes 329# 23-+-7--O--3-+-19 330# | \|/ /|\ \| /| Smaller versions are missing higher indexes 331# | 15-8 | 2--1O | 332# 31 |\/| 1 |\/| 26 333# \ |/\|/|\|/\| / 334# 24-16-+-9--18 335# \ \|/ / 336# 32--17-25 337# 338NAME: layout_geoelf_octagon 339DEPTH: Elf 340WEIGHT: 15 341ORIENT: encompass 342TAGS: overwritable layout allow_dup unrand layout_type_rooms 343TAGS: no_rotate no_vmirror no_hmirror 344{{ 345 local gxm, gym = dgn.max_bounds() 346 extend_map{width = gxm, height = gym, fill = 'x'} 347 348 -- some paramters 349 local depth_fraction = you.depth_fraction() 350 local place_rings = crawl.random_range(2, 4) 351 local extra_corridor_fraction = 0.7 - depth_fraction * 0.2 352 local fancy_room_fraction = (0.025 + depth_fraction * 0.025) * 353 (7 - place_rings) 354 355 -- positions are from layout center 356 local ROOMS_TO_PLACE = { 357 -- center room 358 [0] = { x = 0, y = 0, radius_min = 3, radius_max = 5, offset = 1 }, 359 -- ring 1 360 [1] = { x = 0, y = 12, radius_min = 2, radius_max = 4, offset = 0 }, 361 [2] = { x = 8, y = 8, radius_min = 2, radius_max = 4, offset = 0 }, 362 [3] = { x = 12, y = 0, radius_min = 2, radius_max = 4, offset = 0 }, 363 [4] = { x = 8, y = -8, radius_min = 2, radius_max = 4, offset = 0 }, 364 [5] = { x = 0, y = -12, radius_min = 2, radius_max = 4, offset = 0 }, 365 [6] = { x = -8, y = -8, radius_min = 2, radius_max = 4, offset = 0 }, 366 [7] = { x = -12, y = 0, radius_min = 2, radius_max = 4, offset = 0 }, 367 [8] = { x = -8, y = 8, radius_min = 2, radius_max = 4, offset = 0 }, 368 -- ring 2 369 [9] = { x = 8, y = 20, radius_min = 3, radius_max = 5, offset = 1 }, 370 [10] = { x = 20, y = 8, radius_min = 3, radius_max = 5, offset = 1 }, 371 [11] = { x = 20, y = -8, radius_min = 3, radius_max = 5, offset = 1 }, 372 [12] = { x = 8, y = -20, radius_min = 3, radius_max = 5, offset = 1 }, 373 [13] = { x = -8, y = -20, radius_min = 3, radius_max = 5, offset = 1 }, 374 [14] = { x = -20, y = -8, radius_min = 3, radius_max = 5, offset = 1 }, 375 [15] = { x = -20, y = 8, radius_min = 3, radius_max = 5, offset = 1 }, 376 [16] = { x = -8, y = 20, radius_min = 3, radius_max = 5, offset = 1 }, 377 -- ring 3 378 [17] = { x = 0, y = 28, radius_min = 2, radius_max = 4, offset = 1 }, 379 [18] = { x = 20, y = 20, radius_min = 2, radius_max = 4, offset = 1 }, 380 [19] = { x = 28, y = 0, radius_min = 2, radius_max = 4, offset = 1 }, 381 [20] = { x = 20, y = -20, radius_min = 2, radius_max = 4, offset = 1 }, 382 [21] = { x = 0, y = -28, radius_min = 2, radius_max = 4, offset = 1 }, 383 [22] = { x = -20, y = -20, radius_min = 2, radius_max = 4, offset = 1 }, 384 [23] = { x = -28, y = 0, radius_min = 2, radius_max = 4, offset = 1 }, 385 [24] = { x = -20, y = 20, radius_min = 2, radius_max = 4, offset = 1 }, 386 -- ring 4 387 [25] = { x = 12, y = 28, radius_min = 2, radius_max = 3, offset = 1 }, 388 [26] = { x = 28, y = 12, radius_min = 2, radius_max = 3, offset = 1 }, 389 [27] = { x = 28, y = -12, radius_min = 2, radius_max = 3, offset = 1 }, 390 [28] = { x = 12, y = -28, radius_min = 2, radius_max = 3, offset = 1 }, 391 [29] = { x = -12, y = -28, radius_min = 2, radius_max = 3, offset = 1 }, 392 [30] = { x = -28, y = -12, radius_min = 2, radius_max = 3, offset = 1 }, 393 [31] = { x = -28, y = 12, radius_min = 2, radius_max = 3, offset = 1 }, 394 [32] = { x = -12, y = 28, radius_min = 2, radius_max = 3, offset = 1 }, 395 } 396 397 local DIRECTIONS_IN_ORDER = { 398 [0] = geoelf.directions.S, 399 [1] = geoelf.directions.SE, 400 [2] = geoelf.directions.E, 401 [3] = geoelf.directions.NE, 402 [4] = geoelf.directions.N, 403 [5] = geoelf.directions.NW, 404 [6] = geoelf.directions.W, 405 [7] = geoelf.directions.SW, 406 } 407 408 -- create the arrays 409 local room_data = { count = 0 } 410 local corridor_data = { count = 0 } 411 local rooms_by_position = {} 412 413 -- add rooms from array 414 for i = 0, place_rings * 8 do 415 local offset_max = ROOMS_TO_PLACE[i].offset 416 local x_pos 417 local y_pos 418 local radius 419 if (place_rings == 2) then 420 -- if we are only placing two rings of rooms, we have the 421 -- space to make everything bigger 422 local ROOM_POSITION_LOOKUP = 423 { [ 0] = 0, 424 [ 8] = 10, [ -8] = -10, 425 [ 12] = 14, [-12] = -14, 426 [ 20] = 24, [-20] = -24, 427 [ 28] = 34, [-28] = -34, 428 } 429 x_pos = gxm / 2 + ROOM_POSITION_LOOKUP[ROOMS_TO_PLACE[i].x] + 430 crawl.random_range(-offset_max, offset_max) 431 y_pos = gym / 2 + ROOM_POSITION_LOOKUP[ROOMS_TO_PLACE[i].y] + 432 crawl.random_range(-offset_max, offset_max) 433 radius = crawl.random_range(ROOMS_TO_PLACE[i].radius_min, 434 ROOMS_TO_PLACE[i].radius_max + 1) 435 else 436 x_pos = gxm / 2 + ROOMS_TO_PLACE[i].x + 437 crawl.random_range(-offset_max, offset_max) 438 y_pos = gym / 2 + ROOMS_TO_PLACE[i].y + 439 crawl.random_range(-offset_max, offset_max) 440 radius = crawl.random_range(ROOMS_TO_PLACE[i].radius_min, 441 ROOMS_TO_PLACE[i].radius_max) 442 end 443 444 -- we are only actually checking for vaults 445 if (not find_in_area {x1 = x_pos - radius, y1 = y_pos - radius, 446 x2 = x_pos + radius, y2 = y_pos + radius, 447 find = "", find_vault = true }) then 448 rooms_by_position[i] = geoelf.add_room(room_data, x_pos, y_pos, radius) 449 else 450 rooms_by_position[i] = nil 451 end 452 end 453 454 -- add corridors 455 -- -> the same pattern is repeated 8 times, so we use a loop 456 for i = 0, 7 do 457 local index_ring_1 = 1 + i 458 local index_ring_2 = 9 + i 459 local index_ring_2B = 9 + (i + 7) % 8 460 local index_ring_3 = 17 + i 461 local index_ring_4 = 25 + i 462 local index_ring_4B = 25 + (i + 7) % 8 463 464 -- connect center to ring 1 465 if (rooms_by_position[0] ~= nil and 466 rooms_by_position[index_ring_1] ~= nil) then 467 geoelf.add_corridor(room_data, corridor_data, 468 rooms_by_position[0], 469 rooms_by_position[index_ring_1], 470 DIRECTIONS_IN_ORDER[i], nil) 471 end 472 473 -- connect ring 1 to ring 2 474 if (rooms_by_position[index_ring_1] ~= nil and 475 rooms_by_position[index_ring_2] ~= nil) then 476 geoelf.add_corridor(room_data, corridor_data, 477 rooms_by_position[index_ring_1], 478 rooms_by_position[index_ring_2], 479 DIRECTIONS_IN_ORDER[(i + 1) % 8], nil) 480 end 481 if (rooms_by_position[index_ring_1] ~= nil and 482 rooms_by_position[index_ring_2B] ~= nil) then 483 geoelf.add_corridor(room_data, corridor_data, 484 rooms_by_position[index_ring_1], 485 rooms_by_position[index_ring_2B], 486 DIRECTIONS_IN_ORDER[(i + 7) % 8], nil) 487 end 488 489 -- connect ring 2 in a loop 490 local c4 -- we will need this later 491 if (rooms_by_position[index_ring_2B] ~= nil and 492 rooms_by_position[index_ring_2] ~= nil) then 493 c4 = geoelf.add_corridor(room_data, corridor_data, 494 rooms_by_position[index_ring_2B], 495 rooms_by_position[index_ring_2], 496 DIRECTIONS_IN_ORDER[(i + 2) % 8], nil) 497 else 498 c4 = nil 499 end 500 501 if (place_rings >= 3) then 502 -- connect ring 1 to ring 3 503 if (rooms_by_position[index_ring_1] ~= nil and 504 rooms_by_position[index_ring_3] ~= nil) then 505 geoelf.add_corridor(room_data, corridor_data, 506 rooms_by_position[index_ring_1], 507 rooms_by_position[index_ring_3], 508 DIRECTIONS_IN_ORDER[i], c4) 509 end 510 511 -- connect ring 2 to ring 3 512 if (rooms_by_position[index_ring_2B] ~= nil and 513 rooms_by_position[index_ring_3] ~= nil) then 514 geoelf.add_corridor(room_data, corridor_data, 515 rooms_by_position[index_ring_2B], 516 rooms_by_position[index_ring_3], 517 DIRECTIONS_IN_ORDER[(i + 1) % 8], nil) 518 end 519 if (rooms_by_position[index_ring_2] ~= nil and 520 rooms_by_position[index_ring_3] ~= nil) then 521 geoelf.add_corridor(room_data, corridor_data, 522 rooms_by_position[index_ring_2], 523 rooms_by_position[index_ring_3], 524 DIRECTIONS_IN_ORDER[(i + 7) % 8], nil) 525 end 526 527 if (place_rings >= 4) then 528 -- connect ring 3 to ring 4 529 if (rooms_by_position[index_ring_3] ~= nil and 530 rooms_by_position[index_ring_4] ~= nil) then 531 geoelf.add_corridor(room_data, corridor_data, 532 rooms_by_position[index_ring_3], 533 rooms_by_position[index_ring_4], 534 DIRECTIONS_IN_ORDER[(i + 2) % 8], nil) 535 end 536 if (rooms_by_position[index_ring_3] ~= nil and 537 rooms_by_position[index_ring_4B] ~= nil) then 538 geoelf.add_corridor(room_data, corridor_data, 539 rooms_by_position[index_ring_3], 540 rooms_by_position[index_ring_4B], 541 DIRECTIONS_IN_ORDER[(i + 6) % 8], nil) 542 end 543 end 544 end 545 end 546 547 -- generate the layout 548 geoelf.generate(_G, room_data, corridor_data, extra_corridor_fraction, 549 fancy_room_fraction, false, false) 550}} 551MAP 552ENDMAP 553