###
#
## Maps from named Wizards, unrand and fixedarts
#
# Tukima's Studio
#    threat: 6 dancing weapons, dancing weapon machine generating up to 5 more
#    loot:   the weapons, tukima's book and a scroll of acquirement
#    xp:     14400 or so
#    layout: mirrors; grey and white
#
# Eringya's Formal Garden
#    crumbling stone walls.
#    threat: centaurs, oklobs
#    loot:   a staff and four spellbooks
#    xp:     10500 or so
#    layout: formal (French) garden, flowers, crumbling stone walls
#
# Doroklohe's Tomb
#    threat: either Tomb set or demons or golems
#    loot:   either scrolls or armours or random items
#    xp:     10000+
#    layout: lots of tombs with loot and monsters inside
#    colour: yellow tombs, rest is dark, floor is randomised
#
# Wucad Mu's Monastery
#    threat: "monks", OCS
#    loot:   books, staff of wucad mu
#    xp:     9000+
#    layout: temple-esque!
#    colour: dark walls, red and orangge.
#
# Cigotuvi's Fleshworks
#    threat: lumps, uglies, abominations
#    loot:   tmut. potions, books, rMut, ?oSumm, \oDeath
#    xp:     16000+
#    layout: organic, irregular, twisty, NO SQUARES, NO HARD CORNERS,
#            NOTHING THAT LOOKS PRETTY
#    colour: lightred walls, red doors, magenta floor, yellow 'glass'
#
# Iskenderun's Mystic Tower
#    threat: naga mystics, statues with IOOD and IMB, purple draconians
#    loot:   conjurations-themed randart books
#    xp:     20000+
#    layout: weird fortress tower thing with strange corners
#    colour: purple.
#
# Zonguldrok's Mausoleum
#    threat: zombies, ancient lich, skele warriors
#    loot:   scrolls, potions, spell books and zonguldrok's sword
#    xp:     20000+
#    layout: graveyard
#    colour: darkgrey, lightgrey
#
## Random maps
#
# Cloud Mage's Chambers
#    threat: cloud mage (random name), vapours, air elementals
#    loot:   potions, robe of clouds, air-related spells
#    xp:     20000+
#    layout: "cloud"-esque, clouds.
#    colour: white, silver, lightblue
#
# Hellbinder's Lair:
#    threat: demons, Hellbinder
#    loot:   demonology-related items
#    xp:     15000+
#    layout: sigils, triangles and circles
#    colour: red, darkgrey
#
##
#
# TO-DO:
#
# The flavour messages for the portal vault require flavour, while the actual
# portals themselves could do with an overhaul and some new ones.
#
# *MUST* make these look awesome in tiles, too.
#
# Overall todo: random monster lists for each vault (shadows for Wucad Mu)
#
##

{{
function wizlab_portal (e)
    -- Flavour could use some improvement.
    local desc_long = "This portal has been left open by a careless wizard. " ..
                      "It might lead to their secret laboratory, but beware!" ..
                      " Surely it will be guarded by magical traps and "      ..
                      "terrible monsters."
    local timeout_turns = crawl.random_range(1200, 1700)
    local messager =
        timed_msg {
            visible = true,
            -- $F{xxx} will be substituted with the 'entity' property of the timed
            -- marker, or with the desc property (if entity is not set).
            messages = time_messages(timeout_turns,
                            "$F{The} shimmers.",
                            "$F{The} vibrates and hums gently.",
                            "$F{The} is slightly opaque.",
                            "$F{The} is almost invisible now.")
    }

    e.lua_marker('O',
      timed_marker {
        disappear = "The portal disappears completely.",
        desc = "magical portal",
        desc_long = desc_long,
        entity = 'portal',
        dst = 'wizlab',
        dstname_abbrev = "WizLab",
        dstorigin = "in a Wizard's Laboratory",
        overview = "magical portal",
        turns = timeout_turns,
        floor = "stone_arch",
        msg = messager })
    e.kfeat("O = enter_portal_vault")
    e.tile("O = no_random dngn_portal_wizard_lab")
end

function wizlab_feat_descs()
end

dgn.set_lt_callback("wizlab", "wizlab_feat_descs")

-- Destinations:
function wizlab_setup (e, wizlab_desc)
    e.kfeat("< = exit_portal_vault")
    e.tile("< = no_random dngn_portal_wizard_lab")
    -- This is so that the note shows up properly.
    dgn.set_level_type_origin("in " .. wizlab_desc)
    dgn.set_feature_desc_short("gate leading back to the Dungeon",
                               "portal leading out of here")
    if wizlab_desc ~= "Eringya's Formal Garden" then
      dgn.set_feature_desc_short("empty arch of ancient stone",
                               "empty arch of stone")
    end
end

function wizlab_milestone (e, wizlab_desc)
    crawl.mark_milestone("br.enter", "entered " .. wizlab_desc .. ".", true)
end
}}

default-depth: Vault:2-7, Crypt, D:22-27, Elf:5-7

###############################################################################
# Portal entrances.
#
# Todo: more, and better.
NAME:       enter_wizlab_1
TAGS:       uniq_wizlab chance_wizlab
CHANCE:     5%
ORIENT:     float
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

###############################################################################
# Basic Entrance 2 (by Mu.)
#
NAME:       enter_wizlab_2
TAGS:       uniq_wizlab no_item_gen no_monster_gen chance_wizlab
CHANCE:     5%
ORIENT:     float
SHUFFLE:    tU
TILE:       mn = dngn_transparent_wall_green
COLOUR:     mn = lightgreen
TILE:       c = wall_stone_gray
:           wizlab_portal(_G)
MAP
.................
.bbbbbbbmbbbbbbb.
.bb...b...b...bb.
.n..U...O...U..n.
.bb...b...b...bb.
.bbbbbbb+bbbbbbb.
..bb...b.b...bb..
..n..t.....t..n..
..bb...b.b...bb..
..bbbbbb+bbbbbb..
.................
......c...c......
.....ccc.ccc.....
.................
ENDMAP


###############################################################################
# Basic Entrance 3 (by Mu.)
#
NAME:       enter_wizlab_3
TAGS:       uniq_wizlab no_item_gen no_monster_gen chance_wizlab
CHANCE:     5%
ORIENT:     float
:           wizlab_portal(_G)
MARKER:     ! = lua:fog_machine { \
                 pow_max = 10, delay_min = 10, delay_max = 40, \
                 size = 1, 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 = 1, size_buildup_amnt = 5, \
                 size_buildup_time = 25, cloud_type = "freezing vapour" \
             }
COLOUR:     . = red / blue
KPROP:      .?! = no_rtele_into
TILE:       n = dngn_transparent_wall_magenta
COLOUR:     n = lightmagenta
TILE:       c = wall_stone_gray
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

###############################################################################
# Basic Entrance 4 (by Mu.)
#
NAME:       enter_wizlab_4
TAGS:       uniq_wizlab no_item_gen no_monster_gen chance_wizlab
CHANCE:     5%
ORIENT:     float
:           wizlab_portal(_G)
KFEAT:      ! = floor
COLOUR:     ! = magenta
FTILE:      !O = floor_rough_magenta
MAP
    xxxxx
    w!!!x
   ww!O!x
  www!!!x
 www..www
www..www
ww..www
w..www
@.www
@www
ENDMAP

###############################################################################
# Basic Entrance 5 (by Mu.)
#
NAME:       enter_wizlab_5
TAGS:       uniq_wizlab no_item_gen no_monster_gen chance_wizlab
CHANCE:     5%
ORIENT:     float
COLOUR:     U = random
COLOUR:     W = mutagenic
KFEAT:      o = granite_statue
FTILE:      WU.Oo = floor_rough_magenta
TILE:       b = dngn_crystal_magenta
:           wizlab_portal(_G)
MAP
bbbbbbbbbbb
bbbb...bbbb
bWWU.O.UWWb
bWbb...bbWb
bWWWW.WWWWb
bbbbW.Wbbbb
bbbbW.Wbbbb
bbbbW.Wbbbb
bbbbW.Wbbbb
bbbbo.obbbb
bbbb...bbbb
     @
ENDMAP

