271 lines
10 KiB
Haskell
271 lines
10 KiB
Haskell
module Dodge.Terminal (
|
|
doTerminalCommandEffect,
|
|
makeTermLine,
|
|
commandFutureLines,
|
|
quitCommand,
|
|
helpCommand,
|
|
commandsCommand,
|
|
connectionBlurbLines,
|
|
disconnectTerminal,
|
|
basicTerminal,
|
|
simpleTermMessage,
|
|
damageCodeCommand,
|
|
sensorCommand,
|
|
makeColorTermLine,
|
|
makeTermPara,
|
|
toggleCommand,
|
|
) where
|
|
|
|
import Color
|
|
import Data.Char
|
|
import Data.Foldable
|
|
import qualified Data.Map.Strict as M
|
|
import Data.Maybe
|
|
import Dodge.Data.World
|
|
import Dodge.Default
|
|
import Dodge.SoundLogic
|
|
import Justify
|
|
import LensHelp
|
|
import ListHelp (safeHead, safeUncons)
|
|
import Sound.Data
|
|
|
|
basicTerminal :: Terminal
|
|
basicTerminal =
|
|
defaultTerminal
|
|
{ _tmDisplayedLines = []
|
|
, _tmFutureLines = []
|
|
, _tmMaxLines = 14
|
|
, _tmTitle = "TERMINAL"
|
|
, _tmScrollCommands = [quitCommand]
|
|
, _tmWriteCommands = [helpCommand, commandsCommand]
|
|
, _tmBootProgram = TerminalBootLines connectionBlurb
|
|
, _tmDeathEffect = TmWdWdDoDeathTriggers
|
|
}
|
|
|
|
connectionBlurbLines :: [TerminalLine] -> [TerminalLine]
|
|
connectionBlurbLines tls =
|
|
[ termSoundLine computerBeepingS
|
|
, TerminalLineDisplay 0 (TerminalLineConst "Connecting" termTextColor)
|
|
, TerminalLineDisplay 10 (TerminalLineConst "..." termTextColor)
|
|
, TerminalLineDisplay 10 (TerminalLineConst "Connected" termTextColor)
|
|
]
|
|
++ tls
|
|
++ [TerminalLineTerminalEffect 0 (TmTmSetStatus TerminalReady)]
|
|
|
|
quitCommand :: TerminalCommand
|
|
quitCommand =
|
|
TerminalCommand
|
|
{ _tcString = "quit"
|
|
, _tcAlias = ["q", "exit", "x", "shutdown", ""]
|
|
, _tcHelp = "Disconnects the terminal."
|
|
, _tcEffect = TerminalCommandArguments $ NoArguments [TerminalLineEffect 0 TmWdWdDisconnectTerminal]
|
|
}
|
|
|
|
helpCommand :: TerminalCommand
|
|
helpCommand =
|
|
TerminalCommand
|
|
{ _tcString = "help"
|
|
, _tcAlias = ["h", "man"]
|
|
, _tcHelp = "Displays help for a specific command."
|
|
, _tcEffect = TerminalCommandEffectHelp -- \tm -> OneArgument "AN AVAILABLE COMMAND" . getCommandsHelp tm
|
|
}
|
|
|
|
getCommandsHelp :: Terminal -> World -> M.Map String [TerminalLine]
|
|
getCommandsHelp tm w = foldr f mempty $ getCommands tm
|
|
where
|
|
f tc =
|
|
M.insert
|
|
(_tcString tc)
|
|
( [ makeTermLine "Command:"
|
|
, makeColorTermLine commandColor (_tcString tc)
|
|
, makeTermLine "Aliases:"
|
|
, makeColorTermLine commandColor (unwords (_tcAlias tc))
|
|
]
|
|
++ case argumentHelp tc tm w of
|
|
(arghelp, Nothing) -> makeTermPara $ _tcHelp tc ++ " " ++ arghelp
|
|
(arghelp, Just args) ->
|
|
makeTermPara (_tcHelp tc ++ " " ++ arghelp)
|
|
++ [makeColorTermLine commandColor $ unwords args]
|
|
)
|
|
|
|
commandsCommand :: TerminalCommand
|
|
commandsCommand =
|
|
TerminalCommand
|
|
{ _tcString = "commands"
|
|
, _tcAlias = ["command", "com"]
|
|
, _tcHelp = "Displays available commands."
|
|
, _tcEffect = TerminalCommandEffectCommands
|
|
}
|
|
|
|
connectionBlurb :: [TerminalLine]
|
|
connectionBlurb =
|
|
[ termSoundLine computerBeepingS
|
|
, TerminalLineDisplay 0 (TerminalLineConst "Connecting" termTextColor)
|
|
, TerminalLineDisplay 10 (TerminalLineConst "..." termTextColor)
|
|
, TerminalLineDisplay 10 (TerminalLineConst "Connected" termTextColor)
|
|
, TerminalLineTerminalEffect 0 (TmTmSetStatus TerminalReady)
|
|
]
|
|
|
|
termSoundLine :: SoundID -> TerminalLine
|
|
termSoundLine sid = TerminalLineEffect 0 (TmWdWdTermSound sid)
|
|
|
|
termTextColor :: Color
|
|
termTextColor = greyN 0.9
|
|
|
|
getCommands :: Terminal -> [TerminalCommand]
|
|
getCommands tm = _tmScrollCommands tm ++ _tmWriteCommands tm
|
|
|
|
makeTermLine :: String -> TerminalLine
|
|
makeTermLine = makeColorTermLine termTextColor
|
|
|
|
makeTermPara :: String -> [TerminalLine]
|
|
makeTermPara = map makeTermLine . makeParagraph 60
|
|
|
|
makeColorTermPara :: Color -> String -> [TerminalLine]
|
|
makeColorTermPara col = map (makeColorTermLine col) . makeParagraph 60
|
|
|
|
makeColorTermLine :: Color -> String -> TerminalLine
|
|
makeColorTermLine col str = TerminalLineDisplay 0 $ TerminalLineConst str col
|
|
|
|
commandColor :: Color
|
|
commandColor = yellow
|
|
|
|
doTerminalCommandEffect :: TerminalCommandEffect -> Terminal -> World -> EffectArguments
|
|
doTerminalCommandEffect tce = case tce of
|
|
TerminalCommandArguments eas -> \_ _ -> eas
|
|
TerminalCommandEffectDamageCoding -> \_ -> OneArgument "a damage type" . getDamageCoding
|
|
TerminalCommandEffectSensorParameter -> \tm -> OneArgument "a sensor parameter" . sensorInfoMap tm
|
|
TerminalCommandEffectLinkedObject -> \tm _ -> OneArgument "a linked object" (togglesToEffects tm)
|
|
TerminalCommandEffectHelp -> \tm -> OneArgument "an available command" . getCommandsHelp tm
|
|
TerminalCommandEffectNoArgumentsStr str -> \_ _ -> NoArguments (makeTermPara str)
|
|
TerminalCommandEffectCommands -> \tm _ ->
|
|
NoArguments
|
|
( makeTermLine "Available commands:" :
|
|
makeColorTermPara commandColor (unwords (map _tcString $ getCommands tm))
|
|
)
|
|
TerminalCommandEffectSingleCommand eff followingLines -> \_ _ -> NoArguments $ TerminalLineEffect 0 (TmWdWdfromWdWd eff) : map makeTermLine followingLines
|
|
TerminalCommandEffectNone -> \_ _ -> NoArguments []
|
|
|
|
argumentHelp :: TerminalCommand -> Terminal -> World -> (String, Maybe [String])
|
|
argumentHelp tc tm w = case doTerminalCommandEffect (_tcEffect tc) tm w of
|
|
NoArguments{} -> ("Any arguments provided to this command are ignored.", Nothing)
|
|
OneArgument argtype argm ->
|
|
( "Expects " ++ argtype ++ " as argument. Available arguments: "
|
|
, Just (M.keys argm)
|
|
)
|
|
|
|
--infoCommand :: String -> TerminalCommand
|
|
--infoCommand str =
|
|
-- TerminalCommand
|
|
-- { _tcString = "INFORMATION"
|
|
-- , _tcAlias = ["INFO", "I"]
|
|
-- , _tcHelp = "DISPLAYS INFORMATION CONCERNING THE TERMINAL."
|
|
-- , _tcEffect = TerminalCommandEffectNoArgumentsStr str -- \_ _ -> NoArguments (makeTermPara str)
|
|
-- }
|
|
|
|
--singleCommand :: [String] -> String -> [String] -> String -> WdWd -> TerminalCommand
|
|
--singleCommand followingLines command aliases htext eff =
|
|
-- TerminalCommand
|
|
-- { _tcString = command
|
|
-- , _tcAlias = aliases
|
|
-- , _tcHelp = htext
|
|
-- , _tcEffect = TerminalCommandEffectSingleCommand eff followingLines
|
|
-- }
|
|
|
|
getDamageCoding :: World -> M.Map String [TerminalLine]
|
|
getDamageCoding = decodedtmap . _sensorCoding . _cwgParams . _cwGen . _cWorld
|
|
|
|
sensorInfoMap :: Terminal -> World -> M.Map String [TerminalLine]
|
|
sensorInfoMap tm w =
|
|
M.fromList
|
|
[ ("Requirement", getSensor _proxRequirement tm w)
|
|
, ("Distance", getSensor _proxDist tm w)
|
|
, ("Currentstatus", getSensor _proxStatus tm w)
|
|
, ("Paststatus", getSensor _sensToggle tm w)
|
|
]
|
|
|
|
getSensor :: Show a => (Sensor -> a) -> Terminal -> World -> [TerminalLine]
|
|
getSensor f tm w =
|
|
maybe
|
|
[]
|
|
(makeTermPara . map toLower . show . f)
|
|
(w ^? cWorld . lWorld . machines . ix (_tmMachineID tm) . mcType . _McSensor)
|
|
|
|
toggleCommand :: TerminalCommand
|
|
toggleCommand =
|
|
TerminalCommand
|
|
{ _tcString = "toggle"
|
|
, _tcAlias = ["tog"]
|
|
, _tcHelp = "Performs a reversable effect."
|
|
, _tcEffect = TerminalCommandEffectLinkedObject -- \tm _ -> OneArgument "A LINKED OBJECT" (togglesToEffects tm)
|
|
}
|
|
|
|
decodedtmap :: M.Map DamageType (PaletteColor, DecorationShape) -> M.Map String [TerminalLine]
|
|
decodedtmap = M.mapKeys show . M.map ((: []) . makeTermLine . show)
|
|
|
|
sensorCommand :: TerminalCommand
|
|
sensorCommand =
|
|
TerminalCommand
|
|
{ _tcString = "sensor"
|
|
, _tcAlias = ["sen"]
|
|
, _tcHelp = "Access information concerning the connected sensor."
|
|
, _tcEffect = TerminalCommandEffectSensorParameter -- \tm -> OneArgument "A SENSOR PARAMETER" . sensorInfoMap tm
|
|
}
|
|
|
|
disconnectTerminal :: Terminal -> World -> World
|
|
disconnectTerminal tm =
|
|
(cWorld . lWorld . terminals . ix (_tmID tm) . tmStatus .~ TerminalOff)
|
|
. exitTerminalSubInv
|
|
. ( cWorld . lWorld . terminals . ix (_tmID tm) . tmFutureLines
|
|
.~ [TerminalLineTerminalEffect 0 TmTmClearDisplayedLines]
|
|
)
|
|
|
|
exitTerminalSubInv :: World -> World
|
|
exitTerminalSubInv w = case w ^? hud . hudElement . subInventory . termID of
|
|
Just _ -> w & hud . hudElement . subInventory .~ NoSubInventory
|
|
_ -> w
|
|
|
|
damageCodeCommand :: TerminalCommand
|
|
damageCodeCommand =
|
|
TerminalCommand
|
|
{ _tcString = "damagecode"
|
|
, _tcAlias = ["dcode", "dc"]
|
|
, _tcHelp = "Displays the shape and color associated with a given damage type."
|
|
, _tcEffect = TerminalCommandEffectDamageCoding -- \_ -> OneArgument "A DAMAGE TYPE" . getDamageCoding
|
|
}
|
|
|
|
--infoClearInput :: Terminal -> [TerminalLine] -> World -> World
|
|
--infoClearInput tm tls =
|
|
-- cWorld . lWorld . terminals . ix (_tmID tm)
|
|
-- %~ ( (tmInput .~ TerminalInput T.empty True (0, 0))
|
|
-- . (tmFutureLines ++.~ tls)
|
|
-- )
|
|
|
|
togglesToEffects :: Terminal -> M.Map String [TerminalLine]
|
|
togglesToEffects = fmap f . _tmToggles
|
|
where
|
|
f tt = [TerminalLineEffect 0 $ TmWdWdfromWdWd $ WdWdNegateTrig (_ttTriggerID tt)]
|
|
|
|
simpleTermMessage :: [String] -> Terminal
|
|
simpleTermMessage strs = defaultTerminal & tmFutureLines .~ map makeTermLine strs
|
|
|
|
commandFutureLines :: String -> Terminal -> World -> [TerminalLine]
|
|
commandFutureLines s tm w = fromMaybe [errline "^ Invalid command"] $ do
|
|
(str, args) <- safeUncons $ words s
|
|
command <- find (\tc -> _tcString tc == str || str `elem` _tcAlias tc) (getCommands tm)
|
|
case doTerminalCommandEffect (_tcEffect command) tm w of
|
|
NoArguments tls -> Just tls
|
|
OneArgument argtype m ->
|
|
let setpartial
|
|
| null (_tmPartialCommand tm)
|
|
= TerminalLineTerminalEffect 0 (TmTmSetPartialCommand (Just command)) :
|
|
makeTermPara ("Expects " ++ argtype ++ " as an argument")
|
|
| otherwise =
|
|
TerminalLineTerminalEffect 0 (TmTmSetPartialCommand Nothing) :
|
|
makeTermPara "No argument input, cancelling"
|
|
in Just $
|
|
fromMaybe setpartial $
|
|
safeHead args >>= (m M.!?)
|
|
where
|
|
errline = makeColorTermLine red
|