###############################################################################
# icecave.des: All maps related to the Ice Cave Portal.
#
# <<1>> Entry vaults.
# <<2>> Ice Cave maps.
#
###############################################################################

{{

crawl_require("dlua/dungeon.lua")
crawl_require('dlua/vault.lua')

--[[
Setup function for ice cave entry vaults. Create portal timer marker, determine
ice cave difficulty, and set ice cave chance, and define the ice cave entry
feature.

@tab e The map environment.
]]
function ice_cave_portal(e)
    local timeout_turns = crawl.random_range(600, 800)

    local messager = timed_msg {
        initmsg = { "You feel a wave of frost pass over you.",
                    "There is an entrance to an ice cave on this level. "
                    .. "Hurry and find it before the portal melts!" },
        finalmsg = "The crackling of melting ice is subsiding rapidly.",
        verb = 'crackling',
        noisemaker = 'melting archway',
        ranges = {
            { 5000, 'faint ' },  { 4000, '' },
            { 2500, 'steady ' }, { 1500, 'quick ' },
            { 0, 'loud ' }
        }
    }

    dgn.persist.ice_cave_hard = hard_ice_cave_difficulty()

    if dgn.persist.ice_cave_hard then
        gone = "dngn_portal_glacial_chasm_gone"
    else
        gone = "dngn_portal_ice_cave_gone"
    end

    e.lua_marker('O',
        timed_marker {
          disappear = "The archway melts and disappears.",
          entity = 'archway',
          turns = timeout_turns,
          single_timed = true,
          floor = "expired_portal",
          feat_tile = gone,
          msg = messager })
    e.tags("uniq_icecv chance_icecave")
    e.chance(500)

    e.kfeat("O = enter_ice_cave")
    if dgn.persist.ice_cave_hard then
        e.tile("O = dngn_portal_glacial_chasm")
        e.set_feature_name("enter_ice_cave", "a glacial archway")
    end

    e.colour("a = white")
    e.kfeat("a = x")
    e.rtile("a = wall_ice_block")
    e.colour(".1234 = blue")
    e.ftile(".12345O+^DEFH = floor_ice")
end

--[[
Determine if we're placing a hard difficulty ice cave map. Possible depths for
easy ice caves are D:11-13, Lair, Orc. Hard ice caves are placed in Elf and the
Lair roulette branches. This function must be updated if the depth range of ice
cave changes, which is set by the default-depth statement of the entry vault
section or by the entry maps themselves.

treturn bool True for hard difficulty, false for easy.
]]
function hard_ice_cave_difficulty()

    if you.in_branch("D") or you.in_branch("Lair") or
       you.in_branch("Orc") then
        return false
    end

    return true
end

--[[
Define an Ice Cave exit feature on '<' and set ice cave thematic terrain
descriptions. Should be called after all terrain substitutions are performed.

@tab e The map environment.
]]
function ice_cave_appearance(e)
    e.kfeat("< = exit_ice_cave")

    -- Alter short feature descriptions for all ice cave destination vaults.
    e.set_feature_name("rock_wall", "ice covered rock wall")
    e.set_feature_name("stone_arch", "ice choked empty arch of ancient stone")
    e.set_feature_name("shallow_water", "Some ice crusted shallow water")
    e.set_feature_name("deep_water", "Some ice crusted deep water")
end

--[[
Place a freezing vapour generator on the '!' glyph via a lua marker.

@tab e The map environment.
@number[opt=12] size The number of squares upon which the cloud generator
    will place clouds.
@string[opt="!"] glyphs The glyphs on which to place the marker.
]]
function place_freezing_vapour_machine(e, size, glyphs)
    if size == nil then
        size = 12
    end

    if glyphs == nil then
        glyphs = "!"
    end

    e.lua_marker(glyphs,
        fog_machine { pow_max = 20, cloud_type = "freezing vapour",
                      delay_min = 50, delay_max = 250, size = size,
                      start_clouds = 1, excl_rad = -1 })
end

--[[
Returns monster simulacrum definition strings according to three types,
"mocking", "animal", and "cruel", that are modified by ice cave difficulty.
The "mocking" set tends to resemble player species, the "animal" set contains
beastly simulacrum, and the "cruel" set contains particularly dangerous
simulacrum in terms of speed, attack strength, or number of attacks.

@treturn table A table of strings with keys "mocking", "animal", and "cruel".
]]
function simulacrum_monsters()
    local mons = {}
    if dgn.persist.ice_cave_hard then
        mons["mocking"] = "deep troll simulacrum / minotaur simulacrum" ..
            " / spriggan defender simulacrum"
    else
        mons["mocking"] = "two-headed ogre simulacrum / troll simulacrum" ..
            " / naga simulacrum / spriggan simulacrum"
    end

    if dgn.persist.ice_cave_hard then
        mons["animal"] = "lindwurm simulacrum / dire elephant simulacrum" ..
            " / alligator simulacrum / harpy simulacrum / anaconda simulacrum"
    else
        mons["animal"] = "wolf simulacrum / elephant simulacrum" ..
            " / polar bear simulacrum / cane toad simulacrum" ..
            " / death yak simulacrum"
    end

    if dgn.persist.ice_cave_hard then
        mons["cruel"] = "ettin simulacrum / 7-headed hydra simulacrum" ..
            " / golden dragon simulacrum / caustic shrike simulacrum"
    else
        mons["cruel"] = "dire elephant simulacrum / harpy simulacrum" ..
            " / anaconda simulacrum / 3-headed hydra simulacrum"
    end

    return mons
end

--[[
Define undead and demonic monsters on glyphs 1 through 8 using KMONS, with the
monster types modified by ice cave difficulty. The glyph definitions are
roughly in order of difficulty. Glyph 3 defines a statue monster, which is ice
statue for easy ice caves and obsidian statue for hard ice caves. The glyph 6
monster is a "miniboss" that should be used sparingly in easy ice caves. The
"boss" monsters are on glyphs 7 and 8, with 7 being appropriate for a 2+ size
boss group and 8 being appropriate for a solo boss on easy ice caves or a small
group for hard ice caves.

Also set a random monster list for shadow creatures purposes containing
monsters on glyphs 1,2,4, and 5, with total weights for each glyph having
ratios 18:6:2:1.

@tab e The map environment.
@string[opt] reaper_glyphs If non-nil, a KMONS will be defined on the given
    glyphs for a reaper with a freezing scythe and rC gear, the latter getting
    it to rC+++ and hence freezing vapour immunity.
]]
function ice_cave_undead_demon_monster_set(e, reaper_glyphs)
    simul = simulacrum_monsters()

    local reaper_equip = " ; " .. scythe("freezing") .. " plus:-6"
    -- Make sure this reaper has rC+++ so it doesn't die in freezing vapour.
    if reaper_glyphs ~= nil then
        reaper_equip = reaper_equip .. " . robe ego:cold_resistance" ..
            " . ring of protection from cold"
    end

    if dgn.persist.ice_cave_hard then
        e.kmons("1 = " .. simul["mocking"] .. " / ice devil")
        e.kmons("2 = " .. simul["animal"] .. " / freezing wraith")
        e.kmons("3 = obsidian statue")
        e.kmons("4 = freezing wraith")
        e.kmons("5 = " .. simul["cruel"])
        e.kmons("6 = bog body / white very ugly thing w:2")
        e.kmons("7 = blizzard demon")
        if reaper_glyphs ~= nil then
            e.kmons(reaper_glyphs .. " = reaper" .. reaper_equip)
        end
        e.kmons("8 = ice fiend")

        e.set_random_mon_list(
            -- 144 * 5 = 720 total weight for tier 1.
            dgn.random_entry_arg(simul["mocking"] .. " / ice devil",
                "w:144") ..
            -- 48 * 5 = 240 total weight for tier 2.
            " / " .. dgn.random_entry_arg(simul["animal"], "w:48") ..
            -- 80 weight for tier 4.
            " / freezing wraith w:80" ..
            -- 40 total weight for tier 5.
            " / " .. simul["cruel"])
    else
        -- Default case, meaning glyph 8 and no rC gear.
        if reaper_glyphs == nil then
            reaper_glyphs = "8"
        end

        e.kmons("1 = " .. simul["mocking"] .. "/ white imp / ufetubus")
        e.kmons("2 = " .. simul["animal"])
        e.kmons("3 = ice statue")
        e.kmons("4 = ice devil")
        e.kmons("5 = " .. simul["cruel"])
        e.kmons("6 = freezing wraith / white ugly thing w:2")
        e.kmons("7 = bog body")
        e.kmons(reaper_glyphs .. " = reaper" .. reaper_equip)

        e.set_random_mon_list(
            -- 120 * 6 = 720 total weight for tier 1.
            dgn.random_entry_arg(simul["mocking"] .. " / white imp / ufetubus",
                "w:120") ..
            -- 48 * 5 = 240 total weight for tier 2.
            " / " .. dgn.random_entry_arg(simul["animal"], "w:48") ..
            -- 80 weight for tier 4.
            " / ice devil w:80" ..
            -- 40 total weight for tier 5.
            " / " .. simul["cruel"])
    end
end

--[[
Define natural monsters on glyphs 1 through 8 using KMONS, with the monster
types modified by ice cave difficulty. The glyph definitions are roughly in
order of difficulty. Glyph 3 defines a statue monster, which is ice statue for
easy ice caves and orange crystal statue for hard ice caves. The glyph 6
monster is a "miniboss" that should be used sparingly in easy ice caves. The
"boss" monsters are on glyphs 7 and 8, with 7 being appropriate for a 2+ size
boss group and 8 being appropriate for a solo boss on easy ice caves or a small
group for hard ice caves.

Also set a random monster list for shadow creatures purposes containing
monsters on glyphs 1,2,4, and 5, with total weights for each glyph having
ratios 18:6:2:1.

@tab e The map environment.
]]
function ice_cave_natural_monster_set(e)
    if dgn.persist.ice_cave_hard then
        e.kmons("1 = polar bear / rime drake")
        e.kmons("2 = white ugly thing")
        e.kmons("3 = orange crystal statue")
        e.kmons("4 = ice dragon")
        e.kmons("5 = ironbound frostheart")
        e.kmons("6 = white draconian ; " ..
            dgn.random_item_def({["scimitar"] = 2, ["partisan"] = 2,
                                 ["broad axe"] = 1, ["morningstar"] = 2},
                                "freezing", nil, "|") .. " . cloak")
        e.kmons("7 = frost giant")
        e.kmons("8 = shard shrike")

        -- Weights applied by monster difficulty tiers in a way similar to
        -- ice_cave_undead_demon().
        e.set_random_mon_list("polar bear w:15 / rime drake w:15 \
                              / ice dragon / ironbound frostheart w:5")
    else
        e.kmons("1 = wolf / yak")
        e.kmons("2 = polar bear")
        e.kmons("3 = ice statue")
        e.kmons("4 = rime drake")
        e.kmons("5 = death yak")
        e.kmons("6 = white ugly thing")
        e.kmons("7 = ironbound frostheart")
        e.kmons("8 = frost giant")

        e.set_random_mon_list("wolf w:30 / yak w:30 / polar bear w:15 \
                              / rime drake / death yak w:5")
    end
end

--[[
Define types of thematic armour loot on two KITEMs using the supplied glyphs.
The first aux armour and buckler, the second being "light" armour and a kite
shield, and the third being "heavy" armour and a tower shield. All have some
kind of cold resistance. For hard ice caves, the items are all good_item.

@tab e The map environment.
@string[opt="def"] glyphs A string of three glyphs to use for the three KITEM
    statements.
]]
function ice_cave_armour_loot(e, glyphs)
    if glyphs == nil then
        glyphs = "def"
    end

    local coldres = " ego:cold_resistance pre_id"
    local res = " ego:resistance pre_id"

    local quality = ""
    if dgn.persist.ice_cave_hard then
        quality = " good_item"
    end

    e.kitem(glyphs:sub(1,1) .. " = cloak" .. coldres .. quality .. " w:5" ..
        " / scarf" .. res .. " w:5" .. " / hat" .. quality .. " w:5" ..
        " / helmet" .. quality .. " w:5" .. " / pair of gloves" .. quality ..
        " / pair of boots" .. quality .. " / buckler" .. coldres .. quality)
    e.kitem(glyphs:sub(2,2) .. " = robe" .. res .. quality ..
        " / leather armour" .. res .. quality ..
        " / scale mail" ..  coldres .. quality .. " / skin of zhor w:2" ..
        " / kite shield" ..  coldres .. quality)
    e.kitem(glyphs:sub(3,3) .. " = ice dragon scales" ..  quality ..
        " / chain mail" .. coldres ..  quality ..
        " / plate armour" ..  coldres .. quality ..
        " / crystal plate armour" .. coldres .. quality ..
        " / tower shield" .. coldres .. quality)
end

--[[
Define weapon types on two KITEMs using the supplied glyphs, both of which have
the freezing ego. The first is any weapon, and the second is a large set of
upper-tier weapons. Both weapons definitions include launchers, and the second
includes small weights for the unrands Frostbite and Maxwell's thermic engine.
For easy ice caves, the first definition makes weapons that are 50% good_item,
and for hard ice caves, both definitions are always good_item.

@tab e The map environment.
@string[opt="gh"] glyphs A string of two glyphs to use for the two KITEM
    statements.
]]
function ice_cave_weapon_loot(e, glyphs)
    if glyphs == nil then
        glyphs = "gh"
    end

    local ego = " ego:freezing pre_id"
    if dgn.persist.ice_cave_hard then
        e.kitem(glyphs:sub(1,1) .. " = any weapon" .. ego .. " good_item")
    else
        e.kitem(glyphs:sub(1,1) .. " = any weapon" .. ego ..
            " / any weapon" .. ego .. " good_item")
    end

    -- Some higher-end weapons that work well with the freezing ego.
    local weapons = {
        ["morningstar"] = 10, ["eveningstar"] = 5, ["demon whip"] = 5,
        ["great mace"] = 10, ["giant club"] = 5, ["giant spiked club"] = 5,
        ["demon trident"] = 5, ["partisan"] = 10, ["glaive"] = 10,
        ["bardiche"] = 5, ["scimitar"] = 10, ["demon blade"] = 5,
        ["double sword"] = 5, ["maxwell's thermic engine"] = 2,
        ["great sword"] = 10, ["triple sword"] = 5, ["lajatang"] = 10,
        ["broad axe"] = 10, ["battleaxe"] = 10, ["frostbite"] = 2,
        ["executioner's axe"] = 5, ["hand cannon"] = 10, ["longbow"] = 10,
        ["arbalest"] = 5, ["triple crossbow"] = 5
    }
    local quality = ""
    if dgn.persist.ice_cave_hard then
        quality = " good_item"
    end
    e.kitem(glyphs:sub(2,2) .. " = " ..
        dgn.random_item_def(weapons, "freezing", "pre_id" .. quality))
end

--[[
Define one item slot containing ice or water themed magical items, including
spellbooks, manual, staff of cold, rC jewellery (good_item quality for hard ice
caves), wand of iceblast, phial of floods, and condenser vane.

@tab e The map environment.
@string[opt="i"] glyphs A string of glyphs to use for the single KITEM
    statement.
]]
function ice_cave_magic_loot(e, glyphs)
    if glyphs == nil then
        glyphs = "i"
    end

    local quality = ""
    if dgn.persist.ice_cave_hard then
        quality = " good_item"
    end
    e.kitem(glyphs .. " = book of ice / book of the tundra" ..
        " / randbook disc:ice" ..
        " / manual of ice magic / staff of cold" .. quality ..
        " / ring of protection from cold" .. quality ..
        " / wand of iceblast / phial of floods / condenser vane")
end

--[[
Define some common loot items using six KITEM statements on the supplied glyphs.
The first three are armour, the next two are weapons, and that last is magical
items. See comments for ice_cave_armour_loot, ice_cave_weapon_loot, and
ice_cave_magic_loot for details.

@tab e The map environment.
@string[opt="defghi"] glyphs A string of six glyphs to use for the six KITEM
    statements.
]]
function ice_cave_common_loot(e, glyphs)
    if glyphs == nil then
        glyphs = "defghi"
    end

    ice_cave_armour_loot(e, glyphs:sub(1,3))
    ice_cave_weapon_loot(e, glyphs:sub(4,5))
    ice_cave_magic_loot(e, glyphs:sub(6,6))
end

--[[
Define one kitem glyph containing necromancy themed items, including books,
a manual, staff of necromancy, and an artefact ring of positive energy.

@tab e The map environment.
@string[opt="j"] glyphs Glyphs to use for the single KITEM statement.
]]
function ice_cave_necro_loot(e, glyphs)
    if glyphs == nil then
        glyphs = "j"
    end

    e.kitem(glyphs .. " = book of unlife / randbook disc:ice" ..
            "    disc2:necromancy numspells:6" ..
            "/ manual of necromancy w:5 / staff of necromancy" ..
            "/ ring of positive energy randart")
end

}}