###############################################################################
# Basic Entrance 6 (by Mu.)
#
NAME:       enter_wizlab_6
TAGS:       uniq_wizlab no_item_gen no_monster_gen chance_wizlab
CHANCE:     5%
ORIENT:     float
SUBST:      x = mc.
TILE:       c = wall_stone_white
TILE:       m = dngn_transparent_wall_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

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

default-depth:

###############################################################################
# And arrivals!
###############################################################################
# Firstly, we have Tukima's Dance Studio.
#
NAME:       wizlab_tukima
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
MONS:       dancing weapon
KFEAT:      M = granite_statue
TILE:       M = dngn_machine_tukima
MARKER:     M = lua:props_marker {veto_fragmentation="veto", veto_disintegrate="veto", \
                                  slaved_to="tukima"}
{{
function tukima_machine (data, triggerable, triggerer, marker, ev)
  if triggerer.type ~= "turn" or triggerer.sub_type ~= "countdown" then
    return
  end

  local x, y = marker:pos()
  local you_x, you_y = you.pos()

  if data.weapon_count >= 5 then
    if you.see_cell(x, y) then
      crawl.mpr("The machine makes a dull noise.")
    else
      crawl.mpr("You hear a distant, dull noise.")
    end
    return
  end

  if (you_x == x and you_y == y) then return end
  if dgn.mons_at(x, y) then return end

  dgn.apply_area_cloud(x, y, 1, 6, 1, 10, "black smoke", "other", -1)

  if (not dgn.create_monster(x, y, "generate_awake dancing weapon")) then
    return
  end

  data.weapon_count = data.weapon_count + 1

  if you.see_cell(x, y) then
    crawl.mpr("The machine hisses, and spits out a dancing weapon!")
  else
    crawl.mpr("You hear a distant hissing noise.")
  end
end

local tukima_marker = TriggerableFunction:new {
    func = tukima_machine,
    repeated = true,
    data = {weapon_count=0},
}

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

lua_marker('?', tukima_marker)

if crawl.coinflip() then
  subst("Y = =")
  subst("y = .")
  subst("Rr = c")
else
  subst("Y = c")
  subst("y = m")
  subst("R = .")
  subst("r = =")
end

if crawl.coinflip() then
  subst("X = =")
  subst("x = .")
  subst("Ll = c")
else
  subst("X = c")
  subst("x = m")
  subst("L = .")
  subst("l = =")
end
}}
SUBST:      ? = .
COLOUR:     =cA< = darkgrey
TILE:       c = wall_stone_dark
TILE:       V = dngn_dry_fountain_white
LFLOORTILE: floor_pebble_white
COLOUR:     mMV = silver
TILE:       m = dngn_mirror_wall
KMONS:      8 = ice statue col:silver spells:blink_other;blink_other;blink_other;\
                    blink_other;blink_other;major_healing name:strange_machine \
                    name_replace name_descriptor hd:13 hp:120 \
                    tile:mons_statue_guardian
KITEM:      8 = book of tukima
KMONS:      9 = ice statue col:silver spells:blink_other;blink_other;blink_other;\
                    blink_other;blink_other;major_healing name:strange_machine \
                    name_replace name_descriptor hd:13 hp:120 \
                    tile:mons_statue_guardian
KITEM:      9 = scroll of acquirement
:           local mquote = '"The machine had stood there a long time. It was several '
:                  .. "hundred feet long and could run on a thimbleful of earth or"
:                  .. " water. It had been working seven and a half million years."
:                  .. '"\n  -Sweet Their Blood and Sticky, Albert Teichner'
MARKER:     8 = lua:MonPropsMarker:new {description="A glistening silver machine.\n",\
                   quote=mquote}
MARKER:     9 = lua:MonPropsMarker:new {description="A glistening silver machine.\n",\
                   quote=mquote}
:           dgn.set_feature_desc_short("translucent rock wall",
:                                      "crystal clear mirror")
:           dgn.set_feature_desc_long("translucent rock wall",
:                                     "A glistening mirror, reflecting everything around it.\n")
:           dgn.set_feature_desc_short("granite statue", "strange machine")
:           dgn.set_feature_desc_long("granite statue", "A mechanical contraption," ..
:                                     " all hisses and pops.\n")
:           dgn.set_feature_desc_short("dry fountain", "glistening fountain")
:           dgn.set_feature_desc_long("dry fountain", "A pristine fountain. " ..
:                                     "The only thing it lacks is water.\n")
:           dgn.set_feature_desc_short("stone wall", "black marble wall")
:           dgn.set_feature_desc_long("stone wall", "The marble glistens and shines. It certainly " ..
:                                     "is beautiful!\n")
:           dgn.set_feature_desc_short("Floor", "marble floor")
:           dgn.set_feature_desc_long("Floor", "Where the walls are black marble, the floor is " ..
:                                     "a white and silver, with shades of pink here and there.\n")
:           dgn.set_feature_quote("A granite statue", mquote)
:           set_random_mon_list("dancing weapon")
:           wizlab_setup(_G, "Tukima's Studio")
epilogue{{
            wizlab_milestone(_G, "Tukima's Studio")
}}
MAP
                ccccccc
                ccmmmcc
            cccccm...mccccc
           cc...+.A.<.+...cc
          cc..cccm...mccc..cc
          cc+cccccm.mccccc+cc
          cc.cccccc+cccccc.cc
         cc...cccc...cccc...cc
         cm...mcm..1..mcm...mc
         cm...mcm.....mcm...mc
         cm.V.mcm.....mcm.V.mc
         cm...mcm.....mcm...mc
         cm...mcm..1..mcm...mc
         cc...cccc...cccc...cc
         ccc.cccccc+cccccc.ccc
          cc+ccccm...mcccc+cc
         ccm.mccm.....mccm.mcc
         cm.1..+...V...+..1.mc
        ccXm.mccm.....mccm.mYcc
      cccxccmlcccm...mcccrmccycc
      ccm.mcccLcccm.mcccRcccm.mcc
     ccm...mLLcccm...mcccRRm...mcc
    ccm..$..mcccm..?..mcccm..$..mcc
    cm..$8$..m+m...M...m+m..$9$..mc
    ccm..$..mcccm.....mcccm..$..mcc
     ccm...mcc ccm...mcc ccm...mcc
      ccmmmcc   ccmmmcc   ccmmmcc
       ccccc     ccccc     ccccc
ENDMAP

###############################################################################
# Eringya's Formal Garden
#
# Map was based on this image: http://upload.wikimedia.org/wikipedia/commons/5
#          /58/Plan_du_ch%C3%A2teau_et_des_jardins_de_Clagny_dessin%C3%A9_par_
#          Maraine_XVIIe_si%C3%A8cle.jpg (concat it back together to get the
#          full link).
#
# TODO: Needs vine-covered statues, rose-covered archway.
#       The map is too static. Some ideas by dpeg: loot behind plants or
#       bushes, so you'll have to cut/burn your way there. With catastrophic
#       effects, of course (plants turning into oklobs, fruits turning into
#       spores or (if possible) animated weapons called like the fruit etc.)
#       We could add a interesting little sub-game by having ballistos spawn
#       on their own -- and these could be aggressive ballistos, too!
NAME:       wizlab_eringya
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
MONS:       centaur col:green, centaur warrior col:lightgreen
MONS:       oklob plant
MONS:       stone golem name:vine_covered name_adjective col:lightgreen \
            tile:mons_vine_golem
