###
## Maps from named Wizards, unrand and fixedarts
#
#Wizard    |Threat                  |Loot                     |
#--------------------------------------------------------------
#Cloud Mage|Air elementals, cloud   |potions, robe of clouds, |
#          |spewers, Cloud Mage     |speed/air-related misc   |
#--------------------------------------------------------------
#Hellbinder|Demons, summoners,      |fire / summoning /       |
#          |Hellbinder              |demonic items            |
#--------------------------------------------------------------
#Doroklohe |Demons or liches        |scrolls or armour        |
#          |and mummies             |or random                |
#--------------------------------------------------------------
#Wucad Mu  |Random summon "monks",  |potions of experience,   |
#          |summoning OCS           |crystal ball of Wucad Mu |
#--------------------------------------------------------------
#Cigotuvi  |Uglies, shapeshifters,  |potions of mutation,     |
#          |eyes, monstrosity       |talismans                |
#--------------------------------------------------------------
#Iskenderun|Te Cj, iood statues,    |books, books, books,     |
#          |purple draconians       |robe of the archmagi     |
#--------------------------------------------------------------
#Zonguldrok|derived undead, vamps,  |scrolls, heavy armour,   |
#          |skeles, antique champ   |Zonguldrok's sword       |
#--------------------------------------------------------------
#Golubria  |weirder Spider spawns,  |tloc items, cloaks,      |
#          |Abyss spawns, tloc foes |abyss-escape aides       |
#--------------------------------------------------------------
#Lehudib   |earth-themed monsters,  |Moon Troll Leather Armour|
#          |"space" themed abyss    |random loot and          |
#          |monsters                |randbook of earth +      |
#          |                        |tmut or tloc or conj     |
#--------------------------------------------------------------
#Eringya   |plant monsters, archers |staves, potions,         |
#          |and fenstrider witches  |spectral ego weapons     |
#--------------------------------------------------------------
#Maxwell   |constructs and meaty    |gear with dangerous ego, |
#          |mace wielders           |weapon/armour artifacts  |
#--------------------------------------------------------------
#Yara      |Warrior-mages with      |antimagic weapons, books |
#          |antimagic weapons       |                         |
#--------------------------------------------------------------
#Borgnjnor |Corporeal and ghostly   |necromancy loot, gold    |
#          |undead, warlocks        |                         |
#--------------------------------------------------------------
#Tukima    |Dancing weapons, walking|aux armour, books,       |
#          |tomes, rakshashas       |phantom mirror           |
#--------------------------------------------------------------
#Alistair  |Lots of wizards, invited|consumables, books,      |
#          |guests, ds corrupters   |condenser vane           |
##


#---------------------------------------------------------------------
#Full Name                |Layout               |Colours
#---------------------------------------------------------------
#Doroklohe's Tomb         |densely packed       |yellow walls,
#                         |collapsing tombs     |dark floor
#---------------------------------------------------------------
#Wucad Mu's Monastery     |empty temple         |dark walls,
#                         |                     |autumn trees
#---------------------------------------------------------------
#Cigotuvi's Fleshworks    |organic, irregular,  |magenta/red/yellow
#                         |twisted innards      |flesh/blood tiles
#---------------------------------------------------------------
#Iskenderun's Mystic Tower|fortress tower with  |tons of magenta
#                         |statues, cave corners|
#---------------------------------------------------------------
#Zonguldrok's Mausoleum   |tower, graveyard     |piles of darkgray
#---------------------------------------------------------------
#Roulette of Golubria     |old-abyss mess,      |mostly green,
#                         |teleport chambers maw|rare white or cyan
#---------------------------------------------------------------
#Cloud Mage's Chambers    |"cloud-esque"        |lightgray, white,
#                         |                     |lightblue
#---------------------------------------------------------------
#Hellbinder's Lair        |triangles and circles|red, darkgray,
#                         |sigils               |yellow sigils
#---------------------------------------------------------------
#Lehudib's Moon Base      |Circular and alien   |blue/lightblue/magenta
#                         |base-like structure  |colour-shifting crystal
#---------------------------------------------------------------
#Eringya's Formal Garden  |Gently curving open  |green with a chance for
#                         |paths hedged by trees|red/yellow autumn variant
#---------------------------------------------------------------
#Maxwell's Workshop       |big rooms with forge |metal
#---------------------------------------------------------------
#Yara's Duelist Academy   |campus               |stone and trees
#---------------------------------------------------------------
#Borgnjor's Mausoleum     |split path           |tarlike
#---------------------------------------------------------------
#Tukima's Studio          |mirrored hall        |lightgray/white
#---------------------------------------------------------------
#Alistair's Party Mansion |rooms                |gray/green/white
##

# TO-DO:
#
# Actual portals need quite a bit of editing, and some unique tiles.
# Tiles to fix: Doroklohe's plain floor, Cigotuvi's doorways, less generic
# Iskenderun tiles, Cloud Mage's "white fluffiness" and "sea of clouds".
#
##

