feat: add targetArg to commands
This commit is contained in:
1 parent
1d5768acd1
commit
4e4d22cf2e
1 file changed
+155
@@ -322,3 +322,158 @@ local function hereHandler(methodName, nothingMessage)
|
||||
end
|
||||
end
|
||||
|
||||
Handlers.open = hereHandler("openChest", "there is nothing here to open")
|
||||
Handlers.butcher = hereHandler("butcherCorpse", "there is nothing here to butcher")
|
||||
Handlers.raise = hereHandler("raiseCorpse", "there is nothing here to raise")
|
||||
Handlers.scavenge = hereHandler("scavengeCorpse", "there is nothing here to scavenge")
|
||||
Handlers.harvest = hereHandler("harvestNode", "there is nothing here to harvest")
|
||||
Handlers.ransom = hereHandler("ransomCaptive", "there is nothing here to ransom")
|
||||
Handlers.sellcaptive = hereHandler("sellCaptive", "there is nothing here to sell")
|
||||
Handlers.interrogate = hereHandler("interrogateCaptive", "there is nothing here to interrogate")
|
||||
Handlers.descend = hereHandler("descend", "there are no stairs down here")
|
||||
Handlers[">"] = Handlers.descend
|
||||
Handlers.ascend = hereHandler("ascend", "there are no stairs up here")
|
||||
Handlers["<"] = Handlers.ascend
|
||||
Handlers.enterrift = hereHandler("enterRift", "there is no rift here to cross")
|
||||
Handlers.exitrift = hereHandler("exitRift", "you are not standing across a rift")
|
||||
|
||||
-- Game:startHorde is a deliberate, one-way trial (see its own header: the
|
||||
-- dungeon floor left behind is simply abandoned, there is no exit back) that
|
||||
-- always succeeds and, unlike every hereHandler above, carries no location
|
||||
-- requirement of its own - so this guards against the one real footgun a
|
||||
-- typed command adds that the method itself does not: retyping "horde"
|
||||
-- mid-run would otherwise silently discard the current wave and its
|
||||
-- progress by building a brand new arena on top of it.
|
||||
Handlers.horde = function(game)
|
||||
if game.horde then return false, "you are already fighting in the arena" end
|
||||
game:startHorde()
|
||||
return true, nil
|
||||
end
|
||||
|
||||
Handlers.pray = function(game)
|
||||
local shrine = game.level:shrineAt(game.player.x, game.player.y)
|
||||
if not shrine then return false, "there is no shrine here" end
|
||||
if game:prayAt(shrine) then return true, nil end
|
||||
return false, "your prayer goes unanswered"
|
||||
end
|
||||
|
||||
Handlers.quest = function(game)
|
||||
local board = game.level:questBoardAt(game.player.x, game.player.y)
|
||||
if not board then return false, "there is no quest board here" end
|
||||
if game:tryAcceptQuest(board) then return true, nil end
|
||||
return false, "you cannot take up that bounty"
|
||||
end
|
||||
|
||||
-- Every faction key factions.lua defines, spelled out here (rather than
|
||||
-- discovered from the module at runtime) purely so a bad argument's error
|
||||
-- message can list them by name; the set itself is built from the same
|
||||
-- constants Game:appeaseFaction already trusts, so a typo can never buy
|
||||
-- standing with a faction that does not exist.
|
||||
local FACTION_NAMES = {
|
||||
Factions.MERCHANT, Factions.GOBLINOID, Factions.VERMIN, Factions.ORCISH,
|
||||
Factions.UNDEAD, Factions.BEAST, Factions.CULT, Factions.DRAKE, Factions.BANDIT,
|
||||
}
|
||||
local FACTION_SET = {}
|
||||
for _, name in ipairs(FACTION_NAMES) do FACTION_SET[name] = true end
|
||||
|
||||
Handlers.appease = function(game, args)
|
||||
local faction = args[1]
|
||||
if not faction or not FACTION_SET[faction] then
|
||||
return false, "appease which faction? " .. table.concat(FACTION_NAMES, ", ")
|
||||
end
|
||||
if game:appeaseFaction(faction) then return true, nil end
|
||||
return false, nil
|
||||
end
|
||||
|
||||
Handlers.dig = function(game, args)
|
||||
local dir = DIRS[args[1]]
|
||||
if not dir then return false, "dig which direction?" end
|
||||
if game:dig(dir[1], dir[2]) then return true, nil end
|
||||
return false, "you cannot dig there"
|
||||
end
|
||||
|
||||
-- Disarms a detected-but-unsprung trap one step away in `dir` - the same
|
||||
-- Chebyshev-1 reach Disarm.sweep already uses to notice it in the first
|
||||
-- place (see Game:endPlayerTurn's "you notice a hidden trap nearby"). The
|
||||
-- validity check below duplicates Game:disarmTrap's own guard on purpose:
|
||||
-- unlike every other handler here, a disarm attempt against a real trap
|
||||
-- must still spend the turn even when Disarm.attempt fails and springs it,
|
||||
-- but Game:disarmTrap's own boolean return conflates that spring with "no
|
||||
-- trap here" into the same false - so this handler tells the two apart
|
||||
-- itself instead of trusting the method's return value for turn cost.
|
||||
Handlers.disarm = function(game, args)
|
||||
local dir = DIRS[args[1]]
|
||||
if not dir then return false, "disarm which direction?" end
|
||||
local trap = game.level:trapAt(game.player.x + dir[1], game.player.y + dir[2])
|
||||
if not trap or not trap.detected or trap.revealed then
|
||||
return false, "there is nothing here you have noticed to disarm"
|
||||
end
|
||||
game:disarmTrap(trap)
|
||||
return true, nil
|
||||
end
|
||||
|
||||
-- Crafting/economy verbs (game.lua's forgeGem/mergeGemsAt/socketItem/
|
||||
-- socketRune/temperItem/enchantItem/disenchantItem/repairEquipped/
|
||||
-- stealFromShop/dismissHireling/learnSkill/brewAt), the other half of the
|
||||
-- API choosePlayerAction can already reach that a typed session could not
|
||||
-- until now. Every one of these Game methods already logs its own success
|
||||
-- or failure reason, so a handler only needs its own message for an
|
||||
-- argument so malformed the underlying method can never even be called.
|
||||
|
||||
-- Shared by socket/socketrune/temper/enchant/disenchant: their `target`
|
||||
-- resolves through Game:resolveGear exactly like this, either the literal
|
||||
-- word for currently equipped gear or an inventory slot number for
|
||||
-- anything else (a spare ring, an unequipped bow).
|
||||
local function targetArg(token)
|
||||
if token == "weapon" or token == "armor" then return token end
|
||||
return tonumber(token)
|
||||
end
|
||||
|
||||
Handlers.forge = function(game, args)
|
||||
local element = args[1]
|
||||
if not element then return false, "forge which element? fire, frost, shock or venom" end
|
||||
if game:forgeGem(element) then return true, nil end
|
||||
return false, nil
|
||||
end
|
||||
|
||||
Handlers.merge = function(game, args)
|
||||
local a, b = tonumber(args[1]), tonumber(args[2])
|
||||
if not a or not b then return false, "merge which two gems? give two inventory numbers" end
|
||||
if game:mergeGemsAt(a, b) then return true, nil end
|
||||
return false, "those cannot be merged"
|
||||
end
|
||||
|
||||
Handlers.socket = function(game, args)
|
||||
local target, gemIndex = targetArg(args[1]), tonumber(args[2])
|
||||
if not target or not gemIndex then
|
||||
return false, "socket what into what? give a target (weapon/armor/item number) and a gem number"
|
||||
end
|
||||
if game:socketItem(target, gemIndex) then return true, nil end
|
||||
return false, "that cannot be socketed"
|
||||
end
|
||||
|
||||
Handlers.socketrune = function(game, args)
|
||||
local target, runeIndex = targetArg(args[1]), tonumber(args[2])
|
||||
if not target or not runeIndex then
|
||||
return false, "socket which rune into what? give a target (weapon/armor/item number) and a rune number"
|
||||
end
|
||||
if game:socketRune(target, runeIndex) then return true, nil end
|
||||
return false, "that cannot be socketed"
|
||||
end
|
||||
|
||||
Handlers.temper = function(game, args)
|
||||
local target = targetArg(args[1])
|
||||
if not target then return false, "temper what? weapon, armor or an item number" end
|
||||
if game:temperItem(target) then return true, nil end
|
||||
return false, "that cannot be tempered"
|
||||
end
|
||||
|
||||
Handlers.enchant = function(game, args)
|
||||
local target, affixKey = targetArg(args[1]), args[2]
|
||||
if not target or not affixKey then
|
||||
return false, "enchant what with what? give a target (weapon/armor/item number) and an affix name"
|
||||
end
|
||||
if game:enchantItem(target, affixKey) then return true, nil end
|
||||
return false, "that cannot be enchanted"
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user