MONS:       toadstool
SUBST:      y = ct
COLOUR:     G = lightgrey
KFEAT:      / = stone_arch
KFEAT:      _ = altar_fedhas
MARKER:     A = feat:stone_arch
TILE:       c = wall_brick_vines
LROCKTILE:  wall_brick_vines
LFLOORTILE: floor_grass
ITEM:       any fixed theme book, any fixed level book, any staff
{{

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

  local count = 0

  if crawl.one_chance_in(5) then
    -- Fruit!
    for spot in iter.adjacent_iterator() do
      if not feat.is_solid(spot:xy()) and feat.has_solid_floor(spot:xy())
         and crawl.one_chance_in(3) then
        dgn.create_item(spot.x, spot.y, "pear / apple / choko / apricot / orange"
                          .. "/ banana / strawberry q:4 / lemon / rambutan "
                          .. "/ grape q:7 / sultana q:9 / lychee")
        count = count + 1
      end
    end
    if count > 0 then
      crawl.mpr("Fruit sprouts up around you!")
    end
  else
    for spot in iter.adjacent_iterator() do
      if not feat.is_solid(spot:xy()) and feat.has_solid_floor(spot:xy())
         and not crawl.one_chance_in(3) then
        dgn.create_monster(spot.x, spot.y, "toadstool")
        count = count + 1
      end
    end
    if count > 0 then
      crawl.mpr("Toadstools sprout up around you!")
    end
  end
end

local grow_marker = TriggerableFunction:new { func = grow, repeated = true }

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

lua_marker("_", grow_marker)
}}
:           set_border_fill_type("stone_wall")
:           wizlab_setup(_G, "Eringya's Formal Garden")
:           dgn.set_feature_desc_short("empty arch of ancient stone",
:                                      "rose-covered archway")
:           dgn.set_feature_desc_long("empty arch of ancient stone",
:                                "The roses look beautiful!\n")
:           dgn.set_feature_desc_short("granite statue", "vine-covered statue")
:           dgn.set_feature_desc_long("granite statue", "It looks almost like a " ..
:                                     "monster made entirely from vines.\n")
:           dgn.set_feature_desc_short("stone wall", "crumbing stone wall")
:           dgn.set_feature_desc_long("stone wall", "It looks ancient.\n")
:           dgn.set_feature_desc_short("Floor", "grass-covered ground")
:           dgn.set_feature_desc_long("Floor", "Strewn with leaves and twigs that" ..
:                       " crunch loudly underfoot, the grass is crisp and fresh.\n")
:           set_random_mon_list ("oklob plant / centaur / centaur warrior")
epilogue{{
            wizlab_milestone(_G, "Eringya's Formal Garden")
}}
MAP
ccccccccccccccccccccccccccccccccccccccccccccc
ctttttttttttttttttttttttttttttttttttttttttttc
ctttttttt...........................ttttttttc
ctttt.....tttttttttttt.tttttttttttt.....ttttc
cttt..tt.tttttttttt.......tttttttttt.tt..tttc
ct.1.tGt............<.T.A............tGt.1.tc
cttt..tt.tttttttttt.......tttttttttt.tt..tttc
ctttt.....tttttttttttt.tttttttttttt.....ttttc
ctttttttt...........................ttttttttc
cttttttttttttttttttttt.tttttttttttttttttttttc
ctttttttttyyyttttttty...ytttttttyyytttttttttc
ctttttttty...yttttty.....yttttty...yttttttttc
cttttttt..111.........T.........111..tttttttc
ctttttt...121.tttttc.....cttttt.121...ttttttc
cttttt.tty...yttttttcc=cctttttty...ytt.tttttc
ctttt.tttty.yttttttt.....ttttttty.ytttt.ttttc
cttt.tttttt.tttttttyd232eyttttttt.tttttt.tttc
cttt.tttttt..tttttttydefyttttttt..tttttt.tttc
ctttt.tttttt..tttttttytyttttttt..tttttt.ttttc
cttttt.tttttt..ttttttttttttttt..tttttt.tttttc
ctttttt.tttttt..tttttcccttttt..tttttt.ttttttc
cttttyyy/yyyttt..ttty...yttt..tttyyy/yyyttttc
cttty...1...yttt..ty..1..yt..ttty...1...ytttc
ctty...1T1...yttt....1T1....ttty...1T1...yttc
cttty...1...yttt..ty..2..yt..ttty...1...ytttc
cttttyyy/yyyttt..ttty...yttt..tttyyy/yyyttttc
ctttttt.tttttt..tttttcccttttt..tttttt.ttttttc
cttttt.tttttt..ttttttttttttttt..tttttt.tttttc
ctttt.tttttt..ttttt.G._.G.ttttt..tttttt.ttttc
cttt.tttttt..ttttt...4.4...ttttt..tttttt.tttc
cttt.ttttt..ttttt...........ttttt..ttttt.tttc
ctttt.ttty/ytttt....cc=cc....tttty/yttt.ttttc
cttttt.ty...yttttttcc...cctttttty...yt.tttttc
ctttttt./.1./.ttttcc..2..cctttt./.1./.ttttttc
cttttttty...yt...../.1T1../....ty...ytttttttc
cttttttttyyyttttttty.....ytttttttyyyttttttttc
ctttttttttttttttttttyytyytttttttttttttttttttc
ccccccccccccccccccccccccccccccccccccccccccccc
ENDMAP

###############################################################################
# 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: Tiles.
NAME:       wizlab_doroklohe
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
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
    -- This is ugly.  gly_points should return 1-indexed coordinates.
    -- No longer ugly, as mapgrd is 0-indexed, like gly points.
    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:      b=., c=., d=., e=., f=., g=., h=., i=., j=., k=.
SUBST:      l=., m=., n=., o=., p=., q=., r=., s=., t=., u=.
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:      b=., c=., d=., e=., f=., g=., h=., i=., j=., k=.
SUBST:      l=., m=., n=., o=., p=., q=., r=., s=., t=., u=.
SUBST:      B=., C=., D=., E=., F=., G=., H=., I=., J=., K=.
SUBST:      L=., M=., N=., O=., P=., Q=., R=., S=., T=., U=.
:           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 / *:.
NSUBST:     c = 1:c / *:.
NSUBST:     d = 1:d / *:.
NSUBST:     e = 1:e / *:.
NSUBST:     f = 1:f / *:.
NSUBST:     g = 1:g / *:.
NSUBST:     h = 1:h / *:.
NSUBST:     i = 1:i / *:.
NSUBST:     j = 1:j / *:.
NSUBST:     k = 1:k / *:.
NSUBST:     l = 1:l / *:.
NSUBST:     m = 1:m / *:.
NSUBST:     n = 1:n / *:.
NSUBST:     o = 1:o / *:.
NSUBST:     p = 1:p / *:.
NSUBST:     q = 1:q / *:.
NSUBST:     r = 1:r / *:.
NSUBST:     s = 1:s / *:.
NSUBST:     t = 1:t / *:.
NSUBST:     u = 1:u / *:.
#           Of the outer boxes, three are damaged.
SHUFFLE:    bcdefghijklm
:           box_glyph('b', 'X')
:           box_glyph('c', 'Y')
:           box_glyph('d', 'Z')
SUBST:      b = .
SUBST:      c = .
SUBST:      d = .
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:      e=%, f=%, g=%, h=%, i=%, j=%, k=%, l=%, m=%, n=%
SUBST:      o=*, p=*, q=%, r=*, s=*, t=*, u=*
:           end
#           Monsters
#            0 Tomb set: zombies, mummies
#            1 Demons (if demons are added or reclassified, please change!)
#            2 Golems
#            3 Holy set (for later)
:           local mrnd = crawl.random2(4)
:           if mrnd == 0 then
KMONS:      % = clay golem / wood golem / toenail golem w:2
KMONS:      * = stone golem / crystal golem / iron golem
KMONS:      | = electric golem
:           elseif mrnd == 1 then
KMONS:      % = blue devil / iron devil / ynoxinul / neqoxec / hellion /\
                / chaos spawn / demonic crawler / hellwing / orange demon /\
                shadow demon / tormentor
KMONS:      * = lorocyproca / reaper / soul eater / ice devil / sun demon
KMONS:      | = blue death / green death / pit fiend / fiend / shadow fiend /\
                ice fiend / executioner / balrug / cacodemon
:           else
KMONS:      % = place:D:15 zombie / guardian mummy w:2
KMONS:      * = place:D:27 zombie / greater mummy w:5
KMONS:      | = ancient lich
:           end
#           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 / scroll of enchant weapon III q:2 /\
                scroll of blinking q:2, scroll of fog q:2, scroll of holy word q:2