{{
crawl_require("dlua/dungeon.lua")


function wizlab_portal (e)
    local timeout_turns = crawl.random_range(600, 800)

    local messager =
      timed_msg {
           initmsg = { "You hear the crackle of arcane power.",
                       "There is an entrance to a wizard's laboratory on "
                       .. "this level! Hurry and find it before the "
                       .. "portal closes forever!" },
        finalmsg = "The crackle of the magical portal is almost imperceptible now.",

        verb = 'crackle',
        noisemaker = 'magical portal'
    }

    e.lua_marker('O',
      timed_marker {
        disappear = "The flow of magic halts.",
        entity = 'portal',
        turns = timeout_turns,
        single_timed = true,
        floor = "stone_arch",
        feat_tile = "dngn_portal_bazaar_gone",
        msg = messager })
    e.kfeat("O = enter_wizlab")

    e.tags("uniq_wizlab vaults_wizlab no_item_gen no_monster_gen chance_wizlab")

    -- Replace stone walls with whatever wall type the Vaults level is using.
    if you.in_branch("Vaults") then
        e.subst("c = x")
    end

    e.chance(math.floor(dgn.wizlab_chance_percent / 100 * 10000))
    -- Don't apply the chance in Vaults, since we use a Vaults room for that
    -- branch.
    e.depth_chance("Vaults", 0)
end

-- Destinations:
function wizlab_setup (e)
    e.orient("encompass")
    e.tags("no_item_gen no_monster_gen")
    e.kfeat("< = exit_wizlab")
end

function wizlab_milestone (e, wizlab_desc)
    crawl.mark_milestone("br.enter", "entered " .. wizlab_desc .. ".", "parent")
    crawl.take_note("Entered " .. wizlab_desc)
    crawl.mpr("Welcome to " .. wizlab_desc .. "!")
end

function wizlab_doroklohe_convert_boxes(data, triggerable, triggerer,
                                        marker, ev)
  if triggerer.type ~= "turn" or triggerer.sub_type ~= "countdown" then
    return
  end

  if data.phase == 1 then
    data.phase = data.phase + 1
    crawl.mpr("The walls briefly shake.", "warning")
    return
  elseif data.phase == 2 then
    data.phase = data.phase + 1
    crawl.mpr("The walls violently shake.", "warning")
    return
  elseif data.phase == 3 then
    data.phase = data.phase + 1
    crawl.mpr("The walls fall away. The entombed are set free!", "warning")
    for _, i in ipairs(dgn.find_marker_positions_by_prop("wall_drop", 1)) do
      dgn.terrain_changed(i.x, i.y, "floor", false)
      dgn.place_cloud(i.x, i.y, "black smoke", 2)
    end
    return
  else
    return
  end
end

local function spawn_zombie (x, y, spec)
    dgn.terrain_changed(x, y, "floor", false)
    dgn.place_cloud(x, y, "sparse dust", 5, "", "", 5)
    local mons = dgn.create_monster(x, y, spec)
    mons.set_prop("zonguldrok", 1)
    return mons
end

function wizlab_zonguldrok_spawn_zombies(data, triggerable, triggerer,
                                         marker, ev)
    -- Save compat bit.
    if data.count == nil then
        data.count = 0
    end
    if triggerer.type ~= "turn" or triggerer.sub_type ~= "countdown" then
        return
    end
    local graves = dgn.find_markers_by_prop("grave", 1)

    local list_undead_types = { " zombie", " skeleton", " simulacrum" }

    local list_deriv_undead_base_mons = {
        "cyclops", "two-headed ogre", "swamp dragon",  -- tier 1
        "stone giant", "deep troll", "storm dragon",   -- tier 2
        "juggernaut", "ettin", "golden dragon"         -- tier 3
    }

    local list_regular_undead = {
        "vampire", "skeletal warrior",                 -- tier 1
        "jiangshi", "phantasmal warrior",              -- tier 2
        "vampire knight", "ghoul",                     -- tier 3
    }

    local pick_undead_type
    local pick_undead_base_mon
    local pick_regular_undead
    local x, y
    for _, gmarker in ipairs(graves) do
        pick_undead_type = crawl.random_range(1, 3)
        pick_undead_base_mon = crawl.random_range(1, 3)
        pick_regular_undead = crawl.random_range(1, 2)
        x, y = gmarker:pos()

        if (you.see_cell(x, y) and crawl.one_chance_in(3)) or
            crawl.one_chance_in(8) then

            -- tier 1 spawns
            if data.count < 9 or data.count < 15 and crawl.one_chance_in(6) then
                if crawl.coinflip() then
                    monster = (list_deriv_undead_base_mons[pick_undead_base_mon]
                               .. list_undead_types[pick_undead_type])
                else
                    monster = list_regular_undead[pick_regular_undead]
                end

            -- tier 2 spawns
            elseif data.count < 18 or data.count < 23 and crawl.one_chance_in(4) then
                if crawl.coinflip() then
                    pick_undead_base_mon = pick_undead_base_mon + 3
                    monster = (list_deriv_undead_base_mons[pick_undead_base_mon]
                               .. list_undead_types[pick_undead_type])
                else
                    pick_regular_undead = pick_regular_undead + 2
                    monster = list_regular_undead[pick_regular_undead]
                end

            -- tier 3 spawns
            elseif data.count < 25 or crawl.x_chance_in_y(11, 14) then
                if crawl.coinflip() then
                    pick_undead_base_mon = pick_undead_base_mon + 6
                    monster = (list_deriv_undead_base_mons[pick_undead_base_mon]
                               .. list_undead_types[pick_undead_type])
                else
                    pick_regular_undead = pick_regular_undead + 4
                    monster = list_regular_undead[pick_regular_undead]
                end

            -- tier 4 spawns: always spawn an ancient champion here
            else
                monster = "ancient champion"
            end
            monster = "generate_awake " .. monster
            spawn_zombie(x, y, monster)
            data.count = data.count + 1
            gmarker:remove()
        end
    end
end

function wizlab_zonguldrok_killed_zombie(data, triggerable, triggerer,
                                         marker, ev)
    if data.door_appeared then
        return
    end

    local mons = dgn.mons_from_mid(ev:arg1())
    if not mons.has_prop("zonguldrok") then
        return
    end

    data.number_killed = data.number_killed + 1
    if (#dgn.find_markers_by_prop("grave", 1)) * 2 < data.number_killed * 3
       and #dgn.find_markers_by_prop("grave", 1) < 10 then
        local x, y = marker:pos()
        dgn.tile_feat_changed(x, y, nil)
        dgn.terrain_changed(x, y, "closed_door", false)
        data.door_appeared = true
        if you.see_cell(x, y) then
            crawl.mpr("A door appears!")
        else
            crawl.mpr("The walls vibrate.")
        end
        local gxm, gym = dgn.max_bounds()
        for p in iter.rect_iterator(dgn.point(1, 1), dgn.point(gxm-1, gym-1)) do
            if dgn.fprop_at(p.x, p.y, "no_tele_into") then
               dgn.fprop_changed(p.x, p.y, "no_tele_into")
            end
        end
    end
end


function wizlab_zonguldrok_awaken_wizard(data, triggerable,
                                         triggerer, marker, ev)
    if data.awoke == true then
        return
    end

    -- Place two antique champions
    local ant_pos1 = dgn.find_marker_positions_by_prop("antique_grave_a", 1)[1]
    local ant1 = dgn.create_monster(ant_pos1.x, ant_pos1.y,
                                    "generate_awake antique champion ; " ..
                                    "sword_of_zonguldrok . shadow dragon scales . kite shield good_item")
    local ant_pos2 = dgn.find_marker_positions_by_prop("antique_grave_b", 1)[1]
    local ant2 = dgn.create_monster(ant_pos2.x, ant_pos2.y,
                                    "generate_awake antique champion ; " ..
                                    "double sword ego:draining . shadow dragon scales good_item . kite shield")
    dgn.place_cloud(ant_pos1.x, ant_pos1.y, "black smoke", 5, "", "", 5)
    dgn.place_cloud(ant_pos2.x, ant_pos2.y, "black smoke", 5, "", "", 5)

    if ant1 then
        data.awoke = true
    end
end

function wizlab_wucad_msgfn(data, triggerable, triggerer, marker, ev)
  if data.trig == true then
    return
  end

  if crawl.one_chance_in(3) then
    return
  end

  if dgn.persist.wucad_mu_died == true then
    return
  end

  if data.spot == 1 then
    crawl.mpr("Strange, shadowy figures dance through the air in front of you.", "talk_visual")
    data.trig = true
  elseif data.spot == 2 then
    crawl.mpr("This room is filled with shadowy figures, quietly meditating.", "talk_visual")
    data.trig = true
  elseif data.spot == 3 then
    crawl.mpr("Here, spectral monks perform complicated, martial routines; they fade quickly.", "talk_visual")
    data.trig = true
  elseif data.spot == 4 then
    if you.silenced() then
      return
    end
    crawl.mpr("Faint laughter comes from somewhere. Too faint to be real.", "talk_visual")
    data.trig = true
  elseif data.spot == 5 then
    if you.silenced() then
      return
    end
    crawl.mpr("There is a faint scream of pain from a crouched figure. This too fades quickly.", "talk_visual")
    data.trig = true
  elseif data.spot == 6 then
    crawl.mpr("Grey monks gather around the fountain. They do not speak, nor look at each other.", "talk_visual")
    data.trig = true
  elseif data.spot == 7 then
    crawl.mpr("A figure sits in silent meditation. It spots you, gestures wildly, and disappears.", "talk_visual")
    data.trig = true
  end
end

function wizlab_wucad_summon_monks(data, triggerable, triggerer, marker, ev)
  if triggerer.type ~= "turn" or triggerer.sub_type ~= "countdown" then
    return
  end

  if dgn.persist.wucad_mu_died == true then
    return
  end

  -- For now, no spawning during Step From Time; perhaps monks should
  -- continue to appear, just more slowly. If so, the circle_iterator below
  -- needs a different centre from (0,0).
  if you.pos() == 0 then
    return
  end

  local msp = "demonspawn seen sum:shadow_creatures dur:2 " ..
              "nas:old_memories generate_awake " ..
              "tile:mons_faint_demonspawn_monk / deep troll seen " ..
              "sum:shadow_creatures dur:2 nas:old_memories generate_awake " ..
              "tile:mons_faint_deep_troll_monk / grey draconian monk w:5" ..
              "seen sum:shadow_creatures dur:2 nas:old_memories " ..
              "generate_awake tile:mons_faint_grey_draconian_monk"

  local count = 0
  for point in iter.circle_iterator(3) do
    if crawl.one_chance_in(8) and count < 3 then
      if feat.is_solid(point.x, point.y) or not feat.has_solid_floor(point.x, point.y) then
      else
       local mon = dgn.create_monster(point.x, point.y, msp)
       count = count + 1
      end
    end
  end

  crawl.redraw_view()

  if count == 1 then
    crawl.mpr("One of the shadowy figures appears more solid!", "warning")
  elseif count > 1 then
    crawl.mpr("Shadows coalesce into solid form.", "warning")
  end
end

function callback.wizlab_wucad_wucad_died(data, triggerable,
                                           triggerer, marker, ev)
  dgn.persist.wucad_mu_died = true
  crawl.mpr("The shadows inhabiting this place fade forever.", "talk_visual")
end

function yara_students(e)
    local anti = "ego:antimagic ident:all"
    local will = "ego:willpower ident:all"
    local goodgear = "halberd " .. anti .. " | scimitar " .. anti
                     .. " | morningstar " .. anti .. " | dire flail " .. anti
                     .. " . ring mail " .. will
                     .. " w:3 | scale mail | chain mail "
    local greatweap = "double sword " .. anti .. " | demon blade " .. anti
                      .. " | great sword " .. anti .. " | glaive " .. anti
                      .. " | demon trident " .. anti .. " | bardiche " .. anti
                      .. " | eveningstar " .. anti .. " | demon whip " .. anti
                      .. " | great mace " .. anti .. " | quick blade " .. anti
    local greatarm = "chain mail " .. will .. " | plate armour " .. will
                      .. " | plate armour w:20 | crystal plate armour w:3"
    e.mons("tengu conjurer ; " .. goodgear .. " / ogre mage ; " .. goodgear ..
           " / deep elf knight ; " .. goodgear ..
           " / naga mage ; " .. goodgear ..
           " / salamander mystic ; " .. goodgear ..
           " / arcanist ; " .. goodgear ..
           " / occultist ; " .. goodgear ..
           " / hell knight ; " .. goodgear ..
           " / necromancer ; " .. goodgear ..
           " / vampire mage ; " .. goodgear ..
           " / spriggan air mage ; rapier ego:antimagic . acid dragon scales")
    e.mons("tengu reaver ; " .. greatweap .. " . " .. greatarm ..
           " / draconian knight ; " .. greatweap ..
           " / vampire knight ; " .. greatweap .. " . " .. greatarm)
end


function wizlab_borgnjor_call_souls(data, triggerable, triggerer, marker, ev)
  if triggerer.type ~= "monster_dies" then
    return
  end

  if you.pos() == 0 then
    return
  end

  local mons = dgn.mons_from_mid(ev:arg1())
  if mons.has_prop("borgnjor") then
      return
  end

  if not crawl.one_chance_in(5) then
    return
  end

  local msp = "lost soul seen sum:call_lost_souls dur:1 generate_awake"

  local count = 0
  for point in iter.circle_iterator(6) do
    if crawl.one_chance_in(8) and count < 1 then
      if feat.is_solid(point.x, point.y) or not feat.has_solid_floor(point.x, point.y) then
      else
       local mon = dgn.create_monster(point.x, point.y, msp)
       -- this can still fail if there's already another monster here
       if mon ~= nil then
        mon.set_prop("borgnjor", 1)
        count = count + 1
       end
      end
    end
  end

  crawl.redraw_view()

  if count == 1 then
    crawl.mpr("A lost soul coalesces out of thin air!", "warning")
  end
end
}}

default-depth: Depths, Elf, Crypt, Vaults, !Vaults:$

###############################################################################
# Portal entrances.
#
# Todo: more, and better.
NAME:   mu_enter_wizlab_1
TAGS:   vaults_orient_s
TILE:   m = dngn_transparent_wall_green
COLOUR: m = lightgreen
:       wizlab_portal(_G)
MAP
    wwwww
   wwwwwww
  wwbmbmbww
 wwbb...bbww
wwbm..O..mbww
 wwbb...bbww
  wwbb+bbww
   www.www
    w.@.w
ENDMAP

NAME:    mu_enter_wizlab_2
TAGS:    vaults_orient_s
SHUFFLE: tU
TILE:    m = dngn_transparent_wall_green
COLOUR:  m = lightgreen
TILE:    c = wall_stone_gray
:        wizlab_portal(_G)
MAP
.................
.bbbbbbbmbbbbbbb.
.bb...b...b...bb.
.m..U...O...U..m.
.bb...b...b...bb.
.bbbbbbb+bbbbbbb.
..bb...b.b...bb..
..m..t.....t..m..
..bb...b.b...bb..
..bbbbbb+bbbbbb..
.................
......c...c......
.....ccc.ccc.....
.................
ENDMAP

NAME:   mu_enter_wizlab_3
TAGS:   vaults_orient_s
MARKER: ! = lua:fog_machine { \
             pow_max = 10, delay_min = 10, delay_max = 40, \
             size = 2, size_buildup_amnt = 5, \
             size_buildup_time = 25, cloud_type = "flame" \
         }
MARKER: ? = lua:fog_machine { \
             pow_max = 10, delay_min = 10, delay_max = 40, \
             size = 2, size_buildup_amnt = 5, \
             size_buildup_time = 25, cloud_type = "freezing vapour" \
         }
COLOUR: .' = red / blue
KPROP:  '?! = no_tele_into
SUBST:  ' = .
TILE:   n = dngn_transparent_stone_magenta
COLOUR: n = lightmagenta
TILE:   c = wall_stone_gray
:       wizlab_portal(_G)
MAP
 ccccccccc
cc''!'?''cc
c?'''''''!c
c''nnnnn''c
c''n...n''c
c''n.O.n''c
c'?n...n!'c
c''nn.nn''c
c''nn.nn''c
cc!n.n.n?cc
 ccnn.nncc
  cc.n.cc
   cc.cc
    c@c
ENDMAP

NAME:   mu_enter_wizlab_4
TAGS:   vaults_orient_s
KFEAT:  ! = floor
COLOUR: ! = magenta
FTILE:  !O = floor_rough_magenta
:       wizlab_portal(_G, false)
MAP
    xxxxx
    w!!!x
   ww!O!x
  www!!!x
 www..www
www..www
ww..www
w..www
@.www
@www
ENDMAP

NAME:   mu_enter_wizlab_5
TAGS:   vaults_orient_s
COLOUR: U = random
COLOUR: W = mutagenic
KFEAT:  o = granite_statue
FTILE:  WU.Oo = floor_rough_magenta
TILE:   b = dngn_crystal_magenta
:       wizlab_portal(_G)
: set_feature_name("crystal_wall", "wall of crystal")
MAP
bbbbbbbbbbb
bbbb...bbbb
bWWU.O.UWWb
bWbb...bbWb
bWWWW.WWWWb
bbbbW.Wbbbb
bbbbW.Wbbbb
bbbbW.Wbbbb
bbbbW.Wbbbb
bbbbo.obbbb
bbbb...bbbb
     @
ENDMAP

NAME:       mu_enter_wizlab_6
SUBST:      x = mc.
TILE:       c = wall_stone_white
TILE:       m = dngn_transparent_stone_magenta
FTILE:      mcx.O = floor_rough_magenta
:           wizlab_portal(_G)
MAP
c.c.ccccccc
x.x.x.x..Oc
.x.x.x.x..c
x.x.x.x.x.c
.x.x.x.x.xc
x.x.x.x.x.c
.x.x.x.x.xc
x.x.x.x.x..
.x.x.x.x.xc
x.x.x.x.x..
.x.x.x.x.xc
ENDMAP

NAME:   mu_enter_wizlab_7
# This one doesn't work as well in Vaults, since one entrance tends to become a
# dead end.
WEIGHT: 0 (Vaults)
KFEAT:  apqr = x
# Mimic the rock/floor colors of Zot:1-4
COLOUR: a = white
COLOUR: - = lightgray
COLOUR: p = blue
COLOUR: ' = white
COLOUR: q = lightblue
COLOUR: " = blue
COLOUR: r = magenta
COLOUR: ` = lightblue
TILE:   a = wall_zot_white
TILE:   p = wall_zot_blue
TILE:   q = wall_zot_lightblue
TILE:   r = wall_zot_magenta
FTILE:  - = floor_rough_lightgray
FTILE:  ' = floor_rough_white
FTILE:  " = floor_rough_blue
FTILE:  ` = floor_rough_lightblue
: wizlab_portal(_G)
MAP
xxxxxxxxxxxxx
x...........@
x.xxxxxxxxxxx
x-a''''''''-x
x-a"ppppppa-x
x-a"q````"a-x
x-a"q`rrq"a-x
x-a"q`O`q"a-x
x-a"qrr`q"a-x
x-a"````q"a-x
x-apppppp"a-x
x-''''''''a-x
xxxxxxxxxxx.x
@...........x
xxxxxxxxxxxxx
ENDMAP

NAME:     infiniplex_enter_wizlab_glasses
FTILE:    GO_ = floor_rough_magenta
TILE:     m = dngn_transparent_wall_green
COLOUR:   m = lightgreen
COLOUR:   _ = magenta
TILE:     G = dngn_statue_dragon
: wizlab_portal(_G)
MAP
.......
.bmmmb.
.m_O_m.
.mG_Gm.
.m___m.
.bb_bb.
.......
ENDMAP

NAME:     infiniplex_enter_wizlab_water
FTILE:    cnO_ = floor_rough_magenta
TILE:     n = dngn_transparent_stone_magenta
COLOUR:   n = lightmagenta
COLOUR:   _ = magenta
TILE:     c = wall_stone_white
: wizlab_portal(_G)
MAP
ww......ww
ww.wwww.ww
...wwww...
.wwcnncww.
.wwnO_nww.
.wwn__nww.
.wwcnn_ww.
...wwww...
ww.wwww.ww
ww......ww
ENDMAP

NAME:     infiniplex_enter_wizlab_spiral
SUBST:    G : xG.
SUBST:    x : xx.
MARKER:   ! = lua:fog_machine { \
               pow_max = 8, delay_min = 20, delay_max = 60, \
               walk_dist = 3, size = 1, start_clouds = 1, \
               start_clouds = 1, cloud_type = "freezing vapour" \
           }
MARKER:   ? = lua:fog_machine { \
               pow_max = 8, delay_min = 20, delay_max = 60, \
               walk_dist = 3, size = 1, start_clouds = 1, \
               start_clouds = 1, cloud_type = "mutagenic fog" \
           }
FTILE:    _! = floor_frozen
COLOUR:   _! = lightcyan
FTILE:    -? = floor_rough_magenta
COLOUR:   -? = magenta
: wizlab_portal(_G)
MAP
xx...........xx
xG.bbbbbbbbb.Gx
...bw..........
.b.bw.bbbbbbbb.
.b.bw.bllllllb.
.b.bw.bl.....b.
.b.bw..l.bbb.b.
.b.bwwwO--?b.b.
.b.bbb._..-b.b.
.b....._b.?b.b.
.b!__!_!b.-b.b.
.bbbbbbbb.-b.b.
..........?b...
xG.bbbbbbbbb.Gx
xx...........xx
ENDMAP

NAME:   lightli_enter_wizlab_magi_temple
TAGS:   vaults_orient_n
COLOUR: . = magenta
FTILE:  . = floor_rough_magenta
: wizlab_portal(_G)
MAP
bmm.@.mmb
m.......m
m.bmmmb.m
m.bGOGb.m
m.m...m.m
b.mb.bm.b
b.mb.bm.b
m.m...m.m
m.b...b.m
m.b...b.m
m.......m
bmmbbbmmb
ENDMAP

###############################################################################

default-depth: WizLab

###############################################################################
# Random and semi-random Wizard portals
###############################################################################

###############################################################################
# Chambers of the Cloud Mage (by Mu.)
#
# TODO: Needs an "ocean of clouds" tiles, and fluffy "cotton wool" cloud tiles.
NAME:       wizlab_cloud
TAGS:       no_rotate
MONS:       air elemental w:20 / shock serpent w:5 / spark wasp w:5 \
            / wind drake w:5
MONS:       ghost crab / death drake / apocalypse crab
MONS:       spriggan air mage / blizzard demon
{{
wizname = crawl.make_name()
kmons ("    5 = patrolling Cloud Mage dbname:Cloud_Mage name:"
              .. string.gsub(wizname, " ", "_")
              .. " ; robe_of_clouds . quick blade ego:electrocution \
                     | dagger ego:electrocution | staff of air")
}}
KMONS:      D = twister
MARKER:     ! = lua:fog_machine { \
                pow_max = 10, delay_min = 10, delay_max = 40, \
                size = 2, size_buildup_amnt = 4, \
                size_buildup_time = 25, cloud_type = "white fluffiness" \
            }
# Consumable loot that's both universally good and nice to go for if you can't
# complete the whole map. These along with the 'e' equipment item also help the
# player complete the rest of the map.
ITEM:       potion of haste / potion of resistance w:5 / any potion w:20 \
            / scroll of silence w:5 / scroll of fog w:5 / any scroll w:20
ITEM:       scarf ego:repulsion / book of vapours / condenser vane \
            / staff of air
# Main loot, including some thematic items that are good even if you don't care
# about flight.
ITEM:       any w:20 / star_item / superb_item / any book w:5
ITEM:       randart ring of flight / pair of boots ego:flying \
            / pair of boots ego:rampaging / good_item quick blade \
            / good_item ring of evasion
ITEM:       randbook disc:air
KFEAT:      #6 = deep_water
KPROP:      #6 = no_tele_into
SUBST:      . = .:220 1:8 2:4 3:2
NSUBST:     ' = 2:1 / 1:2 / 1:3 / 15 = 123......
NSUBST:     d = e / d, f = 2:g / h / f, # = 5:D / 4 = D## / *:#
COLOUR:     b = silver
COLOUR:     n = white
LFLOORCOL:  lightblue
LFLOORTILE: floor_rough_lightblue
{{
            set_border_fill_type('open_sea')
            set_random_mon_list("air elemental w:40 / shock serpent \
                / spark wasp / wind drake / ghost crab / apocalypse crab \
                / spriggan air mage / blizzard demon")
            wizlab_setup(_G)
            set_feature_name("floor", "damp floor")
            set_feature_name("crystal_wall", "wall of white crystal")
}}
epilogue{{
            wizlab_milestone(_G, "The Chambers of the Cloud Mage")
}}
#           Map is ugly because border_fill_type doesn't allow for (yet)
#           recolouring.
MAP
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn##################
###################nnn............................nnn################
#################nnn...wwwwwwwwwwwwwwwwwwwwwwwwww...nnn##############
################nn...wwwwwwwbbbbbbbbbbbbbbbbbbbbwww...nn#############
################n..wwwwwwwbbbbbbbbbbbbbbbbbbbbbbwwwww..n#############
###############nn.wwwwwwbbbbbbbb''b''b''b''b''bbwwwwww.nn############
###############n..wwwwwbb.....b'!''''''''''''!'bwwwwww..n############
##############nn.wwwwwwbb.fff.b''''''''''''''''bwwwwwww.nn###########
##############n..wwwwwbbb.fff.b''''''''''''''''bWWWWWWW..n###########
##############n..wwwwwbbb.fff.+'''5''''''''''''+.........n###########
##############n..wwwwwbbb.fff.b''''''''''''''''bWWWWWWW..n###########
##############nn.wwwwwwbb.fff.b''''''''''''''''bwwwwwww.nn###########
###############n..wwwwwbb.....b'!''''''''''''!'bwwwwww..n############
###############nn.wwwwwwbbbbbbbb''b''b''b''b''bbwwwwww.nn############
################n..wwwwwwwbbbbbbbbbbbbbbbbbbbbbbwwwww..n#############
################nn...wwwwwwwbbbbbbbbbbbbbbbbbbbbwww...nn#############
#################nn....wwwwwwwwwwwwwwwwwwwwwwwwww...nnn##############
##################nnnn............................nnn################
#####################bbb.......bbbbbbbbbbbbbbbbbbbb##################
#####################nn.......nn#####nnn#############################
####################nn.......nn#####nn.nn############################
###################nn.......nn#####nn.!.nn###########################
###################n!......nnn####nn.....nnn#########################
###################nnn.......nnn#nn........nn########################
####################nnnn.......nnn..........nn#######################
#######################nnn!.....nnn..........n#######################
########################n.....!nnnbb+bb......nn######################
#######################nnn......nbb---bb!.....n######################
########################n......nbb-----bb.....nn#####################
#######################nnn......b-------b......n#####################
#######################n.!.....n+-<-A-<-+......n#####################
#######################n.b......b-------bn...!nn#####################
#######################n.bn.....bb-----bb......n#####################
#######################b+bbbb....bb---bb!.....nn#####################
#######################n....bn...!bb+bb......nn######################
#######################n.dd.bn.............nnb#######################
#######################n.dd.bnn...........bbbbbbbbb##################
#######################n....b#n..........!...+....n##################
#######################nnnnnb#nn........nnnnnb.dd.n##################
###############################nn......nn####b.dd.n##################
################################nn.!..nn#####b....n##################
#################################nnnnnn######bnnnnn##################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
ENDMAP

###############################################################################
# Halls of the Hellbinder (by Mu.)
NAME:       wizlab_demon
TAGS:       no_rotate no_hmirror no_vmirror
KFEAT:      _ = altar_makhleb
KFEAT:      p = granite_statue
LFLOORTILE: floor_pebble_lightred
LFLOORCOL:  red
LROCKCOL:   red
COLOUR:     c = darkgrey
COLOUR:     -|/\o[]CDEFGHIJKLMNOPQRSTUVWXYZu = yellow
KFEAT:      -|/\o[]CDEFGHIJKLMNOPQRSTUVWXYZu = floor
KFEAT:      u = fountain_blood
TILE:       c = wall_stone_dark
TILE:       p = dngn_statue_demonic_bust / dngn_statue_imp \
                / dngn_statue_cerebov / dngn_statue_ancient_evil
# symbols roughly corresponding to sigil shape
FTILE:      - = sigil_straight_E_W
FTILE:      | = sigil_straight_N_S
FTILE:      / = sigil_straight_NE_SW
FTILE:      \ = sigil_straight_NW_SE
FTILE:      o = sigil_circle
FTILE:      T = sigil_cross
FTILE:      Y = sigil_Y
FTILE:      ] = sigil_Y_left
FTILE:      [ = sigil_Y_right
FTILE:      O = sigil_rhombus
FTILE:      Q = sigil_algiz_left
FTILE:      R = sigil_algiz_right
FTILE:      S = sigil_sharp_E_NE
FTILE:      Z = sigil_sharp_W_SW
FTILE:      K = sigil_straight_E_NE_SW
FTILE:      X = sigil_fourway
FTILE:      U = sigil_Y_inverted
FTILE:      V = sigil_Y_leftleaning
FTILE:      W = sigil_Y_rightleaning
# remaining sigil patterns
FTILE:      C = sigil_curve_S_E
FTILE:      D = sigil_curve_S_W
FTILE:      E = sigil_curve_N_E
FTILE:      F = sigil_curve_N_W
FTILE:      G = sigil_straight_E_SW
FTILE:      H = sigil_straight_W_SE
FTILE:      I = sigil_straight_S_NE
FTILE:      J = sigil_straight_S_NW
FTILE:      L = sigil_straight_N_SE
FTILE:      M = sigil_straight_N_SW
FTILE:      N = sigil_straight_E_NW
FTILE:      P = sigil_straight_W_NE
RTILE:      x = wall_undead
MARKER:     h = lua:fog_machine { \
                pow_max = 10, delay_min = 10, delay_max = 40, \
                size = 2, size_buildup_amnt = 5, \
                size_buildup_time = 25, cloud_type = "flame", \
                excl_rad = 0 }
KMONS:      1 = orange demon / hellwing / red devil / rust devil / \
                sixfirhy / sun demon / soul eater / smoke demon / hell beast
KMONS:      2 = balrug / blizzard demon / cacodemon / green death / \
                hellion / lorocyproca / shadow demon / tormentor
KMONS:      3 = hellephant / dread lich w:5
{{
wizname = crawl.make_name()
kmons("4 = patrolling Hellbinder dbname:Hellbinder name:"
      .. string.gsub(wizname, " ", "_") .. " ; majin-bo")
}}
KITEM:      d = scroll of summoning / w:5 scroll of torment / \
                / any scroll w:20 / potion of haste \
                / potion of heal wounds / any potion w:20
KITEM:      e = any beam wand / any blast wand / \
                ring of fire / ring of ice / randbook disc:summoning
KITEM:      f = demon blade w:1 / demon whip w:1 / demon trident w:1 \
                / manual of summonings w:2 / any randart jewellery w:5 \
                / cloak good_item w:5 / star_item w:25 / superb_item
KITEM:      g = randbook disc:summoning
NSUBST:     d = e / d, ' = 4:1 / 3=12...., " = 4:1 / 3=12....
NSUBST:     ` = 2:1 / 2:2 / 3=12...., ; = 2:1 / 2:2 / 3=12....
NSUBST:     3 = 1:3 / 1, ~ = 2:1 / 3:2 / 4 / 9=12.... / ., f = 1:g / f
{{
set_random_mon_list("common demon w:200 / balrug / blizzard demon / \
                     cacodemon / green death / hell beast / hellion / \
                     lorocyproca / shadow demon / tormentor \
                     / hellephant w:5 / dread lich w:5")
wizlab_setup(_G)
set_feature_name("stone_wall", "black wall")
set_feature_name("rock_wall", "carved rock wall")
}}
epilogue{{ wizlab_milestone(_G, "The Hall of the Hellbinder") }}
MAP
cccccccccccccccccccccccccccccccccccc
ccccccc'ccccccp...A...pcccccc'cccccc
ccccc'''''cccc.........cccc"""""cccc
cccc''G'H''ccc..cc.cc..ccc"""o"""ccc
ccc''/'''\''cc.cc...cc.cc""|"""""/cc
ccc'I'''''J'cc....c....cc"-O-"""/"cc
ccd'|''U''|.....c...c....."|"""/""dc
ccd'|''Y''|.......<.......""""/"""dc
ccc'L'''''M.cc..c...c..cc."""K----cc
ccc''\'''/''cc....c....cc"""/"""""cc
cccc''N'P''ccc.cc...cc.ccc"/"""""ccc
ccccc'''''cccc..cc.cc..cccc"""""cccc
cccccc..cccccu.........uccccc..ccccc
cccccc..cccccc..cc.cc..cccccc..ccccc
cccccc..cc`ccc.cc...cc.ccc,cc..ccccc
ccccccc``````c.c.\./.c.c;;Z;;;cccccc
ccccccc```o````...Y...;;;/;;O;cccccc
cccccc``\```/``c..|..c;;/;;OTO;ccccc
cccccc```\`/```ccd3dcc;/;;;;U;;ccccc
ccccc``\`CXD`/``cc.cc;/;;;;;;;;;cccc
cccccc``\|`|/```.....S--------Zccccc
cccccc```Q3R```.cc.cc;;;;;3;;/;ccccc
ccccccc``ETF```ccd3dcc;;;;;;/;cccccc
cccccccc```````c..|..c;;;;;S;ccccccc
cccccccccc........U........ccccccccc
ccccccccccc....c./.\.c....cccccccccc
ccccccccccc....cc...cc....cccccccccc
cccccccccccc....cc.cc....ccccccccccc
ccccccccccccc.\./...\,/.cccccccccccc
ccccccccccccc..V.....W..cccccccccccc
cccccccccccccc/.......\ccccccccccccc
ccccccccccccccc.......cccccccccccccc
ccccccccccccccccx+++xccccccccccccccc
cccccccccccccccc.....ccccccccccccccc
cccccccccccccc...G.H...ccccccccccccc
cccccccccccc...GP...NH...ccccccccccc
ccccccccccc..G[.......]H..cccccccccc
cccccccccc../..NxxxxxP..\..ccccccccc
cccccccccc.I...xxpupxx...J.ccccccccc
ccccccccc..U..xx~G~H~xx..U..cccccccc
ccccccccc.I.J.~~/~~~\~~.I.J.cccccccc
cccccccc~~|~~~~/~~~~~\~~~~|~~ccccccc
cccccccc~~|~~~/\~~~~~/\~~~|~~ccccccc
cccccccc~~|~~/~~\~~~/~~\~~|~~ccccccc
ccccccc~~~L~/~xx~N~P~xx~\~M~~~cccccc
cccccccf~~~W~~Gxxp_pxxH~~V~~~fcccccc
cccccccff~~~NP~~xxxxx~~NP~~~ffcccccc
ccccccpfff~~~~~~~~~~~~~~~~~fffpccccc
cccccccccccccccccccccccccccccccccccc
ENDMAP

###############################################################################
# Specific Wizard portals
###############################################################################

###############################################################################
# Doroklohe's Forbidden Tomb
#
# It seems as if he practised box casting. I wonder what that's good for.
# Vault by dpeg. Thanks to Enne for box_glyph and to Jude for triggers.
#
# A bleach sun settles in the smog-stained sky
# Dismembered bodies stray in disarray
# Breakfast is served in the Manchester Morgue
# The beginning of a horrifying day
#                                    Impetigo 1992
#
# TODO: Floor tiles, use box_glyph for warning box instead of manual placement.
NAME:       wizlab_doroklohe
TAGS:       no_rotate
LROCKCOL:   yellow
KFEAT:      ! = x
{{
function make_box(cenx, ceny, gly)
  for ox = -1, 1 do
    for oy = -1, 1 do
      local x = cenx + ox
      local y = ceny + oy
      if (x >= 1 and y >= 1 and x <= width() and y <= height()) then
        if (ox ~= 0 or oy ~= 0) then
          mapgrd[x][y] = gly;
        end
      end
    end
  end
end

function box_glyph(findgly, boxgly)
  local glyphs = {gly_points(findgly)}
  for i = 1, #glyphs, 2 do
    make_box(glyphs[i], glyphs[i+1], boxgly)
  end
end
}}
#           There are two layouts: round and grid.
#           Round has 19 boxes: 12 % and 6 * and 1 |
#           Grid has 21 boxes: b-u and |
#           Layout for grid can be regular or random.
#
:           local layout = crawl.random2(13)
:           if layout < 3 then
#           Preparation for the rare regular grid layout.
SUBST:      bcdefghijk = ., lmnopqrstu = .
SUBST:      B=b, C=c, D=d, E=e, F=f, G=g, H=h, I=i, J=j, K=k
SUBST:      L=l, M=m, N=n, O=o, P=p, Q=q, R=r, S=s, T=t, U=u
:           end
:           if layout > 9 then
#           First the round layout...
COLOUR:     _ = darkgrey
KFEAT:      _ = stone_wall
TILE:       _ = wall_stone_black_marked / wall_stone_dark w:4 / wall_stone_black_marked
SUBST:      bcdefghijk = ., lmnopqrstu = .
SUBST:      BCDEFGHIJK = ., LMNOPQRSTU = .
:           else
#           ...and now the grid layout.
SUBST:      _ = .
SUBST:      *=., %=.
SUBST:      B=b, C=c, D=d, E=e, F=f, G=g, H=h, I=i, J=j, K=k
SUBST:      L=l, M=m, N=n, O=o, P=p, Q=q, R=r, S=s, T=t, U=u
NSUBST:     b = 1:b / *:., c = 1:c / *:.
NSUBST:     d = 1:d / *:., e = 1:e / *:.
NSUBST:     f = 1:f / *:., g = 1:g / *:.
NSUBST:     h = 1:h / *:., i = 1:i / *:.
NSUBST:     j = 1:j / *:., k = 1:k / *:.
NSUBST:     l = 1:l / *:., m = 1:m / *:.
NSUBST:     n = 1:n / *:., o = 1:o / *:.
NSUBST:     p = 1:p / *:., q = 1:q / *:.
NSUBST:     r = 1:r / *:., s = 1:s / *:.
NSUBST:     t = 1:t / *:., u = 1:u / *:.
#           Of the outer boxes, three are damaged.
#           TODO: adapt this code for the first box,
#           instead of manually ruining it.
SHUFFLE:    bcdefghijklm
:           box_glyph('b', 'X')
:           box_glyph('c', 'Y')
:           box_glyph('d', 'Z')
SUBST:      bcd = .
NSUBST:     X = 1=. / *=!:20 .:1
NSUBST:     Y = 1=. / *=!:30 .:1
NSUBST:     Z = 1=. / *=!:50 .:1
#           For the other boxes, prepare same setup as for the
#           round layout (i.e. six *'s)
SHUFFLE:    nqru
SUBST:      efghijklmn = %
SUBST:      opqrstu = *
:           end
#           Monsters
#            0 Tomb set: zombies, mummies (weight *2)
#            1 Demons (if demons are added or reclassified, please change!)
:           local mrnd = crawl.random2(3)
:           if mrnd == 0 then
KMONS:      0% = smoke demon / ynoxinul / neqoxec w:6 / ice devil /\
                 chaos spawn / soul eater / sun demon
KMONS:      * = lorocyproca / reaper / shadow demon / tormentor / hellion /\
                blizzard demon / green death / balrug / cacodemon
KMONS:      | = hell sentinel / brimstone fiend / tzitzimitl /\
                ice fiend / executioner
:           set_random_mon_list(
:               "smoke demon / ynoxinul / neqoxec / " ..
:               "chaos spawn / soul eater / sun demon / " ..
:               "lorocyproca / reaper / shadow demon / tormentor / hellion")
:           else
KMONS:      0% = place:Depths:1 zombie / guardian mummy w:4
KMONS:      * = zombie / mummy priest w:6
KMONS:      | = ancient lich / dread lich / royal mummy w:20
:           set_random_mon_list("place:Depths:1 zombie / guardian mummy")
:           end

#           Hints.
KITEM:      ' = wand of digging charges:1 ident:type
KITEM:      " = scroll of revelation q:1 ident:type
#           Loot.
#           0 = scrolls. 1 = armours. 2 = mixed.
:           local lrnd = crawl.random2(3)
:           if lrnd == 0 then
KITEM:      % = any scroll / any scroll q:2 w:3 / any scroll q:3 w:1
:           kitem("* = " .. dgn.good_scrolls)
KITEM:      | = scroll of acquirement q:1 ident:type / \
                scroll of enchant weapon q:3 ident:type / \
                scroll of blinking q:2 ident:type, scroll of fog q:2 ident:type
:           elseif lrnd == 1 then
KITEM:      % = any armour
KITEM:      * = any good_item armour
KITEM:      | = robe ego:resistance ident:type / gold dragon scales
:           else
KITEM:      % = any / star_item w:2
KITEM:      * = star_item / superb_item w:2
KITEM:      | = superb_item
:           end
#           Boxification:
:           box_glyph('%', '!')
:           box_glyph('*', '!')
:           box_glyph('|', '!')
#           Intentionally colouring the floor glyphs of the central room only.
#           The squares beneath the boxes are to remain uncoloured.
NSUBST:     x = 1:. / 1 = x. / *:x
COLOUR:     ^ = darkgrey
TILE:       ^ = wall_stone_black_marked / wall_stone_dark w:4 / wall_stone_black_marked
COLOUR:     = = yellow
KFEAT:      ^ = stone_wall
COLOUR:     . = darkgrey / blue w:3 / cyan w:1
MARKER:     ! = lua:portal_desc {wall_drop=1}
MARKER:     = = lua:portal_desc {wall_drop=1}
MARKER:     x = lua:portal_desc {wall_drop=1}
MARKER:     + = lua:portal_desc {wall_drop=1}
TILE:       !x = wall_sandstone
{{
local box_marker = TriggerableFunction:new {
    func="wizlab_doroklohe_convert_boxes",
    repeated=true, data={phase=1} }

box_marker:add_triggerer(DgnTriggerer:new { type="turn",
    delay_min=500, delay_max=1000})

lua_marker("A", box_marker)
}}
:           set_feature_name("rock_wall", "strange rock wall")
:           set_feature_name("stone_wall", "highly decorated stone wall")
:           set_feature_name("floor", "rough-hewn floor")
:           wizlab_setup(_G)
epilogue{{
            wizlab_milestone(_G, "Doroklohe's Tomb")
}}
MAP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^________________...........________________^
^____________...................____________^
^_________........................._________^
^_______b....cc......d%d......ee....f_______^
^_____bB.....cC%.....dDd.....%Ee.....Ff_____^
^____bb...............................ff____^
^___.....................................___^
^__........%......o*.....*p......%........__^
^__.......nnN....oO.......Pp....Qqq.......__^
^_........................................._^
^_...mm...............................gg..._^
^_...mM..%......*.....|.....*......%..Gg..._^
^_...mm...............................gg..._^
^_........................................._^
^__.......uuU....tT.......Ss....Rrr.......__^
^__........%......t*.....*s......%........__^
^___.....................................___^
^____ll...............................hh____^
^_____lL.....kK%.....xxx.....%Ii.....Hh_____^
^_______l....kk......x0x......ii....h_______^
^_________...........xxx..........._________^
^____________...................____________^
^________________...........________________^
^^^^^^^^^^^^^^^^^^^^^^#^^^^^^^^^^^^^^^^^^^^^^
                ^____'."____^
                ^__.......__^
                ^_...!+!..._^
                ^_.<.+A+.<._^
                ^_...!+!..._^
                ^__.......__^
                ^____...____^
                ^^^^^^^^^^^^^
ENDMAP

##############################################################################
# Cigotuvi's Fleshworks (by Mu.)
#
# Cigotuvi has mastered the art of manipulating flesh, and his lab is a
# living testament to this fact, seeming like the interior of some
# ghastly beast. The walls and floor are slick and membranous, pulsing to an
# unheard heartbeat and oozing thick, green ichor from every inch.
#
# The bulk of Cigotuvi's Fleshworks is devoted to cells that house test
# subjects in various stages of degeneration. Most are sickly humanoids; the
# others are ugly things and abominations.
#
# The central, circular chamber houses Cigotuvi's flesh golem.
# The Eastern half of his lab is dominated by a snaking passageway filled with
# shapeshifters and the occasional ugly thing.
#
# The western half of his lab is full of abominations, including the terrible
# "Cigotuvi's Monster".
#
# TODO:     * door tile is *really* ugly, fix this?
#
NAME:       wizlab_cigotuvi
TAGS:       no_rotate
KPROP:      . = w:1 bloody / w:15 nothing
KPROP:      ' = bloody / w:5 nothing
{{
 local dbtile = "dbname:deformed_humanoid n_adj n_spe tile:mons_deformed_"
 local emaciated = "name:emaciated " .. dbtile
 local febrile = "name:febrile " .. dbtile
 local garbled = "name:garbled " .. dbtile
 local mangled = "name:mangled " .. dbtile
 local sickly = "name:sickly " .. dbtile
 local twisted = "name:twisted " .. dbtile

 mons("human " .. emaciated .. "human / human " .. febrile ..
      "human / human " .. garbled .. "human / human " .. mangled ..
      "human / human " .. sickly .. "human / human " .. twisted .. "human")
 mons("elf " .. emaciated .. "elf / elf " .. febrile ..
      "elf / elf " .. garbled .. "elf / elf " .. mangled ..
      "elf / elf " .. sickly .. "elf / elf " .. twisted .. "elf")
 mons("orc " .. emaciated .. "orc / orc " .. febrile ..
      "orc / orc " .. garbled .. "orc / orc " .. mangled ..
      "orc / orc " .. sickly .. "orc / orc " .. twisted .. "orc")
}}
MONS:       ugly thing, very ugly thing
MONS:       glowing shapeshifter / radroach w:2
MONS:       small abomination
KMONS:      8 = large abomination
KMONS:      9 = generate_awake glass eye
KMONS:      0 = col:red iron golem hd:5 spells:corrupting_pulse.36.magical \
                name:flesh_golem name_replace \
                tile:mons_flesh_golem name_descriptor
KMONS:      & = col:mutagenic primal ox-ox-weird mutant beast \
                name:Cigotuvi's_Monster name_replace tile:mons_cigotuvis_monster
ITEM:       potion of mutation q:1 ident:type
ITEM:       randbook disc:alchemy disc2:necromancy owner:Cigotuvi
ITEM:       flux talisman randart / maw talisman randart / \
            serpent talisman randart / statue talisman w:8 / \
            dragon-blood talisman / storm talisman w:8 / \
            talisman of death w:2
ITEM:       staff of death ident:type, scroll of poison ident:type
ITEM:       w:5 any jewellery randart / w:5 hat_of_the_alchemist / \
            cigotuvi's_embrace
SHUFFLE:    d^ / e~ / g|
NSUBST:     ^ = 2:d / 2:. / * = dd., e = 1:e / 2:f / *:.
NSUBST:     g = 1:g / *:h, i = 1:i / *:$
SUBST:      4 = 4 5:2, " = 6:1 .:16, |~ = .
KPROP:      -FGHIJKPR = no_tele_into
SUBST:      - = ., F = 1, G = 2, H = 3, I = 4, J = 6, K = 7, P = !, R = W
MARKER:     ! = lua:fog_machine { \
                 pow_max = 10, delay_min = 10, delay_max = 40, \
                 size = 1, size_buildup_amnt = 10, \
                 size_buildup_time = 500, cloud_type = "mutagenic fog", \
                 excl_rad = 0 }
MARKER:     ? = lua:fog_machine { \
                 pow_max = 20, delay_min = 10, delay_max = 40, \
                 size = 5, size_buildup_amnt = 10, \
                 size_buildup_time = 25, cloud_type = "mutagenic fog", \
                 excl_rad = 0 }
LFLOORCOL:  magenta
LFLOORTILE: floor_nerves
LROCKTILE:  wall_flesh
TILE:       c = wall_flesh
TILE:       m = wall_transparent_flesh
TILE:       + = no_random dngn_fleshy_orifice
COLOUR:     m = yellow
COLOUR:     c+ = lightred
COLOUR:     W = green
:           set_feature_name("shallow_water", "Viscous fluid")
:           set_feature_name("stone_wall", "sinewy wall")
:           set_feature_name("clear_rock_wall", "thin membrane")
:           set_feature_name("floor", "pulsating floor")
: lua_marker('+', props_marker {
:           door_description_noun="fleshy orifice",
:           door_berserk_verb_open="You part the %s%s",
:           door_berserk_adjective="with a squelch!",
:           door_berserk_verb_close="You squeeze the %s%s closed",
:           door_noisy_verb_open="You part the %s%s with a squelch!",
:           door_noisy_verb_close="You squeeze the %s%s closed with a squelch!",
:           door_airborne_verb_open="You reach down and part the %s%s.",
:           door_airborne_verb_close="You reach down and squeeze the %s%s closed.",
:           door_verb_open="You part the %s%s.",
:           door_verb_close="You squeeze the %s%s shut."
:           })
:           wizlab_setup(_G)
:           set_random_mon_list("large abomination / ugly thing / very ugly thing")
epilogue{{
            wizlab_milestone(_G, "Cigotuvi's Fleshworks")
}}
MAP
ccccccccccccccccccccccccccccccccccccccccccccc
ccgggcccc|cccccccccccAccccccccccccWWWW~5ecccc
c|...|c....|ccc---ccc+cccccccccccWe~~~.45eccc
c|8........|cc-I---m...m--ccccccW~.....845ecc
c.&5.......cc---G--m.7.m-F-cccccW~........ecc
c.8........cc---H--m...m-I--ccccW~.......~Wcc
c|.........cc-cccccm...mc---ccccc.......~Wccc
c|...|ccc+ccccc--cccc+cccccccccccc.....eWcccc
ccgggccc..ccccIII-cm...m--H--ccccc+cccccccccc
cccccccc..ccc--P---m.7.m-F--cccccc""ccccccccc
cc^^cccc..ccc-III--m...m---ccccccc""cc$$i$$cc
c^dd^cc...cccc----cm...m-cccRccccc""c...c...c
c^dd^+...cccccc--cccc+cccc---Rcccc""c...c...c
c^dd^c...ccccccccc-m...m-KK---Rccc""ccc+c+ccc
cc^ccccc+cccccccc--m.7.m---I--Rccc""c...9...c
ccccccc...cccc---F-m...m----K-ccic""c...6...c
cccc.........c--G--m...mc----cc$$c""c..6669.c
c.67...ccc...cc--cccc+cccc--ccc+cc""c..66..cc
c...ccccccc+cccccc.m.....cccc.666c""+.....ccc
cc...ccccc'''cccc..m.....4cc9.666c""ccccccccc
cc...ccc''''''cc.!.m.....<4c9....+"""""""""cc
c..cccc''''''''cc.......c4ccc....cc"""""""""c
c..ccc'''''''''cccccc+cccccccccccccccccccc""c
c..cc''''''''''ccccc...ccccccc""""""""""""""c
c..cc''''''''''ccc.......cccc""""""""""""""cc
c..c'''''''''''cc.........ccc""cccccccccccccc
c..c'c'c'c'c'ccc...........cc""""""""""""""cc
c..c8c8c'c8c8ccc...........ccc""""""""""""""c
c..cccccccccccc.....c.c.....cccccccccccccc""c
c...76........+......?......+"""""ccc"""""""c
c...76........c.....c.c.....c""""""c"""""""cc
ccmmmccccmmmcccc...........cccccc""c""ccccccc
c-----cc-----cccWW.......WWcc""""""c""""""ccc
cc-JJccccIIIcccccWW..0..WWcc""""""ccc""""""cc
ccJJ-cccc-F-ccccccWWWWWWWccc""ccccccccccc""cc
cc-HccccccIIccccccccWWWccccc"""""""""""""""cc
ccccccccccccccccccccccccccccc"""""""""""""ccc
ccccccccccccccccccccccccccccccccccccccccccccc
ENDMAP

###############################################################################
# Iskenderun's Mystic Tower
#
# TODO: Could use more unique tiles.
#       A previous commit labeled this one as boring, though acceptable;
#       hopefully emphasizing the orbs and terrain more than previously
#       should help, though more unique contents could certainly be tried.
#
NAME:       wizlab_iskenderun
TAGS:       no_rotate patrolling
MONS:       tengu conjurer
MONS:       statue hd:12 spells:orb_of_destruction.62.magical \
            tile:mons_statue_mage col:vehumet name:conjurer n_adj
KMONS:      3DEF = purple draconian
KITEM:      D = robe ego:archmagi ident:type, star_item / superb_item, star_item
KITEM:      E = any book, randbook disc:conjuration owner:Iskenderun \
                spells:iskenderun's_mystic_blast&iskenderun's_battlesphere, \
                randbook disc:conjuration owner:Iskenderun
KITEM:      F = any book good_item, any book good_item, any book
KMONS:      DEF = purple draconian
KMONS:      H = purple draconian scorcher / purple draconian annihilator /\
                purple draconian knight / purple draconian stormcaller
COLOUR:     v = magenta
TILE:       v = dngn_metal_wall_magenta
MARKER:     " = lua:fog_machine { \
                pow_max = 10, delay_min = 10, delay_max = 40, \
                size = 15, cloud_type = "purple smoke" }
NSUBST:     1 = 4 = 1:1 3:19 / 6 = 1:2 3:3 / * = 1:15 ., H = 1:H / 1:H. / *:.
SHUFFLE:    '=F- / '=F- / '=F- / F-'= / F-'=, DEF
SUBST:      - = v, ' = ., = = +
LROCKTILE:  wall_zot_magenta
LROCKCOL:   lightmagenta
LFLOORTILE: floor_rough_magenta
LFLOORCOL:  magenta
:           set_random_mon_list("purple draconian / tengu conjurer")
:           wizlab_setup(_G)
epilogue{{
            wizlab_milestone(_G, "Iskenderun's Mystic Tower")
}}
MAP
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
vxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxv
vxxx..x.x.x.x.x.x.xx"xx.x.x.x.x.x.xx.xxxv
vxx<xxAx.x.x.x.x.x.x.x.x.x.x.x.x.x.xx.xxv
vx.x"xxx.x..........x.............xx"x.xv
vx.xx...............................xxxxv
vxxAx...............................x.xxv
vx.xx................................x.xv
vxx.......2.......v...v.......2.......xxv
vx.xx...........v.vv.vv.v............x.xv
vxx............vvv11.11vvv............xxv
vx.x..........v.v1vvvvv1v.v..........x.xv
vxx..........v.v1vvvEvvv1v.v..........xxv
vx.x........vvv1vvvv+vvvv1vvv........x.xv
vxx..........v1vvvH...Hvvv1v..........xxv
vx.x.......vv1vvvH......vvv1vv.......x.xv
vxxx........v1vvv.......vvv1v........xxxv
vx".x...2.....vD+.H.2...+'=.....2...x."xv
vxxx........v1vvv.......vvv1v........xxxv
vx.x.......vv1vvvH......vvv1vv.......x.xv
vxx..........v1vvvH...Hvvv1v..........xxv
vx.x........vvv1vvvv+vvvv1vvv........x.xv
vxx..........v.v1vvvFvvv1v.v..........xxv
vx.x..........v.v1vv-vv1v.v..........x.xv
vxx............vvv11.11vvv............xxv
vx.x............v.vv.vv.v............x.xv
vxx.......2.......v...v.......2.......xxv
vx.x.................................x.xv
vxx.x...............................x.xxv
vxxxx...............................xxxxv
vx.x"xx.............x.............xx"x.xv
vxx.xx.x.x.x.x.x.x.x.x.x.x.x.x.x.x.xx.xxv
vxxx.xx.x.x.x.x.x.xx"xx.x.x.x.x.x.xx.xxxv
vxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxv
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
ENDMAP

###############################################################################
# Zonguldrok's Shrine.
NAME:       wizlab_zonguldrok
TAGS:       no_rotate patrolling
MONS:       skeletal warrior, ancient champion, lich
ITEM:       any scroll / randbook disc:necromancy numspells:1 w:2
# Shortlist of one-handed skeletal warrior weapons.
: local d = "ego:draining good_item "
: local p = "ego:pain good_item "
: item("morningstar " .. d .. " / morningstar " .. p .. " / war axe " .. d ..
:      " / war axe " .. p .. " / trident " .. d .. " / trident " .. p ..
:      " / scimitar " .. d .. " / scimitar " .. p)
ITEM:       shadow dragon scales good_item / shadow dragon scales randart / \
            plate armour good_item / plate armour randart / \
            chain mail good_item / chain mail randart / \
            kite shield randart w:5 / tower shield randart w:5 / \
            talisman of death w:5 / talisman of death randart w:1
KFEAT:      GW = G
NSUBST:     Z = Z / ', d = 6:e / 2:f / * = d:20 e:2, G = 27:G / 4 = G. / *:.
{{
lua_marker("G", portal_desc { grave = 1 })
lua_marker("R", portal_desc { antique_grave_a = 1 })
lua_marker("S", portal_desc { antique_grave_b = 1 })
lua_marker("W", portal_desc { desc="Zonguldrok's gravestone",
        veto_fragmentation="veto", veto_disintegrate="veto", veto_shatter="veto" })

local zombies_appear_marker = TriggerableFunction:new {
    func = "wizlab_zonguldrok_spawn_zombies",
    repeated = true,
    data = {count = 0}
}
local zombies_killed_marker = TriggerableFunction:new {
    data = { number_killed = 0, door_appeared = false },
    func = "wizlab_zonguldrok_killed_zombie",
    repeated = true
}
local wizard_appear_marker = TriggerableFunction:new {
    data = { awoke = false },
    func = "wizlab_zonguldrok_awaken_wizard",
    repeated = true,
    props = { listen_to_replicas = true, only_at_replica = true }
}
wizard_appear_marker:add_triggerer(DgnTriggerer:new {
    type = "player_move" })
zombies_appear_marker:add_triggerer(DgnTriggerer:new {
    type = "turn",
    delay_min = 150,
    delay_max = 250
})
zombies_killed_marker:add_triggerer(DgnTriggerer:new {
    type = "monster_dies",
    target = "any"
})
lua_marker("M", zombies_appear_marker)
lua_marker("D", zombies_killed_marker)
lua_marker("L", Triggerable.synchronized_markers(wizard_appear_marker))
}}
SUBST:      ? = txxx, ! = t..
SUBST:      M = x, CD = c, LZ = "
KPROP:      'def$123L+ = no_tele_into
COLOUR:     "W = lightmagenta
COLOUR:     t = brown / lightgrey w:5
TILE:       W = dngn_zonguldrok_shrine
TILE:       G = dngn_gravestone
TILE:       c = wall_stone_gray
TILE:       t = dngn_tree_dead
FTILE:      " = floor_nerves_darkgray
LFLOORCOL:  darkgrey
LROCKCOL:   darkgrey
LFLOORTILE: floor_tomb
LROCKTILE:  wall_hall_darkgray
: set_feature_name("tree", "dead tree")
: set_feature_name("granite_statue", "gravestone")
: wizlab_setup(_G)
{{
set_random_mon_list(
    -- Selected to make derived and regular undead equal.
       [[ two-headed ogre skeleton / cyclops zombie / swamp dragon simulacrum / ]]
    .. [[ deep troll skeleton / stone giant zombie / storm dragon simulacrum / ]]
    .. [[ ettin skeleton / juggernaut zombie / golden dragon simulacrum / ]]
    .. [[ vampire / skeletal warrior / jiangshi / phantasmal warrior / ]]
    .. [[ vampire knight / ghoul / ancient champion w:20 / lich / ]]
)
}}
epilogue{{
            wizlab_milestone(_G, "Zonguldrok's Shrine")
}}
MAP
M   xxxxxxxxxxxxxxxxxxx
   xx?????????????????xx
  xx?!!!!!!!!!!!!!!!!!?xx
 xx?!!.G.G.G.G.G.G.G.!!?xx
xx?!!.G.G.G.G.G.G.G.G.!!?xx
x?!!.G.G.G.G.G.G.G.G.G.!!?x
x?!.G.G.GcccccccccG.G.G.!?x
x?!G.G.G.cdddcdddc.G.G.G!?x
x?!.G.G.ccdd'+'ddcc.G.G.!?x
x?!G.Gcccddcc+ccddcccG.G!?x
x?!.G.c$dddcLLLcddd$c.G.!?x
x?!G.Gc$$ccc'''ccc$$cG.G!?x
x?!.G.c$$c'''''''c$$c.G.!?x
x?!G.Gcccc'RW'WS'ccccG.G!?x
x?!.G.c''+'RR'SS'+''c.G.!?x
x?!G.Gc'3ccc'''ccc2'cG.G!?x
x?!.G.c''3'c'''c'1''c.G.!?x
x?!G.GcCc''ccccc1'cCcG.G!?x
x?!.G.G.cc'''+'''cc.G.G.!?x
x?!G.G.G.c'''c'''c.G.G.G!?x
x?!.G.G.GccccDccccG.G.G.!?x
x?!!.G.G.G.GV.VG.G.G.G.!!?x
xx?!!.G.G.G..<..G.G.G.!!?xx
 xx?!!.G.G.G.A.G.G.G.!!?xx
  xx?!!!!!!!!!!!!!!!!!?xx
   xx?????????????????xx
    xxxxxxxxxxxxxxxxxxx
ENDMAP

###############################################################################
# Wucad Mu's Monastery
#
# TODO: Could use more "alien" statue tiles.
#       Any spawn list (explicitly used here) blocks any redefinition
#       for monsters, which altogether means the flavour redefinitions
#       of the monks were cut they don't work consistently; currently,
#       retiles apply to the level spawns but not the OCS spawns.
#       dbname use may or may not be warranted to preserve old flavour.
#
#       A prefix as well as suffix but no regular modifier
#       (so, "faint draconian monk") would be the best, if it's done.
NAME:       wizlab_wucad
TAGS:       no_rotate
SUBST:      T = t.
KMONS:      8 = orange crystal statue name:Statue_of_Wucad_Mu n_rpl n_the \
                hd:15 tile:mons_wucad_mu_statue
KITEM:      8 = crystal_ball_of_wucad_mu
COLOUR:     c = darkgrey
COLOUR:     t = lightred / red w:3
TILE:       t = dngn_tree_lightred / dngn_tree_red w:4 / dngn_tree_yellow w:4
# This used to specify dngn_statue_troll as the only middle case, but that tile
# no longer exists.
TILE:       G = dngn_granite_statue / \
                dngn_statue_angel / dngn_statue_imp / \
                dngn_statue_ancient_evil / dngn_statue_ancient_hero
COLOUR:     AG = red
COLOUR:     < = lightred
TILE:       c = dngn_stone_dark
LFLOORTILE: floor_pebble_white
KFEAT:      ' = open_door
KFEAT:      1234567 = .
KMONS:      1234567 = nothing
LROCKCOL:   darkgrey
ITEM:       potion of experience q:1 ident:all
ITEM:       manual of fighting / manual of armour / manual of spellcasting / \
            manual of staves / manual of fighting / manual of dodging
ITEM:       book of hexes / book of dreams / book of dangerous friends
SHUFFLE:    defg
LFLOORCOL:  white

{{
dgn.persist.wucad_mu_died = false

local function trigfn (spot)
  return Triggerable.synchronized_markers(function_at_spot(
            "wizlab_wucad_msgfn",
            { spot=spot, trig = false}, true, { only_at_replica = true,
              listen_to_replicas = true }))
end

lua_marker('1', trigfn(1))
lua_marker('2', trigfn(2))
lua_marker('3', trigfn(3))
lua_marker('4', trigfn(4))
lua_marker('5', trigfn(5))
lua_marker('6', trigfn(6))
lua_marker('7', trigfn(7))


local summon_marker = TriggerableFunction:new ({
    func="wizlab_wucad_summon_monks",
    repeated=true })

summon_marker:add_triggerer(DgnTriggerer:new {type="turn", delay_min=150,
    delay_max=300 })

local wucad_marker = TriggerableFunction:new ({
    func="callback.wizlab_wucad_wucad_died",
    repeated=false })

wucad_marker:add_triggerer(DgnTriggerer:new {type="monster_dies",
    target="Statue of Wucad Mu"})

lua_marker('A', summon_marker)
lua_marker('A', wucad_marker)

}}
MARKER:     G = lua:props_marker { veto_destroy="veto" }
MARKER:     + = lua:props_marker { veto_destroy="veto" }
MARKER:     ' = lua:props_marker { veto_destroy="veto" }
MARKER:     c = lua:props_marker { veto_destroy="veto" }
MARKER:     t = lua:props_marker { veto_destroy="veto" }
:           wizlab_setup(_G)
:           set_border_fill_type("tree")
:           set_random_mon_list([[shadow w:6 / flayed ghost w:2 / wraith w:2 / ]]
:                            .. [[demonspawn / deep troll / ]]
:                            .. [[grey draconian monk w:6 / ]])
:           set_feature_name("tree", "autumnal tree")
:           set_feature_name("stone_wall", "crumbled stone wall")
:           set_feature_name("granite_statue", "strange statue")
epilogue{{
            wizlab_milestone(_G, "Wucad Mu's Monastery")
}}
MAP
tttttttttttttttttttttttttttttttttttttttt
tttttttttttttttttttttttttttttttttttttttt
ttttttttttttttTTTTTTTttttttttttttttttttt
ttttttTTTTTTTT.......TTTTTTTTTTTTttttttt
tttttT.........ccccc.............Ttttttt
ttttT.........cc777cc.............Tttttt
tttT.......cccc77777cccc...........Ttttt
ttT.......cc..cc777cc..cc......ccc..Tttt
ttT......cc....cc+cc....cc....cc6cc..Ttt
ttT.....Tc....G.....G....cT..cc6U6cc.Ttt
ttT.....cc...............cc...cc6cc..Ttt
ttT......+.G.....8.....G.c.....c+c...Ttt
ttT.....cc...............cc..........Ttt
ttT.....Tc....G.....G....cT..........Ttt
ttT.c..cTcc.............cccT.........Ttt
ttTcc++ccccccc.......ccccccc+cc......Ttt
ttcc5555cccdeccc+++cccfgccc444cc.....Ttt
ttc555555c....c.....c....c44444c....Tttt
ttc555555cc.............cc44444cc..ctttt
ttc555555ccccccccccccccccccc+cccc++ccttt
ttcc5555ccc.............ccc222cc3333cctt
tttccccccc...............+22222+33333ctt
ttttttttccc..ccc+++ccc..ccc222cc3333cctt
tttttttttcccccTT111Ttccccccccccccccccttt
ttttttttttttttT11111Tttttttttttttttttttt
ttttttttttttTT.......TTTtttttttttttttttt
tttccccctttT.....G......Tttttttttttttttt
ttcc...cctT..............Ttttttttttttttt
ttc<.A..'.............U..Ttttttttttttttt
ttcc...cctT.....TTTT.....Ttttttttttttttt
tttccccctttT...TTttTT....Ttttttttttttttt
ttttttttttttTTTTttttTTTTTttttttttttttttt
tttttttttttttttttttttttttttttttttttttttt
tttttttttttttttttttttttttttttttttttttttt
ENDMAP

################################################################################
# The Roulette of Golubria (by HangedMan.)
# Golubria's fascination with translocations led her to warp out a sub-realm
# of the Abyss into her own translocations playground, with opaque security
# systems built in to defend her many assorted woven possessions.
#
# Teleporter explanations: three sets of three chained rooms each,
# rotating the same amount of rooms per direction in the same direction,
# though distorted by the use of the ninth room and each set rotated.
NAME:    wizlab_golubria
TAGS:    no_pool_fixup
KMONS:   1 = jumping spider w:15 / redback / orb spider w:5
KMONS:   3 = ghost moth w:15 / entropy weaver / broodmother w:5
# Rough order and weights for the tiered stuff:
# direct abyss spawn (w:120, less at the top),
# abyss demons, abyss undead (both w:30ish),
# elementals, guests (both w:20ish, fuzzed with heavy un/holy overlap.)
{{
 local distoquip = "boomerang ego:dispersal w:20 | " ..
                   "whip ego:distortion | spear ego:distortion | nothing w:5"
 local lowtier = "large abomination w:25 / unseen horror w:15 / " ..
                 "thrashing horror w:30 / raiju w:20 / worldbinder w:30 / " ..
                 "smoke demon / sixfirhy / hellwing / " ..
                 "dire elephant skeleton / anaconda skeleton / " ..
                 "freezing wraith / air elemental / water elemental / " ..
                 "will-o-the-wisp w:5 / mana viper / demonic crawler w:5"
 local midtier = "tentacled starspawn w:50 / very ugly thing w:30 / " ..
                 "glowing shapeshifter w:40 / efreet w:5 / " ..
                 "soul eater / shadow demon / eidolon / " ..
                 "shadow wraith / storm dragon skeleton / death drake / " ..
                 "base draconian w:5 / spark wasp / glowing orange brain w:5"
 local hightier = "starcursed mass w:30 / apocalypse crab w:30 / " ..
                  "tentacled monstrosity w:20 / executioner w:15 /" ..
                  "cacodemon / hellion w:5 / tormentor w:5 /  " ..
                  "lorocyproca w:5 / lich / angel / " ..
                  "profane servitor / balrug w:15 / " ..
                  "blizzard demon w:15 / hellephant / " ..
                  "draconian shifter w:15 / demonspawn corrupter w:5"

 kmons("2 = rakshasa ; " .. distoquip .. " / boggart ; " .. distoquip)
 kmons("04 = " .. lowtier)
 kmons("95 = " .. midtier)
 kmons("6 = " .. hightier .. " / reaper w:15 ; halberd itemname:scythe " ..
                                 "tile:wpn_scythe wtile:scythe ego:distortion")

 dgn.set_random_mon_list(lowtier .. " / " .. midtier .. " / " .. midtier ..
                         " / " .. hightier .. " / " .. hightier .. " / reaper")
}}
KMONS:   7 = eldritch tentacle
KMONS:   8 = obsidian statue

# Translocations items, abyss escape aides, shrouds, and an immeadiate aide.
KITEM:   d = scroll of blinking / scroll of teleportation q:3 w:15 / \
             any scroll w:1
KITEM:   e = any ally scroll / any scroll w:1
KITEM:   f = there-and-back book w:5 / book of displacement w:5 / \
             manual of translocations w:5 / \
             randbook disc:translocation numspells:5 / \
             randbook disc:translocation owner:Golubria numspells:7 \
             spells:passage_of_golubria
KITEM:   g = ring of flight / potion of enlightenment / potion of haste w:5 / \
             scroll of fog / any potion w:1 / any scroll w:1 / any ring w:1
KITEM:   h = pair of boots ego:flying w:8 / pair of boots ego:rampaging w:1 / \
             pair of boots ego:stealth w:8 / pair of boots w:3
KITEM:   i = wand of digging / any wand w:1
KITEM:   j = any level:3, any level:3 / nothing
KITEM:   k = star_item / any w:5, any w:5 / nothing
KITEM:   | = cloak good_item w:75 / randart cloak w:95 / \
             cloak_of_starlight w:20 / cloak_of_the_thief

KFEAT:   m = iron_grate
KFEAT:   ~ = deep_water / web w:2
KFEAT:   ^ = permanent teleport trap / web w:20
KFEAT:   _ = altar_lugonu
KFEAT:   opqsrtuvw@}) = floor
KPROP:   a"_~ = no_tele_into
MARKER:  ^ = lua:fog_machine { cloud_type = "translocational energy", \
             pow_max = 25, delay_min = 30, delay_max = 60, \
             walk_dist = 1, size_min = 2, size_max = 3 }

