From c33c502307523aaaad055811683f96376c47a2d5 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Sun, 6 Sep 2026 15:37:04 +0200 Subject: [PATCH] feat: extend game with Game:castSpell and Game:throwAt --- src/game.lua | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/game.lua b/src/game.lua index 79cff2f..27ade50 100644 --- a/src/game.lua +++ b/src/game.lua @@ -881,7 +881,53 @@ function Game:playerAttack(target) self.log:add(string.format("you grow more skilled with your %s (+%d attack)", masteredKey, masteredBonus)) end if outcome.killed then - self.log:add(target.name .. " dies") + self:awardKill(target) + else + local splitLine = Abilities.onHit(self, target) + if splitLine then self.log:add(splitLine) end + end +end + +-- Attempts to cast a known spell, optionally at a target monster. Returns +-- true and logs its effect on success; on failure logs why and leaves all +-- state - mana included - untouched. +function Game:castSpell(key, target) + self:provoke(target) + local success, lines = Spells.cast(self, self.player, key, target) + self.log:addAll(lines) + if success then self:emitNoise(self.player.x, self.player.y, Noise.SPELL) end + return success +end + +-- Hurls the inventory item at `index` at a monster. The item always leaves +-- the inventory on a successful throw, whatever it did on arrival. +function Game:throwAt(index, target) + local item = self.player.inventory[index] + if not item then return false end + self:provoke(target) + local success, lines = Throwing.resolve(self, self.player, item, target) + if success then + table.remove(self.player.inventory, index) + self:emitNoise(self.player.x, self.player.y, Noise.THROW) + end + self.log:addAll(lines) + return success +end + +-- Throws a net from the inventory at `index` at a battered monster instead +-- of finishing it off in melee (see captives.lua). The net always leaves +-- the inventory once thrown, whether it actually holds the target or not; +-- a genuine catch removes the target from level.entities without ever +-- routing through Game:awardKill, so it earns no xp, essence, quest credit +-- or faction kill penalty - only a captive left standing on the floor. +function Game:captureAt(index, target) + local item = self.player.inventory[index] + if not item then return false end + self:provoke(target) + local success, lines = Captives.resolve(self, self.player, item, target) + if success then + table.remove(self.player.inventory, index) + self:emitNoise(self.player.x, self.player.y, Noise.THROW) self:cleanupDead() end end