feat: extend tiles with Tiles.isLava and Tiles.isChasm
This commit is contained in:
1 parent
b7a55eabed
commit
598dfaf79e
3 files changed
+137
No files matched your search
@@ -0,0 +1,64 @@
|
||||
-- Lever-gated treasure rooms. A vault door only swings open once every lever
|
||||
-- sharing its id has been pulled; the builder places the door at a doorway
|
||||
-- pinch point and scatters its levers only on the side already reachable
|
||||
-- without crossing it, so the puzzle is always solvable and the reward
|
||||
-- sealed behind the door is always genuinely gated by it (see builder.lua's
|
||||
-- vault placement, drawn dead last so it never perturbs any earlier
|
||||
-- system's rng sequence).
|
||||
|
||||
local Items = require("items")
|
||||
local Affixes = require("affixes")
|
||||
|
||||
local Vaults = {}
|
||||
|
||||
local treasureWeapons = {
|
||||
{ name = "vault greatsword", power = 7 },
|
||||
{ name = "vault warhammer", power = 8 },
|
||||
}
|
||||
local treasureArmors = {
|
||||
{ name = "vault aegis", power = 6 },
|
||||
}
|
||||
|
||||
-- A guaranteed affix on a base already well above anything the floor's own
|
||||
-- loot table can roll at this depth - the deterministic reward for solving
|
||||
-- the puzzle, distinct from a normal drop's coin-flip affix (see
|
||||
-- affixes.rollWeapon/rollArmor).
|
||||
function Vaults.treasure(rng, depth)
|
||||
if rng:chance(1, 2) then
|
||||
local base = treasureWeapons[rng:range(1, #treasureWeapons)]
|
||||
local item = Items.weapon(base.name, base.power + depth // 3)
|
||||
return Affixes.decorate(item, Affixes.weapon[rng:range(1, #Affixes.weapon)])
|
||||
end
|
||||
local base = treasureArmors[rng:range(1, #treasureArmors)]
|
||||
local item = Items.armor(base.name, base.power + depth // 3)
|
||||
return Affixes.decorate(item, Affixes.armor[rng:range(1, #Affixes.armor)])
|
||||
end
|
||||
|
||||
function Vaults.doorFor(level, id)
|
||||
for _, door in ipairs(level.vaultDoors) do
|
||||
if door.id == id then return door end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function allPulled(level, id)
|
||||
for _, lever in ipairs(level.vaultLevers) do
|
||||
if lever.id == id and not lever.pulled then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Pulls `lever`, an idempotent no-op returning false if it was already
|
||||
-- thrown. Returns (true, door) the instant this pull completes every lever
|
||||
-- sharing its id and the door has not opened yet, or (true, nil) for a pull
|
||||
-- that leaves the vault still sealed (or already open).
|
||||
function Vaults.pull(level, lever)
|
||||
if lever.pulled then return false end
|
||||
lever.pulled = true
|
||||
if not allPulled(level, lever.id) then return true, nil end
|
||||
local door = Vaults.doorFor(level, lever.id)
|
||||
if door and not door.opened then return true, door end
|
||||
return true, nil
|
||||
end
|
||||
|
||||
return Vaults
|
||||
Reference in new issue
Block a user