###############################################################################
#
# <<1>> Entry vaults.
#
# All must call the function ice_cave_portal() to set the create the portal
# timer and set the common CHANCE value. Any entry placing out-of-depth
# monsters should have a lower weight.
#
###############################################################################

###############################################################################
# Entry vaults that place for both ice cave difficulties.

default-depth: D:11-13, Lair, Orc, Elf, Swamp, Shoals, Snake, Spider

NAME:   portal_ice_cave_entry_pillars_1
TAGS:   transparent
: ice_cave_portal(_G)
MAP
  ...
  .a.
.......
.a.O.a.
.......
  .a.
  ...
ENDMAP

NAME:   portal_ice_cave_entry_pillars_2
TAGS:   transparent
: ice_cave_portal(_G)
MAP
  ...
 ..a..
..a.a..
.a.O.a.
..a.a..
 ..a..
  ...
ENDMAP

NAME:   portal_ice_cave_entry_ice_simulacra
TAGS:   patrolling no_monster_gen transparent
{{
ice_cave_portal(_G)
local simul = simulacrum_monsters()
mons(simul["mocking"])
mons(simul["animal"])
}}
: if you.in_branch("D") then
:     if you.depth() < 12 then
SUBST: 1 = 1.
:     else
SUBST: 1 = 112
:     end
# Savage only for Lair, but fewer.
: elseif you.in_branch("Lair") then
:     if you.depth() < 3 then
SUBST: 1 = 2...
:     else
SUBST: 1 = 2.
:     end
# Orc
: elseif you.in_branch("Orc") then
SUBST: 1 = 112
: else
SUBST: 1 = 12
: end
MAP
..1..
.1.1.
1.O.1
.1.1.
..1..
ENDMAP