:           elseif lrnd == 1 then
KITEM:      % = any armour
KITEM:      * = any good_item armour
KITEM:      | = cursed robe ego:resistance / cursed gold dragon armour
:           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.
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}
TILE:       ! = dngn_stone_wall_yellow
{{

function 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
    if you.silenced() then
      crawl.mpr("The ground shakes.", "warning")
    else
      crawl.mpr("There is a faint hissing noise.", "warning")
    end
    return
  elseif data.phase == 2 then
    data.phase = data.phase + 1
    if you.silenced() then
      crawl.mpr("The ground shakes.", "warning")
    else
      crawl.mpr("There is a loud grinding noise.", "warning")
    end
    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, false, false)
      dgn.place_cloud(i.x, i.y, "black smoke", 2)
    end
    return
  else
    return
  end
end

local box_marker = TriggerableFunction:new {func=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)
}}
:           dgn.set_feature_desc_short("rock wall", "strange rock wall")
:           dgn.set_feature_desc_long("rock wall", "It is decorated with "
:                                  .. "images you might see in a tomb.\n")
:           dgn.set_feature_desc_short("stone wall", "highly decorated stone wall")
:           dgn.set_feature_desc_long("stone wall", "It is covered with disturbing"
:                                  .. ", horrifying images.\n")
:           dgn.set_feature_desc_short("Floor", "rough-hewn floor")
:           dgn.set_feature_desc_long("Floor", "It is rough and uneven in places.\n")
:           wizlab_setup(_G, "Doroklohe's Tomb")
:           set_random_mon_list("mummy")
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%.....jJj.....%Ii.....Hh_____^
^_______l....kk......j%j......ii....h_______^
^_________........................._________^
^____________...................____________^
^________________...........________________^
^^^^^^^^^^^^^^^^^^^^^^.^^^^^^^^^^^^^^^^^^^^^^
                ^____...____^
                ^__.......__^
                ^_...!=!..._^
                ^_.<.=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, pulsating lumps 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
# pulsating lumps 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?
#           * Cigotuvi's Monster needs a much bigger buff. Convert to unique?
NAME:       wizlab_cigotuvi
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
KPROP:      . = w:1 bloody / w:15 nothing
KPROP:      ' = bloody / w:5 nothing
KMONS:      a = human name:sickly name_adjective tile:mons_deformed_human / \
            human name:monstrous name_adjective tile:mons_deformed_human  / \
            human name:deformed name_adjective tile:mons_deformed_human   / \
            human name:twisted name_adjective tile:mons_deformed_human    / \
            human name:grotesque name_adjective tile:mons_deformed_human  / \
            human name:hideous name_adjective tile:mons_deformed_human    / \
            human name:febrile name_adjective tile:mons_deformed_human
KMONS:      b = elf name:sickly name_adjective tile:mons_deformed_elf     / \
            elf name:monstrous name_adjective tile:mons_deformed_elf      / \
            elf name:deformed name_adjective tile:mons_deformed_elf       / \
            elf name:twisted name_adjective tile:mons_deformed_elf        / \
            elf name:grotesque name_adjective tile:mons_deformed_elf      / \
            elf name:hideous name_adjective tile:mons_deformed_elf        / \
            elf name:febrile name_adjective tile:mons_deformed_elf
KMONS:      d = orc name:sickly name_adjective tile:mons_deformed_orc     / \
            orc name:monstrous name_adjective tile:mons_deformed_orc      / \
            orc name:deformed name_adjective tile:mons_deformed_orc       / \
            orc name:twisted name_adjective tile:mons_deformed_orc        / \
            orc name:grotesque name_adjective tile:mons_deformed_orc      / \
            orc name:hideous name_adjective tile:mons_deformed_orc        / \
            orc name:febrile name_adjective tile:mons_deformed_orc
KMONS:      u = ugly thing / w:2 very ugly thing
KMONS:      U = very ugly thing
KMONS:      J = pulsating lump
KMONS:      x = small abomination
KMONS:      X = large abomination
KMONS:      e = generate_awake giant eyeball
SUBST:      " = J:1 / .:6
KMONS:      8 = col:red clay golem name:flesh_golem name_replace \
            tile:mons_flesh_golem name_descriptor
KMONS:      M = col:mutagenic tentacled monstrosity name:Cigotuvi's_Monster \
            name_replace hp:250 tile:mons_cigotuvis_monster
MARKER:     M = lua:MonPropsMarker:new {description="This terrifying creation " \
            .. "looks to have been constructed from the bodyparts of every monstrous " \
            .. "creature imaginable.\n", quote="\"I beheld the wretch -- the "    \
            .. "miserable monster whom I had created. He held up the curtain "    \
            .. "of the bed; and his eyes, if eyes they may be called, were "      \
            .. "fixed on me. His jaws opened, and he muttered some inarticulate " \
            .. "sounds, while a grin wrinkled his cheeks.\"\n  -Frankenstein, Mary Shelley."}
MARKER:     8 = lua:MonPropsMarker:new {description="An animated mound of misshapen flesh.\n"}
:           local sickdesc = "This poor creature looks hideously deformed.\n"
MARKER:     a = lua:MonPropsMarker:new {description=sickdesc, speech_key="Cigotuvi_creatures"}
MARKER:     b = lua:MonPropsMarker:new {description=sickdesc, speech_key="Cigotuvi_creatures"}
MARKER:     d = lua:MonPropsMarker:new {description=sickdesc, speech_key="Cigotuvi_creatures"}
MARKER:     ! = lua:fog_machine { \
                 pow_max = 15, delay_min = 10, delay_max = 40, \
                 size = 1, size_buildup_amnt = 20, \
                 size_buildup_time = 500, cloud_type = "mutagenic fog" \
             }
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" \
             }
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
:           dgn.set_feature_desc_short("Some shallow water", "Viscous fluid")
:           dgn.set_feature_desc_long("Some shallow water", "This sticky "
:            .. "fluid seems to be secreted by the nearby walls. It looks "
:            .. "disgusting.\n")
:           dgn.set_feature_desc_short("stone wall", "sinewy wall")
:           dgn.set_feature_desc_long("stone wall", "These walls look"
:            .. " strangely organic, but incredibly tough and durable.\n")
:           dgn.set_feature_desc_short("translucent rock wall", "thin membrane")
:           dgn.set_feature_desc_long("translucent rock wall", "This strange"
:            .. " membrane is thin enough to see through.\n")
:           dgn.set_feature_desc_short("Floor", "pulsating floor")
:           dgn.set_feature_desc_long("Floor", "This slick floor seems to pulse"
:            .. " to an unknown beat.\n")
: 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."
:           })
KITEM:      $ = potion of degeneration / potion of decay / \
            potion of mutation / w:3 potion of strong poison / \
            w:2 potion of poison / w:5 potion of healing / \
            w:3 potion of heal wounds / w:1 potion of cure mutation
KITEM:      * = gold
KITEM:      % = amulet of resist mutation good_item
KITEM:      : = randbook disc:transmutation owner:Cigotuvi
KITEM:      ^ = book of morphology / randbook disc:transmutation \
                owner:Cigotuvi spell:cigotuvi's_degeneration
