1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
|
--------------------------------------------------------------------------
-- vault.lua: Vault helper functions from more than one file.
--------------------------------------------------------------------------
-- Counting Pan runes for exits.
function count_pan_runes()
local runes = 0
for _, r in ipairs({"demonic","glowing","magical","fiery","dark"}) do
if you.have_rune(r) then
runes = runes + 1
end
end
return runes
end
-- Functionality for some of HangedMan's decor vaults.
function init_hm_decor_walldepth(e, variables)
local a = you.absdepth() * 5
if a - 75 > 0 then
e.subst(variables .. " : x:50 c:" .. a .. " b:" .. a - 75)
else
e.subst(variables .. " : x:50 c:" .. a)
end
end
-- Functionality for Kennysheep vaults.
-- c: outer vault walls
-- x: inner vault walls (could be see-through blocks, or not there at all)
-- t: doodads. fountains, statues or the more decorative walls. Sometimes get replaced by normal walls
-- w: water or lava or trees. or nothing
-- D/F opposite/adjacent vault entrances, that may or may not be there
-- E/H placed in front of the alternate doors. become w tiles if there's no door there
function ks_random_setup(e, norandomexits)
e.tags("no_pool_fixup")
-- 1/2 chance the adjacent door is there, followed by a 1/2 chance every
-- side has a door.
if norandomexits == nil then
e.tags("transparent")
if crawl.one_chance_in(2) then
e.subst("D : +")
e.subst("E : .")
if crawl.one_chance_in(2) then
e.subst("F : +")
e.subst("H : .")
else
e.subst("F : c")
e.subst("H : w")
end
else
e.subst("DF : c")
e.subst("EH : w")
end
end
--rooms have a 1/2 chance of being bordered by water or trees
--q is used as a placeholder for trees to keep them from being
-- re-selected in the next step.
e.subst("w : w.")
e.subst("w : wwwWWqq")
--room setups:
--0 : doodads replaced with walls
--1 : walls replaced with water/lava or removed. doodads may or may not be walls
--2 : doodads picked from more obvious vault decorations
selected = crawl.random2(3)
if selected == 0 then
e.subst("t : x")
e.subst("x : cvbttm")
elseif selected == 1 then
e.subst("x : ..wW")
e.subst("t : .TmbttwG")
elseif selected == 2 then
e.subst("t : .TttG")
e.subst("x : cvbtt")
end
-- Turn q into t for tree borders.
e.subst("q : t")
-- The outer walls are probably stone or rock, but can be metal or crystal.
e.subst("c : ccccxxxxvb")
-- One chance in three of turning all water on the floor into lava.
-- Tree and fountain tiles are changed so the vault looks normal.
if crawl.one_chance_in(3) then
e.subst("Wwt : l")
e.subst("T : V")
end
end
function zot_entry_setup(e)
e.tags("zot_entry")
e.place("Depths:$")
e.orient("float")
e.kitem("R = midnight gem")
e.kfeat("O = enter_zot")
e.mons("patrolling base draconian")
e.mons("fire dragon w:12 / ice dragon w:12 / storm dragon / \
shadow dragon / golden dragon w:12 / wyrmhole w:4")
e.mons("patrolling nonbase draconian")
e.kmons("0 = ettin / rakshasa / glowing shapeshifter w:5 / \
stone giant w:12 / spriggan berserker w:8 / hell knight w:5")
e.kmons("9 = fire giant w:12 / titan w:8 / vampire knight / \
spriggan air mage w:8 / deep troll earth mage w:8 / \
tengu reaver w:12 / tentacled monstrosity / lich w:2")
end
function soh_hangout()
if dgn.persist.soh_hangout == nil then
local hell_branches = { "Geh", "Coc", "Dis", "Tar" }
dgn.persist.soh_hangout = util.random_from(hell_branches)
end
return dgn.persist.soh_hangout
end
-- the Serpent should appear in exactly one hell end. Vaults that call this
-- should guarantee that `D` is present.
function serpent_of_hell_setup(e)
local b = soh_hangout()
if not you.uniques("the Serpent of Hell")
and you.in_branch(b)
and you.depth() == dgn.br_depth(b) then
e.kmons('D = the Serpent of Hell')
end
end
-- Guarantee two or three rare base types with a brand
function hall_of_blades_weapon(e)
local long_blade_type = crawl.one_chance_in(2) and "double sword"
or "triple sword"
local polearm_type = crawl.one_chance_in(2) and "partisan"
or "bardiche"
local types = {"eveningstar", "executioner's axe", polearm_type,
"lajatang", "quick blade", long_blade_type}
local egos = {"flaming", "freezing", "electrocution", "heavy",
"holy_wrath", "pain", "vampirism",
"antimagic", "distortion", "spectral"}
local weapon_t = util.random_subset(types, 3)
local weapon_e = util.random_subset(egos, 3)
e.mons("dancing weapon; good_item " .. weapon_t[1] .. " ego:" .. weapon_e[1])
e.mons("dancing weapon; good_item " .. weapon_t[2] .. " ego:" .. weapon_e[2])
e.mons("dancing weapon; good_item " .. weapon_t[3] .. " ego:" ..
weapon_e[3] .. " / nothing")
end
-- Setup for door vaults to define a common loot set and create the door
-- markers.
function door_vault_setup(e)
-- Don't generate loot in Hells, generate down hatches instead.
if you.in_branch("Geh") or you.in_branch("Tar") or you.in_branch("Coc")
or you.in_branch("Dis") then
e.kfeat("23 = >")
else
e.kitem("1 = * / nothing")
e.kitem("23 = | / nothing")
end
-- The marker affects find_connected_range() so that each door opens and
-- closes separately rather than all of them joining together into a huge
-- gate that opens all at once.
e.lua_marker('+', props_marker { connected_exclude="true" })
e.lua_marker('a',
props_marker { stop_explore="strange structure made of doors" })
e.kfeat("a = runed_clear_door")
end
--[[
Set up a KMONS for a master elementalist vault-defined monster. This monster
will have either the elemental staff or a staff of air and a robe of
resistance, so it has all of the elemental resistances.
@tab e The map environment.
@string glyph The glyph on which to define the KMONS.
]]
function master_elementalist_setup(e, glyph, ele_staff)
local equip_def = " ; elemental staff . robe ego:willpower good_item"
-- Don't want to use the fallback here, so we can know to give resistance
-- ego robe if the elemental staff isn't available.
if you.unrands("elemental staff") then
equip_def = " ; staff of air . robe ego:resistance good_item"
end
e.kmons(glyph .. " = occultist hd:18 name:master_elementalist n_rpl" ..
" n_des n_noc tile:mons_master_elementalist" ..
" spells:lehudib's_crystal_spear.11.wizard;" ..
"chain_lightning.11.wizard;" ..
"fire_storm.11.wizard;" ..
"ozocubu's_refrigeration.11.wizard;" ..
"haste.11.wizard;" ..
"repel_missiles.11.wizard" .. equip_def)
end
-- Three sets of reusable vault feature redefines scattered across the game,
-- kept in this one function for both consistency and ease of use.
function vault_granite_statue_setup(e, glyph, type)
e.kfeat(glyph .. " = granite_statue")
-- Feature name, console colour, tile name.
local statues = {
["broken pillar"] = {"lightgrey", "dngn_crumbled_column"},
["gravestone"] = {"lightgrey", "dngn_gravestone"},
["sarcophagus"] = {"yellow", "dngn_sarcophagus_pedestal_right"},
["scintillating statue"] = {"mountain", "dngn_scintillating_statue"},
}
for name, contents in pairs(statues) do
if type == name then
e.colour(glyph .. " = " .. contents[1])
e.tile(glyph .. " = " .. contents[2])
end
end
e.set_feature_name("granite_statue", type)
end
function vault_metal_statue_setup(e, glyph, type)
e.kfeat(glyph .. " = metal_statue")
local statues = {
["golden statue"] = {"yellow", "dngn_golden_statue"},
["silver statue"] = {"silver", "dngn_silver_statue"},
["iron statue"] = {"cyan", "dngn_statue_iron"},
["mystic cage"] = {"mist", "dngn_mystic_cage"},
["arcane conduit"] = {"vehumet", "arcane_conduit"},
["misfortune conduit"] = {"shimmer_blue", "misfortune_conduit"},
["dimensional conduit"] = {"warp", "dimensional_conduit"},
["soul conduit"] = {"smoke", "soul_conduit"},
["alchemical conduit"] = {"poison", "alchemical_conduit"},
["fiery conduit"] = {"fire", "fiery_conduit"},
["icy conduit"] = {"ice", "icy_conduit"},
["earthen conduit"] = {"earth", "earthen_conduit"},
["storm conduit"] = {"electricity", "storm_conduit"},
["enigmatic dynamo"] = {"magic", "dngn_enigmatic_dynamo"},
["nascence circuit"] = {"magic", "dngn_nascence_circuit"}
}
for name, contents in pairs(statues) do
if type == name then
e.colour(glyph .. " = " .. contents[1])
e.tile(glyph .. " = " .. contents[2])
end
end
e.set_feature_name("metal_statue", type)
end
function decorative_floor (e, glyph, type)
e.kfeat(glyph .. ' = decorative_floor')
local dec = {
["flower patch"] = {"green", "dngn_flower_patch"},
["garden patch"] = {"yellow", "dngn_garden_patch"},
["floral vase"] = {"yellow", "dngn_flower_pot"},
["mourning vase"] = {"magenta", "dngn_dark_flower_pot"},
["broken floral vase"] = {"magenta", "dngn_flower_pot_broken / " ..
"dngn_dark_flower_pot_broken"},
["orcish standard"] = {"lightcyan", "dngn_ensign_beogh"},
["infernal standard"] = {"red", "dngn_ensign_gehenna"},
["fur brush"] = {"brown", "dngn_yak_fur"},
["mop and bucket"] = {"lightblue", "dngn_mop"},
["bloodied mop and bucket"] = {"lightred", "dngn_mop_bloody"}
}
for name, contents in pairs(dec) do
if type == name then
e.colour(glyph .. " = " .. contents[1])
e.tile(glyph .. " = " .. contents[2])
end
end
e.set_feature_name('decorative_floor', type)
end
-- A reusable poison / fire / snake theming for statues that show up in Snake.
function snake_statue_setup (e, glyph)
if crawl.x_chance_in_y(2, 3) then
vault_metal_statue_setup(e, glyph, "alchemical conduit")
else
vault_metal_statue_setup(e, glyph, "fiery conduit")
end
e.tile("G : dngn_statue_naga / dngn_statue_archer w:7")
end
-- A function that uses what's in the mon-pick-data (and bands) for V in 0.32
-- for several distinct, tiered, depths-scaling themes + decorations.
function index_vaults_room_themes (e, set, hard)
e.tags('luniq_vaults_room_' .. set)
local d = you.depth() + 1
if hard then
e.tags("vaults_hard")
d = d + 1
else
e.tags("vaults_room")
end
if set == 'magic' then
local sl = 1
if crawl.x_chance_in_y(d, 10) then
sl = sl + 1
end
e.mons('ugly thing w:' .. 7 - d .. ' / lindwurm w:4 / ' ..
'freezing wraith w:4 / crystal guardian w:' .. d)
e.mons('great orb of eyes w:' .. 7 - d .. ' / ' ..
'boggart band w:5 / glowing orange brain w:' .. d + 1)
e.mons('arcanist w:' .. 14 - d * 2 .. ' / sphinx marauder w:8 / ' ..
'ironbound convoker w:4 / ironbound mechanist w:4')
e.mons('deep elf annihilator / deep elf sorcerer / lich / ' ..
'guardian sphinx w:5 / tengu reaver')
e.item('robe / mundane hat')
e.item('randbook numspells:1 slevels:' .. sl .. ' / ' ..
'mundane ring of magical power w:2')
e.tile('c = wall_studio')
elseif set == 'icebox' then
e.tags('no_wall_fixup')
local f = 'ego:freezing pre_id'
local c = 'ego:cold_resistance pre_id'
e.mons('white ugly thing w:' .. 8 - d * 2 .. ' / ' ..
'redback simulacrum w:' .. 8 - d * 2 .. ' / ' ..
'freezing wraith w:2 / guardian sphinx simulacrum w:' .. d - 1)
e.mons('necromancer w:2 / arcanist / white very ugly thing')
e.mons('ironbound frostheart / frost giant w:1')
e.mons('golden dragon / tengu reaver w:25 ; halberd ' .. f .. ' | war axe ' .. f ..
' . ring mail ' .. c)
e.kitem('d : dagger ' .. f .. ' no_pickup / ' ..
'long sword ' .. f .. ' no_pickup/ ' ..
'mace ' .. f .. ' no_pickup')
e.kitem('e = robe ' .. c .. ' / leather armour ' .. c)
e.kfeat('m = cache of meat')
e.kfeat('I = rock_wall')
e.tile('I = wall_ice_block')
e.tile('v = dngn_metal_wall_lightblue')
e.set_feature_name("rock_wall", "ice covered rock wall")
elseif set == 'garden' then
e.tags('no_pool_fixup')
e.mons('harpy w:' .. 80 - d * 20 .. ' / ' ..
'redback w:' .. 100 - d * 16 .. ' / ' ..
'wolf spider w:' .. 20 - d * 3 .. ' / ' ..
'lindwurm w:' .. 140 - d * 20 .. ' / ' ..
'dire elephant w:' .. d * 3 )
e.mons('dire elephant w:' .. 18 - d * 3 .. ' / ' ..
'formless jellyfish w:' .. 2 + d * 4 .. ' / ' ..
'guardian sphinx w:' .. 2 + d * 2)
e.mons('ironbound preserver w:' .. 10 - d * 2 .. ' / ' ..
'entropy weaver w:' .. 2 + d * 3 .. ' / ' ..
'ironbound beastmaster w:' .. -2 + d * 4)
e.kmons('S = bush')
e.kfeat('F = cache of fruit')
e.ftile('`SF = floor_lair')
e.tile('T = dngn_fountain_novelty_fancy')
e.kitem('d = animal skin / club / whip w:5 / quarterstaff w:5')
decorative_floor(e, 'p', "garden patch")
elseif set == 'rangers' then
local eq = "arbalest w:29 | hand cannon w:1 . " ..
" scimitar . ring mail | scale mail"
e.mons('centaur warrior w:' .. 6 - d * 2 .. ' / ' ..
'yaktaur w:' .. 6 - d * 2 .. ' / ' ..
'polterguardian w:' .. 6 - d * 2 )
e.mons('vault sentinel w:' .. 8 - d * 2 .. ' ; ' .. eq .. ' / ' ..
'orc knight w:' .. 2 + d * 2 .. ' ; ' .. eq .. ' / ' ..
'yaktaur captain w:' .. 2 + d * 2)
e.mons('orc warlord w:' .. 2 + d * 2 .. ' ; ' .. eq .. ' / ' ..
'deep elf high priest w:' .. 2 + d * 3 .. ' / ' ..
'vault warden w:' .. 2 + d * 4 .. ' ; ' .. eq)
e.mons('stone giant')
e.kmons('U = training dummy ; nothing')
e.item('sling no_pickup w:5 / shortbow no_pickup / arbalest no_pickup')
elseif set == 'warriorcrypt' then
e.tags('no_wall_fixup')
e.mons('vault guard w:' .. 14 - d .. ' / ' ..
'vault sentinel w:' .. 10 - d .. ' / ' ..
'orc knight')
e.mons('necromancer w:' .. 10 - d .. ' / ' ..
'flayed ghost w:' .. 10 - d .. ' / ' ..
'phantasmal warrior w:' .. d + 2)
e.mons('war gargoyle w:' .. 16 - d * 2 .. ' / ' ..
'deep elf death mage w:4 / ' ..
'undying armoury w:' .. -2 + d)
e.mons('deep elf death mage w:5 / lich / ancient lich')
e.item('human skeleton / ogre skeleton w:1 / orc skeleton w:1')
e.kfeat('u = rock_wall')
e.tile('u = wall_undead')
e.tile('c = wall_crypt')
e.tile('G = dngn_statue_angel / dngn_statue_wraith / dngn_statue_twins / ' ..
'dngn_statue_dwarf / dngn_statue_sword / dngn_statue_centaur')
end
end
|