###############################################################################
# Entry vaults that only place easy ice cave entrances

default-depth: D:11-13, Lair, Orc

NAME:   portal_ice_cave_entry_imps
TAGS:   patrolling no_monster_gen transparent
: ice_cave_portal(_G)
MONS:   white imp
MAP
..1..
.111.
11O11
.111.
..1..
ENDMAP

NAME:   portal_ice_cave_entry_animals_and_master
TAGS:   patrolling no_monster_gen
DEPTH:  D:11-13, Lair:3-, Orc
WEIGHT: 5
: ice_cave_portal(_G)
MONS:   wolf, yak, polar bear, rime drake, ice dragon
SUBST:  D = 12 .:1, E = 2 3:5 .:1, F = 3 4:2, H = 4:8 5:2
MAP
xx    xxxxxxx
axxxxxxaaaaaxx
aaxaaaaa...aax
@aaaaDa.E.F.ax
a.a..D...O.Hax
aa.aaaD.E.F.ax
xaaaaa.a...aax
xxxxxaaaaaaaxx
    xxxxxxxxx
ENDMAP

NAME:   portal_ice_cave_demonic_guard
TAGS:   patrolling no_monster_gen
: ice_cave_portal(_G)
MONS:   ice devil
MAP
xxxxxxxxx
xaaaaaaax
xa..O..ax
xa.....ax
xa.1.1.ax
xa.....ax
xaaa.aaax
xxaa.aaxx
xxa...axx
xxa+a+axx
ENDMAP

NAME:   portal_ice_cave_rime
TAGS:   patrolling no_monster_gen no_pool_fixup transparent
: ice_cave_portal(_G)
MONS:   rime drake
MAP
  '''''
 wwwww''
'waaaaa''
'waO1...'
'wa1....w
'wa...wa'
''a..waw
 ''..aw
  ''w'
ENDMAP

NAME:   portal_ice_cave_entry_guarded_snowflake
TAGS:   no_monster_gen transparent
: ice_cave_portal(_G)
MONS:   polar bear, rime drake
MAP
.....a.....
.a...a...a.
...aa.aa...
..a.a.a.a..
..aa...aa..
aa..1O2..aa
..aa...aa..
..a.a.a.a..
...aa.aa...
.a...a...a.
.....a.....
ENDMAP

###############################################################################
# Entry vaults that only place hard ice cave entrances

default-depth: Elf, Swamp, Shoals, Snake, Spider

NAME:   portal_ice_cave_entry_pillars_three
TAGS:   transparent
: ice_cave_portal(_G)
MAP
   ...
....a...
.a...aa.
..aaOaa..
 .aa...a.
 ...a....
   ...
ENDMAP

NAME:   portal_ice_cave_entry_pillars_four
TAGS:   transparent
: ice_cave_portal(_G)
MAP
   ...
  .a.a.
 .a.a.a.
.a.a.a.a.
..a.O.a..
.a.a.a.a.
 .a.a.a.
  .a.a.
   ...
ENDMAP

NAME:   portal_ice_cave_entry_horrid_things
TAGS:   patrolling no_monster_gen transparent
DEPTH:  Elf, Snake, Swamp
WEIGHT: 5
: ice_cave_portal(_G)
MONS:   white ugly thing, freezing wraith, azure jelly / white very ugly thing
SUBST:  1 = 1., 2 = 2 .:3, 3 = 3:3 2:7
MAP
xxxxxxxxxxxxxxxxxxxxxxx
xxaaaaaxaaaaaaaaaaxxxxx
xaa...aaa........aaxxxx
xa.....a....2..1..aaaaa
xa..O..+..3...1.1.....+
xa.....a....2..1..aaaaa
xaa...aaa........aaxxxx
xxaaaaaxaaaaaaaaaaxxxxx
xxxxxxxxxxxxxxxxxxxxxxx
ENDMAP

NAME:   portal_ice_cave_entry_ice_statue_one
TAGS:   no_monster_gen no_pool_fixup transparent
: ice_cave_portal(_G)
MONS:   ice statue
KFEAT:  ^ = web trap
: if you.in_branch("Swamp") then
SUBST:  + = ., x = t
: elseif you.in_branch("Shoals") then
SUBST:  x = w
: elseif you.in_branch("Spider") then
SUBST:  + = ^
: end
MAP
 xxxxxxx
xxaaaaaxx
xaa...aax
xa..O..ax
xa.....ax
xa..1..ax
xa.....ax
xaa...aax
xxaa+aaxx
ENDMAP

NAME:   portal_ice_cave_entry_ice_statue_two
TAGS:   transparent patrolling no_monster_gen
: ice_cave_portal(_G)
MONS:   ice statue, ice dragon
SUBST:  2 = 1:9 2:1
MAP
   .....
 .........
...........
.....1.....
.....O.....
.....2.....
...........
 .........
   .....
ENDMAP

NAME:   portal_ice_cave_entry_dragon
TAGS:   no_monster_gen no_pool_fixup patrolling
MONS:   ice dragon
: ice_cave_portal(_G)
: if you.in_branch("Swamp") then
SUBST:  x = t
: elseif you.in_branch("Shoals") then
SUBST:  x = w
: end
MAP
xxxxxxxx
xaaaaaxx
xaO..aax
xa.1a.ax
xa.a..a@
xaa..a.'
xxaaa..'
xxxx@'''
ENDMAP

NAME:   portal_ice_cave_entry_frozen_things
TAGS:   no_monster_gen transparent
MONS:   freezing wraith, azure jelly
SUBST:  2 = 12.
: ice_cave_portal(_G)
MAP
  '''''
 ''aaa''
''aaOaa''
'aa.2.aa'
'a.....a'
'a.1.1.a'
'aaa.aaa'
'aaa.aaa'
'aaa+aaa'
'''''''''
ENDMAP

NAME:     portal_ice_cave_entry_ugly_swarm
TAGS:     no_monster_gen transparent patrolling
MONS:     white ugly thing, white very ugly thing
SHUFFLE:  ABC
SUBST:    a = aa.
NSUBST:   1 = 12 / 4=1 / ., . = 8=1. / .
: ice_cave_portal(_G)
MAP
    '''''''
   '''''''''
  '''.....'''
 '''.a.a.a.'''
'''.........'''
''.a..111..a.''
''...11111...''
''.a.11O11.a.''
''...11111...''
''.a..111..a.''
'''.........'''
 '''.a.a.a.'''
  '''.....'''
   '''''''''
    '''''''
ENDMAP

###############################################################################
#
# <<2>> Ice Cave maps.
#
# Ice caves feature monsters that have some form of ice-themed attack, or at
# least convey a sense that they could survive in a cold place. Terrain-wise,
# ice caves have white-colored walls and sometimes use freezing vapour machines
# and deep water. All maps should have an escape very close to the start, so
# the player can back away if the challenge is deemed too much to handle. Many
# maps place equipment at early or midway points that grants cold resistance,
# so that players lacking that might have a better chance to complete the map.
# Many maps have randomized shortcuts through deep water or freezing vapour
# machines that let the player bypass difficult portions of the map, or use the
# water or clouds to their advantage.
#
# Ideally all maps will implement an easy and a hard variant, checking the
# variable dgn.persist.ice_cave_hard, which is true for hard ice caves. Easy
# ice caves should be challenging but completable for most characters in the
# mid Dungeon, Lair, and Orc. Hard ice caves should be challenging for
# characters in late Dungeon, Lair Branches, and Elf. If a map concept can
# somehow only work at one of the two difficulties, it should veto for the
# other difficulty. For example, an easy-only map would veto for hard ice caves
# with:
#
#     veto {{ return dgn.persist.ice_cave_hard }}
#
# All maps should also call the function ice_cave_appearance() at the end of
# their statements define the exit feature and terrain appearance.
#
###############################################################################

default-depth: IceCv

###############################################################################
# The small caves.
#
# A set of maps with "small" cave systems that feature a specific theme and a
# main path without many chokepoints. They feature an early or midway point one
# can reach for some loot if more difficult challenge at the end can't be
# finished.