KITEM:      | = staff of death
KITEM:      l = scroll of summoning
NSUBST:     L = 1:| / *:l
:           wizlab_setup(_G, "Cigotuvi's Fleshworks")
:           set_random_mon_list("pulsating lump / small abomination / ugly thing / very ugly thing")
epilogue{{
            wizlab_milestone(_G, "Cigotuvi's Fleshworks")
}}
MAP
ccccccccccccccccccccccccccccccccccccccccccccc
ccLLLcccc.cccccccccccAccccccccccccWWWW.U:cccc
c.....c.....ccc...ccc+cccccccccccW.....uU^ccc
c.X.........cc.u...m...m..ccccccW.......uU:cc
c.M........cc...b..m.x.m.a.cccccW..........cc
c.X........cc...d..m...m.u..ccccW.........Wcc
c..........cc.cccccm...mc...ccccc........Wccc
c.....ccc+ccccc..cccc+cccccccccccc......Wcccc
ccLLLccc..ccccuuu.cm...m..d..ccccc+cccccccccc
cccccccc..ccc..!...m.x.m.a..cccccc""ccccccccc
cc$$cccc..ccc.uuu..m...m...ccccccc""cc**%**cc
c$$$$cc...cccc....cm...m.cccWccccc""c...cee.c
c$$$$+...cccccc..cccc+cccc...Wcccc""c...c...c
c$$$$c...ccccccccc.m...m.xx...Wccc""cmm+c+mmc
cc$ccccc+cccccccc..m.x.m...u..Wccc""c.......c
ccccccc...cccc...a.m...m....x.cc.c""c.......c
cccc.........c..b..m...mc....cc..c""c...!...c
c.xJ...ccc...cc..cccc+cccc..cc...c""c......cc
c...ccccccc+cccccc.m.....ccccJJJJc""+.....ccc
cc...ccccc'''cccc..m.....uccJJJJJc""ccccccccc
cc...ccc''''''cc.!.m.....<uc.....+"""""""""cc
c..cccc''''''''cc.......cuccc....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..cXcXcXcXcXccc...........ccc""""""""""""""c
c..cccccccccccc.....c.c.....cccccccccccccc""c
c...xJ........+......?......+"""""ccc"""""""c
c...xJ........c.....c.c.....c""""""c"""""""cc
ccmmmccccmmmcccc...........cccccc""c""ccccccc
c.....cc.....cccWW.......WWcc""""""c""""""ccc
cc.JJccccuuucccccWW..8..WWcc""""""ccc""""""cc
ccJJ.cccc.a.ccccccWWWWWWWccc""ccccccccccc""cc
cc.dccccccuuccccccccWWWccccc"""""""""""""""cc
ccccccccccccccccccccccccccccc"""""""""""""ccc
ccccccccccccccccccccccccccccccccccccccccccccc
ENDMAP

###############################################################################
# Iskenderun's Mystic Tower
#
# TODO: Fix up the tiles to make them pretty. It's really quite boring. I've
#       no idea how it could be improved or made interesting, but I think that
#       a few boring maps is fine--it means that you don't know exactly what
#       you're going to get.
NAME:       wizlab_iskenderun
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup patrolling
:           wizlab_setup(_G, "Iskenderun's Mystic Tower")
MONS:       purple draconian / deep elf mage spells:iskenderun's_mystic_blast \
            / nothing
MONS:       statue tile:mons_statue_mage spells:iskenderun's_mystic_blast;orb_of\
            _destruction col:lightmagenta
KITEM:      D = star_item, star_item / superb_item, star_item
KITEM:      E = randbook disc:conjuration owner:Iskenderun spell:iskenderun's_mystic\
                _blast, randbook disc:conjuration owner:Iskenderun, any book
KITEM:      F = any book good_item, any book good_item, any book
KMONS:      DEF = purple draconian
COLOUR:     v = magenta
COLOUR:     Uc = lightmagenta
TILE:       c = wall_zot_magenta
TILE:       v = dngn_metal_wall_magenta
LFLOORTILE: floor_rough_magenta
LFLOORCOL:  magenta
MARKER:     + = lua:restrict_door()
MARKER:     R = lua:fog_machine { \
                pow_max = 10, delay_min = 10, delay_max = 40, \
                size = 15, cloud_type = "purple smoke" \
            }
SUBST:      R = .
KFEAT:      - = altar_sif_muna
KFEAT:      _ = altar_vehumet
SHUFFLE:    DEF
:           set_random_mon_list("purple draconian / deep elf mage")
epilogue{{
            wizlab_milestone(_G, "Iskenderun's Mystic Tower")
}}
MAP
ccccccccccccccccccccccccccccccccccccccccccc
cAc..c.c.c.c.c.c.c.ccRcc.c.c.c.c.c.c.cc.cRc
cc.cc<c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.cc.cc
c.c.ccc.............c.c..............cc.c.c
c.cc...................................cccc
cc<c......2.....................2......c.cc
c.cc.............v.vv.vv.v..............c.c
cc..............vvv.1R1.vvv..............cc
c.c............v.v.1vvv1.v.v............c.c
cc............vvvv1vvEvv1vvvv............cc
c.c..........v..v1vvv+vvv1v..v..........c.c
cc..........vv.v1vv.....vv1v.vv..........cc
c.c........v.vv1vv.......vv1vv.v........c.c
cccc.......vvv1vvv.......vvv1vvv.......cccc
cR.....2......RvD+...2...+1+R......2.....Rc
cccc.......vvv1vvv.......vvv1vvv.......cccc
c.c........v.vv1vv.......vv1vv.v........c.c
cc..........vv.v1vv.....vv11.vv..........cc
c.c..........v..v1vvv+vvv1v..v..........c.c
cc............vvvv1vvFvv1vvvv............cc
c.c............v.v.1vvv1.v.v............c.c
cc..............vvv.1R1.vvv..............cc
c.c..............v.vv.vv.v..............c.c
cc.c......2.....................2......c.cc
cccc...................................cccc
c.c.cc..............c.c..............cc.c.c
cc.cc.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.cc.cc
cRc.cc.c.c.c.c.c.c.ccRcc.c.c.c.c.c.c.cc.cRc
ccccccccccccccccccccccccccccccccccccccccccc
ENDMAP

###############################################################################
# Zonguldrok's Shrine
NAME:       wizlab_zonguldrok
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
:           wizlab_setup(_G, "Zonguldrok's Shrine")
SUBST:      ? = txxx
SUBST:      ! = t..
SUBST:      G = G...
MONS:       patrolling skeletal warrior
COLOUR:     t = darkgrey / lightgrey
TILE:       t = dngn_tree_dead
LFLOORCOL:  darkgrey
LROCKCOL:   darkgrey
NSUBST:     d = 1:e / *:d
ITEM:       any scroll / any potion / any book w:2
ITEM:       long sword unrand:sword_of_zonguldrok
{{
lua_marker("G", portal_desc { grave = 1 })
lua_marker("W", portal_desc { wizard_grave = 1,
        desc="Zonguldrok's gravestone",
        desc_long="A gravestone. The name 'Zonguldrok' is engraved on it in golden letters.\n"})

function spawn_zombies (data, triggerable, triggerer, marker, ev)
    function spawn_zombie (x, y, spec)
        dgn.terrain_changed(x, y, "floor", false, false, false)
        local mons = dgn.create_monster(x, y, spec)
        return mons
    end

    if triggerer.type ~= "turn" or triggerer.sub_type ~= "countdown" then
        return
    end

    local graves = dgn.find_markers_by_prop("grave", 1)
    local x, y
    for _, gmarker in ipairs(graves) do
        x, y = gmarker:pos()
        if (you.see_cell(x, y) and crawl.one_chance_in(3)) or
            crawl.one_chance_in(8) then
            spawn_zombie(x, y, "generate_awake human zombie")
            gmarker:remove()
        end
    end
end

function killed_zombie (data, triggerable, triggerer, marker, ev)
    local mons = dgn.mons_from_index(ev:arg1())
    if not string.find(mons.full_name, "zombie") then
        return
    end

    data.number_killed = data.number_killed + 1
    if #dgn.find_markers_by_prop("grave", 1) < data.number_killed then
        local x, y = marker:pos()
        dgn.tile_feat_changed(x, y, nil)
        dgn.terrain_changed(x, y, "closed_door", false, false, false)
    end
end

function awaken_wizard (data, triggerable, triggerer, marker, ev)
    function spawn_zombie (x, y, spec)
        dgn.terrain_changed(x, y, "floor", false, false, false)
        local mons = dgn.create_monster(x, y, spec)
        return mons
    end

    if data.awoke == true then
        return
    end

    local graves = dgn.find_marker_positions_by_prop("wizard_grave", 1)
    for _, pos in ipairs(graves) do
        local lich = spawn_zombie(pos.x, pos.y, "generate_awake ancient lich "
                 .."col:brown name:antique_lich name_replace name_descriptor"
                 .." tile:mons_zonguldrok_lich")
        lich.set_prop("description", "A lich who has grown expensive over countless years.\n")
    end

    data.awoke = true
end

local zombies_appear_marker = TriggerableFunction:new {
    func = spawn_zombies,
    repeated = true
}

local zombies_killed_marker = TriggerableFunction:new {
    data = {
        number_killed = 0
    },
    func = killed_zombie,
    repeated = true
}

local wizard_appear_marker = TriggerableFunction:new {
    data = {
        awoke = 0
    },
    func = awaken_wizard,
    repeated = true,
    props = {listen_to_slaves = true, only_at_slave = true }
    }

wizard_appear_marker:add_triggerer(DgnTriggerer:new {
    type = "player_move" })

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

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))

}}
:           dgn.set_feature_desc_short("granite statue", "gravestone")
:           dgn.set_feature_desc_long("granite statue", "A nameless grave. The question "
:               .. "remains: is it the grave that is nameless, or the person who lies "
:               .. "in that grave?\n")
:           dgn.set_feature_desc_short("Floor", "ground")
:           dgn.set_feature_desc_long("Floor", "No life grows here. It is completely dead.\n")
SUBST:      M = x
SUBST:      D = c
COLOUR:     W = yellow
TILE:       W = dngn_gravestone_ornate
TILE:       G = dngn_gravestone
SUBST:      W = G
SUBST:      L = .
LFLOORTILE: floor_tomb
LROCKTILE:  wall_hall_darkgray
TILE:       c = wall_stone_gray
:           set_random_mon_list("human zombie / skeletal warrior")
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.c.ddcdd.c.G.G.G!?x
x?!.G.G.ccdd.c.ddcc.G.G.!?x
x?!G.Gcccddcc+ccddcccG.G!?x
x?!.G.c.dd.cLLLc.dd.c.G.!?x
x?!G.Gc$.ccc...ccc.$cG.G!?x
x?!.G.c$$c.......c$$c.G.!?x
x?!G.Gcccc...W...ccccG.G!?x
x?!.G.c..+.......+..c.G.!?x
x?!G.Gc.1ccc...ccc1.cG.G!?x
x?!.G.c..1.c...c.1..c.G.!?x
x?!G.Gccc.1ccccc1.cccG.G!?x
x?!.G.G.cc.1.c.1.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.G...G.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: I think this is done, apart from not having "alien"-esque statue tiles.
NAME:       wizlab_wucad
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
SUBST:      T = t.
KMONS:      8 = orange crystal statue name:Statue_of_Wucad_Mu n_rpl n_the hd:20 hp:300
KITEM:      8 = quarterstaff unrand:staff_of_wucad_mu, book of enchantments
COLOUR:     =c = darkgrey
COLOUR:     t = lightred / red w:3
TILE:       t = dngn_tree_lightred / dngn_tree_red w:4 / dngn_tree_yellow w:4
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, manual of fighting / manual of armour / manual of \
            spellcasting, manual of staves / manual of fighting / manual of dodging,\
            potion of gain dexterity / potion of gain strength / potion of gain \
            intelligence
LFLOORCOL:  white
{{
dgn.persist.wucad_mu_died = false

local function 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

local function trigfn (spot)
  return Triggerable.synchronized_markers(function_at_spot(msgfn,
            { spot=spot, trig = false}, true, { only_at_slave = true,
              listen_to_slaves = 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 function 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

  local msp = "human name:monk n_suf col:white hd:10 dur:2 sum:shadow_creatures" ..
            " nas:old_memories tile:mons_human_monk seen / rock troll name:monk n_suf"..
            " dur:2 seen sum:shadow_creatures nas:old_memories tile:mons_rock_troll_monk" ..
            " / iron troll name:monk n_suf col:white dur:2 sum:shadow_creatures " ..
            " nas:old_memories seen tile:mons_iron_troll_monk w:5"

  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)
       mon.set_prop("description", "It seems a flimsy representation of a monk;"
                                .. " nothing more than a half-formed memory.\n")
       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

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

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

local function 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

local wucad_marker = TriggerableFunction:new ({ func=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_fragmentation="veto", veto_disintegrate="veto", \
                                  veto_shatter="veto" }
MARKER:     = = lua:props_marker {veto_fragmentation="veto", veto_disintegrate="veto", \
                                  veto_shatter="veto" }
MARKER:     + = lua:props_marker {veto_fragmentation="veto", veto_disintegrate="veto", \
                                  veto_shatter="veto" }
MARKER:     ' = lua:props_marker {veto_fragmentation="veto", veto_disintegrate="veto", \
                                  veto_shatter="veto" }
MARKER:     c = lua:props_marker {veto_fragmentation="veto", veto_disintegrate="veto", \
                                  veto_shatter="veto" }
MARKER:     t = lua:props_marker {veto_fragmentation="veto", veto_disintegrate="veto", \
                                  veto_shatter="veto", veto_fire="veto" }
:           wizlab_setup(_G, "Wucad Mu's Monastery")
:           set_border_fill_type("tree")
:           set_random_mon_list("shadow / phantom w:1 / flayed ghost w:1 / hungry ghost w:1")
:           dgn.set_feature_desc_short("tree", "autumnal tree")
:           dgn.set_feature_desc_long("tree", "These trees, large as they are, appear to be "
:               .. "permanently locked in an autumnal moment: leaves, coloured red and gold, "
:               .. "fall from branches and float gracefully to the floor. Before they even "
:               .. "reach the ground, however, a shadow passes, and when the shimmer is gone, "
:               .. "the leaves are once more on the branch, ready to fall again.\n")
:           dgn.set_feature_desc_short("stone wall", "crumbled stone wall")
:           dgn.set_feature_desc_long("stone wall", "These walls, though they have fallen "
:               .. "into disrepair, appear as locked in time as the trees, ready to collapse, "
:               .. "but utterly unable to.\n")
:           dgn.set_feature_desc_short("granite statue", "strange statue")
:           dgn.set_feature_desc_long("granite statue", "The features of this statue are strange "
:               .. "and alien. Is it because the statue is worn and tarnished that it has become "
:               .. "so unrecognisable? Or is it that the subject was something demonic and evil?\n")
:           dgn.set_feature_desc_short("Floor", "timeless floor")
:           dgn.set_feature_desc_long("Floor", "Though a thousand feet may have trod these floors, "
:               .. "they appear timeless and indestructible.\n")
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.....ccG.............Gcc...cc6cc..Ttt
ttT......+.......8.......+.....c+c...Ttt
ttT.....ccG.............Gcc..........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
tttttttttttT.........TTTTTTttttttttttttt
tttccccctttT.....G........Ttcccccttttttt
ttcc...cctT..............Ttcc...cctttttt
ttc..A..'..................'..<..ctttttt
ttcc...cctT.....TTTT.....Ttcc...cctttttt
tttccccctttT...TTttTT....Tttcccccttttttt
ttttttttttttTTTTttttTTTTTttttttttttttttt
tttttttttttttttttttttttttttttttttttttttt
tttttttttttttttttttttttttttttttttttttttt
ENDMAP

###############################################################################
# Random and semi-random Wizard vaults
###############################################################################

###############################################################################
# Chambers of the Cloud Mage
#
# TODO: Needs an "ocean of clouds" tiles, and fluffy "cotton wool" cloud tiles.
#       Most everything else is done, except redescriptions.
NAME:       wizlab_cloud
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
{{
wizname = crawl.make_name()

kmons ("    1 = col:silver patrolling wizard name:" .. string.gsub(wizname, " ", "_")
         .. "_the_Cloud_Mage name_replace"
         .. " name_definite spells:mephitic_cloud;freezing_cloud;poisonous_cloud;"
         .. "airstrike;blink_range;blink_range hd:20 hp:150 ;"
         .. " robe unrand:robe_of_clouds . quick blade ego:electrocution |"
         .. " quick blade ego:freezing | dagger ego:speed | dagger ego:electrocution"
         .. " | dagger ego:freezing")
}}
KMONS:      * = w:5 vapour / w:20 air elemental
SUBST:      . = .:120 *
MARKER:     ! = lua:fog_machine { \
                pow_max = 10, delay_min = 10, delay_max = 40, \
                size = 1, size_buildup_amnt = 5, \
                size_buildup_time = 25, cloud_type = "grey smoke", \
                colour = "white", name = "white fluffiness" \
            }
KITEM:      % = w:20 potion of levitation / w:20 potion of water / \
            potion of magic / potion of speed / potion of resistance / \
            gold / potion of agility / potion of brilliance
KITEM:      ? = randbook disc:air
KITEM:      $ = wand of lightning / staff of air / ring of levitation /\
            gold / scroll of silence / ring of teleport control / \
            amulet of controlled flight / quick blade / ring of evasion /\
            ring of see invisible / book of clouds / any book w:15 /\
            any good_item / any w:20
KFEAT:      # = deep_water
NSUBST:     $ = 2:? / *:$
SUBST:      $ = $%
COLOUR:     +<bo = white
LFLOORCOL:  lightblue
LFLOORTILE: floor_rough_lightblue
TILE:       o = dngn_transparent_wall_white
TILE:       b = dngn_crystal_white
COLOUR:     wW# = silver
:           set_border_fill_type('open_sea')
:           set_random_mon_list("vapour / air elemental")
:           wizlab_setup(_G, "The Chambers of " .. wizname .. " the Cloud Mage")
:           dgn.set_feature_desc_short("Floor", "damp floor")
:           dgn.set_feature_desc_long("Floor", "Perhaps it is the humidity, or the constant flow of clouds, but the floor here remains forever damp.\n")
:           dgn.set_feature_desc_short("wall of green crystal", "wall of white crystal")
:           dgn.set_feature_desc_short("translucent unnaturally hard rock wall", "wall of transparent white crystal")
MARKER:     " = lua:portal_desc { desc="sigil-covered floor", desc_long="This area of floor is marked with strange sigils and symbols. You cannot understand them, but for some reason the sight of them makes you tremble.\n" }

epilogue{{
            wizlab_milestone(_G, "The Chambers of " .. wizname .. " the Cloud Mage")
}}
#           Map is ugly because border_fill_type doesn't allow for (yet)
#           recolouring.
MAP
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################oooooooooooooooooooooooooooooo##################
###################ooo............................ooo################
#################ooo...wwwwwwwwwwwwwwwwwwwwwwwwww...ooo##############
################oo...wwwwwwwbbbbbbbbbbbbbbbbbbbbwww...oo#############
################o..wwwwwwwbbbbbbbbbbbbbbbbbbbbbbwwwww..o#############
###############oo.wwwwwwbbbbbbbb..b..b..b..b..bbwwwwww.oo############
###############o..wwwwwbb.....b.!............!.bwwwwww..o############
##############oo.wwwwwwbb.$$$.b................bwwwwwww.oo###########
##############o..wwwwwbbb.$$$.b................bWWWWWWW..o###########
##############o..wwwwwbbb.$$$.+...1............+.........o###########
##############o..wwwwwbbb.$$$.b................bWWWWWWW..o###########
##############oo.wwwwwwbb.$$$.b................bwwwwwww.oo###########
###############o..wwwwwbb.....b.!............!.bwwwwww..o############
###############oo.wwwwwwbbbbbbbb..b..b..b..b..bbwwwwww.oo############
################o..wwwwwwwbbbbbbbbbbbbbbbbbbbbbbwwwww..o#############
################oo...wwwwwwwbbbbbbbbbbbbbbbbbbbbwww...oo#############
#################oo....wwwwwwwwwwwwwwwwwwwwwwwwww...ooo##############
##################oooo............................ooo################
#####################bbb.......bbbbbbbbbbbbbbbbbbbb##################
#####################oo.......oo#####ooo#############################
####################oo.......oo#####oo.oo############################
###################oo.......oo#####oo.!.oo###########################
###################o!.....!ooo####oo.....ooo#########################
###################ooo.......ooo#oo........oo########################
####################oooo.......ooo..........oo#######################
#######################ooo!.....ooo..........o#######################
########################o.....!ooobb+bb......oo######################
#######################ooo......obb...bb!.....o######################
########################o......obb.....bb.....oo#####################
#######################ooo......b.......b......o#####################
#######################o.!.....ob.<.A.<.b......o#####################
#######################o.b......b.......bo...!oo#####################
#######################o.bo.....bb.....bb......o#####################
#######################b+bbbb....bb...bb!.....oo#####################
#######################o....bo...!bbbbb......oo######################
#######################o.%%.bo.............oob#######################
#######################o.%%.boo...........bbbbbbbbb##################
#######################o....b#o..........!...+....o##################
#######################ooooob#oo........ooooob.%%.o##################
###############################oo......oo####b.%%.o##################
################################oo.!..oo#####b....o##################
#################################oooooo######booooo##################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
#####################################################################
ENDMAP

###############################################################################
# Halls of the Hellbinder (by Mu.)
NAME:       wizlab_demon
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
LFLOORCOL:  red
LROCKCOL:   red
COLOUR:     c = darkgrey
COLOUR:     " = yellow
KPROP:      ' = bloody / nothing
KFEAT:      _ = altar_makhleb
KPROP:      _ = bloody
TILE:       c = wall_stone_dark
FTILE:      " = floor_snake
LFLOORTILE: floor_pebble_lightred
RTILE:      x = wall_undead
MARKER:     ! = lua:fog_machine { \
                pow_max = 10, delay_min = 10, delay_max = 40, \
                size = 1, size_buildup_amnt = 5, \
                size_buildup_time = 25, cloud_type = "flame" }
KMONS:      2 = w:1 Lorocyproca / w:20 soul eater / w:20 reaper /\
            w:20 ice devil / w:20 sun demon / hellion
KMONS:      3 = blue devil / iron devil / shadow demon / neqoxec /\
            w:5 tormentor / ynoxinul
KMONS:      4 = kobold demonologist / deep elf demonologist
KMONS:      5 = blue death / green death / cacodemon
{{
wizname = crawl.make_name()

kmons     ("1 = col:fire patrolling wizard name:" .. string.gsub(wizname, " ", "_")
              .. "_the_Hellbinder name_replace"
              .." spells:call_imp;summon_demon;haste;hellfire;blink_away;throw_flame"
              .." hd:20 hp:150 ; demon blade . robe")
}}
KITEM:      $ = gold / w:1 scroll of torment / w:1 scroll of summoning
KITEM:      | = rod of demonology / ring of fire / ring of protection from fire /\
            amulet of conservation / scroll of torment / scroll of summoning /\
            demon blade w:1 / demon whip w:1 / demon trident w:1 / gold / wand of fire /\
            wand of draining / staff of summoning / any book w:30 / any good_item w:15
KITEM:      B = randbook disc:summoning
NSUBST:     | = 2:B / *:|
:           set_random_mon_list([[imp / shadow imp / lemure / iron imp / quasit / white imp / ]]
:                        .. [[ufetubus / midge / red devil / rotting devil / hairy devil / ]])
:           wizlab_setup(_G, "The Hall of " .. wizname .. " the Hellbinder")
:           dgn.set_feature_desc_short("Floor", "hot floor")
:           dgn.set_feature_desc_long("Floor", "Deep below the floor burns a fire hotter than any other fire: the fire of hell. The floor is hot to the touch.\n")
:           dgn.set_feature_desc_short("stone wall", "black wall")
:           dgn.set_feature_desc_long("stone wall", "Perhaps stone, or solid charcoal, or a substance found only in the deepest hells.\n")
:           dgn.set_feature_desc_short("rock wall", "carved rock wall")
:           dgn.set_feature_desc_long("rock wall", "It is decorated with images of death and destruction.\n")
MARKER:     " = lua:portal_desc { desc="sigil-covered floor", desc_long="This area of floor is marked with strange sigils and symbols. You cannot understand them, but for some reason the sight of them makes you tremble.\n" }
epilogue{{
            wizlab_milestone(_G, "The Hall of " .. wizname .. " the Hellbinder")
}}
MAP
cccccccccccccccccccccccccccccccccccccccccccccc
ccccccc.cccccc...................cccccc.cccccc
ccccc.....cccc.cc+ccccc+ccccc+cc.cccc.....cccc
cccc.."""..ccc.c...cccc.cccc...c.ccc..."...ccc
ccc.."..."..cc.+.A.ccc...ccc.<.+.cc.."....."cc
ccc."...3.".cc.c...cc.....cc...c.cc.""".3.".cc
cc.."..3.."....ccccc..c.c..ccccc.....".3."...c
cc..".3..."....cccc..cc.cc..cccc......3."....c
ccc.".....".cc.ccc.....4.....ccc.cc...."""""cc
ccc.."..."..cc.cc..cccc.cccc..cc.cc...".....cc
cccc.."""..ccc.+...............+.ccc.".....ccc
ccccc.....cccc.ccccccccccccccccc.cccc.....cccc
ccccccc.cccccc...................cccccc.cccccc
ccccccc.cccccc.cccccccc.cccccccc.cccccc.cccccc
ccccccc.ccccccc.cccccc.c.cccccc.ccccccc.cccccc
ccccccc.cccccccc.cccc.ccc.cccc.cccccccc.cccccc
ccccccc.ccccccccc.cc.ccccc.cc.ccccccccc.cccccc
ccccccc.cccccccccc..ccccccc..cccccccccc.cccccc
ccccccc.cccc.5...................5.cccc.cccccc
ccccccc.cccc..ccccccccc.ccccccccc..cccc.cccccc
ccccccc.ccccc..cccc$$$c.c$$$cccc..ccccc.cccccc
ccccccc.cccccc..ccc$$$+.+$$$ccc..cccccc.cccccc
ccccccc.cc.cccc..cc$$$c.c$$$cc..cccc.cc.cccccc
ccccccc......ccc..ccccc.ccccc..ccc.."...cccccc
ccccccc..."...ccc..cccc.cccc..ccc.."..".cccccc
cccccc.."..."..ccc..ccc.ccc..ccc.."..""".ccccc
cccccc..."2"...cccc..cc.cc..cccc."2222"..ccccc
ccccc.."2"""2"..cccc.......cccc.".........cccc
cccccc..""2""...ccccc."4".ccccc""""""""""ccccc
cccccc..."."....ccccc.."..ccccc........".ccccc
ccccccc.."""....ccccc.."..ccccc.......".cccccc
cccccccc........ccccc.....ccccc......".ccccccc
cccccccccc......cccc..ccc..cccc......ccccccccc
ccccccccccc.....ccc..ccccc..ccc.....cccccccccc
cccccccccccc.....c...ccccc...c.....ccccccccccc
cccccccccccc.."."..cc.ccc.cc.."."..ccccccccccc
ccccccccccccc.."..cccc.c.cccc.."..cccccccccccc
ccccccccccccc."...ccccc!ccccc...".cccccccccccc
cccccccccccccc.....ccc.c.ccc.....ccccccccccccc
ccccccccccccccc.....c.ccc.c.....cccccccccccccc
ccccccccccccccccc.....ccc.....cccccccccccccccc
ccccccccccccccccccc.........cccccccccccccccccc
ccccccccccccccccccccc.....cccccccccccccccccccc
ccccccccccccccccccccccc+cccccccccccccccccccccc
ccccccccccccccccccccc.....cccccccccccccccccccc
ccccccccccccccccccc..."""...cccccccccccccccccc
ccccccccccccccccc...""...""...cccccccccccccccc
cccccccccccccccc.."".......""..ccccccccccccccc
ccccccccccccccc.."..".....".."..cccccccccccccc
ccccccccccccccc.".............".cccccccccccccc
cccccccccccccc.."....."."....."..ccccccccccccc
cccccccccccccc."."..."..."...".".ccccccccccccc
ccccccccccccc.."...."..1.."...."..cccccccccccc
ccccccccccccc.."..."".'''.""..."..cccccccccccc
ccccccccccccc..".."xx"'_'"xx".."..cccccccccccc
cccccccccccc....""..xx"'"xx..""....ccccccccccc
cccccccccccc|..."..".xxxxx.".."...|ccccccccccc
cccccccccccc||..."".........""...||ccccccccccc
cccccccccccc|||.................|||ccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccc
ENDMAP

