feat: extend game with Game:learnSkill and Game:useSkill
This commit is contained in:
1 parent
b4e2c7a431
commit
e850ef2d5e
1 file changed
+115
-8
+115
-8
@@ -2295,27 +2295,134 @@ function Game:hungerTorchTick()
|
||||
self.player.hp = math.min(self.player.maxHp, self.player.hp + weatherRegen)
|
||||
end
|
||||
end
|
||||
local curseDrain = Curses.drainAmount(self.player)
|
||||
if curseDrain > 0 then
|
||||
self.player.hp = self.player.hp - curseDrain
|
||||
self.log:add("a cursed affliction saps your strength")
|
||||
end
|
||||
local diseaseLine = Disease.tick(self.player)
|
||||
if diseaseLine then self.log:add(diseaseLine) end
|
||||
local hungerLine = Hunger.tick(self.player)
|
||||
if hungerLine then self.log:add(hungerLine) end
|
||||
if self.player.light.fuel > 0 then
|
||||
self.player.light.fuel = self.player.light.fuel - 1
|
||||
end
|
||||
if self.player.mana < self.player.maxMana then
|
||||
self.player.mana = self.player.mana + 1
|
||||
end
|
||||
end
|
||||
|
||||
function Game:endPlayerTurn()
|
||||
self.turnState = nil
|
||||
Scheduler.spend(self.player)
|
||||
self:hungerTorchTick()
|
||||
Hazards.step(self.level, self.rng)
|
||||
Nodes.step(self.level)
|
||||
Corpses.step(self.level)
|
||||
for _, trap in ipairs(Disarm.sweep(self.level, self.rng, self.player.x, self.player.y)) do
|
||||
self.log:add("you notice a hidden trap nearby")
|
||||
end
|
||||
for _, door in ipairs(Secrets.sweep(self.level, self.rng, self.player.x, self.player.y)) do
|
||||
self.log:add("you notice a hidden door in the wall")
|
||||
end
|
||||
local eventLine = Events.step(self.level, self.rng)
|
||||
if eventLine then self.log:add(eventLine) end
|
||||
Skills.tickCooldowns(self.player)
|
||||
self:resolveQuest()
|
||||
self.turn = self.turn + 1
|
||||
if self.turn % Mercenaries.WAGE_INTERVAL == 0 then
|
||||
local wageLine = Mercenaries.payWage(self)
|
||||
if wageLine then self.log:add(wageLine) end
|
||||
end
|
||||
self:computeVisible()
|
||||
local sanityLine = Sanity.tick(self)
|
||||
if sanityLine then self.log:add(sanityLine) end
|
||||
if Sanity.rollScream(self.rng, self) then
|
||||
self.log:add("a scream of raw terror tears from your throat")
|
||||
end
|
||||
if self.horde then
|
||||
local hordeLine = Horde.tick(self)
|
||||
if hordeLine then self.log:add(hordeLine) end
|
||||
end
|
||||
end
|
||||
|
||||
-- Spends a skill point to permanently learn `key`, gated by class, level and
|
||||
-- point balance (see skills.lua). Free of any turn cost.
|
||||
function Game:learnSkill(key)
|
||||
local success, message = Skills.learn(self.player, key)
|
||||
if message then self.log:add(message) end
|
||||
return success
|
||||
end
|
||||
|
||||
-- Attempts to use the active skill `key`, forwarding any extra arguments
|
||||
-- (a target monster, or two for multishot) straight to skills.lua.
|
||||
function Game:useSkill(key, ...)
|
||||
local success, lines = Skills.use(self, key, ...)
|
||||
self.log:addAll(lines)
|
||||
return success
|
||||
end
|
||||
|
||||
-- Shared head of any player turn, whether the autopilot or a typed command
|
||||
-- is about to decide what happens next: runs every other actor up to the
|
||||
-- player, ticks the status/water/hazard afflictions that land on the
|
||||
-- player's own turn boundary, and rolls the stun/panic checks that can
|
||||
-- consume the turn before any action is even chosen. Returns "halt" once
|
||||
-- play cannot continue this call (already won, or dead at any point along
|
||||
-- the way - the caller must not act or spend a turn), "skip" once the turn
|
||||
-- is already spent on a stun or a panic scream, or "ready" once the caller
|
||||
-- is clear to choose and perform an action of its own.
|
||||
--
|
||||
-- Cached on self.turnState until Game:endPlayerTurn clears it, so calling
|
||||
-- this more than once before a turn is actually spent - the one new
|
||||
-- situation Game:manualStep introduces, since a rejected typed command
|
||||
-- spends no turn and its caller is free to just try again - never re-rolls
|
||||
-- the stun/panic check or re-ticks poison, fire or hunger a second time for
|
||||
-- a turn the player has not actually finished taking yet. Game:autoStep
|
||||
-- never revisits an unspent turn this way, so the cache is invisible to it.
|
||||
function Game:beginTurn()
|
||||
if self.turnState then return self.turnState end
|
||||
if self.won then self.turnState = "halt"; return "halt" end
|
||||
self:runToPlayer()
|
||||
if not self.player:isAlive() then self.turnState = "halt"; return "halt" end
|
||||
self.log:addAll(Status.tick(self.player))
|
||||
if not self.player:isAlive() then self.turnState = "halt"; return "halt" end
|
||||
Conductivity.tick(self.level, self.player)
|
||||
local hazardLine = Hazards.afflict(self.level, self.player)
|
||||
if hazardLine then self.log:add(hazardLine) end
|
||||
if not self.player:isAlive() then self.turnState = "halt"; return "halt" end
|
||||
if Status.skipsTurn(self.player) then
|
||||
self.log:add("you are stunned")
|
||||
self.turnState = "skip"
|
||||
elseif Sanity.rollPanic(self.rng, self.player) then
|
||||
self.log:add("terror seizes you and the turn slips away")
|
||||
self.turnState = "skip"
|
||||
else
|
||||
self.turnState = "ready"
|
||||
end
|
||||
return self.turnState
|
||||
end
|
||||
|
||||
function Game:autoStep()
|
||||
self:runToPlayer()
|
||||
if not self.player:isAlive() then return end
|
||||
self.log:addAll(Status.tick(self.player))
|
||||
if not self.player:isAlive() then return end
|
||||
if Status.skipsTurn(self.player) then
|
||||
self.log:add("you are stunned")
|
||||
else
|
||||
self:choosePlayerAction()
|
||||
local state = self:beginTurn()
|
||||
if state == "halt" then return end
|
||||
if state == "ready" then self:choosePlayerAction() end
|
||||
self:endPlayerTurn()
|
||||
end
|
||||
|
||||
-- Human-driven counterpart to Game:autoStep: runs the exact same pre-turn
|
||||
-- checks, then hands `text` to commands.lua instead of letting
|
||||
-- choosePlayerAction decide on its own. Returns (consumesTurn, message) from
|
||||
-- Commands.apply so a caller (warren.lua's --play REPL, or a test driving a
|
||||
-- fixed script of commands) can tell a wasted keystroke from a turn the
|
||||
-- world actually answered. A stun or panic rolled during beginTurn still
|
||||
-- spends the turn and ends it exactly like autoStep, without ever looking at
|
||||
-- `text` - the player was never in control of that turn to begin with.
|
||||
function Game:manualStep(text)
|
||||
local state = self:beginTurn()
|
||||
if state == "halt" then return false, "there is nothing left to do" end
|
||||
if state == "skip" then
|
||||
self:endPlayerTurn()
|
||||
return true, nil
|
||||
end
|
||||
self:endPlayerTurn()
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user