module Game.LambdaHack.Client.UI.Content.KeyKind
( KeyKind(..), evalKeyDef
, addCmdCategory, replaceDesc, moveItemTriple, repeatTriple
, mouseLMB, mouseMMB, mouseRMB
, goToCmd, runToAllCmd, autoexploreCmd, autoexplore25Cmd
, aimFlingCmd, projectI, projectA, flingTs, applyI, applyIK
, grabItems, dropItems, descTs, defaultHeroSelect
) where
import Prelude ()
import Game.LambdaHack.Common.Prelude
import qualified Data.Char as Char
import qualified NLP.Miniutter.English as MU
import Game.LambdaHack.Client.UI.ActorUI (verbCStore)
import Game.LambdaHack.Client.UI.HumanCmd
import qualified Game.LambdaHack.Client.UI.Key as K
import Game.LambdaHack.Common.Misc
newtype KeyKind = KeyKind
{ rhumanCommands :: [(K.KM, CmdTriple)]
}
evalKeyDef :: (String, CmdTriple) -> (K.KM, CmdTriple)
evalKeyDef (t, triple@(cats, _, _)) =
let km = if CmdInternal `elem` cats
then K.KM K.NoModifier $ K.Unknown t
else K.mkKM t
in (km, triple)
addCmdCategory :: CmdCategory -> CmdTriple -> CmdTriple
addCmdCategory cat (cats, desc, cmd) = (cat : cats, desc, cmd)
replaceDesc :: Text -> CmdTriple -> CmdTriple
replaceDesc desc (cats, _, cmd) = (cats, desc, cmd)
replaceCmd :: HumanCmd -> CmdTriple -> CmdTriple
replaceCmd cmd (cats, desc, _) = (cats, desc, cmd)
moveItemTriple :: [CStore] -> CStore -> MU.Part -> Bool -> CmdTriple
moveItemTriple stores1 store2 object auto =
let verb = MU.Text $ verbCStore store2
desc = makePhrase [verb, object]
in ([CmdItemMenu], desc, MoveItem stores1 store2 Nothing auto)
repeatTriple :: Int -> CmdTriple
repeatTriple n = ( [CmdMeta]
, "voice recorded commands" <+> tshow n <+> "times"
, Repeat n )
mouseLMB :: CmdTriple
mouseLMB =
( [CmdMouse]
, "set x-hair to enemy/go to pointer for 25 steps"
, ByAimMode
{ exploration = ByArea $ common ++
[ (CaMapLeader, grabCmd)
, (CaMapParty, PickLeaderWithPointer)
, (CaMap, goToCmd)
, (CaArenaName, Help)
, (CaPercentSeen, autoexploreCmd) ]
, aiming = ByArea $ common ++
[ (CaMap, AimPointerEnemy)
, (CaArenaName, Accept)
, (CaPercentSeen, XhairStair True) ] } )
where
common =
[ (CaMessage, Clear)
, (CaLevelNumber, AimAscend 1)
, (CaXhairDesc, AimEnemy)
, (CaSelected, PickLeaderWithPointer)
, (CaCalmGauge, Macro ["KP_5", "C-V"])
, (CaHPGauge, Wait)
, (CaTargetDesc, ChooseItemMenu $ MStore CInv) ]
mouseMMB :: CmdTriple
mouseMMB = ( [CmdMouse]
, "snap x-hair to floor under pointer"
, XhairPointerFloor )
mouseRMB :: CmdTriple
mouseRMB =
( [CmdMouse]
, "fling at enemy/run to pointer collectively for 25 steps"
, ByAimMode
{ exploration = ByArea $ common ++
[ (CaMapLeader, dropCmd)
, (CaMapParty, SelectWithPointer)
, (CaMap, runToAllCmd)
, (CaArenaName, MainMenu)
, (CaPercentSeen, autoexplore25Cmd)
, (CaTargetDesc, projectICmd flingTs) ]
, aiming = ByArea $ common ++
[ (CaMap, aimFlingCmd)
, (CaArenaName, Cancel)
, (CaPercentSeen, XhairStair False)
, (CaTargetDesc, ComposeUnlessError ItemClear TgtClear) ] } )
where
common =
[ (CaMessage, ChooseItemMenu MLoreItem)
, (CaLevelNumber, AimAscend (-1))
, (CaXhairDesc, AimItem)
, (CaSelected, SelectWithPointer)
, (CaCalmGauge, Macro ["C-KP_5", "V"])
, (CaHPGauge, Wait10) ]
goToCmd :: HumanCmd
goToCmd = Macro ["MiddleButtonRelease", "C-semicolon", "C-/", "C-V"]
runToAllCmd :: HumanCmd
runToAllCmd = Macro ["MiddleButtonRelease", "C-colon", "C-/", "C-V"]
autoexploreCmd :: HumanCmd
autoexploreCmd = Macro ["C-?", "C-/", "C-V"]
autoexplore25Cmd :: HumanCmd
autoexplore25Cmd = Macro ["'", "C-?", "C-/", "'", "C-V"]
aimFlingCmd :: HumanCmd
aimFlingCmd = ComposeIfLocal AimPointerEnemy (projectICmd flingTs)
projectICmd :: [Trigger] -> HumanCmd
projectICmd ts = ByItemMode
{ ts
, notChosen = ComposeUnlessError (ChooseItemProject ts) (Project ts)
, chosen = Project ts }
projectI :: [Trigger] -> CmdTriple
projectI ts = ([], descTs ts, projectICmd ts)
projectA :: [Trigger] -> CmdTriple
projectA ts = replaceCmd ByAimMode { exploration = AimTgt
, aiming = projectICmd ts } (projectI ts)
flingTs :: [Trigger]
flingTs = [ApplyItem { verb = "fling"
, object = "projectile"
, symbol = ' ' }]
applyIK :: [Trigger] -> CmdTriple
applyIK ts =
let apply = Apply ts
in ([], descTs ts, ByItemMode
{ ts
, notChosen = ComposeUnlessError (ChooseItemApply ts) apply
, chosen = apply })
applyI :: [Trigger] -> CmdTriple
applyI ts =
let apply = Compose2ndLocal (Apply ts) ItemClear
in ([], descTs ts, ByItemMode
{ ts
, notChosen = ComposeUnlessError (ChooseItemApply ts) apply
, chosen = apply })
grabCmd :: HumanCmd
grabCmd = MoveItem [CGround] CEqp (Just "grab") True
grabItems :: Text -> CmdTriple
grabItems t = ([CmdMove, CmdItemMenu], t, grabCmd)
dropCmd :: HumanCmd
dropCmd = MoveItem [CEqp, CInv, CSha] CGround Nothing False
dropItems :: Text -> CmdTriple
dropItems t = ([CmdMove, CmdItemMenu], t, dropCmd)
descTs :: [Trigger] -> Text
descTs [] = "trigger a thing"
descTs (t : _) = makePhrase [verb t, object t]
defaultHeroSelect :: Int -> (String, CmdTriple)
defaultHeroSelect k = ([Char.intToDigit k], ([CmdMeta], "", PickLeader k))