###############################################################################
# Incomplete and TODO work area.
#
# See git history for previous versions of Ozocubu, Alistair.
#
# PLANNING AREA:
#
# From spells:
#
# Alistair's Brewery: mutated wizards, mephitic cloud generators,
#    cupboards full of potions, confused monsters.
# Lee's Rapid Deconstructor: golems and "monk" or otherwise unarmed creatures,
#    exploding features and exploding corpses. It's a timed vault, so you have
#    to get to the loot quickly and avoid the hordes of monsters.
# Lehudib's Crystal Spire:  crystal walls and crystal golems, crystal monsters,
#    spear throwers (statues with crystal spear), possibly the unrand as the
#    loot.
# Maxwell's Forge: Maxwell employs a bunch of angels to churn out weapons;
#    stashes of hammers, flame clouds, other "smithy" styled themes, with black
#    smoke.
# Olgreb's Toxic Laboratory: poisonous clouds, a toxic radiance effect,
#    poisonous monsters, possibly even a "poison" effect that bypasses rPois,
#    potions of poison and potions dropped converting into potions of poison.
# Ozocubu's Refrigerator: simulacra, refrigeration effect, a solid stone room
#    inside of an "ice cave", freezing clouds.
#
# From unrands:
#
# Cekugob's Oubliette: a randomised maze (though not a labyrinth) with skeletal
#    guards, and with occasionally hidden. Cekugob's amulet as the loot,
#    possibly.
# Botono's Bayou: A bay-like area with small huts, wizards that cast negative
#    related spells, shadow dragons, rebranded swamp worms, wraiths, spectrals.
# Ukta's Hut: phantoms, other "ghosts", ogre mages and ogres, druidic style,
#    wooden walls set in a forest (more "earthy" than Eringya's Garden)
# The Alchemist's Tower: gold turned into things, things turned into gold.
#

