feat: extend game with Game:fireAt and Game:appeaseFaction
This commit is contained in:
1 parent
c33c502307
commit
b3943d9b6e
1 file changed
+173
+173
@@ -930,6 +930,179 @@ function Game:captureAt(index, target)
|
|||||||
self:emitNoise(self.player.x, self.player.y, Noise.THROW)
|
self:emitNoise(self.player.x, self.player.y, Noise.THROW)
|
||||||
self:cleanupDead()
|
self:cleanupDead()
|
||||||
end
|
end
|
||||||
|
self.log:addAll(lines)
|
||||||
|
return success
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Looses an arrow from the player's equipped bow at a monster. The arrow
|
||||||
|
-- always leaves the quiver on a successful shot, whatever it did on arrival.
|
||||||
|
function Game:fireAt(target)
|
||||||
|
self:provoke(target)
|
||||||
|
local success, lines = Ranged.fire(self, self.player, target)
|
||||||
|
self.log:addAll(lines)
|
||||||
|
if success then self:emitNoise(self.player.x, self.player.y, Noise.RANGED) end
|
||||||
|
return success
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Spends gold to smooth over the player's standing with `faction` (see
|
||||||
|
-- factions.lua): cools a grudge, or pads an existing friendship, by a fixed
|
||||||
|
-- amount. The asking price climbs the deeper the relationship has soured.
|
||||||
|
function Game:appeaseFaction(faction)
|
||||||
|
local success, cost = Factions.appease(self.player, faction)
|
||||||
|
if success then
|
||||||
|
self.log:add(string.format("your tribute smooths things over with the %s (%d gold)", faction, cost))
|
||||||
|
elseif cost == 0 then
|
||||||
|
self.log:add(string.format("the %s already think as well of you as they're going to", faction))
|
||||||
|
else
|
||||||
|
self.log:add(string.format("you need %d gold to make peace with the %s", cost, faction))
|
||||||
|
end
|
||||||
|
return success
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prays at the shrine standing under the player, spending its gold price for
|
||||||
|
-- a shot at a permanent blessing (or, with rising odds the more this altar
|
||||||
|
-- has already been used, a curse instead). Returns false without any state
|
||||||
|
-- change when there is no shrine here or its price cannot be met.
|
||||||
|
function Game:prayAt(shrine)
|
||||||
|
local success, lines = Shrines.pray(self, shrine)
|
||||||
|
self.log:addAll(lines)
|
||||||
|
return success
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Swings the player's equipped pick at whatever lies one step away in
|
||||||
|
-- (dx, dy): a plain wall or the rubble left by an earlier swing. Returns
|
||||||
|
-- false without spending the swing when there is no pick readied or the
|
||||||
|
-- target cell has nothing left to dig (open floor, a vault door, out of
|
||||||
|
-- bounds); otherwise always spends one use of the pick's durability, even on
|
||||||
|
-- an unlucky cave-in that costs hp instead of progress (see digging.lua).
|
||||||
|
function Game:dig(dx, dy)
|
||||||
|
if not self.player.pick then
|
||||||
|
self.log:add("you have nothing to dig with")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local nx, ny = self.player.x + dx, self.player.y + dy
|
||||||
|
if not Digging.canDig(self.level.map, nx, ny) then
|
||||||
|
self.log:add("there is nothing here to dig")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
self.log:add(Digging.swing(self, self.player, nx, ny))
|
||||||
|
local brokenLine = Digging.wearPick(self.player)
|
||||||
|
if brokenLine then self.log:add(brokenLine) end
|
||||||
|
self:emitNoise(nx, ny, Noise.DIG)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Harvests whatever resource node stands under the player: an ore vein pays
|
||||||
|
-- out essence, a gem seam yields a raw gem, both free of any gold cost -
|
||||||
|
-- unlike a shrine's prayer, the only thing rationing this is the node's own
|
||||||
|
-- charges (see nodes.lua). Returns false without state change when there is
|
||||||
|
-- no node here or it has already been picked dry this trip.
|
||||||
|
function Game:harvestNode()
|
||||||
|
local node = self.level:nodeAt(self.player.x, self.player.y)
|
||||||
|
if not node then
|
||||||
|
self.log:add("there is nothing here to harvest")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local success, line = Nodes.harvest(self, node)
|
||||||
|
self.log:add(line)
|
||||||
|
return success
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Butchers whatever corpse lies under the player into raw meat (Items.FOOD),
|
||||||
|
-- eaten later exactly like a found ration - unless the corpse has already
|
||||||
|
-- gone past its rot threshold (corpses.lua), in which case it poisons the
|
||||||
|
-- player instead. Either way the corpse itself is spent in one stroke.
|
||||||
|
-- Returns false without state change when there is nothing here to carve.
|
||||||
|
function Game:butcherCorpse()
|
||||||
|
local corpse = self.level:corpseAt(self.player.x, self.player.y)
|
||||||
|
if not corpse then
|
||||||
|
self.log:add("there is nothing here to butcher")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
self.log:add(Corpses.butcher(self, corpse))
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Raises whatever fresh corpse lies under the player into a temporary
|
||||||
|
-- skeletal thrall (see reanimation.lua), spending both the corpse and a
|
||||||
|
-- bite of sanity in one stroke - a deliberate trade the autopilot never
|
||||||
|
-- makes on its own, unlike Game:butcherCorpse's free meal, so this is only
|
||||||
|
-- ever called directly. Returns false without state change when there is
|
||||||
|
-- no corpse here or Reanimation.raise itself refuses the attempt.
|
||||||
|
function Game:raiseCorpse()
|
||||||
|
local corpse = self.level:corpseAt(self.player.x, self.player.y)
|
||||||
|
if not corpse then
|
||||||
|
self.log:add("there is nothing here to raise")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local thrall, failMsg = Reanimation.raise(self, corpse)
|
||||||
|
if not thrall then
|
||||||
|
self.log:add(failMsg)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
self.log:add("bones knit and rise - your " .. thrall.name .. " answers the call")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Carves whatever fresh corpse lies under the player for the herb its own
|
||||||
|
-- kind carries (see scavenging.lua) instead of a meal or a thrall - a third
|
||||||
|
-- deliberate trade for the same tile, only ever called directly like
|
||||||
|
-- Game:raiseCorpse, never by the autopilot. Returns false without state
|
||||||
|
-- change when there is no corpse here or Scavenging.harvest itself refuses.
|
||||||
|
function Game:scavengeCorpse()
|
||||||
|
local corpse = self.level:corpseAt(self.player.x, self.player.y)
|
||||||
|
if not corpse then
|
||||||
|
self.log:add("there is nothing here to scavenge")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local harvested, message = Scavenging.harvest(self, corpse)
|
||||||
|
self.log:add(message)
|
||||||
|
return harvested
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Opens whatever chest stands under the player. An unlocked one (or one
|
||||||
|
-- already forced open) yields its hoard outright; a locked one first tries
|
||||||
|
-- a carried key, exactly like Game:openDoor's own certain trade, and only
|
||||||
|
-- falls back to a lockpick gamble (Chests.pick, which risks springing a
|
||||||
|
-- trapped lock) once no key can be found. Returns false without state
|
||||||
|
-- change when there is nothing here to open, it is already empty, or it is
|
||||||
|
-- locked with neither a key nor a lockpick on hand.
|
||||||
|
function Game:openChest()
|
||||||
|
local chest = self.level:chestAt(self.player.x, self.player.y)
|
||||||
|
if not chest then
|
||||||
|
self.log:add("there is nothing here to open")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if chest.opened then
|
||||||
|
self.log:add("this chest is already empty")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local success, line
|
||||||
|
if not Chests.isLocked(chest) then
|
||||||
|
success, line = Chests.open(self.player, chest)
|
||||||
|
else
|
||||||
|
success, line = Chests.unlockWithKey(self.player, chest)
|
||||||
|
if not success then success, line = Chests.pick(self, chest) end
|
||||||
|
end
|
||||||
|
self.log:add(line)
|
||||||
|
if success then self.stats.chestsOpened = self.stats.chestsOpened + 1 end
|
||||||
|
return success
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Frees whatever captive stands under the player back to its own kind for
|
||||||
|
-- nothing but goodwill (see Captives.ransom) - the one resolution that can
|
||||||
|
-- pull a wary tribal faction (factions.lua's neutralFactions) back out of
|
||||||
|
-- open hostility rather than deepening it further. Returns false without
|
||||||
|
-- state change when there is no captive here.
|
||||||
|
function Game:ransomCaptive()
|
||||||
|
local captive = self.level:captiveAt(self.player.x, self.player.y)
|
||||||
|
if not captive then
|
||||||
|
self.log:add("there is nothing here to ransom")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
Captives.ransom(self.level, self.player, captive)
|
||||||
|
self.log:add(string.format("you release %s - the %s think a little better of you for it", captive.name, captive.faction))
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function Game:openDoor(x, y)
|
function Game:openDoor(x, y)
|
||||||
|
|||||||
Reference in new issue
Block a user