# Foes: Natural monster set with one frost giant for easy difficulty and two or
# more for hard difficulty.
#
# Loot: Common ice cave loot set, with an emphasis on weapons, plus some
# potions.
NAME:    ice_cave_small_giant
TAGS:    no_item_gen no_monster_gen no_pool_fixup
ORIENT:  encompass
: ice_cave_common_loot(_G)
: kitem("j = " .. dgn.loot_potions)
: ice_cave_natural_monster_set(_G)
# For easy ice cave, always one frost giant and the potion area has fewer
# monsters with only 33% chance for the 6 glyph miniboss. For hard ice cave,
# minimum of two frost giants, with 25% each for up to two more, and the potion
# area has more monsters and always has a miniboss.
: if dgn.persist.ice_cave_hard then
NSUBST:  E8 = 2=7 / 7..., F = 6 / 5 / 2=5. / 4=12.. / .
: else
NSUBST:  F = 556 / 2=5. / 2=12.. / .
: end
NSUBST:  D = 45
# Randomize tunnel layout and the loot composition and locations.
SHUFFLE: "w / 'a
SUBST:   'a = x, j = j.
NSUBST:  d = 3=def... / 5=gh.. / 2=i. / .
: ice_cave_appearance(_G)
MAP
                  xxxxx        xxxxxxxx
                xxx...xxxx  xxxx1D....xx
         xxxxxxxx...x....xxxx...D.x....xxxx
      xxxx......1..xxxx...xD1D.xxxxxxx...1xxxx
     xx.......1..4.xxxxxx....xxxxxxxxxxxxD1..xxx
   xxx...xxxxE8E2....xxxxxxxxxxxxxxxxxxxxxx....xxx
  xx...xxxddxxE5..1...xxxxxxxxxxxxxxxxxxxxxxx....xxx
  x...xxdddddxx..1.....xxxxxxxxxxxxxxxxxxxxxxxx....x
  x...x$$$$dddx.......xxxxxxxxxxxxxxxxxxxxxxxxxxx..x
  x...x....$$xx.....xxxxxxxxxxxxxxxxxxxxxxxxxxxx11xx
  xx.......xxx.....xxxxxxxxxxxxxxxxxxxxxxxxxx...Dxx
   xx............xxxxxxxxxxxxxxxxxxxxxxxxx......xx
 xxx"xx.........x'aaaxxxxxxxxxxxxxxxxxxx...x.xxxx
 xwwwxxxxxxxxxxxxxaaaxxxxxxxxxxxxxxxxxx..xxxxx
 xxwwwxxxxxxxxxaaaaaxxxxxxxxxxxxxxxxxx..xx
 xwwwwxxxxxxxxxxxaaa'xxxxxxxxxxxxxxx3...xxx
 xwwwxxxxxxxxxxxxxx'x'xxxxxxxxxxxxx.......xxx
xxwwxxxxxxxxxxxxxxxx'xxxxxxx"xxxxxxxx.......xxx
x""xxxxxxxxxxxxxxxx''xxxxx"""xxxxxxxxx....D...xx
xx""xxxxxxxxxxxxxx''xxxxxx"""""..xxxxxxxD......x
 xx""xxxxxxxxxxxx'x'xxxx"""xxx.......xxx.......x
  x"x"xxxxxxxxxxx''xxxxx"xx'''xx......24x.....xx
  xx"""xxxxxxxxxxx''xxx""x''x'''x....1..2....xx
   xxx""""xxxxxxxxx''xx"xx''xxxxxx.1......1.xx
     xxx"x"xxxxxxxxx'xx""xx''xx  xx.x....x.xx
      xxx"xxxxxxxxx''x""xxxx''xx  xxxx..xxxx
     xx"""xxxxxxxx'x'x"x"xxxx''xx   xx..x
    xx""xxxxxxxxxx''xxx"x"xxxx''x  xx..xx
   xx""x"xxxxxxxxxx''xxx""xxx''xx  x..xx
  xx""x"xxxxxxxxxxxx'xxxx""x''xx   x...xx
  x""xxxxxxxxxxxxxx'x'xxxx""'xx    xx...xx
  x"x"xxxxxxxxxxxxxx'''xxxx..x      xx12.x
 xx""xxxxxxxxxxxxxxxx'xF.xF.xx      xx1.1x