###############################################################################
# Alistair's Brewery
#
# TODO: Do.
NAME:       wizlab_alistair
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Alistair's Brewery")
epilogue{{
            wizlab_milestone(_G, "Alistair's Brewery")
}}
MAP
ENDMAP

###############################################################################
# Lee's Rapid Deconstructor
#
# TODO: Do.
NAME:       wizlab_lee
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Lee's Rapid Deconstructor")
epilogue{{
            wizlab_milestone(_G, "Lee's Rapid Deconstructor")
}}
MAP
ENDMAP

###############################################################################
# Lehudib's Crystal Spire
#
# TODO: Do.
NAME:       wizlab_lehudib
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Lehudib's Crystal Spire")
epilogue{{
            wizlab_milestone(_G, "Lehudib's Crystal Spire")
}}
MAP
ENDMAP

###############################################################################
# Maxwell's Forge
#
# TODO: Do.
NAME:       wizlab_maxwell
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Maxwell's Forge")
epilogue{{
            wizlab_milestone(_G, "Maxwell's Forge")
}}
MAP
ENDMAP

###############################################################################
# Olgreb's Toxic Laboratory
#
# TODO: Do.
NAME:       wizlab_olgreb
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Olgreb's Toxic Laboratory")
epilogue{{
            wizlab_milestone(_G, "Olgreb's Toxic Laboratory")
}}
MAP
ENDMAP

