################################################################################
# Layouts for The Vaults (mumra's rewrite)
#
# This file contains map headers for picking the main layout. It mainly calls
# off to functions which are held in dlua/v_layouts.lua. The idea is that
# layout parameters (and importantly DEPTH, WEIGHT, etc.) can be easily tweaked
# in this header and all building logic happens in pure *.lua files.
#
# It uses all the mini vaults from layout_vaults_*.des and places these as
# rooms within structured areas. These vaults can use various tags to
# modify the way they are used within the layouts. A vault requires at least
# one of the following to even be used:
#
# - vaults_room
#     A standard room. These are the most commonly used type and therefore will
#     be seen a lot.
#     As such they should used standard monster/item placement (8s, 9s, etc.),
#     be extremely sparing with any obvious layout features, and be heavily
#     randomised.
#
# - vaults_hard
#     Tough rooms. Similar to a standard room but more likely to feature 8s and 9s.
#
# - vaults_rare
#     Rare rooms. These are more like normal branch minivaults. They can contain
#     more interesting features and they might
#
# - vaults_empty
#     Empty rooms. These provide furniture for areas that we otherwise want empty.
#     They should allow normal monster placement.
#
# In addition there are some specific modifier tags:
#
# - vaults_no_windows
#     The vault will never have windows.
#
# - vaults_orient_n
# - vaults_orient_e
# - vaults_orient_s
# - vaults_orient_w
#     Controls the orientation of the vault. A vault can have multiple of these
#     tags if it designed to be entered from multiple directions, in which case a
#     random orientation will be picked from the ones you have specified. If it
#     has none of these tags then it will be randomly rotated.
#     Specifically the tags mean "the vault can be entered from this direction".
#     It doesn't mean your vault won't be rotated, it just means that the door
#     will be placed at the correct size as you've designed it. So if you have
#     vaults_orient_n, but the vault is placed rotated 90 degrees clockwise, then
#     the door will be at the west.
#     These tags also control how additional sub-rooms might get attached onto
#     your room. If you have vaults_orient_n and vaults_orient_s then your vault
#     could get used as a corridor connecting one part of the layout to another
#     room.
#
# TODO: Should the documentation above be moved to a text file in docs or even
#       to general vault authoring docmentation? -mumra
#

default-depth: Vaults

# Include layout code
: crawl_require("dlua/v_layouts.lua")

################################################################################
# Ring Layout
#
# A square corridor with rooms around the edge and in the center. It is possible
# to lose
#
# The layouts all require no mirror or rotate, otherwise this messes with
# placement of the sub vaults, since we have to be quite specific with where
# we want them and how they are placed. This doesn't matter, because the
# layouts are built in a way that is already symmetrically random.
#
# We call parameterised functions to build the levels. This means we can vary
# the parameters with different DEPTH or WEIGHT settings to make certain
# layout styles more or less likely.
NAME: layout_vaults_ring
DEPTH: Vaults
WEIGHT: 25
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_ring layout_type_vaults
: build_vaults_ring_layout(_G, 5, 20)
MAP
ENDMAP

################################################################################
# Omnibox
#
# This will generate anything from chaotic city to maze (through "square ring
# huge center" / "square ring chaotic city") and more!
#
# Apologies if this is just too little code.
NAME: layout_vaults_omnibox
DEPTH: Vaults
WEIGHT: 30
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_box layout_type_vaults
{{
  local gxm,gym = dgn.max_bounds()
  local min_size = 6
  local p1 = { x = crawl.random_range(1,gxm - 2 - min_size), y = crawl.random_range(1,gym - 2 - min_size) }
  local p2 = { x = crawl.random_range(p1.x + min_size - 1, gxm - 2), y = crawl.random_range(p1.y + min_size - 1, gym - 2) }
  build_vaults_layout(_G, "Omnibox", { { type = "floor", corner1 = p1, corner2 = p2 } })
}}
MAP
ENDMAP

################################################################################
# Omnicross
#
# Generates junctions of various kinds, including big crosses, t-junctions, and
# corners (potentially thick enough for cities in the middle) and more!
NAME: layout_vaults_omnicross
DEPTH: Vaults
WEIGHT: 30
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_cross layout_type_vaults
{{
  local gxm,gym = dgn.max_bounds()
  -- Corridor widths
  local min_width,max_width = 4,20
  local width1,width2 = crawl.random_range(min_width,max_width),crawl.random_range(min_width,max_width)
  -- Positions along either axis
  local pos1,pos2 = crawl.random_range(1,gym-2-width1),crawl.random_range(1,gxm-2-width2)
  -- Corridor lengths
  local length1,length2 = crawl.random_range((gxm+1)/2,gxm-2),crawl.random_range((gym+1)/2,gym-2)
  -- Intersect positions
  local inter1,inter2 = crawl.random_range(math.max(1,pos2-length1+width2),math.min(gxm-1-length1,pos2)),crawl.random_range(math.max(1,pos1-length2+width1),math.min(gym-1-length2,pos1))

  build_vaults_layout(_G, "Omnicross", {
    { type = "floor", corner1 = { x = inter1, y = pos1 }, corner2 = { x = inter1 + length1 - 1, y = pos1 + width1 - 1 } },
    { type = "floor", corner1 = { x = pos2, y = inter2 }, corner2 = { x = pos2 + width2 - 1, y = inter2 + length2 - 1 } },
  })
}}
MAP
ENDMAP