# Randomize the teleporter rotation mechanisms in weird rotations
# that ever-so-importantly ensure every chamber is accessible from one another.
SHUFFLE: ozRrIUuLO / uLOozRrIU / rIUuLOozR, pZSsJVvMP / vMPpZSsJV / sJVvMPpZS
SHUFFLE: zRIULO / RzUIOL, ZSJVMP / SZVJPM, HTKW / THWK
SUBST:   H = O, I = P, J = Q, K = R, L = S, M = T, Y = U, z = V, Z = W
# Place the center's features, enemies, and items.
NSUBST:  @ = 1:w / 1:Y / 1:Q / *:<, 7 = 2:7 / *:`
NSUBST:  ` = 1:3 / 1:6 / 4:d / 3:| / 1:|j / 1:i / 4:j / *:`
# Randomize enemies outside of the center.
NSUBST:  2 = 1:6 / 2 = 66993 / 2:9 / 1:. / * = 9222
NSUBST:  1 = 2:3 / 1:6 / 2:2 / 3 = 012 / 2:. / *:1, 0 = 2:9 / 1:6 / 1:. / *:0
NSUBST:  4 = 1:3 / 3:5 / 1:. / *:4
# Randomize starting / chambers, chamber / reward items, and escapes.
NSUBST:  A = 1:) / 1:< / 1:{ / 1:A, ( = 1:} / 1:( / *:<
NSUBST:  [ = 2:< / 1:3 / *:d, d = 2:k / 2:e / 2:f / 3:g / 2:eegghhj / *:d
SUBST:   e = de, j = jjjjg., k = kkj
# Randomize outside terrain and chamber pillars / glass.
NSUBST:  a = 4:_ / 4:_^ / *:a, + = 1:+ / *:c
SUBST:   a = ":40 x:40 cccCC~, - = ':40 x:40 ccCC~~, E = nccCC
SUBST:   c = cccb, C = cb, B = ccbn...

# Finally leave nightmare randomization and go over to colour / tile nonsense.
COLOUR:  n = lightgreen
COLOUR:  c = white
COLOUR:  OPQRSTUVW&{( = warp
COLOUR:  opqrstuvw@}) = gold
COLOUR:  X = darkgrey
LFLOORCOL: green
FTILE:   '"Gbca-n45_+ = floor_demonic_green
FTILE:   .012369AB< = floor_rough_green / floor_pebble_green w:15
FTILE:   `~^78m = floor_demonic_green / floor_pebble_green / floor_rough_green w:5
FTILE:   defghijk| = floor_rough_green
LROCKTILE: wall_zot_green
TILE:    b = dngn_crystal_green / dngn_crystal_cyan w:5
TILE:    c = dngn_stone_wall_green / dngn_stone_wall_cyan w:5
TILE:    n = dngn_transparent_stone_green / dngn_transparent_stone_cyan w:5
TILE:    X = dngn_dimension_edge
FTILE:   OPQRSTUVW&{( = floor_rough_green
TILE:    opqrstuvw@}) = floor_black_cobalt

