{{

-- This is an arena. If you kill everything before the time limit you win gold,
-- arena points, and get some extra time to rest. Shops are very important here.
-- When the last monster spawns, you get about 60 turns before the round ends.
--
-- Difficulty ramps up quickly. The first boss (round 5) is hard if you don't
-- use items or god powers. There's enough gold at the start to get a decent
-- item or two by round 5. The first two bosses tend to die fast. Later ones
-- are a different matter.
--
-- Every fifth fight is a boss. You get a rune after them. Unlike normal rounds,
-- they will end as soon as you kill the boss. Many of them have their HP/HD
-- messed with. After round 27, bosses come every 3rd round. The reward for
-- killing a boss is an "acquire any" item.
--
-- 1/5 of all normal rounds are lightning rounds. To win, you only need to
-- survive. Killing all the monsters will be nearly impossible because of how
-- fast they spawn.
--
-- After round 27 the orb will drop, but picking it up is optional. You can do
-- so to win, or for massive arena points. Round 42 is the final one.
-- That round will give you the 10th rune if you survive, but it's designed to
-- be almost impossible without extreme tactics (like using tomb cards or quad
-- damage). It is much harder than anything you will find in a zig.
--
-- Arena points are just for style. The formula is:
--      (1 + (enemies_killed)) * (round number) * (multiplier)
-- with "multiplier" getting +1 for every round you fully clear (kill everyone)
-- and +2 for boss kills. It resets to 1 if you fail to clear a round, and 27 if
-- you are carrying the orb. Therefore, points are mostly skill, but there is
-- a substantial luck factor.
--
-- As for gold, the amount you gain is based on your score multiplier (up to
-- x5) and the current round number. Enemies killed is not a factor.
--
-- Killing all the enemies can be very hard, and a lot of luck is involved. You
-- only get about 60 turns to kill the last enemy, and it might spawn in a far
-- away spot. This is intentional.
--
-- XXX: Zin is overpowered.

crawl_require('dlua/vault.lua')

function arena_sprint_is_boss_round(round_id)
    return (round_id < 27 and round_id % 5 == 0) or (round_id > 27 and round_id % 3 == 0)
end


function arena_sprint_spawn_enemies(data)
    local sp = dgn.find_marker_positions_by_prop(data.spawn_dir, 1)
    for _, pos in ipairs(sp) do
        if data.num_spawned >= data.round_enemies then
            break
        end
        if crawl.one_chance_in(#sp) then
            if arena_sprint_is_boss_round(data.round_id) and not data.boss_spawned then
                local dude = dgn.create_monster(pos.x, pos.y, data.monster_set[2])
                if dude then
                    dude.set_prop("boss_mons", 1)
                    dude.beh = mons.behaviour("wander")
                    data.num_spawned = data.num_spawned + 1
                    data.boss_spawned = true
                    dgn.apply_area_cloud(pos.x, pos.y, 10, 10, 1, 1,
                                         "translocational energy", "other", -1)
                    crawl.dpr("Spawned " .. crawl.grammar(dude.name, "a") .. " (" .. data.spawn_timer .. ").")
                end
            else
                local dude = dgn.create_monster(pos.x, pos.y, data.monster_set[1])
                if dude then
                    if dude.experience > 0 then
                        -- Plants, fungi, etc, don't count
                        dude.set_prop("arena_replica", 1)
                        data.num_spawned = data.num_spawned + 1
                    end
                    dude.beh = mons.behaviour("wander")
                    dgn.apply_area_cloud(pos.x, pos.y, 10, 10, 1, 1,
                                         "translocational energy", "other", -1)
                    crawl.dpr("Spawned " .. crawl.grammar(dude.name, "a") .. " (" .. data.spawn_timer .. ").")
                end
            end
        end
    end
end


function arena_sprint_end_round(data)
    data.between_rounds = true

    local you_x, you_y = you.pos()

    -- Place orb / rune
    if arena_sprint_is_boss_round(data.round_id) then
        crawl.mpr("A rune of Zot has appeared.", "orb")
        dgn.create_item(you_x, you_y, data.monster_set[3])
        data.time_left = 1500 + crawl.random2(500)
        if data.round_id > 27 then
            local p = dgn.find_marker_positions_by_prop("centre_point", 1)[1]
            dgn.grid(p.x, p.y, "exit_dungeon")
            if data.round_id < 42 then
                crawl.mpr("The exit has re-opened... for now.", "orb")
            else
                crawl.mpr("The exit has re-opened.", "orb")
            end
        end
    elseif data.round_id == 27 then
        crawl.mpr("The Orb of Zot has appeared in the centre of the arena!", "orb")
        local p = dgn.find_marker_positions_by_prop("centre_point", 1)[1]
        dgn.create_item(p.x, p.y, "orb of zot")
        data.time_left = 1500 + crawl.random2(500)
    end

    -- Guarantee at least 15 turns of rest
    data.time_left = data.time_left + 150

    -- Scoring
    local style_gain = (1 + data.num_killed) * data.round_id
    local gold_gain = 10 * data.round_id

    if you.have_orb() and data.style_mult < 27 then
        data.style_mult = 27
    end

    if data.num_killed >= data.round_enemies or data.lightning_round then
        data.style_mult = data.style_mult + 1
        if arena_sprint_is_boss_round(data.round_id) then
            crawl.mpr("<yellow>You have won a prize for killing the boss!</yellow>", "warning")
            -- Extra score multiplier for killing the boss.
            data.style_mult = data.style_mult + 1
            -- Reward for boss kills.
            dgn.create_item(you_x, you_y, "acquire any")
            dgn.create_item(you_x, you_y, "any parchment level:100")
            dgn.create_item(you_x, you_y, "potion of experience q:1 pre_id")
        else
            crawl.mpr("<yellow>Victory!</yellow>", "warning")
        end
        crawl.mpr("Score multiplier: " .. data.style_mult .. "x", "intrinsic_gain")
        -- Gold multiplier is capped at 5x
        gold_gain = gold_gain * math.min(data.style_mult, 5)
    else
        if you.have_orb() and data.style_mult > 27 then
            data.style_mult = 27
            crawl.mpr("Score multiplier reset to 27x", "intrinsic_gain")
        elseif data.style_mult > 1 then
            crawl.mpr("You lost your score multiplier.", "intrinsic_gain")
            data.style_mult = 1
        end
    end

    style_gain = style_gain * data.style_mult
    local style_points = dgn.persist.arena_style_points + style_gain
    dgn.persist.arena_style_points = style_points
    if style_points > 1 then
        crawl.mpr("You now have " .. style_points .. " arena points " ..
                  "(gained " .. style_gain .. ").", "intrinsic_gain")
    else
        crawl.mpr("You now have 1 arena point.", "intrinsic_gain")
    end
    crawl.take_note("Arena points: " .. style_points ..
                    " (+" .. style_gain .. ") [x" .. data.style_mult .. "]",
                    "intrinsic_gain")

    dgn.create_item(you_x, you_y, "gold q:" .. gold_gain)

    -- This dismisses *every* monster on the entire level, including
    -- your allies.
    local gxm, gym = dgn.max_bounds()
    for p in iter.rect_iterator(dgn.point(1, 1), dgn.point(gxm - 2, gym - 2)) do
        local dude = dgn.mons_at(p.x, p.y)
        if dude then
            dgn.apply_area_cloud(p.x, p.y, 5, 10, 1, 1,
                                 "translocational energy", "other", 10)
            dude.dismiss()
        end
    end

    if data.round_id == 42 then
        crawl.mpr("<white>The arena falls silent. Everyone but you is dead.</white>")
        crawl.mpr("<white>There is nothing to do now but take the Orb and leave.</white>")
        crawl.mpr("<white>Congratulations, champion.</white>")
        data.finished = true
    else
        data.round_id = data.round_id + 1
    end
    crawl.more()
end


function arena_sprint_ominous_countdown(time_left, waiting)
    if not waiting then
        if time_left > 0
            and (time_left == 500
                or time_left == 200
                or time_left == 150
                or time_left == 100
                or (time_left <= 50 and time_left % 10 == 0))
        then
            crawl.mpr(time_left / 10 .. "...", "duration")
        elseif time_left <= 0 then
            crawl.mpr("Time's up!", "duration")
            --crawl.more()
            crawl.mpr("The arena falls silent.")
        end
    elseif time_left == 20 and waiting then
        -- There was more of a countdown here, but it felt too spammy.
        crawl.mpr("<yellow>Get ready!</yellow>", "warning")
    end
end


function arena_sprint_get_monster_set(round, boss)
    if not boss then
        if round == 27 then
            return {"place:Zot:$ / orb guardian w:60 / tiamat / " ..
                    "orb of appropriateness / electric golem / killer klown / " ..
                    "ancient lich / dread lich / protean progenitor / " ..
                    "ghost moth / moth of wrath"}
        end

        local mon_set = {}

        -- First two rounds have a more limited, less lethal set.
        if round == 1 and crawl.coinflip() then
            return {"place:D:2 / place:D:4 / w:4 sigmund / w:2 jessica / w:2 terence"}
        elseif round <= 2 then
            mon_set = {
                "place:D:3 / place:D:5 / w:4 sigmund / w:2 jessica / w:2 terence",
                "goblin / hobgoblin / kobold / kobold brigand / ijyb w:6 / pikel w:4",
                "rat / quokka / river rat / w:2 hell rat / w:6 pargi",
                "ball python / adder w:15 / water moccasin w:5",
                "orc w:40 / orc wizard w:8 / orc priest w:5 / w:5 orc warrior",
                "gnoll w:35 / hound w:5 / gnoll sergeant / gnoll bouda / crazy yiuf",
                "crimson imp w:15 / shadow imp w:15 / grinder w:3 / w:2 eustachio",
                "zombie w:15 / rat draugr ; mundane dagger / wight w:5 / phantom",
                "scorpion / scorpion simulacrum w:2 / redback w:1 / bombardier beetle w:2",
                "endoplasm / w:5 jelly",
                "clockroach w:20 / scorpion / ribbon worm"
            }
        elseif round <= 5 then
            mon_set = {
                -- Branches: D, Orc, Elf, Lair, Shoals, Swamp, Spider, Snake, Slime,
                -- Hive, Crypt, Pan, Tomb
                "place:D:6 w:15 / place:D:10 w:15 / w:2 edmund / w:2 maurice /\
                    w:1 cassandra / w:1 joseph",
                "w:30 place:Orc / orc wizard / orc warrior / w:3 orc knight /\
                    orc priest / orc high priest w:1 / blorkula the orcula w:3 / urug w:1",
                "orc wizard / deep elf pyromancer / fire bat / water elemental",
                "place:Lair / w:5 yak / w:3 komodo dragon / w:3 basilisk /\
                    w:1 death yak / river rat / hell rat / w:2 dream sheep",
                "w:20 merfolk / w:5 merfolk siren / hippogriff w:15 / centaur /\
                    w:1 harpy / w:5 cyclops / w:1 snapping turtle",
                "w:5 bog body / w:5 tyrant leech / w:5 swamp drake /\
                    bullfrog / w:2 cane toad / w:2 hydra /\
                    w:2 vampire mosquito",
                "scorpion w:20 / bes kemwar w:5 / jumping spider w:12 /\
                    tarantella w:5 / culicivora",
                "ball python / adder w:15 / water moccasin / naga /\
                    salamander w:4",
                "jelly / w:5 endoplasm / glass eye / w:2 shining eye",
                "killer bee w:20 / w:5 queen bee",
                "place:D:7 zombie / place:D:4 draugr / wight / weeping skull w:5 /\
                    phantom w:5 / bes kemwar w:5 / w:1 josephine",
                "drude / ufetubus / white imp / orange demon / chaos spawn",
                "w:20 mummy / w:5 guardian mummy / w:5 menkaure",
                -- Fire, Air, Earth, Water, Death
                "w:20 fire bat / fire elemental / hell hound w:5 / maggie w:1",
                "steam dragon / goblin rider w:5 / hippogriff w:5 /\
                    lightning spire w:5 / sky beast w:25",
                "rock fish w:15 / gargoyle w:5 / kobold geomancer w:5 /\
                    rust devil / iron imp w:15",
                "w:20 ice beast / w:20 simulacrum / rime drake / w:5 water elemental",
                "wight / wraith / w:15 spectral thing",
                -- Misc
                "kobold / kobold brigand / kobold geomancer w:3 / w:2 sonja",
                "jackal w:1 / hound w:5 / wolf w:20 / hell hound w:7 / w:3 grum",
                "ogre w:35 / two-headed ogre / ogre mage w:5 / w:2 erolcha",
                "bullfrog w:20 / blink frog w:6 / cane toad w:6 / prince ribbit w:2",
                "gnoll / gnoll bouda / gnoll sergeant / hound / wolf",
                -- Gimmicks
                "brain worm", "orc priest", "vampire bat",
                "kobold name:flame-cult_kobold tile:mons_flame_cult_kobold " ..
                    "n_rpl n_noc n_des perm_ench:inner_flame",
             }
        elseif round <= 10 then
            mon_set = {
                -- Branches: D, Orc, Elf, Lair, Shoals, Swamp, Spider, Snake, Slime,
                -- Hive, Crypt, Pan, Tomb
                "place:D:11 w:15 / place:D:14 w:15 / w:2 erica / w:2 harold /\
                    w:1 rupert",
                "w:20 place:Orc:$ / orc wizard / orc warrior / orc knight /\
                    orc priest / orc high priest w:3 / orc sorcerer w:2 /\
                    orc warlord w:1 / urug w:2",
                "deep elf pyromancer / deep elf zephyrmancer /\
                    deep elf knight / deep elf archer / fire elemental /\
                    water elemental / orc sorcerer w:2",
                "place:Lair:3 w:30 / rupert w:1",
                "place:Shoals",
                "bog body w:5 / tyrant leech w:5  / swamp drake w:5 /\
                    cane toad / goliath frog / alligator w:5 / hydra /\
                    vampire mosquito w:2",
                "scorpion w:20 / bes kemwar w:5 / jumping spider w:12 /\
                    tarantella w:5 / culicivora",
                "water moccasin / black mamba / mana viper /\
                     naga / naga warrior / naga mage / salamander",
                "jelly w:15 / glass eye / w:1 shining eye /\
                    w:3 golden eye / w:2 slime creature",
                "killer bee w:15 / w:5 queen bee / w:1 oklob plant",
                "w:3 skeletal warrior / wight / weeping skull /\
                 place:D:7 zombie w:5 / place:D:7 draugr w:5 /\
                 flayed ghost w:5 / phantom w:5 / shadowghast w:3 /\
                 silent spectre / w:4 josephine",
                "rust devil / hellwing / chaos spawn / soul eater / smoke demon",
                "mummy / w:5 guardian mummy / w:1 mummy priest",
                -- Fire, Air, Earth, Water, Death
                "fire bat / fire elemental / red devil ; trident ego:flaming /\
                    sun demon w:5 / efreet w:2 / hell hound",
                "steam dragon w:5 / hippogriff w:5 / wind drake w:5 /\
                    lightning spire / sky beast w:20",
                "rock fish w:5 / gargoyle w:5 / boulder beetle /\
                    rust devil w:15 / basilisk / catoblepas w:5 / jorgrun w:1",
                "ice beast / rime drake / ogre simulacrum /\
                    ice devil / water elemental",
                "wraith w:20 / spectral vault guard / phantasmal warrior / w:2 nergalle",
                -- Misc
                "kobold geomancer / kobold demonologist",
                "centaur w:20 / centaur warrior w:2 / nessos w:1",
                "ugly thing",
                "tyrant leech / ribbon worm / brain worm w:5",
                "ogre w:15 / two-headed ogre / ogre mage w:5 / w:1 erolcha",
                "troll / deep troll w:12 / iron troll w:2",
                "rime drake / swamp drake / steam dragon / swamp dragon /\
                 acid dragon / komodo dragon",
                "bes kemwar / bog body",
                "shapeshifter hd:7",
                "polar bear",
                -- Gimmicks
                "brain worm", "marrowcuda",
                "kobold name:flame-cult_kobold tile:mons_flame_cult_kobold " ..
                    "n_rpl n_noc n_des perm_ench:inner_flame",
                "dwarf name:drunken n_adj n_des n_noc perm_ench:confusion"
            }
        elseif round <= 15 then
            mon_set = {
                -- Branches: D, Orc, Elf, Lair, Shoals, Swamp, Spider, Snake,
                -- Slime, Hive, Crypt, Pan, Tomb
                "place:D:$ w:24 / w:1 louise / w:1 donald / w:1 kirke",
                "w:20 place:Orc:$ / orc wizard / orc sorcerer w:3 / orc warrior / orc knight /\
                    orc warlord w:3 / orc priest / orc high priest w:4 / urug w:3",
                "deep elf zephyrmancer / deep elf archer / deep elf knight /\
                    fire elemental / water elemental w:5 / air elemental /\
                    dancing weapon w:20 / orc sorcerer w:5",
                "place:Lair:$ w:100 / hydra / catoblepas / dire elephant / w:5 gastronok",
                "place:Shoals:$ w:20 / w:6 merfolk avatar / w:5 water nymph",
                "place:Swamp:$ w:20 / w:6 hydra / w:5 swamp dragon",
                "place:Spider:$ w:20 / orb spider w:5 / emperor scorpion w:2 /\
                    broodmother w:2",
                "place:Snake:$ w:20 / w:5 naga mage / w:5 naga warrior / w:5 nagaraja",
                "place:Slime",
                "killer bee / queen bee / meliai w:2 / oklob plant w:2",
                "place:Crypt / w:2 josephine",
                "common demon w:30 / kobold demonologist w:5 / frances w:3",
                "mummy / w:5 guardian mummy / w:2 mummy priest / w:1 guardian sphinx",
                -- Fire, Air, Earth, Water, Death
                "w:5 fire bat / fire elemental /\
                    sun demon / efreet / hell hound /\
                    hell hog / w:5 fire crab",
                "w:1 storm dragon / air elemental / wind drake w:5 /\
                    hippogriff w:5 / goblin rider w:5",
                "earth elemental w:5 / gargoyle w:15 / boulder beetle / \
                    rust devil / mountainshell w:5 / w:1 roxanne /\
                    iron dragon w:2 / stone giant w:3",
                "ice beast w:5 / rime drake w:5 / hydra simulacrum /\
                    stone giant simulacrum / golden dragon simulacrum /\
                    water elemental / water nymph",
                "wraith / eidolon / phantasmal warrior / w:2 nergalle",
                -- Misc
                "centaur w:15 / centaur warrior w:5 / nessos w:1",
                "w:15 ugly thing / w:1 very ugly thing",
                "vampire mosquito / hornet / obsidian bat",
                "ogre mage / vampire mage / naga mage",
                "troll / deep troll / iron troll",
                "rime drake w:5 / swamp drake / swamp dragon /\
                    acid dragon w:5 / komodo dragon w:5 / lindwurm w:5 /\
                    fire dragon w:5 / ice dragon w:5 / storm dragon w:1",
                "ghoul / bog body w:15 / cognitogaunt w:5",
                "shapeshifter",
                -- Gimmicks
                "neqoxec", "obsidian bat",
                "moth of wrath / w:20 two-headed ogre",
                "boulder beetle", "orb spider", "redback / sea snake w:3",
                "golden eye w:30 / shining eye"
            }
        elseif round <= 20 then
            mon_set = {
                -- Branches: D, Orc, Elf, Lair, Shoals, Swamp, Spider, Snake,
                -- Slime, Blade, Forest, Crypt, Pan, Tomb, Hell
                "place:D:$ w:30 / w:1 nikola / w:1 frederick",
                "place:Orc:$ / orc sorcerer w:3 / orc knight / orc warlord w:3 /\
                    iron troll w:5 / stone giant w:5 / orc high priest w:4",
                "deep elf high priest / deep elf demonologist / deep elf annihilator /\
                    deep elf sorcerer / deep elf death mage / deep elf elementalist /\
                    deep elf blademaster / deep elf master archer /\
                    deep elf knight w:60 / deep elf archer w:60 /\
                    thermic dynamo w:40 / dancing weapon w:40",
                "mountainshell / torpor snail / dire elephant / skyshark",
                "place:Shoals:$ w:30 / merfolk javelineer / merfolk impaler /\
                    merfolk aquamancer",
                "place:Swamp:$ / hydra / swamp dragon / w:5 green death",
                "place:Spider:$ / wolf spider / orb spider / w:5 emperor scorpion /\
                    w:5 ghost moth",
                "place:Snake:$ / naga mage / naga warrior / nagaraja /\
                    guardian serpent / anaconda",
                "place:Slime:$",
                "dancing weapon",
                "place:Forest",
                "place:Crypt:$",
                "common demon w:30 / greater demon w:5",
                "mummy / w:5 guardian mummy / w:2 mummy priest / w:5 guardian sphinx",
                "place:Hell w:30 / geryon w:1",
                -- Fire, Air, Earth, Water, Death
                "fire elemental / fire dragon / sun demon / efreet / hell hound /\
                    hell hog / fire crab / fire giant / w:5 balrug / w:1 margery /\
                    w:2 azrael",
                "storm dragon / air elemental / w:5 wind drake / spriggan air mage /\
                    w:3 titan / w:1 nikola",
                "earth elemental / iron troll w:5 / stone giant /\
                    rust devil / mountainshell / w:1 crystal guardian /\
                    w:2 iron dragon / w:3 iron elemental / w:2 quicksilver dragon",
                "hydra simulacrum / stone giant simulacrum /\
                    golden dragon simulacrum / water nymph /\
                    ironbound frostheart / merfolk aquamancer / frost giant",
                "death cob / death yak / death drake w:5 / deep elf death mage /\
                    death knight / green death",
                -- Misc
                "centaur / centaur warrior",
                "yaktaur w:15 / yaktaur captain w:5",
                "ugly thing / crawling flesh cage w:4 /\
                 very ugly thing w:1 / wretched star w:1",
                "kobold fleshcrafter / large abomination w:5",
                "ogre mage / vampire mage / naga mage /\
                    lich / w:5 ancient lich / w:1 frederick",
                "cyclops / stone giant / w:5 frost giant / w:5 fire giant /\
                    w:1 titan",
                "fire dragon / ice dragon / storm dragon / w:5 shadow dragon /\
                    w:5 golden dragon / w:1 xtahua",
                "yak / dream sheep / death yak / catoblepas / apis w:2",
                "glowing shapeshifter",
                "hell knight / w:5 necromancer / w:1 margery",
                "wraith / wight / phantasmal warrior / skeletal warrior /\
                    vampire / ghoul / mummy / flayed ghost / death cob /\
                    profane servitor",
                "vault guard / necromancer / hell knight / arcanist w:5 / occultist w:5 /\
                    killer klown",
                "base draconian / w:1 nonbase draconian",
                "golden eye / shining eye w:5 / glass eye / eye of devastation /\
                    great orb of eyes / eye of draining w:5",
                "vampire / vampire knight / vampire mage / w:1 jory",
                -- Gimmicks
                "neqoxec", "smoke demon", "catoblepas",
                "moth of wrath / w:20 stone giant",
                "orb spider", "golden eye w:30 / shining eye", "tormentor",
                "skeletal warrior / w:5 skeletal warrior ; dart ego:atropa"
            }
        elseif round <= 26 then
            mon_set = {
                -- Branches: Vaults, Orc, Elf, Shoals, Swamp, Spider, Snake, Slime,
                -- Blade, Forest, Crypt, Pan, Tomb, Hell
                "vault guard w:50 / ancient lich w:5 / lich / yaktaur /\
                    yaktaur captain w:3 / stone giant / shadow dragon /\
                    titan w:5",
                "w:20 place:Orc:$ / orc sorcerer w:3 / orc knight / orc warlord w:5 /\
                    iron troll w:5 / stone giant w:5 / orc high priest w:4 /\
                    moth of wrath",
                "deep elf high priest / deep elf demonologist / deep elf annihilator /\
                    deep elf sorcerer / deep elf death mage / deep elf elementalist /\
                    deep elf blademaster / deep elf master archer /\
                    deep elf knight w:20 / deep elf archer w:20 /\
                    dancing weapon w:15 / thermic dynamo w:15",
                "place:Shoals:$ / merfolk javelineer / merfolk impaler /\
                    merfolk aquamancer / sphinx marauder",
                "hydra w:5 / fenstrider witch / shambling mangrove w:5 /\
                    green death / death drake",
                "place:Spider:$ w:5 / wolf spider / orb spider / emperor scorpion /\
                    ghost moth / moth of wrath",
                "place:Snake:$ w:5 / naga mage / naga warrior / w:20 nagaraja /\
                    guardian serpent / w:5 anaconda",
                "place:Slime:$ / acid blob / star jelly / great orb of eyes",
                "dancing weapon",
                "place:Forest:$ w:20 / spriggan defender / spriggan rider /\
                    spriggan air mage / spriggan druid w:3 / spriggan berserker",
                "place:Crypt:$ w:25 / w:3 lich / w:5 vampire knight /\
                    bone dragon w:2 / boris w:2 / curse skull w:2",
                "any demon w:30 / pandemonium lord",
                "place:Tomb:$ w:70 / guardian sphinx w:20 / royal mummy",
                "place:Hell w:25 / geryon w:2 / nellie w:2",
                -- Elements/hells, Holy
                "crystal guardian / hell sentinel / iron dragon / quicksilver dragon /\
                    walking earthen tome / stone giant / iron giant",
                "orb of fire w:5 / brimstone fiend / balrug / hellion /\
                    fire giant / sun demon / fire vortex / will-o-the-wisp",
                "orb of winter w:5 / place:Coc:$ w:15 / ice fiend /\
                    blizzard demon / ice devil",
                "spriggan air mage / w:5 titan / w:5 electric golem / wind drake /\
                    air elemental / storm dragon",
                "orb of entropy w:5 / tzitzimitl / reaper / shadow dragon /\
                    death drake / deep elf death mage / lich w:15 /\
                    ancient lich w:5 / death knight w:5 /\
                    eye of draining w:5 / place:Tar:$ w:30",
                "daeva / angel / cherub / pearl dragon / ophan / apis w:2",
                -- Misc
                "kobold blastminer / yaktaur captain",
                "very ugly thing / crawling flesh cage w:4 / wretched star w:1",
                "lich / w:5 ancient lich / w:2 boris",
                "stone giant / frost giant / fire giant / titan / w:1 chuck",
                "fire dragon / ice dragon / storm dragon / shadow dragon /\
                    golden dragon / quicksilver dragon / iron dragon / w:1 xtahua",
                "glowing shapeshifter",
                "hell knight w:20 / w:1 margery",
                "vault guard / necromancer / hell knight / arcanist w:5 / occultist w:5 /\
                    killer klown",
                "base draconian / w:5 nonbase draconian",
                "golden eye / shining eye w:2 / glass eye / eye of devastation /\
                    eye of draining w:5 / great orb of eyes / ophan w:5",
                "vampire knight / vampire mage / vampire bloodprince / w:1 jory",
                "hellion / hell sentinel / sin beast / hell hog / hell knight /\
                    hell hound / hellephant / hellwing / w:2 nellie",
                "profane servitor w:20 / angel / daeva / cherub / seraph w:5",
                -- Gimmicks
                "neqoxec", "smoke demon", "catoblepas",
                "moth of wrath / w:20 ettin", "orb spider", "undertaker",
                "chonchon", "star jelly / starcursed mass",
                "shining eye", "tormentor", "tentacled monstrosity",
                "skeletal warrior / skeletal warrior ; dart ego:atropa",
                "unseen horror / shadow wraith w:15 / ghost moth",
                "curse toe / w:20 deathcap / w:4 murray",
                "reaper / sin beast / geryon w:1",
                "mana viper / spriggan berserker ; war axe ego:antimagic . animal skin /\
                    void ooze w:15 / cognitogaunt w:5 / ghost moth",
                "glass eye w:5 / ettin",
                "executioner / w:1 ignacio",
                "ghost moth / moth of wrath / meliai w:5 / vampire mosquito w:30"
            }
        elseif round <= 36 then
            mon_set = {
                -- Branches: Vaults, Orc, Elf, Shoals, Swamp, Spider, Snake,
                -- Slime, Blade, Forest, Crypt, Pan, Tomb, Hell
                "vault guard / ancient lich w:5 / lich / yaktaur /\
                    yaktaur captain w:3 / stone giant / shadow dragon /\
                    titan w:5 / golden dragon / glowing shapeshifter",
                "orc sorcerer / orc knight / orc warlord /\
                    iron troll w:5 / stone giant w:5 / orc high priest /\
                    moth of wrath",
                "deep elf high priest / deep elf demonologist /\
                    deep elf annihilator / deep elf sorcerer /\
                    deep elf death mage / deep elf elementalist /\
                    deep elf blademaster / deep elf master archer /\
                    dancing weapon / thermic dynamo",
                "place:Shoals:$ / merfolk javelineer / merfolk impaler w:5 /\
                    merfolk aquamancer / sphinx marauder",
                "fenstrider witch w:5 / green death / death drake",
                "broodmother w:5 / orb spider w:5 / emperor scorpion /\
                    ghost moth / moth of wrath",
                "place:Snake:$ w:2 / w:40 nagaraja / guardian serpent / w:5 anaconda",
                "place:Slime:$ / acid blob w:30 / colossal amoeba / glass eye /\
                    void ooze / star jelly w:5 / morphogenic ooze / slymdra w:5",
                "dancing weapon ; bardiche good_item",
                "chonchon w:2 / spriggan defender / spriggan air mage /\
                    spriggan druid / spriggan berserker / alderking",
                "bone dragon w:2 / lich / ancient lich w:5 /\
                    curse skull w:1 / w:5 curse toe",
                "any demon w:20 / pandemonium lord",
                "place:Tomb:$ w:30 / guardian sphinx w:20 / royal mummy",
                "hellephant w:15 / w:1 nellie",
                -- Elements/hells, Holy
                "hell sentinel / iron dragon / quicksilver dragon /\
                    quicksilver elemental / iron giant / walking earthen tome",
                "orb of fire / brimstone fiend / balrug / hellion /\
                    fire giant / sun moth",
                "orb of winter / shard shrike / blizzard demon /\
                    white draconian / white draconian knight /\
                    walking frostbound tome",
                "spriggan air mage / titan / electric golem / storm dragon",
                "tzitzimitl / reaper / shadow dragon / death drake /\
                    deep elf death mage / ancient lich /\
                    orb of entropy / place:Tar:$ w:20",
                "daeva / angel / cherub / fravashi w:15 / pearl dragon w:15 /\
                     ophan / apis w:5",
                -- Misc
                "naga sharpshooter w:3 / yaktaur captain / vashnia w:1",
                "lich / ancient lich",
                "stone giant / w:15 frost giant / w:15 fire giant / w:15 titan",
                "w:5 fire dragon / w:5 ice dragon / w:7 storm dragon / shadow dragon /\
                    golden dragon / quicksilver dragon / iron dragon / wyrmhole w:3",
                "glowing shapeshifter hd:18",
                "w:5 base draconian / nonbase draconian",
                "golden eye / shining eye / glass eye / eye of devastation /\
                    eye of draining w:5 / great orb of eyes / w:5 ophan",
                "vampire knight / vampire mage w:5 / vampire bloodprince / jory w:1",
                "w:20 hellion / hell sentinel / sin beast / hell hog / hell knight /\
                    hell hound / hellephant / hellwing / w:2 nellie",
                "profane servitor w:25 / angel / daeva / fravashi w:5 /\
                    cherub / seraph",
                -- Gimmicks
                "undertaker", "chonchon", "star jelly / starcursed mass",
                "moth of wrath / w:20 ettin", "orb spider", "nekomata",
                "shining eye", "tormentor",
                "unseen horror / shadow wraith / ghost moth",
                "reaper / sin beast / geryon w:1",
                "spriggan berserker ; war axe ego:antimagic . animal skin /\
                 void ooze / cognitogaunt w:5 / ghost moth /\
                 demonspawn warmonger w:5",
                "glass eye w:5 / tentacled monstrosity",
                "executioner / w:1 ignacio / w:5 death drake",
                "ghost moth / moth of wrath / sun moth",
                -- Aaaarggghhhhh!
                "daeva / w:15 angel",
                "royal mummy / mummy priest / guardian mummy",
                "air elemental name:greater n_adj perm_ench:polar_vortex col:lightcyan / air elemental w:20",
                "iron golem hd:20 exp:2777 col:magenta tile:mons_orb_golem name:orb_golem " ..
                    "n_rpl n_des n_spe spells:orb_of_destruction.70.natural",
                "brimstone fiend / ice fiend / tzitzimitl / executioner / hell sentinel",
                "titan / spriggan air mage / blizzard demon / w:20 air elemental",
                "guardian sphinx / place:Tomb:$",
                "orb of fire / orb of winter / orb of entropy",
                "hellion / w:5 efreet"
            }
        else -- Because somehow, the above stuff was too easy.
            mon_set = {
                -- Branches: Vaults, Orc, Elf, Shoals, Swamp, Spider, Snake, Slime,
                -- Blade, Forest, Crypt, Pan, Tomb, Hell
                "ironbound thunderhulk / vault warden w:3 / deep elf master archer w:3 /\
                    titan w:15 / golden dragon w:20 / glowing shapeshifter hd:20 /\
                    undying armoury / ancient lich w:15",
                "orc warlord w:25 / juggernaut w:5 / orc high priest w:15 /\
                    moth of wrath w:5 / undying armoury w:5",
                "deep elf high priest / deep elf elementalist / thermic dynamo /\
                    deep elf blademaster w:20 / deep elf master archer w:20",
                "merfolk javelineer / merfolk aquamancer / water nymph /\
                    elemental wellspring / ice fiend",
                "thorn hunter w:5 / green death / death drake w:15",
                "orb spider / emperor scorpion / ghost moth / moth of wrath",
                "nagaraja w:20 / guardian serpent / salamander tyrant",
                "acid blob w:25 / rockslime w:5 / star jelly w:5 /\
                    six-headed slymdra w:5 / morphogenic ooze w:5 /\
                    glass eye / void ooze",
                "dancing weapon ; bardiche ego:speed / zenata w:1",
                "chonchon w:2 / spriggan air mage / alderking",
                "ancient lich / curse skull w:6 / boris w:1",
                "demonspawn warmonger / demonspawn soul scholar /\
                    demonspawn corrupter / demonspawn blood saint /\
                    brimstone fiend / ice fiend / tzitzimitl / hell sentinel /\
                    pandemonium lord w:80",
                "guardian sphinx w:20 / royal mummy",
                "hellephant w:15 / w:1 nellie",
                -- Elements/hells, Holy
                "hell sentinel / quicksilver elemental /\
                    iron giant / caustic shrike / walking crystal tome",
                "orb of fire w:25 / brimstone fiend / balrug / hellion w:5 /\
                    fire giant / searing wretch w:5 / oni incarcerator w:5",
                "orb of winter w:25 / blizzard demon w:5 / shard shrike /\
                    white draconian knight / walking frostbound tome",
                "spriggan air mage / titan / electric golem w:20 /\
                    storm dragon / spark wasp",
                "orb of entropy w:25 / tzitzimitl / reaper / shadow dragon /\
                    death drake / deep elf death mage / bone dragon w:5 /\
                    demonspawn soul scholar",
                "daeva w:20 / angel / cherub w:5 / fravashi w:15 /\
                    pearl dragon w:15 / ophan / apis",
                -- Misc
                "deep elf master archer",
                "ancient lich / dread lich",
                "frost giant / fire giant / w:15 titan / iron giant",
                "storm dragon w:7 / golden dragon w:15 /\
                    quicksilver dragon w:15 / iron dragon w:7 / wyrmhole",
                "protean progenitor", "vampire bloodprince",
                "draconian stormcaller / draconian knight / draconian shifter",
                "golden eye / shining eye / glass eye w:15 / eye of devastation /\
                    eye of draining / great orb of eyes / ophan w:5",
                "w:30 hellion / hell sentinel / sin beast / hell hog / hell knight /\
                    hell hound / hellephant / w:2 nellie",
                "profane servitor w:25 / angel w:5 / daeva / fravashi /\
                    cherub w:5 / seraph w:15",
                -- Gimmicks
                "cacodemon", "sun moth", "catoblepas / iron golem w:5",
                "moth of wrath / w:20 juggernaut", "orb spider", "apocalypse crab",
                "guardian sphinx / walking divine tome", "tormentor",
                "unseen horror / shadow wraith / ghost moth w:15",
                "reaper / sin beast / geryon w:1",
                "ghost moth / cognitogaunt / demonspawn warmonger",
                "glass eye w:5 / tentacled monstrosity",
                "executioner / w:1 ignacio / w:5 death drake",
                -- Just die already!
                "daeva", "demonspawn corrupter",
                "nekomata ; triple crossbow good_item . triple sword good_item . robe",
                "antique champion ; shadow dragon scales . kite shield . double sword",
                "royal mummy / mummy priest",
                "air elemental name:greater n_adj perm_ench:polar_vortex col:lightcyan",
                "iron golem hd:20 exp:2777 col:magenta tile:mons_orb_golem name:orb_golem " ..
                    "n_rpl n_des n_spe spells:orb_of_destruction.70.natural",
                "brimstone fiend / ice fiend / tzitzimitl w:5 / hell sentinel",
                "titan / spriggan air mage / blizzard demon",
                "orb of fire / orb of winter / orb of entropy",
                "hellion"
            }
        end

        local picked = crawl.random2(#mon_set) + 1
        crawl.dpr("Picking monster set " .. picked .. " of " .. #mon_set .. ": " ..
                  mon_set[picked])

        return {mon_set[picked]}
    else
        local which_boss = math.floor(math.min(round, 27) / 5)
        if round >= 27 then
            which_boss = which_boss + math.floor((round - 27) / 3)
        end
        return dgn.persist.arena_sprint_boss_set[which_boss]
    end
end


function arena_sprint_init_boss_table()
    -- This is called once when the map is loaded, and pre-determines the order
    -- of boss matches.
    --
    -- For the first two fights, there are five possible bosses per rune. The
    -- next three have two possible per rune. The rest just have one (but the
    -- order is random). The reason for doing it this way is because the early
    -- bosses will be the ones you see the most often, so they call for the
    -- most variety.

    local bs = {}
    if crawl.coinflip() then
        bs[1] = {"place:Snake", "aizul hd:7 hp:120 exp:791 / " ..
                 "naga warrior name:naga_warlord n_rpl n_des n_noc col:cyan hp:130 exp:890 / " ..
                 "anaconda name:giant n_adj n_noc hp:130 exp:1026 col:lightred",
                 "serpentine rune of zot"}
    else
        bs[1] = {"place:Swamp", "lernaean hydra / " ..
                 "arcanist name:witch tile:mons_witch n_rpl n_des n_noc col:green hp:130 exp:982 " ..
                   "spells:mephitic_cloud.15.wizard;" ..
                          "summon_hydra.15.wizard;" ..
                          "invisibility.15.wizard;" ..
                          "blink_away.15.wizard.emergency",
                 "decaying rune of zot"}
    end

    if crawl.coinflip() then
        bs[2] = {"place:Spider", "arachne hp:250 exp:4586 / " ..
                 "wolf spider name:dire n_adj n_noc col:blue hp:300 exp:1030 / " ..
                 "jumping spider name:phase_spider n_rpl n_des never_corpse " ..
                    "col:lightgreen spells:blink_away.58.natural hp:300 exp:856",
                 "gossamer rune of zot"}
    else
        bs[2] = {"place:Shoals", "polyphemus hp:350 exp:2584 / ilsuiw hp:250 exp:1735 / " ..
                 "merfolk avatar name:dimme tile:mons_dimme n_rpl n_des n_spe " ..
                    "col:lightmagenta hp:300 exp:1343 spells:avatar_song.160.natural;" ..
                                                   "malign_gateway.40.natural",
                 "barnacled rune of zot"}
    end

    if crawl.coinflip() then
        -- Elementalist boss is from mu_elemental_laboratory
        bs[3] = {"place:Elf w:300 / deep elf sorcerer / deep elf blademaster / " ..
                 "deep elf master archer / deep elf annihilator / deep elf high priest",
                 "fannar hp:400 hd:14 exp:2748 / " ..
                 master_elementalist_setup(_G, true),
                 "elven rune of zot"}
    else
        bs[3] = {"thorn hunter / shambling mangrove / sun moth / broodmother / " ..
                 "death yak / dire elephant / spriggan air mage w:5 / " ..
                 "spriggan berserker w:5", "agnes hp:335 exp:3113",
                 "mossy rune of zot"}
    end

    bs[4] = {"place:Slime", "dissolution hp:430 exp:16041/ " ..
             "acid blob name:sulphuric n_adj col:white hp:450 exp:4488/ " ..
             "great orb of eyes name:greater_orb_of_eyes n_rpl n_des n_noc col:green hp:600 exp:2502",
             "slimy rune of zot"}
    bs[5] = {"vault guard / place:Vaults", "mennas hp:250 exp:6462/ mara hp:300 exp:8019 / " ..
             "vault guard name:captain n_suf n_noc col:lightcyan hp:800 hd:26 exp:9592",
             "silver rune of zot"}
    if crawl.coinflip() then
        bs[5], bs[4] = bs[4], bs[5]
    end

    bs[6] = {"place:Dis:$", "dispater", "iron rune of zot"}
    bs[7] = {"place:Tar:$", "ereshkigal", "bone rune of zot"}
    bs[8] = {"place:Geh:$", "asmodeus", "obsidian rune of zot"}
    bs[9] = {"place:Coc:$", "antaeus", "icy rune of zot"}
    -- Pan sets are very roughly based on those in pan.des
    bs[10] = {"sin beast / zykzyl / protean progenitor / " ..
              "tentacled monstrosity / glass eye / golden eye / " ..
              "eye of devastation / shining eye", "mnoleg", "glowing rune of zot"}
    bs[11] = {"smoke demon / blizzard demon / green death / rakshasa / " ..
              "nekomata / nagaraja / merfolk aquamancer / jorogumo / " ..
              "fenstrider witch / titan / lich / draconian annihilator / " ..
              "deep elf annihilator", "lom lobon", "magical rune of zot"}
    bs[12] = {"efreet / sun moth / undying armoury / balrug / brimstone fiend",
              "cerebov", "fiery rune of zot"}
    bs[13] = {"shadow demon / soul eater / reaper / executioner / curse skull",
              "gloorx vloq", "dark rune of zot"}
    bs[14] = {"guardian mummy w:15 / mummy priest w:3 / royal mummy w:2",
               "khufu hp:500 exp:8988", "golden rune of zot"}
    -- Shuffle the above 9. We only wind up using 6 through 9
    for i = 14, 7, -1 do
        local r = crawl.random_range(6, i)
        bs[i], bs[r] = bs[r], bs[i]
    end

    -- Final (and tenth) boss
    bs[10] = {"pandemonium lord",
              "ancient lich name:Master_Blaster n_rpl hd:30 hp:1500 exp:62027 col:lightmagenta " ..
              "spells:fire_storm.32.wizard;glaciate.16.wizard;miasma_breath.16.wizard;blink_away.16.wizard.emergency", "demonic rune of zot"}
    return bs
end


function thing_do_arena(data, triggerable, triggerer, marker, ev)

    if data.finished then
        return
    end

    -- Count kills
    if triggerer.type == "monster_dies" and not data.between_rounds then
        local mons = dgn.mons_from_mid(ev:arg1())
        if mons.has_prop("arena_replica") then
            data.num_killed = data.num_killed + 1
        elseif mons.has_prop("boss_mons") then
            data.num_killed = data.round_enemies
        end
        if data.num_killed >= data.round_enemies then
            -- You win.
            arena_sprint_end_round(data)
        end
        return
    end

    -- Pause the timer if you use step from time.
    if you.pos() == 0 then
        return
    end

    -- Pause if you're somehow absent for more than 10 turns, somehow.
    if ev:ticks() >= 100 then
        return
    end

    if triggerer.type == "turn" and triggerer.sub_type == "countdown" then
        if data.between_rounds then
            data.time_left = data.time_left - 1
            arena_sprint_ominous_countdown(data.time_left, data.between_rounds)

            if data.time_left <= 0 then
                crawl.take_note("Round " .. data.round_id .. ".")
                crawl.mpr("ROUND " .. data.round_id .. "!", "warning")
                if data.round_id == 42 then
                    crawl.mpr("FINAL BOSS!", "warning")
                elseif arena_sprint_is_boss_round(data.round_id) then
                    crawl.mpr("BOSS ROUND!", "warning")
                elseif data.round_id == 27 then
                    crawl.mpr("ZOT ROUND!", "orb")
                else
                    crawl.mpr("FIGHT!", "warning")
                end

                data.time_left = 510 + crawl.random2(200)

                -- Non-boss rounds have more enemies, and a more random amount
                data.round_enemies = 5 + crawl.div_rand_round(data.round_id, 3)
                if not arena_sprint_is_boss_round(data.round_id) then
                    data.round_enemies = data.round_enemies + crawl.random2(crawl.div_rand_round(data.round_id, 3))
                end
                crawl.dpr("Number to spawn: " .. data.round_enemies .. ".")

                -- 1/5 chance of a normal round being a lightning round
                data.lightning_round = false
                if data.round_id ~= 27 and data.round_id ~= 1 and crawl.one_chance_in(5)
                    and not arena_sprint_is_boss_round(data.round_id)
                then
                    data.spawn_rate = 1
                    data.lightning_round = true
                    crawl.mpr("LIGHTNING ROUND!", "warning")
                else
                    data.spawn_rate = math.ceil((1000 + crawl.random2(500)) / data.round_enemies)
                end
                crawl.dpr("Spawn rate: " .. data.spawn_rate .. ".")
                data.spawn_timer = 0

                data.num_killed = 0
                data.num_spawned = 0
                data.boss_spawned = false
                data.monster_set = arena_sprint_get_monster_set(data.round_id,
                                                                arena_sprint_is_boss_round(data.round_id))

                if data.round_id > 27 then
                    local p = dgn.find_marker_positions_by_prop("centre_point", 1)[1]
                    if feat.is_stair(p.x, p.y) then
                        dgn.grid(p.x, p.y, "floor")
                        crawl.mpr("The exit has been sealed! It will re-open when you get the next rune.")
                    end
                end

                -- 50% chance of picking a specific direction to spawn from, else
                -- spawn from all four directions.
                if crawl.coinflip() then
                    local directions = {"north", "east", "south", "west"}
                    data.spawn_dir = directions[crawl.random2(#directions) + 1]
                    crawl.mpr("You sense a tension in the " .. data.spawn_dir .. ".")
                else
                    data.spawn_dir = "spawn_point"
                end

                data.between_rounds = false
            end
        else -- Active round
            if data.num_spawned >= data.round_enemies or data.spawn_timer > 3000 then
                -- Final countdown... starts at just above 50 turns to go. Triggers
                -- when all enemies spawn or when 300 turns is passed. The latter
                -- mainly happens when the portals get blocked.
                data.time_left = data.time_left - 1
                arena_sprint_ominous_countdown(data.time_left, data.between_rounds)
            else
                data.spawn_timer = data.spawn_timer + 1
                -- If the round takes more than 100 turns, speed things up a lot
                if data.spawn_timer > 1000 and data.spawn_rate > 1 then
                    data.spawn_rate = data.spawn_rate - 1
                    crawl.dpr("Speeding up...")
                end
            end

            if data.spawn_timer % data.spawn_rate == 0 or data.num_spawned == 0 then
                arena_sprint_spawn_enemies(data)
            end

            if data.time_left <= 0 then
                arena_sprint_end_round(data)
            end
        end
    end
end

-- Should return two values: the score, and false to indicate that we
-- don't want to add the default score.
function arena_sprint_score (won)
    local points = dgn.persist.arena_style_points
    local runes = you.num_runes()

    if won and runes > 0 then
        points = points * runes
    end
    return points, false
end

}}

NAME:       arena_sprint
TAGS:       sprint no_item_gen no_trap_gen no_rotate no_hmirror no_vmirror
DESC:       Sprint VI: "Thunderdome"
ORDER:      6
ORIENT:     encompass
LROCKTILE:  wall_hall
{{
    -- Yes, 15 is the same as the normal game but it's nice to be explicit
    -- in Sprint maps since they don't typically place exactly 15.
    crawl.set_max_runes(15)

    local arena_marker = TriggerableFunction:new {
        data = {
            num_killed = 0,
            num_spawned = 0,
            boss_spawned = false,
            round_id = 1,
            round_enemies = 0,      -- How many you need to fight
            spawn_rate = 0,
            spawn_timer = 0,        -- Counter for monster spawning
            lightning_round = false,
            time_left = 60,         -- How much time is left
            between_rounds = true,  -- Are we waiting for the next round?
            finished = false,       -- You somehow beat round 42
            monster_set = {},
            style_mult = 1,
            spawn_dir = ""          -- Which spawn points to use?
        },
        func = "thing_do_arena",
        repeated = true
    }

    arena_marker:add_triggerer(DgnTriggerer:new {
        type = "monster_dies",
        -- Note: target is "any", but we don't do anything unless it has
        -- the "arena_replica" or "boss_mons" property
        target = "any"
    })

    arena_marker:add_triggerer(DgnTriggerer:new {
        type = "turn",
        delay = 1
    })

    dgn.persist.arena_sprint_boss_set = arena_sprint_init_boss_table()

    -- Storing this in dgn.persist rather than arena_marker.data so that
    -- arena_sprint_score can access it.
    dgn.persist.arena_style_points = 0
    dgn.persist.calc_score = global_function("arena_sprint_score");

    lua_marker("{", arena_marker)
    lua_marker("{", portal_desc { centre_point = 1 })
    lua_marker("T", portal_desc { spawn_point = 1, north = 1 })
    lua_marker("U", portal_desc { spawn_point = 1, east = 1 })
    lua_marker("V", portal_desc { spawn_point = 1, south = 1 })
    lua_marker("W", portal_desc { spawn_point = 1, west = 1 })
    lua_marker("Y", portal_desc { spawn_point = 1, north = 1, west = 1 })
    lua_marker("Z", portal_desc { spawn_point = 1, north = 1, east = 1 })
    lua_marker("!", portal_desc { spawn_point = 1, south = 1, west = 1 })
    lua_marker("?", portal_desc { spawn_point = 1, south = 1, east = 1 })

    set_feature_name("dry_fountain", "spawn point")

    crawl.mpr("<cyan>You have entered the arena!\n" ..
              "You will win if you kill everything that spawns (including allies).\n" ..
              "If it is a boss round, you only need to kill the boss in order to win.\n" ..
              "If it is a lightning round, you only need to survive!</cyan>")
}}
# No exploration gods. Positions are random, and you don't have enough time to
# reach an altar before the game starts.
# NB: At present, there are 24 slots in the map, that's enough to take
# us to up to 'u'; if you want more you'll have to rejigger the map.
NSUBST: B = 0 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / h / i / j / k / l / \
            m / n / o / p / q / *:.
KFEAT:  0 = altar_zin
KFEAT:  1 = altar_the_shining_one
KFEAT:  2 = altar_lugonu
KFEAT:  3 = altar_kikubaaqudgha
KFEAT:  4 = altar_yredelemnul
KFEAT:  5 = altar_xom
KFEAT:  6 = altar_vehumet
KFEAT:  7 = altar_okawaru
KFEAT:  8 = altar_makhleb
KFEAT:  9 = altar_sif_muna
KFEAT:  h = altar_trog
KFEAT:  i = altar_beogh
KFEAT:  j = altar_cheibriados
KFEAT:  k = altar_fedhas
KFEAT:  l = altar_dithmenos
KFEAT:  m = altar_gozag
KFEAT:  n = altar_qazlal
KFEAT:  o = altar_ru
KFEAT:  p = altar_uskayaw
KFEAT:  q = altar_wu_jian
KITEM:  { = scroll of blinking q:3, scroll of fog q:3 pre_id, \
            potion of heal wounds q:3, potion of haste q:3, \
            any blast wand charges:5 pre_id, \
            any beam wand charges:5 pre_id, \
            potion of resistance pre_id, gold q:200
KFEAT:  { = {

# Shops have the same prices and (largely) the same items. Early on, you can
# only afford a few things. If you make it far enough, you'll be getting enough
# gold to buy anything you want.
#
# One shop sells experience potions for 500 gold. Later on, this is a good price.
# Early on it's a bit of a trap - that 500 can buy a lot of crucial items, and
# early experience levels come quickly enough that the potions aren't worth it.
#
# For your convenience, shop positions are not randomized, and are roughly
# grouped by category.

KFEAT:  C = scroll shop type:Sphere suffix:Station count:8 greed:17 use_all ; \
            orb ego:attunement | orb ego:energy | orb ego:glass | \
            orb ego:guile | orb ego:mayhem | orb ego:mesmerism | \
            orb ego:pyromania | orb ego:stardust
KFEAT:  D = book shop type:Must-Have suffix:Magic greed:7 count:18 use_all ; \
            book of blasting | book of blood | book of burglary | \
            book of chaos | book of death | book of displacement | \
            book of duality | book of the earth | book of hexes | \
            book of minor magic | book of the moon | book of movement | \
            book of power | book of weapons | book of the wilderness | \
            grand grimoire | necronomicon | book of annihilations
KFEAT:  EP = scroll shop greed:10 use_all count:14 ; \
            scroll of blinking q:3 | scroll of blinking q:4 | scroll of blinking q:5 |\
            scroll of fog q:3 | scroll of fog q:4 | scroll of fog q:5 |\
            scroll of silence q:3 | scroll of brand weapon | scroll of vulnerability q:3 |\
            scroll of amnesia q:5 | scroll of enchant weapon q:8 |\
            scroll of enchant armour q:4 | scroll of enchant armour q:4
KFEAT:  FS = distillery shop use_all count:17 greed:7 ; \
             potion of haste q:3 | potion of haste q:4 | potion of haste q:5 |\
             potion of attraction q:6 | potion of might q:6 | potion of brilliance q:6 |\
             potion of mutation | potion of mutation q:2 | potion of mutation q:3 |\
             potion of resistance q:6 | potion of resistance q:6 | potion of magic q:6 |\
             potion of magic q:6 | potion of berserk rage q:5 | potion of berserk rage q:5 |\
             potion of enlightenment q:2 | potion of ambrosia q:2
KFEAT:  O = distillery shop type:Do-It-Yourself suffix:Clinic count:17 use_all greed:7 ; \
            potion of heal wounds q:3 | potion of heal wounds q:3 | potion of heal wounds q:3 |\
            potion of heal wounds q:3 | potion of heal wounds q:3 | potion of heal wounds q:3 |\
            potion of heal wounds q:3 | potion of heal wounds q:3 | potion of heal wounds q:3 |\
            potion of heal wounds q:3 | potion of heal wounds q:3 | potion of heal wounds q:3 |\
            potion of curing q:4 | potion of curing q:4 | potion of curing q:4 |\
            potion of curing q:4 | potion of curing q:4
KFEAT:  I = antiques shop type:Jewellery count:17 greed:9 ; \
            any jewellery randart
KFEAT:  J = general shop type:Miscellaneous suffix:Merchandise count:14 greed:15 use_all ; \
            ring of protection from fire | ring of protection from cold |\
            ring of positive energy | ring of poison resistance |\
            ring of willpower | ring of see invisible | \
            amulet of reflection | amulet of regeneration | any misc | any misc
KFEAT:  K = antique armour shop count:17 use_all type:Advanced suffix:Armour greed:35 ; \
            pair of gloves randart | pair of gloves randart | pair of boots randart |\
            pair of boots randart | helmet randart | hat randart | buckler randart |\
            kite shield randart | cloak randart | cloak randart | robe randart | animal skin randart |\
            tower shield randart | robe randart | buckler randart | leather armour randart
KFEAT:  L = armour shop count:18 greed:12 type:Basic suffix:Armour use_all ; \
            mundane storm dragon scales | mundane fire dragon scales |\
            mundane shadow dragon scales | mundane quicksilver dragon scales |\
            mundane ice dragon scales | mundane golden dragon scales |\
            mundane steam dragon scales | mundane swamp dragon scales |\
            mundane pearl dragon scales | mundane acid dragon scales |\
            mundane troll leather armour | mundane crystal plate armour |\
            mundane plate armour | mundane barding | mundane cloak |\
            mundane buckler | mundane pair of gloves | mundane helmet
KFEAT:  M = jewellery shop type:Timeless suffix:Talismans count:19 greed:7 use_all ; \
            quill talisman | inkwell talisman | rimehorn talisman |\
            scarab talisman | medusa talisman | maw talisman | blade talisman |\
            serpent talisman | spider talisman | lupine talisman |\
            wellspring talisman | fortress talisman | sanguine talisman |\
            dragon-coil talisman | granite talisman | riddle talisman |\
            hive talisman | storm talisman | talisman of death
KFEAT:  N = weapon shop type:Staff suffix:Store count:7 use_all greed:30 ; \
            staff of fire | staff of air | staff of earth | staff of cold |\
            staff of alchemy | staff of necromancy | staff of conjuration
KFEAT:  Q = weapon shop type:Weapon suffix:Rack count:17 use_all greed:30 ; \
            mundane quick blade | mundane demon blade |\
            mundane triple sword | mundane broad axe |\
            mundane executioner's axe | mundane demon whip |\
            mundane great mace | mundane giant spiked club |\
            mundane partisan | mundane bardiche |\
            mundane lajatang | mundane longbow |\
            mundane hand cannon | mundane triple crossbow
KFEAT:  H = distillery shop type:Bottled suffix:Wisdom count:5 use_all greed:6 ; \
            potion of experience q:1 | potion of experience q:1 |\
            potion of experience q:2 | potion of experience q:3 |\
            potion of experience q:3
KFEAT:  R = general shop type:Premium suffix:Goods use_all count:11 greed:20 ; \
            quad damage | quad damage | quad damage |\
            potion of heal wounds q:5 | potion of heal wounds q:5 |\
            potion of haste q:5 | potion of haste q:5 | \
            any misc | any misc | any misc | any misc
SUBST:  b : cb
TILE:   c = wall_marble
KFEAT:  TUVWYZ!? = dry_fountain
TILE:   TUVWYZ!? = floor_black_cobalt
COLOUR: TUVWYZ!? = magenta
MAP
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXcccccXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXccTTTccXXXXXXXXXXXXXX
XXXXXXXXXXXXXXc.....cXXXXXXXXXXXXXX
XXXXXXXXXXXXXcc.....ccXXXXXXXXXXXXX
XXXXXXXXXXXXccP.....DccXXXXXXXXXXXX
XXXXXXXXXXXXcE.......NcXXXXXXXXXXXX
XXXXXXXXXXXXcB.......BcXXXXXXXXXXXX
XXXXXXXXXXXXcB.......BcXXXXXXXXXXXX
XXXXXXXXXXXXcB.......BcXXXXXXXXXXXX
XXXXXXXXXXccc.........cccXXXXXXXXXX
XXXXXXXXXXcY...........ZcXXXXXXXXXX
XXXXXcccccc.G.........G.ccccccXXXXX
XXXXccMBBB......xxx......BBBFccXXXX
XXcccI........G.xxx.G........ScccXX
Xcc.............xxx.............ccX
XcW..........xxx...xxx..........UcX
XcW..........xxx.{.xxx..........UcX
XcW..........xxx...xxx..........UcX
Xcc.............xxx.............ccX
XXcccK........G.xxx.G........HcccXX
XXXXccCBBB......xxx......BBBOccXXXX
XXXXXcccccc.G.........G.ccccccXXXXX
XXXXXXXXXXc!...........?cXXXXXXXXXX
XXXXXXXXXXccc.........cccXXXXXXXXXX
XXXXXXXXXXXXcB.......BcXXXXXXXXXXXX
XXXXXXXXXXXXcB.......BcXXXXXXXXXXXX
XXXXXXXXXXXXcB.......BcXXXXXXXXXXXX
XXXXXXXXXXXXcR.......QcXXXXXXXXXXXX
XXXXXXXXXXXXccJ.....LccXXXXXXXXXXXX
XXXXXXXXXXXXXcc.....ccXXXXXXXXXXXXX
XXXXXXXXXXXXXXccVVVccXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXcccccXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ENDMAP