################################################################################
# Omnigrid
#
# Uses a box-packing algorithm to subdivide the map into randomly-sized areas
# which can either be mini city clusters or solid walls for embedding rooms in.
#
# Technically capable but unlikely to produce a quadrants layout.
NAME: layout_vaults_omnigrid
DEPTH: Vaults
WEIGHT: 50
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_grid layout_type_vaults
: build_vaults_layout(_G, "Omnigrid", layout_primitive_omnigrid(), { max_rooms = 20, max_room_tries = 10, max_place_tries = 20 })
MAP
ENDMAP


################################################################################
# Grid
#
# Basically like V:5 except it might be divided into smaller areas than quadrants,
# and we randomise things by omitting or jittering some segments
NAME: layout_vaults_quadrants
DEPTH: Vaults
WEIGHT: 20
ORIENT: encompass
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_grid layout_type_vaults
CHANCE: 100%
{{
  -- TODO: smaller actual rooms with more grid divisions?; jitter rooms when corridors are wide enough
  -- Perhaps lose the outer border with 4 divisions
  local gxm,gym = dgn.max_bounds()
  local paint = { { type = "floor", corner1 = { x = 1, y = 1 }, corner2 = { x = gxm-2, y = gym-2 } } }
  local bisectx = crawl.random_range(2,4)
  local bisecty = crawl.random_range(2,4)

  -- Determine corridor / border sizes
  local padx,pady = 2,2
  if bisectx == 2 then padx = 3 end
  if bisectx == 4 then padx = 1 end
  if bisecty == 2 then pady = 3 end
  if bisecty == 4 then pady = 1 end

  for i = 0, (bisectx-1), 1 do
    for j = 0, (bisecty-1), 1 do
      -- 1/3 chance to skip this quadrant
      if not crawl.one_chance_in(3) then
        table.insert(paint, { type = "wall",
          corner1 = { x = 1 + math.floor((gxm - 2) / bisectx ) * i + padx, y = 1 + math.floor((gym - 2) / bisecty) * j + pady },
          corner2 = { x = 1 + math.floor((gxm - 2) / bisectx ) * (i+1) - padx - 1, y = 1 + math.floor((gym - 2) / bisecty) * (j+1) - pady - 1 }
        })
      end
    end
  end

  build_vaults_layout(_G, "Quadrants", paint, { max_rooms = 20, max_room_tries = 10, max_place_tries = 30 } )
}}
MAP
ENDMAP

# This has a big cross bang in the center; omnicross can potentially do this but it's unlikely.
NAME: layout_vaults_big_cross
DEPTH: Vaults
WEIGHT: 10
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_cross layout_type_vaults
: build_vaults_cross_layout(_G)
MAP
ENDMAP

# The following couple have somewhat low weights because they're not doing anything any different than omnibox can produce,
# although it would take a fairly specific and relatively unlikely omnibox to produce exactly the same effect so they
# should stay in on their own right. However the basic maze is fairly pointless because omnibox quite regularly does
# something very similar.
NAME: layout_vaults_big_room
DEPTH: Vaults
WEIGHT: 20
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_room layout_type_vaults
: build_vaults_big_room_layout(_G, 10, 20)
MAP
ENDMAP

NAME: layout_vaults_chaotic_city
DEPTH: Vaults
WEIGHT: 20
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_room layout_type_vaults
: build_vaults_chaotic_city_layout(_G, 5, 0.5)
MAP
ENDMAP

NAME: layout_vaults_maze
DEPTH: Vaults
WEIGHT: 10
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_maze layout_type_vaults
: build_vaults_maze_layout(_G)
MAP
ENDMAP

# Snakey maze consistently struggles to place rooms. Set to weight zero for now.
NAME: layout_vaults_maze_snakey
DEPTH: Vaults
WEIGHT: 10
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_maze layout_type_vaults
: build_vaults_maze_snakey_layout(_G)
MAP
ENDMAP

NAME: layout_vaults_maze_bifur
DEPTH: Vaults
WEIGHT: 10
ORIENT: encompass
CHANCE: 100%
TAGS: overwritable layout allow_dup unrand no_rotate no_pool_fixup
TAGS: no_hmirror no_vmirror chance_vaults uniq_vaults_maze layout_type_vaults
: build_vaults_maze_bifur_layout(_G)
MAP
ENDMAP