xx""xxxxxxxxxxxxxxxxxxFjx.xxx       x...xx
x""xxxxxxxxxxxxxxxxF.xjxjxFxx      xx...xx
x"x"xxxxxxxxxxxxxxx.xjxjxjFxx     xx.....xx
xx"x"xxxx""x"xxxxxx".F.F.Fxx      x...A...x
 xx""""x""""x""x""""xxxxxxx       x.......x
  xxxx"""xxx"x""""xxx             xx..<..xx
     xxxxx xxxxxxxx                xx...xx
                                    xxxxx
ENDMAP

# Foes: Icy dragon-themed monsters. End boss is either a dragon, with ice
# dragon for easy, golden for hard, or white draconian, with ordinary draconian
# for easy, draconian knight for hard.
#
# Loot: A lot of gold, some jewellery, and possible items from the common loot
# set.
NAME:    ice_cave_small_dragons
TAGS:    no_item_gen no_monster_gen no_pool_fixup
ORIENT:  encompass
: ice_cave_common_loot(_G)
KITEM:   j = any jewellery
# For easy ice caves, there are two ice statues, the boss is white draconian
# instead of ice dragon half the time, and the higher quality jewellery is
# good_item. For hard ice cave, there is one orange crystal statue and another
# tier 2 monster, whenand the high quality jewellery is always randart.
: if dgn.persist.ice_cave_hard then
KITEM:   k = any jewellery randart
MONS:    lindwurm simulacrum / ice dragon simulacrum \
         / storm dragon simulacrum / golden dragon simulacrum
MONS:    ice dragon, orange crystal statue, golden dragon
{{
kmons("D = white draconian ; " ..
    dgn.random_item_def({["scimitar"] = 2, ["halberd"] = 2, ["broad axe"] = 1,
       ["morningstar"] = 2}, "freezing", nil, "|") .. " . cloak")
kmons("E = white draconian knight ; " ..
    dgn.monster_weapon("knight", "freezing", "good_item", "|") ..
    " . cloak good_item")
set_random_mon_list("lindwurm simulacrum / swamp dragon simulacrum \
                     / ice dragon simulacrum / golden dragon simulacrum \
                     / white draconian / ice dragon")
}}
# 50% chance for dragons vs draconians.
NSUBST:  3 = 3 / 2
SHUFFLE: 24 / DE
: else
KITEM:   k = any jewellery good_item
MONS:    steam dragon simulacrum / acid dragon simulacrum \
         / komodo dragon simulacrum / lindwurm simulacrum w:5
MONS:    rime drake, ice statue, ice dragon, white draconian
{{
set_random_mon_list("steam dragon simulacrum / acid dragon simulacrum \
    / komodo dragon simulacrum / lindwurm simulacrum \
                     / rime drake w:20")
}}
# 50% chance for a white draconian boss instead of an ice dragon.
SUBST:   4 = 45
: end
# Two guaranteed jewellery with 4 pieces on average.
NSUBST:  j = j / *=j$$$, k = k / *=k$$$
# Make each of d through i have about a 50% chance of placing, and reduce the
# gold placed to about 22 piles on-average.
SUBST:   $ = $:440 d e f g h i .:140
# Randomize the winding tunnels.
SHUFFLE: 'w / "a
SUBST:   "a = x
: ice_cave_appearance(_G)
MAP
                         xxxxxxxx
                      xxxx......xxxx
                     xx......x....1xxx
                     x...xx.xxx..12..xxx
                   xxxxx..xxx$$..24..jkxx
                  xx...xx.xx$$$$1...jkjjx
                  xx.x....x$$$$$$$.jkjjxx
                 xx..xxx.xxxx$$$$$$xxx''x
              xxxx11xxxxxxxxxxxxxxxxxwx'x
           xxxx.111xxxxxxxxxxxxxxxxwwwwwxx
         xxx.....1xxxxxxxxxxxxxxxxwwwwwwxxx
        xx...xxxxxxxxxxxxxxxxxxxxxxwwwwxxxx
       xx..xxxxxxxxxxxxxxxxxxxxxxxxx'xxxxxx
     xxx..xxxxxxxxxxxxxxxxxxxxxxxxx..xxxxx
   xxx....xxxxxxxxxxx"xxxxxx""""x....xxxxx
  xx........xxxxxxxx"""x"x"""x"x.'xx.xxxx
 xx...........xxxx"""x""x""xxxx"x''xx""xx
xx..............x""xxxxx"xxxxxxxxx''xx""xx
x.......2........xxxxxxxxxxxxxxxxxx''x"x"x
x.................xxxxxxxxxxxxxxxxxx'xx"xx
xx....1.1.1.....x'''xxxxxxxxxxxxxx'''x""x
 xx.............xxx''xx''xxxx'''x'x'xx"xx
  xx..........xxxxxx'''''''x''x''''xx""x
   xx3x....x3xxxxxxxx'xxxx'''1xxxxx"""xx
    xxxx..xxxxxxxxxxxxxxxxx$$$xxx""""xx
      xx..xxxxxxxxxxxxx"""1$2*$xx"x"xx
     xx..xxxxxxxxxxxxx""x"1$$|$1xx"xx
     x..xxxx"xxxxxxxxx""xxx1x1x""""x
     x...x"""""xxxxxxxx"""xxxxxx"xxx
     xx..."x"x"""xxxxx"x""x    xxx
      xx.1.xxxxx"""x"xx""xx
      xx1.1x   xxx""""""xx
      x...xx     xxxx"xxx
     xx...xx        xxx
    xx.....xx
    x...A...x
    x.......x
    xx..<..xx
     xx...xx
      xxxxx
ENDMAP

# Foes: Undead + demons set. For easy ice caves, a necromancer boss, and for
# hard ice caves, the necromancer is a sub boss with a lich end boss.
#
# Loot: Common loot set along with a necromancy loot item.
NAME:    ice_cave_small_necro
TAGS:    no_item_gen no_monster_gen no_pool_fixup
ORIENT:  encompass
KPROP:   yY'j = bloody
: ice_cave_common_loot(_G)
: ice_cave_necro_loot(_G)
: ice_cave_undead_demon_monster_set(_G)
KMONS:   D = necromancer
KFEAT:   _ = altar_kikubaaqudgha
KFEAT:   ^ = alarm trap
KFEAT:   y = x
KFEAT:   " = +
# For the easy ice cave, necromancer + elephants as boss, second area gets a
# mix of appropriate monsters. For the hard ice cave, lich and friends as boss
# and necromancer + dire elephants + friends in second area.
: if dgn.persist.ice_cave_hard then
KMONS:   E = lich
SUBST:   D = E, K = D
:else
SUBST:   K = 5
:end
SHUFFLE: fghi, def
SUBST:   f = f*, N = 456, - = ........^
# Set up two shortcuts, each with a 50% to be open. Each open shortcut has a
# 50% chance to be open space with a freezing cloud machine and a 50% chance to
# be deep water.
SHUFFLE: apq / aa! / zzz / zzz
SUBST:   a = ., pq = w, z = x
: place_freezing_vapour_machine(_G, 8)
# Replace this glyph with floor so we can re-use it.
SUBST:   ! = .
SHUFFLE: rsu / rr! / zzz / zzz
SUBST:   r = ., su = w, z = x
: place_freezing_vapour_machine(_G, 12)
: ice_cave_appearance(_G)
MAP
                          xxxxxx
                        xxx....xx
                      xxx.......x
              xxxxxx xx...xxx..xx
             xxpqppxxx...xxx..xx
            xxppppxxx...xxx..xx
    xxxxxxxxxpqpxaaxN..xxx...x
   xx.G...G.aappxx...Nxxxx..xx     xxxxx
xxxx.........xxxx....xxxxx...xxx xxx...xxxx
xfx....2_424.xxxx..xxxxxxxx....xxx...2....xx
x*+.....K...2xxxx...xxxxxxxx.......2.1.2...xx
xgx....52N.N42xxxx.N.xxxxxxxxxx...1.....1...x
xxxx..4...N24xxxxxxxN..xxxxxxxxx............x
   xxxG5.4G...xxxxxxxx...xxxxxxxx2........2xx
     xxxxxx....xxxxxxxx....xxxxxxx1x....x1xx
          xxx...xx.xxxxxx....xxxxxxxx..xxxx
   xyyyyyxx....xx...xxxxxxx...xxxxxxx..x
   xyYj'yxx..xxx..x..xxxxxxxx..xxxxx..xx
   xyyy"yxxx.....xxx.....xxx..xxsxx..xx
  xxN.'''Nxxx...xxxxx........xxxssr...xx
 xx...4D4.2xxxxxxxxxG.N..N...xxssurx...xx
xx.2x$**$x.2xxxxxxd%...1.....xxsssxxx.22x
x..2xxhixx2..xxxxxe%....N....rsusssxx2.2x
x....xxxx...xxxxxxxxx.......xrxsssxx...xx
xxx.........xxxxxxxxxxx...xxxxsssxxx...xx
  x...3....xxxxxxxxxxxxx..xxxxxxxxx.....xx
  xx------xxxxx.xxxxxxxxxx..xx   x...A...x
   xx----xxxxx....xxxxx..x...xx  x.......x
    x---xx.x...xx....x.....xxx   xx..<..xx
    xx.......xxxxxx....xxxxx      xx...xx
     xxx.xx.xx    xxxxxx           xxxxx
       xxxxxx
ENDMAP

# Foes: Undead + demon set with a demonic boss.
# Loot: Common loot set.
NAME:    ice_cave_small_demon
TAGS:    no_item_gen no_monster_gen no_pool_fixup
ORIENT:  encompass
: ice_cave_common_loot(_G)
: ice_cave_undead_demon_monster_set(_G, "E")
# For hard ice caves, place an obsidian statue and a 50% chance for an OCS.
# fiend. For the boss, 50% chance for either reapers or ice fiend. If reapers,
# two guaranteed and 33% each for up to two more. If ice fiend, 50% chance for
# a second. For easy ice caves, always place a single reaper.
: if dgn.persist.ice_cave_hard then
KMONS:   D = orange crystal statue
SHUFFLE: EF / 8H
NSUBST:  3 = 3 / D4, F = E / E.., H = 8. / .
: else
SUBST:   6 = 56
: end
SHUFFLE: dg, fh
SUBST:   i = e|ii
# Place middle-tier monsters and cloud generators in the boss chamber.
SHUFFLE: JK / LM / NO / PQ / RS
SUBST:   JL = 44., KM = !, MNOPQR = ., Z = 25
: place_freezing_vapour_machine(_G)
# Add in 1s and 2s throughout the map, doing this last so we have more space.
NSUBST:  . = 6=1 / 6=1. / 2 / 2=2. / .
# Set up two shortcuts, each with a 50% to be open. Each open shortcut has a
# 50% chance to be open space with a freezing vapour machine and a 50% chance
# to be deep water.
SHUFFLE: apq / aa! / zzz / zzz
SUBST:   a = ., pq = w, z = x
: place_freezing_vapour_machine(_G, 12)
# Replace this glyph with floor so we can re-use it.
SUBST:   ! = .
SHUFFLE: rsu / rr! / zzz / zzz
SUBST:   r = ., su = w, z = x, b = bbccc
: place_freezing_vapour_machine(_G, 8)
TILE:    b = bedevilled_crystal_cocytus
: set_feature_name("crystal_wall", "bedevilled crystal wall")
: ice_cave_appearance(_G)
MAP
                    xxxxxx
                  xxx....xxx
                 xx........xxx
                xx....xxx....xx
  xxxxx         x...xxx6xxx...xxx
 xx...xxxxx     x...xx4...xxxx..xx
xx.4..2...xx xxxxxx..xx....2xx...x
x1......1..xxx.x...........gxxx..x
xx..........x.........xx..dxx...xx
x.1.....1.......xxrxxxxxxxxx...xx
xx............xxxsssxxxxxxx...xx
 x..........xxxxssuxxxxxxK..xxx
 x3x....x3xxxxxxxxrr....J..xx
 xxxx..xxxxxxxxxx......JKJ..xxx
   xx..axxpxxxx....xx.........xxx
  xx..xapqpax.....xx..xxxx..Q...xx
  x..xxpppxaZ.M.x.....N..x...P...xx
  x...xxxxxx..L.xxx..O.N.xx.PQP..Zxx
  xx...xxxxxZLML..xx..N...xx.......x
   xx.-.xxxxx.........x.O........Zxx
   xx---xxxxxx...xxx..x..xxx.....xx
   x---xxxxxxxxxxx....x.....x..xxx
  xx---xxxxxxxxx...S..x.....xxxx
 xx-----xxxxxxxxx.xx.R...Sxxx
 x---A---xxxxxccccc.R.R.ccccc
 x-------xxxxxc*.$cccFccc$.*c
 xx--<--xxxxxxc.....FEF.....c
  xx---xxxxxxxcf.$cc*i*cc$.hc
   xxxxxxxxxxxcccccccbccccccc
         xxxxx
ENDMAP

# This is an ice cave which is also a tomb of a necromancer who likes staying
# alive and simulacrums, or just a chillout of an ice fiend. By Zaba.
#
# Foes: Undead + demon set with necromancer + bog body or demon boss for easy
# ice caves, or either reapers or fiend for hard ice caves.
#
# Loot: Common loot set with a necromancy themed item.
NAME:    ice_cave_tombish
TAGS:    no_item_gen no_monster_gen
ORIENT:  encompass
: ice_cave_common_loot(_G)
: ice_cave_necro_loot(_G)
# Scroll loot under statues.
KITEM:   3 = any scroll
: kitem("D8 = " .. dgn.loot_scrolls)
KITEM:   D = any scroll
# For easy ice caves, small chance for freezing wraiths in tomb area. For the
# boss, a 50% chance for either necromancer plus bog body or reaper. For hard
# ice caves, bog bodies in tomb area. The boss is 50% chance reapers versus one
# or two ice fiends. For reapers, minimum of two, 33% chance each for up to two
# more. For ice fiend, minimum of one and 50% chance for another.
: if dgn.persist.ice_cave_hard then
: ice_cave_undead_demon_monster_set(_G)
: kmons("D7 = reaper ; " .. scythe("freezing") .. " plus:-6")
SHUFFLE: D7 / 88
NSUBST:  7 = 7 / 7.., 8 = 8 / 8. / .
NSUBST:  4 = 6 / 446, F = 122445
: else
: ice_cave_undead_demon_monster_set(_G)
KMONS:   D = necromancer
SHUFFLE: D7 / 88
NSUBST:  7 = 7 / ., 8 = 8 / .
SUBST:   4 = 4:70 6, F = .12244
: end
# Shuffle main loot chamber items, and then the locations of the non-necro loot
# items to possibly be at other locations and to possibly include magical loot.
SHUFFLE: fghi, defgh
SUBST:   d = d*, e = e*, f = f*, g = g*, h = h*
# A little extra decor opportunity...
SUBST:   S : SSG
: vault_metal_statue_setup(_G, "S", "icy conduit")
: ice_cave_appearance(_G)
MAP
      xxxxx
     xx...xx
    xx.....xx
    x...A...x
    x...<...x
    xx.....xx
     xx...xx
      x...xx
      xx..1x
      xx..1x
      x...xx
   xxxx...xxxx
  xx3x.....x3xx
 xx...........xx
 x.............x
xx.............xx
x.......F.......x
x....F.....F....x
x.......U.......x
x....F.....F....x
x.......F.......x
xx.............xx
 x.cnnc...cnnc.x
 xxc44c...c44cxx
  xcVdcc+cceVcx
  ccc+c...c+ccc
  c...c...c...c
ccc.ccc...ccc.ccc
c...c5c...c5c...c
c+ccc+c...c+ccc+c
c.c5+.......+5c.c
c.ccc.G...G.ccc.c
c.c5+.......+5c.c
c.ccc.G...G.ccc.c
c.+...........+.c
c.ccc.G...G.ccc.c
c.c5+.......+5c.c
c.ccc.G...G.ccc.c
c.c5+.......+5c.c
c+cccccc+cccccc+c
c...............c
ccccS.ccccc.Scccc
   cc.cfDgc.cc
    c.c7U7c.c
    c.ch7ic.c
    c.cc+cc.c
    c.......c
    ccccVcccc
       ccc
ENDMAP

############################################################################
# The sprawling caverns.
#
# A winding, tight cavern with a hard challenge at the end. You can always go
# back to the beginning to retreat. The caverns are more rare than the caves.
#
# Details below are common to all caverns maps we have thus far.
# Foes: 50% chance each of either the undead+demons set or the natural set.
# Loot: Common loot set plus random wands/misc, potions, and scrolls.

NAME:    ice_cave_caverns_01
TAGS:    no_item_gen no_monster_gen no_pool_fixup
ORIENT:  encompass
: ice_cave_common_loot(_G)
: kitem("j = any wand / any potion w:5 / any scroll w:5")
: kitem("k = any misc / " .. dgn.loot_potions .. " / " .. dgn.loot_scrolls)
# Pick one of two themes, undead/demons or natural monsters.
: if crawl.coinflip() then
:     ice_cave_undead_demon_monster_set(_G)
: else
:     ice_cave_natural_monster_set(_G)
: end
# Randomize bosses tiers and shuffle statue monster and miniboss locations.
SHUFFLE: 7F / F8, 3H / UJ
# For easy ice caves, 33% chance for the "miniboss" fight to be a solo 6,
# otherwise two or three tier 5s. For the boss, either a fight with two tier 7
# or one tier 8, along with other friends. For hard ice cave, the miniboss is
# always includes a 6 tier along with one to two tier 5s. For the boss, still
# two tier 7s or one tier 8.
: if dgn.persist.ice_cave_hard then
NSUBST:  J = 6 / 5.
: else
SUBST:   J : JJK
NSUBST:  J = 2=5 / 5., K = 6 / .
: end
# Randomize loot so that two armour pieces will be at various places in the
# map, and randomize loot locations at the end stash.
SHUFFLE: efghi, def
SUBST:   D = 12, E = 2 4:2 5:5, 2 = 2 .:5
# Choose one of two possible paths to open up.
SHUFFLE: '-
SUBST:   ' = x
# Set up three shortcuts, each with a 50% to be open. Each open shortcut has a
# 50% chance to be open space with a freezing vapour machine and a 50% chance
# to be deep water.
SHUFFLE: apq / aa! / ZZZ / ZZZ
SUBST:   a = ., pq = w, Z = x
: place_freezing_vapour_machine(_G, 12)
# Replace this glyph with floor so we can re-use it.
SUBST:   ! = .
SHUFFLE: rsu / rr! / ZZZ / ZZZ
SUBST:   r = ., su = w, Z = x
: place_freezing_vapour_machine(_G, 12)
SUBST:   ! = .
SHUFFLE: yz" / yy! / ZZZ / ZZZ
SUBST:   y = ., z" = w, Z = x
: place_freezing_vapour_machine(_G, 12)
: ice_cave_appearance(_G)
MAP
   xxx         xxxx     xxxx xxxx
 xxx.xx       xx-'xx  xxxppxxxppxxxxx xxxx      xxxxxxxxxx      xxx
xx....x    xxxx....xxxxppppppppppxx*xxx$$xxxxxxxx...xx...xxxxxxxxkxx
x...A.xxxxxx....xx....xxpppppppaaa*x*xxx$$x-.x...xx...xx...xxxxxjxjx
x.<....'-....xxxxxxx...aaqppqppqpxx*x.xxxx.'x..xxxxxxxxxx....Hxxx.xx
xx..xx....xxxxxxxx1111xxppppppppppxxxx...xxxxx..xxxxxxxxxx..3.Hx.xx
xxxxxxxxxxxxxxx....xxxxxxxxppppppxx11..x...x..xxxxxxxxxxxxx....Hxx
        xxx.....xxxx------xxppxxxxD1xxxxxx..xxxxxxxxxxxxxx...xxyxxx
     xxxx..xxxxxx---xx-----xxxx...xxxxxxxxxxxxxxxxxxxxxxx...xxxzzzx
   xxx....xxxxx--xxxxxxxx---xx..xxxxxxxxxxxxxxxxxxxxxx....xxxxzzzxxx
  xx...xxxxxxx-xxxx....xxx--xxx..xxxxxxxxxxxxxxx....x...xxxxxzzxz"zxx
xxx..xxxxxxxx-xxx...xx...xxx-xxx..xxxxxxxxxxx...xx....xxxxxxxxxxxxzzx
x...xxxxxxxxxx-...x.xxxx...xx-x..xxxxxxxxxxx..xxxxxxxxxxxxxxxx.xxxyzx
x..xxxxxxxxxxx1E1xxxjxxxx...x-xx.11xxxxxxxxxx...xxxxxxxxxe.*x.x.xxyxx
xx..xxxxxxxxx...xxxdxxx...xxx-xxxxD1xxxxxxxxxx..1.xxxxxx.JUJ.xxx..x
xx..xxxxxxxxx....xxxx..xxxwxx-xx...xxxxxxxxxxxx.1..xxxxxx..Jxx..xxx
 x..xxxxxxxxx'x.xxxxxD...xxwwx-xxxx1.xxxxxxxxxxxxDE.D.xxxxx..xx...xx
 x...xxxxxxx..'xxxxxxx1..Dxxwwx--xxxD.xxsxsxxxxxxxD.E1.xxxx..xxxE5Exx
 xx..-xxxxx..xxxxxxxxxxxD.1xxwwxx---11rrssssxxxxxxxx.D..x...xxxD7F7Dx
  x...-xx-..xxxxxxxxxxxx-x1.xxwwxx'''xxxsssusssxxxxxxx-...xxxxxxD5Dxxx
  x...x--xx..1xxxxxxxx--x-..'xxwx'x'xxxxxxssssssssxx..xxxxx.xxx..xxx|x
  x222x''x''x..xx1xxx----xxxx'xx'''xx    xxssussusrrx.xxxx.<.xxx.$*fgx
  xx'.'xx'xx1.x.1...2xxxxx  xx'''xxx      xxxssssssxxx''........x|hikx
   xxxxxxxxxxxxxxxxxxx       xx'xx          xssxsxxx xxxxxx.xxxxxxxxxx
                              xxx           xxxxxx        xxx
ENDMAP

# See ice_cave_caverns_01 for comments on most statements; only statements
# different in this map are commented.
NAME:    ice_cave_caverns_02
TAGS:    no_item_gen no_monster_gen no_pool_fixup
ORIENT:  encompass
: ice_cave_common_loot(_G)
: kitem("j = any wand / any potion w:5 / any scroll w:5")
: kitem("k = any misc / " .. dgn.loot_potions .. " / " .. dgn.loot_scrolls)
: if crawl.coinflip() then
:     ice_cave_undead_demon_monster_set(_G)
: else
:     ice_cave_natural_monster_set(_G)
: end
KFEAT:   y = w
SHUFFLE: 7F / F8, 3H / UJ
: if dgn.persist.ice_cave_hard then
NSUBST:  J = 6 / 5.
: else
SUBST:   J : JJK
NSUBST:  J = 2=5 / 5., K = 6 / .
: end
SHUFFLE: fghik, def
SUBST:   D = 12, E = 2 4:2 5:5, 2 = 2 .:5
SHUFFLE: '-
SUBST:   '=x
# A fixed shortcut through a freezing vapour generators with a 50% chance to
# place.
SUBST:   r = rx
: place_freezing_vapour_machine(_G, 6, "r")
# Two shortcut set up in a similar fashion to ice_cave_caverns_01.
SHUFFLE: apq / aa! / zzz / zzz
SUBST:   a = ., pq = w, z = x
: place_freezing_vapour_machine(_G, 8)
SUBST:   ! = .
SHUFFLE: suy / ss! / zzz / zzz
SUBST:   s = ., uy = w, z = x
: place_freezing_vapour_machine(_G, 12)
: ice_cave_appearance(_G)
MAP
 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxx    xxxxxxxx    xxxxxxxx
 x..xappppxax.x.'x-.xD..Dxxxxxxxxxx....x.Wxxxxxx1DE1D.xx  xx......xx
 x.<.xppqpax...x.x.x.x1D.Dxxxxxxx'''..x.xxWWxx1DxxD.E1.xxxx..xxxJJJxx
 xx..xxppxx..xxx-.'xx.xxD.1xxxx'''xxx.-xxxxWWWxxxxxx....x...xxxe.U.*x
  x.A.xxxx..xxxxxxxwwwwxxx1.x'''xxxxx---xxxxWWwwwwwxxx-...xxxxxx...xx
  x...xxxxx...xxxxxwwwwwxx..'xxxxxxxxxx--xxwwwwwwwxx--xxxxxxxxx..xxx
  x...xxxxxxx..xx1-'xxwwxxx--xxxxx'''x--xxwwwwwwwxx'x-xxxx..xxxx..x
  xx.11xxxxx1.x...1.2xxwx---xx.*.*.xx..xxxwwwwwwwww'.x.x..xx.x..xxx
  x11.xxxxxxxx1xxxxx1.xxxx--x.j.T.j.xxx..xwwwwwwwwx'x-..xxxxx.xxx
  xx..xxxxxxxx2..1x11..xxxx-...*.*..xx...xxwwwwwwx'...xxx   xxx
   xx.xxxxxxxxxxxx.xxx..xxxx...xxxxxxxxx..xxwwwxxx.-xxx
xxxxx..xxxx.x*...xxxx...xxxxxx.-xxxxxxx1xxxxxxxxx..xx
xdx$xx..xr....-'..xxxxx..xxx''.-xxxxx.Dxxxxsxxxxxx..xxx
xx$x.xx..xx..xxxx..xxxxxx..''xx--xxxx11Dsxuuuuxxxxx...xxx
x$x..x....xx..xxx..xxxxxxx--xxxx-xx.1.xxsuuuuuuxxxxx....xxx
xx.xx.x..xxx..xx.HHxxxxxxxx1.xxxx...xxxxxuyuuuxxxxxxx.D.5.xx
xxxxxx..xxxx...xxH3.xxxxxx'-.1x'''xxxxxxuuuuyuuxxxxxx.DE.D.xx
   xx..xxxx...xxxx...xxxx..x..''xxxxxxxxxuuuusxxx$$x.5E.D...xx
   x...xx...xxxx.x.xxxxx...x.xxxx  xxxxxxuxuxsxi*$$...7F7.xx.xxx
   x..xxD..xx  xx|x.xx...xx.xx      xxxxxxxxxxfk|$$$...xxxxxx..xxxxx
   x...2.2xx    xx....xxxxxxx        xxxxxxxxxxgh|$$$$.x    xxx....xxx
   xx11Dxxx     xxxxxxx                       xxxxxxxxxx      xxx...<x
    xxxxx                                                       xxxxxx
ENDMAP

# See ice_cave_caverns_01 for comments on most statements; only statements
# different in this map are commented.
NAME:    ice_cave_caverns_03
TAGS:    no_item_gen no_monster_gen no_pool_fixup
ORIENT:  encompass
: ice_cave_common_loot(_G)
: kitem("j = any wand / any potion w:5 / any scroll w:5")
: kitem("k = any misc / " .. dgn.loot_potions .. " / " .. dgn.loot_scrolls)
: if crawl.coinflip() then
:     ice_cave_undead_demon_monster_set(_G)
: else
:     ice_cave_natural_monster_set(_G)
: end
SHUFFLE: 7F / F8, 3H / UJ
: if dgn.persist.ice_cave_hard then
NSUBST:  J = 6 / 5.
: else
SUBST:   J : JJK
NSUBST:  J = 2=5 / 5., K = 6 / .
: end
SHUFFLE: fghik, def
SUBST:   D = 12, E = 2 4:2 5:5, 2 = 2 .:5
SHUFFLE: '-
# Two shortcut set up in a similar fashion to ice_cave_caverns_01.
SHUFFLE: apq / aa! / zzz / zzz
SUBST:   a = ., pq = w, z = x
: place_freezing_vapour_machine(_G, 8)
SUBST:   ! = .
SHUFFLE: rsu / rr! / zzz / zzz
SUBST:   r = ., su = w, z = x
: place_freezing_vapour_machine(_G, 12)
: ice_cave_appearance(_G)
MAP
                                 xxxxx
                                 x$e*xx      xxxxxxxxxx
                                 x.UJxxxxxxxxx...xx...xxx
                              xxxx.JJ..x..x...xx...xx.DDxxx
                              xWxxxxx....x..xxxxxxxxxx.DDExxx
                              xWxWxWW.xxxxx..xxxxxxxxxx.2D2Dx
                              xxWWWWxW..xx..xxxxxxxxxxxxE7F7x
                           xxxxWWxwWWxx...xxxxxxxxxxxxx.2Dxxx
                          xx.WWxxxxxrrxxxxxxxxxxxxxxxx...xx
               xxxxxxxxxxxx..xxxxsssssssssssxxxxxxx....xxxx
             xxx....xxxxxxxx..xxxssssusssssrr<...x...xx.xkxx
           xxx...xx...xxxxxxx..xxxxsssssussxxxx....xxxxxix|x
          xx.EEx.xxxxD1Dxxxx..xxx xxssssssxxxxxxxxxx  x$x$xhx
         xx.E.xxx$xxxxDDDxxxx...xx xxsxssxxx          xx|xgxx
         x...xxx$xxx11Dxxxxxxxx..x  xxxxxxx            xxfxx
         xx....xxxx..xxxxxxxxx...xx                     xxx
        xx.x.xxxpx....xxxxxxxxxx..xx
       xx...xxxppxx....xxxxxxx'''..xx
      xx..xxxxxpqpxxx...xxxx''xxxx.-xx
      x.1xxxxxapppppaxx..x'''xxxxx---xx
      xx.11xxxaxxxxxxa...''xxxxx'xxx--x
       xxx1.xx.xxxxxx-xx--xxxxx''''--xx
        x..x......xxxx---xx.*.*.xx..xxx
        xxx.xxxxx..xxxx--x.j.T.j.xxx..x
          x2..2x....xxxx-...*.*..xx...xx
       xxxxxxxx.xxx.1xxxx...xxxxxxxxx..x
      xx1x...'xxxx.1.xxxxxx.-xxxxxxx1xxx
  xxxxx1...-x..xxxxx11xxxx'.--x---1Dxx
 xx..<xx..xxxx..xxxxxx..''xx-x-xxx11Dx
 xA..xxxx..xxx..xxxxxxx--xxxx-xx.11xxx
 x....xxx..xx.HHxxxxxxxx1.xxx-...xxx
 x...xxxx...xxH3.xxxxxxxx.1x'''xxx
xx..xxxx21.xxxx...xxxx..x..''xxx
x...xx.12xxxxdx.xxxxx...x.xxxx
x..xx...xx  xx*x.xx...xx.xx
x......xx   xxx....xxxxxxx
xx...xxx     xxxxxxx
 xxxxxx
ENDMAP

###############################################################################
# The ice statue gardens.
#
# These vaults rely on devious placement of ice or orange crystal statues and
# forcing players to face them (if they want loot, that is).
#
# Foes: Simulacra, ice or orange crystal statue monsters, freezing wraiths, and
# white (very) ugly things.
#
# Loot: Some items from the common loot set, random items, star_item and
# superb_item.

# Previously called ice_cave_statue_garden_teleport, when it used the old
# teleporter lua feature.
NAME:   ice_cave_statue_garden_transporter
TAGS:   no_item_gen no_monster_gen no_pool_fixup
ORIENT: encompass
{{
ice_cave_common_loot(_G)
local simul = simulacrum_monsters()
mons(simul["animal"])
mons(simul["cruel"])
}}
# For easy ice caves, both statues are ice statues, and a freezing wraith has a
# 50% chance of replacing one of the two white ugly thing. For hard ice caves,
# there is one orange crystal statue with two freezing wraiths, always two
# white very ugly things, the first chamber has more cruel simulacra, and there
# are two more star_items.
: if dgn.persist.ice_cave_hard then
MONS:   orange crystal statue, freezing wraith, white very ugly thing
# 12 * 5 = 60 total weight for animal simulacra, 4 * 5 = 20 total weight for
# cruel simulacra, and 10 weight for freezing wraiths.
: set_random_mon_list(dgn.random_entry_arg(simul["animal"], "w:12") ..
:     " / " .. dgn.random_entry_arg(simul["cruel"], "w:5")  ..
:     " / freezing wraith")
SUBST:  1 = 112, 3 = 4, D = 3, E = *
NSUBST: % = * / %
:else
MONS:   ice statue, freezing wraith, white ugly thing
: set_random_mon_list(dgn.random_entry_arg(simul["animal"], "w:16") ..
:     " / " .. simul["cruel"])
NSUBST: 1 = 2=1 / 4=1112.... / ., 5 = 45 / 5
SUBST:  D = *
:end
SUBST:  d = def***, g = gh**, i = i*
MARKER: P = lua:transp_loc("statue_garden_entry")
MARKER: Q = lua:transp_dest_loc("statue_garden_entry")
MARKER: R = lua:transp_loc("statue_garden_exit")
MARKER: S = lua:transp_dest_loc("statue_garden_exit")
: ice_cave_appearance(_G)
MAP
ccccccccccccccc
cR..3EgDiE3..<c
c.....*|*.....c
ccG....5....Gcc
 ccG.......Gcc
  ccG..Q..Gcc
  xccnnnnnccx
 xx...GPG...xx
 x...%.S.%...x
xx.1..*d*..1.xx
x......%......x
x..1.G.5.G.1..x
x.............x
xx.1.1...1.1.xx
 x...........x
 x...........x
 xx.........xx
  xx...A...xx
   xx..<..xx
    xxxxxxx
ENDMAP

NAME:   ice_cave_statue_garden_chambered
TAGS:   no_item_gen no_monster_gen no_pool_fixup
ORIENT: encompass
{{
ice_cave_common_loot(_G)
local simul = simulacrum_monsters()
mons(simul["animal"])
mons(simul["cruel"])
}}
# For easy ice caves, three ice statues in the middle chamber, and a freezing
# wraith has a 50% chance of replacing one of the two white ugly thing. For
# hard ice caves, there are two orange crystal statues in the middle chamber,
# always two white very ugly things total. Two freezing wraiths are added to
# the final chamber, and there two more star_items.
: if dgn.persist.ice_cave_hard then
MONS:   orange crystal statue, freezing wraith, white very ugly thing
# 12 * 5 = 60 total weight for animal simulacra, 4 * 5 = 20 total weight for
# cruel simulacra, and 10 weight for freezing wraiths.
: set_random_mon_list(dgn.random_entry_arg(simul["animal"], "w:12") ..
:     " / " .. dgn.random_entry_arg(simul["cruel"], "w:5")  ..
:     " / freezing wraith")
NSUBST: D = 3 / 1
SUBST:  E = 124, F = 4, 1 = 112, J = *
: else
MONS:   ice statue, freezing wraith, white ugly thing
: set_random_mon_list(dgn.random_entry_arg(simul["animal"], "w:16") ..
:    " / " .. simul["cruel"])
NSUBST: 1 = 2=1 / 4=1112.... / ., D = 2=3 / 1, 5 = 45 / 5
: end
NSUBST: d = def*** / *
SUBST:  g = gh||, i = i|
: ice_cave_appearance(_G)
MAP
ccccccccc
cg*JiJ*|c
c*.....*c
c%.....%c
c.......c
c2..5..2c
cc.....cc
cccF.Fccc
cccc3cccc
ccc.E.ccc
cc.....cc
cD.....Dc
c...5...c
c.......c
cE.....Ec
cD.....Dc
cccc.cccc
xd%...%dx
x*E...E*x
x%.....%x
x.11111.x
x..111..x
xx.....xx
xxx...xxx
xxxx.xxxx
xxx...xxx
xx.....xx
x...A...x
x.......x
x.......x
x...<...x
x.......x
xxxxxxxxx
ENDMAP

###############################################################################
# A jelly themed ice cave
#
# Foes: Simulacra, ice statue, slime creatures, and a few high level jellies,
# especially azure jellies.
#
# Loot: Guaranteed randart ice-themed weapon, armour, jewellery, or book, along
# with some items from the common loot set and star_items.
NAME:    ice_cave_hellmonk_azure_passage
TAGS:    no_item_gen no_monster_gen
ORIENT:  encompass
: ice_cave_common_loot(_G)
# Loot always includes at least one randart so Jiyva worshipers get something
KITEM:   j = any weapon randart ego:freezing pre_id / any armour randart \
             / ice dragon scales randart w:5 \
             / ring of protection from cold randart pre_id \
             / any ring randart / any amulet randart \
             / randbook disc:ice numspells:3
KMONS:   _ = azure jelly
KFEAT:   _ = altar_jiyva
KFEAT:   D = slimy_wall
SUBST:   * = dj *:60, d = defghi, 1 = 1.., 3 = 113334
SHUFFLE: qrs
# For easy ice cave, use ice statues,
# boss slimes, including a rockslime.
: if dgn.persist.ice_cave_hard then
MONS:    glowing shapeshifter simulacrum / slime creature simulacrum \
         / great orb of eyes simulacrum
MONS:    orange crystal statue, slime creature band, void ooze
MONS:    azure jelly, rockslime
{{
set_random_mon_list("glowing shapeshifter simulacrum w:20" ..
    " / slime creature simulacrum w:20 / great orb of eyes simulacrum w:20" ..
    " / slime creature w:40 / void ooze w:20 / azure jelly")
}}
SUBST:   p = 4, q = 455, r = 5, s = 6
: else
MONS:    shapeshifter simulacrum / glowing shapeshifter simulacrum \
         / slime creature simulacrum / great orb of eyes simulacrum
MONS:    ice statue, slime creature band, void ooze, azure jelly
{{
set_random_mon_list("shapeshifter simulacrum" ..
    " / glowing shapeshifter simulacrum / slime creature simulacrum" ..
    " / great orb of eyes simulacrum / slime creature w:20 / void ooze")
}}
SUBST:   q = 34455
:end
NSUBST:  2 = 2 / 2=2. / .
# 50% chance for slimy wall passages, otherwise fill with rock.
SHUFFLE: DE / FF
SUBST:   E = ., F = x
: ice_cave_appearance(_G)
MAP
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxx..3......xxxxxxxx.....xxxxxxxxx
xxxxxxx.......11...pxxxx.......rxxxxxxxx
xxxxx1.....xxx.....xxxx.....D....**xxxxx
xxxx2....DDDD.....xxx.....D........*xxxx
xxxx....EEEE....3.x.......s._.D....jxxxx
xxxx31...DDDD.....1.......D........*xxxx
xxxxx..1....xxxxxxxxxx......D....**xxxxx
xxxxxx...11...xxxxxxxxxx.......qxxxxxxxx
xxxxxxxxx3....21....xxxxxx.....xxxxxxxxx
xxxxxxxxxx........1......xxxxxxxxxxxxxxx
xxxxxxxxxxxxxDEDxxxx.....1.xxxxxxxxxxxxx
xxxxxxxxxxxxxDEDxxxxxx.....3.xxxxxxxxxxx
xxxxxxx....2....xxxxxxxx....xxxxxxxxxxxx
xxxxx..1........xxxxxxx..1.xxx..1..xxxxx
xxxx..1...xxx..1..xxx2...DDx.1......xxxx
xxxx.....DDxxxx..1......EE....x2..1.xxxx
xxxx3...EEE.d*xxx....xxDD...1xx.....xxxx
xxxxx.....Dx*d..xxxxxxxx..1.xx...3.xxxxx
xxxxxx1....xx.p..2xx...1..xxx.....xxxxxx
xxxxxxxxx...xxxx.......xxxx...1xxxxxxxxx
xxxxxxxxxx.1..xxxx.p.xxx..1..xxxxxxxxxxx
xxxxxxxxxxxx.1..1xxxxx.....xxxxxxxxxxxxx
xxxxxxxxxxxxxxx...111...xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxx..A..xxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxx.<.xxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ENDMAP