###############################################################################
# Ozocubu's Refrigerator
#
# TODO: Do.
NAME:       wizlab_ozocubu
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Ozocubu's Refrigerator")
epilogue{{
            wizlab_milestone(_G, "Ozocubu's Refrigerator")
}}
MAP
ENDMAP

###############################################################################
# Cekugob's Oubliette
#
# TODO: Do.
NAME:       wizlab_cekugob
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Cekugob's Oubliette")
epilogue{{
            wizlab_milestone(_G, "Cekugob's Oubliette")
}}
MAP
ENDMAP

###############################################################################
# Botono's Bayou
#
# TODO: Do.
NAME:       wizlab_botono
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Botono's Bayou")
epilogue{{
            wizlab_milestone(_G, "Botono's Bayou")
}}
MAP
ENDMAP

###############################################################################
# Ukta's Hut
#
# TODO: Do.
NAME:       wizlab_ukta
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "Ukta's Hut")
epilogue{{
            wizlab_milestone(_G, "Ukta's Hut")
}}
MAP
ENDMAP

###############################################################################
# The Alchemist's Tower
#
# TODO: Do.
NAME:       wizlab_alchemist
ORIENT:     encompass
TAGS:       wizlab no_item_gen no_monster_gen no_rotate allow_dup
WEIGHT:     0
:           wizlab_setup(_G, "The Alchemist's Tower")
epilogue{{
            wizlab_milestone(_G, "The Alchemist's Tower")
}}
MAP
ENDMAP