{{
local trans_glyph = "OPQRSTUVW&{("
local trans_dest_glyph = "opqrstuvw@})"
for i = 1, #trans_glyph do
    lua_marker(trans_glyph:sub(i,i), transp_loc("loc_" .. tostring(i)))
    lua_marker(trans_dest_glyph:sub(i,i),
               transp_dest_loc("loc_" .. tostring(i)))
end
set_border_fill_type('permarock_wall')
set_feature_name("permarock_wall", "The dimension's edge")
set_feature_name("crystal_wall", "wall of crystal")
wizlab_setup(_G)
}}

epilogue{{
            wizlab_milestone(_G, "The Roulette of Golubria")
}}
MAP
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXcccccccEEccccccccccXXXXXXXXXXXXXXXXX
XXXXXccccccXXXXccxxxcc.o..ccxxxxxxccXXXXccccccXXXXXX
XXXEEc...Pccccccxaacc......ccaaaaaxccccccZ...cEEXXXX
XXXEv.....ccxxxxaaacz......Rcaaaaaaxxxxcc.....pEXXXX
XXcc.......naaaaaaan..BBBB..naaaaaaaaaan.......ccXXX
XXc....B...n"aaaaa"n..0B2...n"aaaaaaaa"n...B....cXXX
XXc...BBB.1c"aaaaa"c...B....c"aaaaaaaa"c0.BBB...cXXX
XXc....BB..cccaaaaacc......ccaaaaaaaaccc..BB....cXXX
XXcM.....2...caaaaaac1.[..1caaaaaaaaac...2.....ScXXX
XXccc..0..[..caaaaaacc....cc---aaaaaac..[..1..cccXXX
XXXccnncc..1.ccaaaa--cc..cc-----aaaacc.1..ccnnccXXXX
XXXcxa""c.....c--a--'-c+cc-''-'--a--c.....c""aXcXXXX
XXXcxaaacccc..c'---'-''-'-'--'-'---'c..ccccaaaxcXXXX
XXccxaaaaaaccc+-'-'------4------'-'-+cccaaaaaaxccXXX
Xccxaaaaaaaa-'---'------'~'------'---'-aaaaaaaaxcXXX
Xcxaaaaaaaaa--'-4-'--'-'---'-'--'-4-'--aaaaaaaaaxcXX
Xcxaaaaaaaaaa--'-~-''C'C'-'C'C''-~-'--aaaaaaaaaaxcXX
Xcxaaaaaaaaa--'-'-'CCCCCC(CCCCCC'-'-'--aaaa""aaaxcXX
Xcxaaaaaaaa--'---'CnCC^'CnC'^CCnC'---'--aaccnnccxcXX
Xcxaaaaaaaa-'----'CCnC'`'n'`'CnCC'----'-ccc...HcccXX
Xcxaaa""aaa--'--'CCCC@```````@CCCC'--'-cc1......ccXX
Xcxccnnccaa-'----'C^'`````````'^C'---'cc....0B...cXXXXXXXXX
XcccO...ccc-'---'CC'````m7m````'CC'---+..[.BBB..qEXXXnnnnnX
Xcc......1cc-'-'-'CC'``mm`mm```CC'-'-'c.....2B...EXXXnA.AnX
Xc.........cc-4~--(nn``78_87``nn(--~4-cc.........cXXXn...nX
XE...B2.....c'-'-'CC'``mm`mm```CC'-'-'-cc1......ccXXXnA.AnX
XEu..BBB.[..+---'CC'````m7m````'CC'---'-ccc...TcccXXXnnnnnX
Xc...B0....cc'---'C^'`````````'^C'----'-aaccnnccxcXXXXXXXXX
Xcc......1cc-'--'CCCC@```````@CCCC'--'--aaa""aaaxcXX
XcccL...ccc-'----'CCnC'`'n'`'CnCC'----'-aaaaaaaaxcXX
Xcxccnnccaa--'---'CnCC^'CnC'^CCnC'---'--aaaaaaaaxcXX
Xcxaaa""aaaa--'-'-'CCCCCC(CCCCCC'-'-'--aaaaaaaaaxcXX
Xcxaaaaaaaaaa--'-~-''C'C'-'C'C''-~-'--aaaaaaaaaaxcXX
Xcxaaaaaaaaa--'-4-'--'-'---'-'--'-4-'--aaaaaaaaaxcXX
Xccxaaaaaaaa-'---'------'~'------'---'-aaaaaaaaxccXX
XXccxaaaaaaccc+-'-'------4------'-'-+cccaaaaaaxccXXX
XXXcxaaaaccc..c'---'-'--'-'-''-'---'c..ccccaaaxcXXXX
XXXcxa""cc....c--a--'-''-cc+c-'--a--c.....c""axcXXXX
XXXccnncc..1.ccaaaa-----cc..cc--aaaacc.1..ccnnccXXXX
XXccc..1..[..caaaaaaaaacc....ccaaaaaac..[..0..cccXXX
XXcW.....2...caaaaaaaaac1..[.1caaaaaac...2.....IcXXX
XXc....BB..cccaaaaaaaacc......ccaaaaaccc..BB....cXXX
XXc...BBB.0c"aaaaaaaa"c....B...c"aaaaa"c1.BBB...cXXX
XXc....B...n"aaaaaaaa"n...2B0..n"aaaaa"n...B....cXXX
XXcc.......naaaaaaaaaan...BBB..naaaaaaan.......EcXXX
XXXEt.....ccxxxxaaaaaacV......Jcaaaxxxxcc.....rcXXXX
XXXEEc...Kccccccxaaaaacc......ccaaxccccccU...EcEXXXX
XXXXXccccccXXXXccxxxxxxcc..s.ccxxxccXXXXccccccXXXXXX
XXXXXXXXXXXXXXXXccccccccccEEcccccccXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENDMAP

###############################################################################
# Lehudib's Moon Base by gammafunk

# Lehudib, who penned many writings on earth magic, eventually tired of
# studying this world and sought to uncover the secrets of our moon. After
# arriving there through unknown means, the wizard carved out a fortress on the
# moon's surface, filling it with bizarre monstrosities. Who can say what
# mysteries the self-described Lunar Mage uncovered in such isolation?
# Adventurers who manage to reach the remote Moon Base of Lehudib may indeed
# find powers beyond their comprehension!

NAME:       wizlab_lehudib
KPROP:      ` = no_tele_into
KMONS:      LM = demonic plant
MONS:       w:15 tentacled starspawn / stone giant / eye of devastation
MONS:       w:20 glowing orange brain / w:12 great orb of eyes / w:5 neqoxec \
            / w:3 golden eye band
MONS:       starcursed mass / brown very ugly thing band
MONS:       cacodemon
MONS:       quicksilver dragon / war gargoyle / crystal guardian \
            / wretched star
MONS:       orange crystal statue name:lunar_statue n_rpl n_des \
                spells:brain_bite.24.magical;draining_gaze.24.magical;\
                       lehudib's_crystal_spear.24.magical;\
                       shadow_creatures.48.magical \
                col:lightmagenta tile:mons_zot_statue
MONS:       moon troll ; moon troll leather armour

: item(dgn.loot_scrolls .. " / " .. dgn.loot_potions)
ITEM:       potion of mutation
# Equal chance between randart jewellery and good aux armour.
: item("any randart jewellery w:60" .. " / " .. dgn.good_aux_armour)
ITEM:       randbook owner:Lehudib disc:earth disc2:alchemy \
                     spells:lehudib's_crystal_spear \
            / randbook owner:Lehudib disc:earth disc2:translocation \
                     spells:lehudib's_crystal_spear \
            / randbook owner:Lehudib disc:earth disc2:conjuration \
                     spells:lehudib's_crystal_spear

## The substitutions/shuffles below give 1/3 chance each of both paths
## open, D-path open, or E-path open, and gives 1/4 chance for the
## portal being in any of the 4 locations.
SHUFFLE:    DENOPQK / FERSOO? / EFOOZ!?
## For both paths open, 50% each of South or East portals. For D-path,
## 1/4 chance of East, 3/4 chance of North, For E-path, 1/4 chance of
## South, 3/4 chance of West.
SHUFFLE:    NQ / QN, RS / SR / SR / SR, !Z / Z! / Z! / Z!
SUBST:      DE = ., F = c, K = n, OPQS! = G, RZ = N, ? = .
## Remaining level randomization
SHUFFLE:    Hyp / Mgo
SUBST:      o = 1234, ' = llc, ; = .JJJJJ, yp = .
NSUBST:     h = 2:1 / ., i = 2:1 / ., j = 2:1 / ., k = 2:1 / ., q = 2:1 / .
NSUBST:     r = 3:1 / ., s = 3:1 / ., u = 1:1 / ., z = 1 / 1234, " = 3:J / .
NSUBST:     * = 2:d / *, ` = 3:M / 3=M. / 2:e / 3=..e / 4 / 233 / .

{{
set_random_mon_list("eye of devastation / stone giant " ..
                    "/ tentacled starspawn / glowing orange brain " ..
                    "/ great orb of eyes / neqoxec w:5 / golden eye w:5 " ..
                    "/ very ugly thing w:5 / starcursed mass w:5 " ..
                    "/ cacodemon w:1 / quicksilver dragon w:1 " ..
                    "/ war gargoyle w:1 / crystal guardian w:1 " ..
                    "/ wretched star w:1")
}}
MARKER:     N = lua:transp_loc("moon_troll_entry")
MARKER:     H = lua:transp_dest_loc("moon_troll_entry")
MARKER:     _ = lua:transp_loc("moon_troll_exit")
MARKER:     & = lua:transp_dest_loc("moon_troll_exit")
KFEAT:      J = crystal_wall
TILE:       c = wall_moon
LFLOORTILE: floor_pebble_lightblue
LFLOORCOL:  lightblue
LROCKTILE:  wall_moon
COLOUR:     b = silver
COLOUR:     J = disjunction
COLOUR:     c = blue
:           wizlab_setup(_G)
epilogue {{
            wizlab_milestone(_G, "Lehudib's Moon Base")
}}
MAP
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccbbbccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccc*bPb*cccccccccccccccccccccccccccc
cccccccccccccccccccccccccc.......ccccccccccccccccccccccccccc
cccccccccccccccccccccccccc...5...ccccccccccccccccccccccccccc
cccccccccccccccccccccccccccc...ccccccccccc..cccccccccccccccc
cccccccc.A.ccccccccccccj............ccccc.....cccccccccccccc
ccccccc.....ccccccccj....v...v..jv.....cc......ccccccccccccc
cccccc.......ccccccc.....v.......v........rJJ...cccccccccccc
cccccc...&...cccccccc.....jccccc......cc..JJJ....ccccccccccc
cccccc.......cccccccc.jccccccccccccc......JJJ.....cccccccccc
ccccccc......cccccccccccccccccccccccccc...JJ..JJ...ccccccccc
cccccccc.<....cccccccccccccccccccccccc......2JJJ....cccccccc
cccccccccccc...ccccccccccccc...ccccccc..JJ..JJJ......ccccccc
ccccccccccccc...ccccccE................JJJ..JJ3.JJJ..ccccccc
cccccccccccccc...ccc.qE......J.........JJJ.r...JJJJ...cccccc
ccccccccccccccc.......Ec..J..2..J..c...JJ......JJJr...cccccc
cccccccccccccccc.......cc....v....cc.......JJJ.......ccccccc
cccvvbbbvvcccccc.......qc..vvvvv..c.......JJJJ.....ccccccccc
ccvv*bOb*vvccccc...JJ...cc..vvv2.cc...JJ..JJJr...ccccccccccc
ccv.......vcccc....JJJ...c....2..c...JJJ.......ccccccccccccc
ccv...5...vccccq....JJJ..cc.....cc..JJJr.....ccccccccccccccc
ccv.......vcccDDD....JJ..qccnnnccr..JJ.......ccccccccccccccc
ccv.v...v.vccc..ccq......ccc|_|ccc.......cc..ccccccccc.kcccc
ccv..ivi..vcc....ccc....cc%d|f|d%cc....ccc....ccccccc...Lccc
ccv..vvv..vccc.....cccqcc.%bbbbb%.ccrccc.....cc.kc......cccc
ccvi..v..ivccc.v...cHccc..bb...bb..cccMc...v.cL..ck.vv..cccc
ccvv.....vvccc....ccu.bb...........bb.gcc....cc..cc.v*.ccccc
cccv.....vccc..v..n...b.............b...n..v.2+.........bbcc
cccv.viv.vccc..v..n...b......7......b...n..v..+.......5.Qbcc
cccv.....vccc2.v..np..b....z...z....b..on..v..+.........bbcc
ccvv.....vvccc....cc..bb...........bb..cc....cc..cc.v*.ccccc
ccv..ivi..vccc.v..2c...b...........b...c2..v.cL..ck.vv..cccc
ccv..vvv..vccc.....c...bb.........bb...c.....cc.kc......cccc
ccv...v...vcc2...cccc...bb.......bb...cccc...2ccccccc...Lccc
ccv.v...v.vccc..cc..c....bbb...bbb....c.3cc..cc`````cc.kcccc
ccv.......vccc......cc...............cc...c++c```````c++cccc
ccvv.....vvcccc......cc.............cc2...c..m```````m..cccc
ccccc....cccccc.......ccc.........ccc.....c..m```````m..cccc
cccccc...ccccccc..v.....cccc...cccc....u..c..cc`````cc..cccc
ccccccc...ccccccc..........cnnnc......JJ..c...cmmmmmc...cccc
cccccccc...cccccc..vv.v...................cc...........ccccc
ccccccccc...ccccc..vvs.................J...ccL.......Lcccccc
cccccccccc...cccs......cccc.....cccc.....Ju.ccc.....ccc'cccc
cccc.cccccc........v..cccccc.h.ccccccu..JJ....cnKnKnc..''ccc
ccc...cccccc....vv...ccccccc+++ccccccc..................''cc
cc.....ccccc..v.vv..sccccccc...ccccccc...................'cc
ccc..v..cccc........ccccch.G...G.hccccc....u;.."".""..;..''c
cccc..2.......sv....cccc...........ccccu...;;.".....".;;..'c
ccccc..vv.v.vv.....ccccc...........ccccc...;.."....."..;..'c
cccccc.vv...vv.vv.scccch...cc.cc...hcccc...;JJJJJ6JJJJJ;..'c
cccccc..s......vv.ccccc...cc...cc...ccccc..;JJJJJ+JJJJJ;..'c
ccccccc..v.3......cccc....c.....c....cccc..;JJJJJfJJJJJ;..'c
cccccccc...v.vv..ccccc...............ccccc..;JJJJJJJJJ;..''c
ccccccccc....vv..ccccL.h.....5.....h.Lccc''.....JJJ.....''cc
ccccccccccc.....cccccc....c*...*c....ccccc''...........''ccc
ccccccccccccc.scccccccccccccbNbcccccccccccc'''''''''''''cccc
ccccccccccccccccccccccccccccbbbccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ENDMAP

###############################################################################
# Eringya's Formal Garden
# Redesigned by Hellmonk, loosely based on the old layout but reshaped to work
# better with the monster set. No lua gimmick, just a set of plant and archery
# themed monsters, plus some fenstrider witches.
# Loot: staves, books, spectral branded weapons
# Could use a slightly different grass tile for better color contrast
NAME:       wizlab_eringya
TAGS:       no_rotate
MONS:       deep elf archer w:5 / faun / centaur warrior
MONS:       yaktaur / satyr / naga sharpshooter
MONS:       shambling mangrove, thorn hunter / eleionoma, deep elf master archer
MONS:       fenstrider witch, bush
KMONS:      P = oklob plant
ITEM:       any book, any magical staff
: local s = "ego:spectral no_pickup "
: item(dgn.loot_potions)
: item("demon blade " .. s .. "w:3 / demon whip " .. s .. "w:3 / " ..
:      "demon trident " .. s .. "w:3 / broad axe " .. s .. "w:2 / " ..
:      "lajatang " .. s .. "w:4 / quarterstaff randart plus:12 " .. s .. " w:1")
KITEM:      h = potion of lignification ident:type q:4 / \
                scroll of poison q:4 ident:type, \
                randbook owner:Eringya numspells:1 spells:eringya's_noxious_bog
KFEAT:      - = stone_arch
KFEAT:      _ = altar_fedhas
SHUFFLE:    pq/rs
SUBST:      q : y., r : y., p = ., s = .
NSUBST:     1 = 3:1 / *=1...., 2 = 2:2 / *=2..., 3 = 1:4 / 1:3 / *=34....
NSUBST:     5 = 2:5 / * = 5.., 7 = 1:P / 4:7 / *=P7777ttV........
NSUBST:     ; = 2:d / 2:e / 1:g / 1:h / * = deff, A = 1:< /*:A
SUBST:      y = ct
MARKER:     A = feat:stone_arch
COLOUR:     G = lightgrey
TILE:       c = wall_brick_vines
: if crawl.one_chance_in(4) then
COLOUR:     t = lightred / red w:3 / green w:3 / lightgreen w:1
TILE:       t = dngn_tree_lightred / dngn_tree_red w:4 / dngn_tree_yellow w:4
: end
#should use statue_archer, but currently that doesn't work
TILE:       G = dngn_statue_centaur
LROCKTILE:  wall_brick_vines
LFLOORTILE: floor_grass
:           set_random_mon_list(
:               "deep elf archer / faun / centaur warrior / yaktaur / " ..
:               " satyr / naga sharpshooter / shambling mangrove / " ..
:               "thorn hunter w:5 / eleionoma w:5 / deep elf master archer w:2")
:           wizlab_setup(_G)
epilogue {{
            wizlab_milestone(_G, "Eringya's Formal Garden")
}}
MAP
ccccccccccccccccccccccccccccccccccccccccccccc
ctttttttttttttttttttttttttttttttttttttttttttc
cttttttttttt1....1....t....1....1tttttttttttc
cttttttt.............................tttttttc
ctttt1....tttttttttttt.tttttttttttt....1ttttc
cttt.....tttttttttt.......tttttttttt.....tttc
ctt...tt...ttt......G...G......ttt...tt...ttc
cty1.ttt2............A.A............2ttt.1ytc
ctt...tt......ttt...G...G...ttt......tt...ttc
cttt.....tttttttttt.......tttttttttt.....tttc
ctttt1....tttttttttttt.tttttttttttt....1ttttc
cttttttt.......1.............1.......tttttttc
cttttttttttt1.....1.......1.....1tttttttttttc
cttttttttttttttttttttT.Tttttttttttttttttttttc
cttttttttt.2.ttttttt.....ttttttt.2.tttttttttc
ctttttttt.....t...t...T...t...t.....ttttttttc
cttttttt...t....7.....7.....7....t...tttttttc
ctttttt....1......tc.....ct......1....ttttttc
cttttt..t......tttttcc-ccttttt......t..tttttc
ctttt...tt.7..tttttt.....tttttt..7.tt...ttttc
cttt...tttt..tttttt...3...tttttt..tttt...tttc
cttt.2.tttt...tttttt2.2.2tttttt...tttt.2.tttc
ctttt...tttt.2.tttttt;t;tttttt.2.tttt...ttttc
ctttttp.pttttq.qtttttttttttttq.qttttp.ptttttc
cttttttpppttttqqqttttyyyttttqqqttttpppttttttc
cttttp..-..pttq...tt..2..tt...qttp..-..pttttc
ctty.........ytt....1...1....tty.........yttc
ctt;1..tTt..1;ytt.3...T...3.tty;1..tTt..1;ttc
ctty....3...2ytt....1...1....tty2...3....yttc
ctttt2..-...tt....tt;.3.;tt....tt...-..2ttttc
ctttttt...tttt...ttttytytttt...tttt...ttttttc
cttttt...tttt2..ttttttgtttttt..2tttt...tttttc
ctttt11.tttt...tttt5G;_;G5tttt...tttt.11ttttc
cttt..2tttt1.2tttt....3....tttt2.1tttt2..tttc
cttt7..ttt...tttt2....6....2tttt...ttt..7tttc
ctttt...t.7..tttG;.........;Gttt..7.t...ttttc
cttttt........tttttcc5.5ccttttt........tttttc
ctttttt.-.6.-..tttcc..7..ccttt..-.6.-.ttttttc
cttttttt........t.7-..T..-7.t........tttttttc
cttttttttt3...11.............11...3tttttttttc
cttttttttttt..12...7..4..7...21..tttttttttttc
cttttttttttttttt.............tttttttttttttttc
cttttttttttttttttttt2.;.2tttttttttttttttttttc
ctttttttttttttttttttttttttttttttttttttttttttc
ccccccccccccccccccccccccccccccccccccccccccccc
ENDMAP

###############################################################################
# Maxwell's Workshop
# Designed by Hellmonk. Features a lot of constructs in a layout of
# interconnected rooms. Boss is an electric golem (formerly used in tomb of
# Doroklohe as part of a construct set there). Loot includes items with
# "dangerous" properties, such as rampaging or harm.
NAME:       wizlab_maxwell
TAGS:       no_rotate no_pool_fixup
MONS:       peacekeeper / gargoyle / earth elemental w:5
MONS:       molten gargoyle / salamander / fire elemental w:5
MONS:       salamander tyrant / fire giant ; great mace ego:flaming
MONS:       war gargoyle / crystal guardian
MONS:       ettin / ironbound preserver ; great mace /\
            fire giant ; great mace ego:flaming /\
            frost giant ; great mace ego:freezing /\
            angel ; great mace ego:holy_wrath w:5
MONS:       ironbound thunderhulk ; great mace ego:electrocution
MONS:       patrolling electric golem
KMONS:      P = lightning spire
ITEM:       scarf ego:harm w:25 / boots ego:rampaging w:25 /\
            boots ego:rampaging randart / ring of fire randart /\
            any armour good_item ego:ponderous randart / ring of ice randart /\
            plate armour good_item ego:ponderousness / any weapon ego:chaos /\
            maxwell's patent armour w:2 / maxwell's thermic engine w:2
ITEM:       any armour good_item w:20 / any weapon good_item w:20 /\
            any weapon randart / any armour randart / any jewellery randart w:5
ITEM:       potion of attraction ident:all / any scroll w:20 /\
            scroll of vulnerability ident:all / any potion w:20
SHUFFLE:    DE/JK, pqrs, ;~
SUBST:      D : b+, E:., J:., K: b+, F:.+, p:v, q:b., r: v.., s:b...
SUBST:      ;:v+., -:v+.., ~:., 1 = 1..., 2 = 2..
NSUBST:     3 = 1:3 / *=3.., 4 = 1:4 / *=4.., 5 = 1:5 / *=5.., 6 = 2:6 / *=6..
NSUBST:     7 = 1:7 / *:P,  A = 1:< /*:A, H = 2:4 / 4:1 / *=11bG
NSUBST:     e = 3:e / *=dff
TILE:       v = dngn_metal_wall_cyan
:           set_random_mon_list(
:               "gargoyle / earth elemental / molten gargoyle / " ..
:               "peacekeeper / war gargoyle / crystal guardian w:2 / " ..
:               "ironbound thunderhulk / electric golem w:1")
:           wizlab_setup(_G)
epilogue {{
            wizlab_milestone(_G, "Maxwell's Workshop")
}}
MAP
                        vvvvvvvvvvv
                      vvv..eeree..vvv
                      v6s..rrrrr..s6v
                      v..s.sspss.s..v
                     vv...psspssp...vv
                     v...r.prprp.r...v
                     vq.r..rpppr..r.qv
                     vqq..ppppppp..qqv
                     vqqqq6qeeq7q6qqqv
                     vqqq.q7qeeq.qqqqv
                     vqq..ppppppp..qqv
        vvvvvvvvvvvvvvq.r..rpppr..r.qv
        vlllllvvvvvvvv...r.prprp.r...v
        vlllllvvvvvvvvv...psspssp...vv
        vlllllvvvvvvvvv6.s.sspss.s.6v
        vlllllvvvvvvvvvvs..rrrrr..svv
       vvnnlnnvvvvvvvvvvvv...r...vvv
      vv.3nln3.vvvvvvvvvvvvv+++vvv
     vv..2nln2..vvvvvvvvvvvH6.6Hvvvvv
    vv...2nln2...vvvvvvvvvv.....vvvvvv
    v2.2nnnlnnn2.2vvvvvH...4...4...Hvv
    v...nllllln...vvvvv....v111v....vv
    v...nllllln...vvvvv....veeev....vv
    v2..nllllln..2vvvvvH...vvvvv...Hvv
    v...nllllln...vvvvvvvD..bbb..Dvvvv
    v..2nllllln2..vvvvH..DD..H..DD..Hv
    vG..nnnnnnn..Gv..v....v..P..v....v
    v...3..3..3...+.4+....v.....v....v
    v...v..2..v...v..v....vH...Hv....v
    v...v2.3.2v...vvvvH..EvvFFFvvE..Hv
    v2vvvvdddvvvv2vvvvvvvEH.....HEvvvv
    v...vvvdvvv...vvvvvvv....v....v
    v...vvvvvvv...vvvvvvv....v....v
    vv..vv222vv..vvvvvvvvH.......Hv
     vv.........vvvvvvvvvvvvv+vvvvvv
      vv.......vvvvvvvvv1.~.5...5.1v
       vv.....vvvvvvvvvv..~..1.....v
        vvv+vvvvvvvvvvvv..v--v--v..v
       vv.....vvvvvvvvvv..v1.v..v..v
 vvvvvvvG1...1Gvvvvvvvvv..;..5..~.fv
vv...vv.1..G..1.vvvvvvvv..;.....~5fv
v..G..v.........v1....1v..vvvvvvv;;v
v1.4..+.G1.G.1G.+...4..+..;.....~5fv
v..G..v.........v1....1v..;..5..~.fv
vv...vv....G....vvvvvvvv..v1.v..v..v
 vvvvvvG1....1Gvvvvvvvvv..v--v--v..v
      vvv.....vvvvvvvvvv..~..1.....v
        vvv+vvvvvvvvvvvv1.~.....5.1v
        vv...vvvvvvvvvvvvvvvvvvvvvvv
        v.....v
        v.AGA.v
        v.....v
        vv...vv
         vvvvv
ENDMAP

###############################################################################
# Yara's Duelist Academy
# Designed by Hellmonk. Features warrior-mages with antimagic weaponry.
# Said weaponry makes up part of the loot here. The remainder of the loot is
# books, random good items, and gold.
NAME:   wizlab_yara
TAGS:   no_rotate
:       yara_students(_G)
MONS:   mana viper, quicksilver dragon
KMONS:  P = bush
{{
wizname = crawl.make_name()
kmons("5 = patrolling Head Instructor dbname:Head_Instructor name:"
      .. string.gsub(wizname, " ", "_") .. " ; triple sword ego:antimagic \
            . triple sword ego:antimagic . plate armour ego:willpower")
}}
ITEM:   any book w:15 / randbook disc:hexes owner:Yara w:4 / spellbinder w:1
ITEM:   scroll of enchant armour ident:all / scroll of enchant weapon ident:all
NSUBST: * = 4:d / 4:e / *=*., 5 = 1:5 / *:1, D = 1:2 / *=G1
NSUBST: E = 1:2 / *:1, 3 = 1:4 / * = 3", A = 1:< / *:A
SUBST:  P : Pt", F = 211111, 1 = 1...., x = xxxx., - = x
FTILE:  125.*de$G+ = floor_limestone
FTILE:  Tt"PA<34 = floor_dirt / floor_grass:15
TILE:   x = wall_brick
TILE:   c = wall_church
:           set_random_mon_list(
:               "mana viper / tengu conjurer / ogre mage / " ..
:               "deep elf knight / arcanist / occultist / naga mage / " ..
:               "salamander mystic / necromancer / vampire mage / " ..
:               "tengu reaver w:1 / quicksilver dragon w:1")
:           wizlab_setup(_G)
epilogue {{
            wizlab_milestone(_G, "Yara's Duelist Academy")
}}
MAP
          cccccccccccccccccccc
          c***cGF.1..1.FGc***c
          c***c..........c***c
          cFFFc..1....1..cFFFc
          c...c..cc55cc..c...c
          c...+5........5+...ctt
     ttt  ccccc...1..1...ccccc3tt
  tttt""""""""cc........cc""""""tt
 tt"""..1....11ccc....ccc"""""3""tt
tt""..xxxx.......cc++cc111"""T"""3t
t".11xx.....11....1..1....""""3""tt
t".1xx.11.xx.............1xx"""ttt
t".xx..1.xx...1.xxt""txx..1xxttt
t".xx..1xx...1.xx"3""3"xx...xxcccccccccccc
t"1x...xx.....xx"3""""3"xx.....11......11c
t".x...x.....xx"""c""c"""xx..............c
t".x11.x..t..x""c""33""c""xx...cc"cc"cc..c
t".t...t..t..t""""PWWP""""txx..cD"D""Dc..c
t".........."""c"PWWWWP"c"".x..""""""""..c
t"1....11.t."""c"WWWWWW"c""....c""cc"Dc.1c
cccc++cccct."""""WWWWWW""""t...cD"cc""c.1c
c*.c..c.*ctt"""c"PWWWWP"c""x...""""""""..c
cE.+..+.Ec-t""""c"PWWP"c"""x...cD""D"Dc..c
ccccE.cccc-t""""""""""""""txt..cc"cc"cc..c
cE.+..+.Ec-t""""""c33c""""---............c
c*.c..cE*c---"""""t""t""""---..11......11c
ccccE.cccc  --"""tt""tt"""--cccccccccccccc
c*.c..cE*c   --"""t""t"""--
cEE+..+.Ec    --""""""""--
cccc.Ecccc     --""""""--
cE.+..+.Ec      --""""--
c*.c.EcE*c       -G""G-
cccccccccc      --""""--
               --""""""--
               t""A""A""t
               t""""""""t
               --""""""--
                --T""T--
                 ------
ENDMAP

###############################################################################
# Borgnjor's Mausoleum
# Designed by Hellmonk. Split map layout with corporeal undead on one side and
# incorporeal undead on the other. Lost souls spawn continuously, and the ending
# includes some halazid warlocks and their servants. Loot is necromancy
# themed, as you'd expect.
NAME:   wizlab_borgnjor
TAGS:   no_rotate
MONS:   spectral spriggan berserker / spectral titan / spectral spark wasp /\
        spectral harpy / spectral quicksilver dragon / spectral wolf spider /\
        spectral caustic shrike / phantasmal warrior w:60
MONS:   flayed ghost / shadow wraith / eidolon
MONS:   spriggan berserker zombie / titan zombie / spark wasp zombie /\
        harpy zombie / quicksilver dragon zombie / wolf spider zombie /\
        caustic shrike zombie / skeletal warrior w:30 / jiangshi w:30
MONS:   ancient champion / revenant, laughing skull
MONS:   deep elf death mage / vampire mage / necromancer, halazid warlock
ITEM:   randbook disc:necromancy numspells:6 owner:Borgnjor w:5 / any book /\
        necronomicon / randbook disc:necromancy / staff of death /\
        macabre finger necklace w:1 / sceptre of torment w:1
ITEM:   any book / scroll of torment ident:all q:3 /\
        any weapon good_item ego:pain / any weapon good_item ego:vampirism
ITEM:   any ring / any amulet w:5
: if crawl.one_chance_in(4) then
SUBST:   F = c..., E = cccc., D = c
: else
SUBST:   D = c., E = c.., F = c
: end
SHUFFLE: 12/34
NSUBST:  7 = 3:7 / 1:. / * = 775., 6 = 2:6 / * = 6.
NSUBST:  4 = 2:4 / 1:. / *=4.., 2 = 2:2 / * = 2..
NSUBST:  A = 1:< / *:A
SUBST:   1 = 1.., 3 = 3.., 5 = 55..., V = VVVY
TILE:    c = wall_borg_stone
LFLOORTILE: floor_borg
{{
local summon_marker = TriggerableFunction:new ({
    func="wizlab_borgnjor_call_souls",
    repeated=true })

summon_marker:add_triggerer(DgnTriggerer:new {type="monster_dies",
    target = "any"})

lua_marker('A', summon_marker)
}}
:           set_random_mon_list(
:               "skeletal warrior / flayed ghost / phantasmal warrior / " ..
:               "necromancer / vampire mage / shadow wraith / " ..
:               "revenant w:2 / ancient champion w:2")
:           wizlab_setup(_G)
epilogue {{
            wizlab_milestone(_G, "Borgnjor's Mausoleum")
}}
MAP
             ccccc
           ccc565ccc
          cc.5...5.cc
         cc..5.7.5..cc
        cc5.5c+++c5.5cc
        c6..cc...cc..6c
       cc5.cc..7..cc.5cc
       c...c5.5.5.5c...c
       c2.2cY57575Yc4.4c
       c.5.c.76.67.c.5.c
      ccc..cc.$$$.cc..ccc
     cc1c...ccfffcc...c3cc
    cc11FF...cc+cc...FF33cc
   cc2111FF.11cec33.FF3334cc
  cc......FF..cec..FF......cc
 cc...EE...cc2cec4cc...EE...cc
 c1..EE...cc..cdc..cc...EE..3c
 c..EE..2cc..1cdc3..cc4..EE..c
 c..EE11cc12.2ccc4.43cc33EE..c
 c..E..1c11EE..D..EE33c3..E..c
 c..D..cc2.EE.264.EE.4cc..D..c
 c..D..c..EEEE1D3EEEE..c..D..c
cc.2D2.c.EEcE.1D3.EcEE.c.4D4.cc
c1..D..c..EcEE1D3EEcE..c..D..3c
c1..D..cc.EEE..c..EEE.cc..D..3c
c1..D..2c..E..ccc..E..c4..D..3c
c1..D...c...11cVc33...c...D..3c
c...c..1...1.cc.cc.3...3..c...c
cc..FF..1..ccc...ccc..3..FF..cc
 c...FF....cV.....Vc....FF...c
 c....FF..2c...A...c4..FF....c
 c.....ccccc.......ccccc.....c
 c..c1.......cc.cc.......3c..c
 c1.EE.......cc.cc.......EE.3c
 cc1...ccccc.......ccccc...3cc
  cc1.cc   c...A...c   cc.3cc
   cccc    cV.....Vc    cccc
           ccc...ccc
             cc.cc
              cVc
              ccc
ENDMAP

###############################################################################
# Tukima's Studio
# Reimplemented by Hellmonk. Features dancing weapons and walking tomes, plus
# some strange machines that mirror the player. Loot always contains a phantom
# mirror in addition to some book and aux armour items (plus the weapons).
NAME:   wizlab_tukima
TAGS:   no_rotate
MONS:   rakshasa, dancing weapon
MONS:   dancing weapon; hand cannon ego:flaming w:15 /\
        dancing weapon; hand cannon ego:freezing w:15 /\
        dancing weapon; hand cannon ego:venom /\
        dancing weapon; hand cannon ego:electrocution w:2 /\
        dancing weapon; hand cannon randart ego:penetration w:1 /\
        dancing weapon; longbow ego:flaming w:15 /\
        dancing weapon; longbow ego:freezing w:15 /\
        dancing weapon; longbow ego:venom /\
        dancing weapon; longbow ego:electrocution w:2 /\
        dancing weapon; longbow randart ego:speed w:1 /\
        dancing weapon; triple crossbow ego:flaming w:15 /\
        dancing weapon; triple crossbow ego:freezing w:15 /\
        dancing weapon; triple crossbow ego:venom w:5 /\
        dancing weapon; triple crossbow ego:electrocution w:5 /\
        dancing weapon; triple crossbow randart ego:penetration w:1
MONS:   walking frostbound tome / walking earthen tome / walking crystal tome /\
        walking divine tome
MONS:   strange machine
ITEM:   hat good_item / pair of boots good_item / scarf good_item /\
        cloak good_item / pair of gloves good_item / randbook disc:hexes /\
        any book w:35 / any armour good_item w:5
ITEM:   phantom mirror
KFEAT:   ~ = closed_clear_door
SUBST:      ':cc., ":cc., -:mV, 1 = 11..., 2 = 2...
NSUBST:     d = 1:e / *:d, 3 = 2:3 / * = 3..., 4 = 1:4 / *= 42.., A = 1:< / *:A
NSUBST:     5 = 1:5 / *:5.
TILE:       c = wall_marble_tukima
TILE:       V = dngn_dry_fountain_white
LFLOORTILE: floor_w_marble
:           set_random_mon_list("dancing weapon / rakshasa")
:           wizlab_setup(_G)
epilogue{{
            wizlab_milestone(_G, "Tukima's Studio")
}}
MAP
            ccccccc
            ccmmmcc
        ccccccA.Acccccc
       ccm...c...c...mcc
       cc.............cc
      cc..ccm.....mcc..cc
      c~~ccccm...mcccc~~c
      c2.."""cm~mc"""..2c
     ccc.1c"""..."""c1.ccc
     cmm..mcm.....mcm..mmc
     cm...mcm.....mcm...mc
     cm...mcm..2..mcm...mc
     cm...mcm..V..mcm...mc
     cm2..mcm1...1mcm..2mc
     cm...mcm..1..mcm...mc
     cm1.2mcm2.2.2mcm2.1mc
     cc1..c'''...'''c..1cc
     ccc..'''cm2mc'''..ccc
      cc~~cccm...mccc~~cc
     ccm1.mcm1...1mcm.1mcc
     cm.3.mcm3.V.3mcm.3.mc
    ccm..mccm2...2mccm..mcc
  cccm...mcccm.5.mcccm...mcc
  ccm2.-.1mcccm.mcccm1.-.2mcc
 ccm2....mcccm121mcccm....2mcc
ccm..mm...mmm.....mmm...mm..mcc
cm4..cm......2.5.2......mc..4mc
ccm.....mm.3...4...3.mm.....mcc
 ccmd4.mccmmm.....mmmccm.4dmcc
  ccmmmccccccdddddccccccmmmcc
   ccccc    ccmmmcc    ccccc
             ccccc
ENDMAP

###############################################################################
# Alistair's Party Mansion
# Designed by Hellmonk. Features degeneration clouds that statrot the player.
# Monster set pulls from associated weird wizard creatures and branch invitation
# monsters for forceful invitation/planerend. Bosses are demonspawn corrupters
NAME:       wizlab_alistair
TAGS:       no_rotate
MONS:   arcanist / occultist / boggart w:4 / deep elf zephyrmancer w:6 /\
        deep elf pyromancer w:6 / worldbinder w:2
MONS:   great orb of eyes / glowing orange brain / sphinx / cacodemon w:2 /\
        very ugly thing / glowing shapeshifter / entropy weaver /\
        green death w:2 / tentacled starspawn / golden eye band w:6 /\
        worldbinder / glass eye w:4
MONS:   nagaraja / deep elf high priest / sphinx w:5 / deep elf sorcerer /\
        worldbinder
MONS:   arcanist / occultist / necromancer w:4 / hell knight w:4 / worldbinder
MONS:   demonspawn corrupter
KMONS:  J = occultist generate_awake perm_ench:confusion ; nothing
KMONS:  H = torpor snail / ghost moth / guardian serpent / water nymph /\
            acid blob / anaconda / swamp dragon
KMONS:  F = spriggan druid / deep elf pyromancer / arcanist w:5 / occultist w:5
KMONS:  E = water nymph / merfolk aquamancer / merfolk javelineer /\
            merfolk aquamancer / arcanist ; nothing / occultist ; nothing
KMONS:  D = stone giant / ettin
ITEM:       potion of degeneration ident:all
:item(dgn.loot_scrolls .. " / " .. dgn.loot_potions)
ITEM:   scroll of acquirement ident:all q:1
ITEM:   any book w:30 / randbook disc:alchemy / condenser vane w:1
KITEM:  " = gold q:1 no_pickup
KITEM:  H = any magical staff no_pickup
KITEM:  Q = star_item
KITEM:  JKL = potion of degeneration ident:all
KFEAT:  E = shallow_water
KFEAT:  N = granite_statue
NSUBST: A = 1:< / *:A, D = 1:D/*:-, W = 1:E / * = E:1 W:16, F = 1:F / * = F----
NSUBST: H = 1:H / *:", e = 4:e / 1:g / *=eedg, 5 = 3:5 / *=5..
NSUBST: 3 = 3:3 / *= 3...., ? = 2:? / *=?..., 4 = 2:4 / *= 4...., J=1:J / *:-
SUBST:  N = N'', ' = 1:15 2:25 K:15 ':825, . = d:1 .:15, - = L:1 -:70
MARKER:     ? = lua:fog_machine { \
                pow_max = 10, delay_min = 10, delay_max = 50, \
                size = 2, size_buildup_amnt = 3, \
                size_buildup_time = 25, cloud_type = "degeneration" \
            }
MARKER:     H = lua:fog_machine { \
                pow_max = 10, delay_min = 10, delay_max = 50, \
                size = 3, size_buildup_amnt = 3, \
                size_buildup_time = 25, cloud_type = "degeneration" \
            }
TILE:   c = wall_stone_gray
FTILE:  H" = floor_mosaic
FTILE:  N'12K = floor_w_marble
FTILE:  -FTtAJLDQ< = floor_grass
:           set_random_mon_list(
:               "arcanist w:20 / occultist w:20 / necromancer / boggart / " ..
:               "glowing orange brain / worldbinder / sphinx / " ..
:               "demonspawn corrupter w:1")
:           wizlab_setup(_G)
epilogue{{
            wizlab_milestone(_G, "Alistair's Party Mansion")
}}
MAP
                  ccccc
                  cefec
                  ceeec
                  ceeec
    ccccccccccccccccc+c
    c3.3+3?3c3..3+...5c
ccccc...c...c.3..c.3.5c
ce5.c.3.c3..c...3c...5c
ce..+...cc+cc+cccc+cccc
ce..c...+?....?....c
ce5.c3..c..33..33..c
ccccccccc+cccccccc+c
    cee3c'''NNNN'''cccccccccc
    c444c''''''''''+....4..4c
    ccc+c''N''''N''+..WWWW?.c
    c44.c''''''''''n.WWWWWW4c
    c3..+''''NN''''n.WWWWWW.c
    c...cN''""""'''n.?WWWW..c
    c+ccc'''"HH"'''n4......4c
    c..3c'N'"HH"'N'cccccnn+nctttttt
    c4..+'''""""'''c4eecF----ttt-?tttttttttt
    c4.?c'''''''''Nc..3c-F-Fttt-----F----ttt
    ccc+c''''NN''''c3..ct---t-------WWW---tt
    c44.c''N''''N''c...cF-T-F---T-?WWWWWF-Qt
    c...+''''''''''c..4ct---tt------WWW---tt
    c...cNN'''''NN'+...cttFtttt-----F----ttt
    c+ccccccc++ccccccccctt--tttt-?tt--tttt
    c..4.4.G.?..G.4.4..ct--Fttttttttttttt
    c.3..............3.ct--tttttttttttttt
    c..4G..........G4..ctt-tttt
  ttc+ccccccc++ccccccc+ctF-tttt
 tttc.....4cG..Gc4.....ct-J-ttt
ttttc..3...c....c...3..ct--ttt
ttttc......+.??.+......ct-tttt
ttttc4...3.c....c.3...4ct--ttt
ttttccccccccc++ccccccccc---tt
ttttt--------DD----------Fttt
tttttF--J------------------tt
tttttt-----ttttttt---J-tttttt
 ttttttt--tt--J--tt---tttttttt
  ttttt---t--T-T--t--ttttttttt
  tttttt-------------ttttttttt
    ttttt-----A------ttttttttt
      tttt--T---T--tttttttttt
       tttt---A----tttttttttt
        ttt------ttttttttttt
        ttt--T-T-ttttttttt
         ttt----ttttttttt
         ttttttttttttt
         tttttttttttt
          tttt  tttt
ENDMAP
