feat: add Quests.generate, Quests.describe and Ranged.ammoIndex
This commit is contained in:
1 parent
54569d9e04
commit
10488b48e8
2 files changed
+163
No files matched your search
@@ -0,0 +1,90 @@
|
||||
-- Bounty boards scattered through the dungeon from depth two on. Each board
|
||||
-- is built with exactly one bounty already written on it (a cull, a hoard or
|
||||
-- a depth pact), fixed at generation time from the floor's own rng so a given
|
||||
-- (worldSeed, depth) always offers the identical bounty. Standing on an
|
||||
-- unclaimed board binds the player to its pact for free (no turn spent, same
|
||||
-- as learning a skill); a board only ever grants one bounty in its lifetime,
|
||||
-- so re-rolling by revisiting an already-claimed board is not possible. A
|
||||
-- bound pact resolves itself the instant its condition is met - no trip back
|
||||
-- to the board required - paying out gold, xp and essence in one stroke.
|
||||
|
||||
local Monsters = require("monsters")
|
||||
|
||||
local Quests = {}
|
||||
|
||||
Quests.CULL = "cull"
|
||||
Quests.HOARD = "hoard"
|
||||
Quests.DEPTH = "depth"
|
||||
|
||||
-- Fixed order so a given rng draw always names the same kind.
|
||||
Quests.order = { Quests.CULL, Quests.HOARD, Quests.DEPTH }
|
||||
|
||||
-- Builds the one bounty a freshly placed board offers on `depth`, clamping any
|
||||
-- depth target to `maxDepth` so a pact can never demand the unreachable.
|
||||
function Quests.generate(rng, depth, maxDepth)
|
||||
local kind = Quests.order[rng:range(1, #Quests.order)]
|
||||
local bounty = {
|
||||
kind = kind,
|
||||
rewardGold = 15 + depth * 8,
|
||||
rewardXp = 10 + depth * 4,
|
||||
}
|
||||
if kind == Quests.CULL then
|
||||
local eligible = Monsters.forDepth(depth)
|
||||
local spec = eligible[rng:range(1, #eligible)]
|
||||
bounty.species = spec.key
|
||||
bounty.speciesName = spec.name
|
||||
bounty.need = rng:range(2, 4)
|
||||
bounty.have = 0
|
||||
elseif kind == Quests.HOARD then
|
||||
bounty.need = 40 + depth * 20
|
||||
else
|
||||
bounty.need = math.min(depth + rng:range(2, 4), maxDepth)
|
||||
end
|
||||
return bounty
|
||||
end
|
||||
|
||||
function Quests.describe(bounty)
|
||||
if bounty.kind == Quests.CULL then
|
||||
return string.format("cull %d %s (%d/%d)", bounty.need, bounty.speciesName, bounty.have, bounty.need)
|
||||
elseif bounty.kind == Quests.HOARD then
|
||||
return string.format("amass %d gold", bounty.need)
|
||||
end
|
||||
return string.format("reach depth %d", bounty.need)
|
||||
end
|
||||
|
||||
-- Binds `player` to `board`'s bounty, provided the player is not already
|
||||
-- bound to one and the board has not already been claimed. Returns (true,
|
||||
-- line) on success or (false, line) explaining why not.
|
||||
function Quests.accept(player, board)
|
||||
if player.quest then
|
||||
return false, "you already hold a bounty"
|
||||
end
|
||||
if board.claimed then
|
||||
return false, "this board's ledger is already spent"
|
||||
end
|
||||
board.claimed = true
|
||||
player.quest = board.quest
|
||||
return true, "you bind yourself to a bounty: " .. Quests.describe(board.quest)
|
||||
end
|
||||
|
||||
-- Registers a kill toward the player's active cull bounty if the species
|
||||
-- matches. A no-op for any other kind, an unrelated species, or no bounty.
|
||||
function Quests.registerKill(player, species)
|
||||
local bounty = player.quest
|
||||
if bounty and bounty.kind == Quests.CULL and species == bounty.species and bounty.have < bounty.need then
|
||||
bounty.have = bounty.have + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- True once `player`'s active bounty (if any) is fulfilled by the current
|
||||
-- state: a cull once its tally is met, a hoard once live gold clears its
|
||||
-- absolute target, a depth pact once the player has reached it.
|
||||
function Quests.resolved(player, depth)
|
||||
local bounty = player.quest
|
||||
if not bounty then return false end
|
||||
if bounty.kind == Quests.CULL then return bounty.have >= bounty.need end
|
||||
if bounty.kind == Quests.HOARD then return player.gold >= bounty.need end
|
||||
return depth >= bounty.need
|
||||
end
|
||||
|
||||
return Quests
|
||||
Reference in new issue
Block a user