# # This portal vault is supposed to be themeless like ziggurats, # but defined by a time limit and randomized through many subvaults. # Run through and fight each room, grab the loot, and keep going, # as the gauntlet starts closing up behind you... # # Though not often seen in the homicidal rage expressed in most encounters in the Dungeon, # its demons and devils appreciate temptation and torture as much as you'd expect them to. # # # Thanks to DracoOmega for early testing. {{ function gauntlet_portal(e) local messager = timed_msg { initmsg = { "You hear the roar of a distant crowd.", "There is an entrance to a gauntlet on this level. " .. "Hurry and find it before the portal moves!" }, finalmsg = "The crackling of melting ice is subsiding rapidly.", verb = 'restlessness', noisemaker = 'crowd', ranges = { { 5000, 'faint ' }, { 4000, '' }, { 2500, 'steady ' }, { 1500, 'rapid ' }, { 0, 'loud ' } } } dgn.persist.gauntlet_hard = gauntlet_difficulty() e.lua_marker('O', timed_marker { disappear = "The archway melts and disappears.", desc = "frozen archway", entity = 'archway', dst = "IceCv", dstname = "ice_cave", overview = "frozen archway", turns = timeout_turns_long, turns_short = timeout_turns_short, floor = "expired_portal", feat_tile = "dngn_portal_ice_cave_gone", msg = messager }) e.kfeat("O = enter_portal_vault") e.colour("O = white") e.tile("O = dngn_portal_ice_cave") end function teleporter_gauntlet_switch_fn(data, triggerable, triggerer, marker, ev) local position = dgn.point(marker:pos()) my_slaves = dgn.find_marker_positions_by_prop("teleport_spot", data.teleport_spot) if you.teleport_to(my_slaves[1].x, my_slaves[1].y, true) then crawl.mpr("Your surroundings suddenly seem different!") else crawl.mpr("There is a strange hissing noise.") end end function gauntlet_milestone(e) crawl.mark_milestone("br.enter", "entered a Gauntlet.") end function gauntlet_subvaults(e) e.tags('no_monster_gen no_item_gen no_pool_fixup') e.tags('allow_dup luniq') e.weight('2') e.kfeat('M = iron_grate') end function gauntlet_bosses(e) e.mons("fire giant / ettin / " .. "orc warlord ; battleaxe good_item race:orcish . " .. "plate armour race:orcish / " .. "deep elf annihilator / deep elf high priest / " .. "satyr / alligator snapping turtle / " .. "storm dragon / ancient bear / ghost moth / " .. "flayed ghost / vampire knight / unborn / " .. "eidolon / ghoul / acid blob / " .. "thorn hunter / treant / green death / " .. "reaper / blizzard demon / cacodemon / " .. "starcursed mass") e.mons("titan / sphinx / greater naga / " .. "spriggan defender / deep elf master archer / " .. "deep elf blademaster / draconian knight / " .. "quicksilver dragon / iron dragon / " .. "shadow dragon / golden dragon / " .. "ancient champion / profane servitor / bone dragon / " .. "lich / revenant / mummy priest / " .. "glowing shapeshifter hd:18 / " .. "dancing weapon ; glaive good_item ident:type / " .. "balrug / hellion / tentacled monstrosity / " .. "apocalypse crab / executioner / angel") e.mons("greater mummy / draconian annihilator / " .. "draconian scorcher / draconian zealot / " .. "ancient lich / electric golem / " .. "brimstone fiend / ice fiend / shadow fiend / " .. "curse skull / eldritch tentacle / " .. "daeva / pearl dragon") end function gauntlet_items(e) -- If we're going to involve monsters across all branches, -- we might as well offer an extremely wide range of potential loot -- always containing items worth caring about. -- XXX: Not balanced in the slightest. e.kitem('% = potion of curing / potion of heal wounds / \ potion of might / potion of agility / potion of brilliance / \ potion of invisibility / potion of restore abilities / \ potion of berserk rage / scroll of identify / \ scroll of fear / scroll of magic mapping / \ honeycomb q:6') e.kitem('* = any book / potion of speed / potion of magic / \ potion of resistance / scroll of summoning / \ scroll of enchant armour q:1 / scroll of vulnerability / \ wand of cold / wand of fire / naga barding / centaur barding / \ ring of regeneration / ring of invisibility / \ ring of teleport control / ring of slaying w:2 / \ amulet of resist mutation / amulet of faith / \ amulet of conservation / \ fan of gales / stone of tremors / phial of floods / \ lamp of fire / legendary deck') e.kitem('| = wand of heal wounds / wand of hasting / wand of teleportation / \ demon trident / demon whip / demon blade / \ trishula / sacred scourge / eudemon blade / \ mottled dragon armour / pearl dragon armour / \ crystal plate armour / gold dragon armour / \ ring of slaying randart good_item / ring of wizardry randart good_item / \ ring of regeneration randart good_item / \ ring of teleport control randart good_item / \ amulet of faith randart good_item / \ amulet of conservation randart good_item / \ scroll of blinking q:5 / scroll of fog q:5 / \ scroll of enchant armour q:5 / scroll of enchant weapon III q:5 / \ scroll of recharging q:5 / scroll of magic mapping q:5 / \ bolt ego:steel q:100 w:5 / bolt ego:penetration q:100 w:5 / \ arrow ego:dispersal q:100 / sling bullet ego:steel q:100 / \ javelin ego:steel q:20 w:5 / bolt ego:penetration q:20 w:5 / \ Necronomicon / royal jelly q:5 / piece of ambrosia q:5 / \ potion of beneficial mutation q:2 / \ potion of cure mutation q:2 / potion of experience q:2 / \ acquire gold / any rod') end -- Check placing an easy or hard gauntlet by depth. -- Easy gauntlets appear in D:14-19 and Vaults:1. -- Hard gauntlets appear in D:19-27, Elf:1-3, and Vaults:1-4. -- The portal vault was intended to add variety to post-Lair post-Orc portals, -- but this might not be enough early placements; what would be appropiate? function gauntlet_difficulty() -- "First default to easy destinations." local hard = false -- "Handle overlapping [depth] for easy and hard maps with a coinflip." if you.branch() == "D" and you.depth() == 19 or you.branch() == "Vaults" and you.depth() == 1 then hard = crawl.coinflip() end if you.branch() == "D" and you.depth() >= 20 or you.branch() == "Elf" or you.branch() == "Vaults" and you.depth() >= 1 then hard = true end return hard end }} ################################################################################ # Entries. default-depth: D:18-, Vaults, Elf, Crypt, Forest NAME: gauntlet1 TAGS: uniq_gauntlet transparent chance_gauntlet ORIENT: float : gauntlet_portal(_G) MAP ..b. .b..bb. .bb.b.. b..O..b ..b.bb. .bb..b. ..b.. ENDMAP # Mock-ups of the gauntlet structure with randomly chosen enemies... # or a bunch of closets that could lead to a portal seen immeadiately with glass. # The portal vault itself is about rushing, the entries could try to as well, ################################################################################ # Portal branch maps. # default-depth: Gauntlet default-depth: IceCv # Man, I'd prefer the subvaults arranged by diagonals to save space. # Possible reconstructive work for later. # NAME: gauntlet2 TAGS: no_monster_gen no_item_gen generate_awake patrolling ORIENT: encompass : gauntlet_bosses(_G) KFEAT: < = exit_portal_vault KFEAT: DEFGHIJKPQRS-( = teleporter KFEAT: defghijkpqrs_) = floor TILE: o = dngn_transparent_wall_blue COLOUR: o = blue LFLOORTILE: floor_marble LFLOORCOL: magenta TILE: X = wall_marble COLOUR: X = white COLOUR: DEFGHIJKPQRS-( = warp COLOUR: defghijkpqrs_) = gold FTILE: DEFGHIJKPQRS-( = floor_crystal_squares FTILE: defghijkpqrs_) = floor_black_cobalt NSUBST: D = 1:E / *:D, F = 1:H / *:F, G = 1:H / *:G, I = 1:K / *:I, J = 1:K / *:J NSUBST: P = 1:R / *:P, Q = 1:R / *:Q, - = 1:S / *:-, ( = 1:S / *:( SUBST: ! = F, ? = G, @ = I, & = J, ^ = P, ~ = Q, [ = -, ] = ( : gauntlet_items(_G) {{ local teleporter_glyph = "DEFGHIJKPQRS-(" local teleport_spot_glyph = "defghijkpqrs_)" local tele_marker = {} for i = 1, #teleporter_glyph do tele_marker[i] = TriggerableFunction:new { func="teleporter_gauntlet_switch_fn", data = {teleport_spot=i}, repeated=true } tele_marker[i]:add_triggerer(DgnTriggerer:new { type="player_move" }) lua_marker(teleporter_glyph:sub(i,i), tele_marker[i]) lua_marker(teleport_spot_glyph:sub(i,i), portal_desc { teleport_spot=i}) end }} MAP XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXFXXXXXFXXXXXIXXXXXIXXXXXPXXPXXPXXXXX-XX-XX-XXXXXXXXXXXX XXXXXX.......XXXXX.......XXXXX.......XXXXX.......XXXX..XXXXXX XX.X.X.....1.X..XX.1.....X..XX.....2.X..XX.2.....X..X....XXXX XX...X...c...X..XX...c...X..XX...c...X..XX...c...X..XX....XXX XX...X...f...X!.XX...i...X@.XX...p...X^.X-..._...X[.XX....XXX XX...X...c...X..XX...c...X..XX...c...X..XX...c...X..XX.....XX XXD.DX.1.....X..XX.....2.X..XX.2.....X..XX.....3.X..XX.%...XX XX...X.......X..XX.......X..XX.......X..XX.......X..XX%|%.XXX XX...XFXoXoXFX..XXIXoXoXIX..XXPXoXoXPX..XX-XoXoX-X..XX.%..XXX XX...XXXoXoXXX..XXXXoXoXXX..XXXXoXoXXX..XXXXoXoXXX..oo....XXX XXAd