feat: extend effects with isPlayer
This commit is contained in:
1 parent
142051057b
commit
2c8fea0556
1 file changed
+110
-8
+110
-8
@@ -4,37 +4,120 @@
|
||||
|
||||
local Status = require("status")
|
||||
local Identify = require("identify")
|
||||
local Hazards = require("hazards")
|
||||
local Resistances = require("resistances")
|
||||
local Curses = require("curses")
|
||||
local Sanity = require("sanity")
|
||||
local Disease = require("disease")
|
||||
|
||||
local Effects = {}
|
||||
|
||||
local handlers = {}
|
||||
|
||||
-- Every handler below phrases its own log line by hand rather than always
|
||||
-- templating a bare "%s <third-person-singular-verb>" onto target.name,
|
||||
-- because Effects.apply's only call site (Game:useItem) always hands it the
|
||||
-- player, whose name is the pronoun "you" - a subject that takes the plain
|
||||
-- ("you heal", "you are poisoned") verb form English gives second person,
|
||||
-- not the third-person-singular form ("heals", "is") a named monster like
|
||||
-- "orc" would take. Kept branching on target.kind rather than hardcoding
|
||||
-- "you" outright so a future non-player caller (a companion drinking its
|
||||
-- own potion, say) still reads correctly without touching this file - the
|
||||
-- same isPlayer-branch convention Game:springTrap and Game:checkTerrainFor
|
||||
-- already use for the identical pronoun problem.
|
||||
local function isPlayer(target)
|
||||
return target.kind == "player"
|
||||
end
|
||||
|
||||
handlers.heal = function(game, target, item)
|
||||
local before = target.hp
|
||||
target.hp = math.min(target.maxHp, target.hp + item.power)
|
||||
return { string.format("%s heals %d", target.name, target.hp - before) }
|
||||
local healed = target.hp - before
|
||||
return { isPlayer(target) and string.format("you heal %d", healed)
|
||||
or string.format("%s heals %d", target.name, healed) }
|
||||
end
|
||||
|
||||
handlers.poison = function(game, target, item)
|
||||
Status.apply(target, Status.POISON, 6, item.power)
|
||||
return { string.format("%s is poisoned", target.name) }
|
||||
return { isPlayer(target) and "you are poisoned" or string.format("%s is poisoned", target.name) }
|
||||
end
|
||||
|
||||
handlers.strength = function(game, target, _)
|
||||
Status.apply(target, Status.STRENGTH, 30, 3)
|
||||
return { string.format("%s feels mightier", target.name) }
|
||||
return { isPlayer(target) and "you feel mightier" or string.format("%s feels mightier", target.name) }
|
||||
end
|
||||
|
||||
handlers.haste = function(game, target, _)
|
||||
Status.apply(target, Status.HASTE, 20, 1)
|
||||
return { string.format("%s speeds up", target.name) }
|
||||
return { isPlayer(target) and "you speed up" or string.format("%s speeds up", target.name) }
|
||||
end
|
||||
|
||||
handlers.fortify = function(game, target, _)
|
||||
Status.apply(target, Status.SHIELD, 15, 1)
|
||||
return { isPlayer(target) and "you feel fortified" or string.format("%s feels fortified", target.name) }
|
||||
end
|
||||
|
||||
-- Same shape as haste/fortify - a timed self-buff, not a hostile effect -
|
||||
-- but see status.lua's Status.LEVITATE for what it actually unlocks: a
|
||||
-- levitating target ignores lava, chasms, ice, and ground-pressure traps
|
||||
-- entirely until it wears off (Game:checkTerrainFor/checkTrapFor).
|
||||
handlers.levitate = function(game, target, _)
|
||||
Status.apply(target, Status.LEVITATE, 20, 1)
|
||||
return { isPlayer(target) and "you rise off the ground" or string.format("%s rises off the ground", target.name) }
|
||||
end
|
||||
|
||||
handlers.clarity = function(game, target, item)
|
||||
Sanity.adjust(target, item.power)
|
||||
return { isPlayer(target) and string.format("your mind steadies (sanity %d/%d)", Sanity.current(target), Sanity.MAX)
|
||||
or string.format("%s's mind steadies (sanity %d/%d)", target.name, Sanity.current(target), Sanity.MAX) }
|
||||
end
|
||||
|
||||
-- "Cleansing" always meant purging disease; it never touched the status
|
||||
-- effects (poison, burning, stun, slow, weaken, discord, confuse, blind)
|
||||
-- that every other cure-shaped word in the game implies, leaving those
|
||||
-- curable only by waiting out their duration. Now strips both.
|
||||
handlers.cure = function(game, target, _)
|
||||
local diseaseCured = Disease.cure(target)
|
||||
local liftedStatuses = Status.cureHostile(target)
|
||||
local statusList = table.concat(liftedStatuses, ", ")
|
||||
if diseaseCured and #liftedStatuses > 0 then
|
||||
return { isPlayer(target)
|
||||
and string.format("your affliction is cleansed away, and the %s fades", statusList)
|
||||
or string.format("%s's affliction is cleansed away, and the %s fades", target.name, statusList) }
|
||||
elseif diseaseCured then
|
||||
return { isPlayer(target) and "your affliction is cleansed away"
|
||||
or string.format("%s's affliction is cleansed away", target.name) }
|
||||
elseif #liftedStatuses > 0 then
|
||||
return { isPlayer(target) and string.format("your %s fades", statusList)
|
||||
or string.format("%s's %s fades", target.name, statusList) }
|
||||
end
|
||||
return { isPlayer(target) and "you feel a faint tingle, but had nothing to cleanse"
|
||||
or string.format("%s feels a faint tingle, but had nothing to cleanse", target.name) }
|
||||
end
|
||||
|
||||
-- Same duration/potency as the confuse spell and trap (see status.lua's
|
||||
-- Status.CONFUSE and its mirrors in Game:movePlayer/Ai.act) so drinking an
|
||||
-- unidentified potion of confusion is exactly as bad as walking into a
|
||||
-- confuse trap, not a weaker or stronger flavor of the same status.
|
||||
handlers.confuse = function(game, target, _)
|
||||
Status.apply(target, Status.CONFUSE, 6, 1)
|
||||
return { isPlayer(target) and "your mind reels with confusion"
|
||||
or string.format("%s's mind reels with confusion", target.name) }
|
||||
end
|
||||
|
||||
-- Same duration/potency as the blind trap (see Game:springTrap) so drinking
|
||||
-- an unidentified potion of blindness is exactly as bad as walking into a
|
||||
-- flash trap, not a weaker or stronger flavor of the same status.
|
||||
handlers.blind = function(game, target, _)
|
||||
Status.apply(target, Status.BLIND, 6, 1)
|
||||
return { isPlayer(target) and "you are struck blind" or string.format("%s is struck blind", target.name) }
|
||||
end
|
||||
|
||||
handlers.teleport = function(game, target, _)
|
||||
local x, y = game:randomFloorCell()
|
||||
if x then
|
||||
target.x, target.y = x, y
|
||||
return { target.name .. " blinks away" }
|
||||
return { isPlayer(target) and "you blink away" or (target.name .. " blinks away") }
|
||||
end
|
||||
return { "the teleport fizzles" }
|
||||
end
|
||||
@@ -45,11 +128,28 @@ handlers.mapping = function(game, _, _)
|
||||
end
|
||||
|
||||
handlers.identify = function(game, target, _)
|
||||
local lines = {}
|
||||
local revealed = Identify.revealFirstUnknown(game.identify, target.inventory)
|
||||
if revealed then
|
||||
return { "it is " .. revealed.name }
|
||||
lines[#lines + 1] = "it is " .. revealed.name
|
||||
end
|
||||
return { "nothing left to identify" }
|
||||
local cursedFind = Curses.revealFirstUnknown(target)
|
||||
if cursedFind then
|
||||
lines[#lines + 1] = "you sense a curse upon your " .. cursedFind.name
|
||||
end
|
||||
if #lines == 0 then
|
||||
lines[#lines + 1] = "nothing left to identify"
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
handlers.removecurse = function(game, target, _)
|
||||
local count = Curses.cleanseWorn(target)
|
||||
if count == 0 then
|
||||
return { "you feel a faint tingle, but nothing you wear is cursed" }
|
||||
end
|
||||
return { string.format("a wave of purifying light lifts %d curse%s from your gear",
|
||||
count, count == 1 and "" or "s") }
|
||||
end
|
||||
|
||||
handlers.fireball = function(game, target, _)
|
||||
@@ -59,12 +159,14 @@ handlers.fireball = function(game, target, _)
|
||||
if monster:isAlive() then
|
||||
local dist = math.max(math.abs(monster.x - target.x), math.abs(monster.y - target.y))
|
||||
if dist <= radius then
|
||||
monster.hp = monster.hp - 8
|
||||
monster.hp = monster.hp - Resistances.apply(monster, 8, Resistances.FIRE)
|
||||
Status.apply(monster, Status.BURNING, 3, 2)
|
||||
Hazards.ignite(game.level, monster.x, monster.y, 3, 2)
|
||||
burned = burned + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
Hazards.ignite(game.level, target.x, target.y, 3, 2)
|
||||
game:cleanupDead()
|
||||
return { string.format("fire engulfs %d foes", burned) }
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user