module Game.LambdaHack.Client.UI.FrameM
( pushFrame, promptGetKey, stopPlayBack, animate, fadeOutOrIn
#ifdef EXPOSE_INTERNAL
, drawOverlay, renderFrames, resetPlayBack
#endif
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import qualified Data.EnumMap.Strict as EM
import qualified Data.Vector.Unboxed as U
import Game.LambdaHack.Client.ClientOptions
import Game.LambdaHack.Client.MonadClient
import Game.LambdaHack.Client.State
import Game.LambdaHack.Client.UI.Animation
import Game.LambdaHack.Client.UI.Content.Screen
import Game.LambdaHack.Client.UI.ContentClientUI
import Game.LambdaHack.Client.UI.DrawM
import Game.LambdaHack.Client.UI.Frame
import qualified Game.LambdaHack.Client.UI.Key as K
import Game.LambdaHack.Client.UI.MonadClientUI
import Game.LambdaHack.Client.UI.Msg
import Game.LambdaHack.Client.UI.MsgM
import Game.LambdaHack.Client.UI.Overlay
import Game.LambdaHack.Client.UI.SessionUI
import Game.LambdaHack.Common.ActorState
import Game.LambdaHack.Common.Faction
import Game.LambdaHack.Common.MonadStateRead
import Game.LambdaHack.Common.State
import Game.LambdaHack.Common.Types
import qualified Game.LambdaHack.Definition.Color as Color
drawOverlay :: MonadClientUI m
=> ColorMode -> Bool -> Overlay -> LevelId -> m PreFrame
drawOverlay dm onBlank topTrunc lid = do
CCUI{coscreen=coscreen@ScreenContent{rwidth, rheight}} <- getsSession sccui
basicFrame <- if onBlank
then do
let m = U.replicate (rwidth * rheight)
(Color.attrCharW32 Color.spaceAttrW32)
return (m, FrameForall $ \_v -> return ())
else drawHudFrame dm lid
return $! overlayFrameWithLines coscreen onBlank topTrunc basicFrame
pushFrame :: MonadClientUI m => m ()
pushFrame = do
keyPressed <- anyKeyPressed
unless keyPressed $ do
lidV <- viewedLevelUI
report <- getReportUI
let truncRep = [renderReport report]
frame <- drawOverlay ColorFull False truncRep lidV
displayFrames lidV [Just frame]
promptGetKey :: MonadClientUI m
=> ColorMode -> Overlay -> Bool -> [K.KM] -> m K.KM
promptGetKey dm ov onBlank frontKeyKeys = do
lidV <- viewedLevelUI
keyPressed <- anyKeyPressed
report <- getsSession $ newReport . shistory
let msgDisturbs = anyInReport disturbsResting report
lastPlayOld <- getsSession slastPlay
km <- case lastPlayOld of
km : kms | not keyPressed
&& (null frontKeyKeys || km `elem` frontKeyKeys)
&& not msgDisturbs -> do
frontKeyFrame <- drawOverlay dm onBlank ov lidV
displayFrames lidV [Just frontKeyFrame]
modifySession $ \sess -> sess {slastPlay = kms}
msgAdd MsgMacro $ "Voicing '" <> tshow km <> "'."
return km
_ : _ -> do
resetPlayBack
resetPressedKeys
let ov2 = [textFgToAL Color.BrYellow "*interrupted*" | keyPressed] ++ ov
frontKeyFrame <- drawOverlay dm onBlank ov2 lidV
recordHistory
connFrontendFrontKey frontKeyKeys frontKeyFrame
[] -> do
modifySession $ \sess -> sess {srunning = Nothing}
frontKeyFrame <- drawOverlay dm onBlank ov lidV
when (dm /= ColorFull)
resetPressedKeys
recordHistory
connFrontendFrontKey frontKeyKeys frontKeyFrame
LastRecord seqCurrent seqPrevious k <- getsSession slastRecord
let slastRecord = LastRecord (km : seqCurrent) seqPrevious k
modifySession $ \sess -> sess { slastRecord
, sdisplayNeeded = False }
return km
stopPlayBack :: MonadClientUI m => m ()
stopPlayBack = msgAdd0 MsgStopPlayback "!"
resetPlayBack :: MonadClientUI m => m ()
resetPlayBack = do
lastPlayOld <- getsSession slastPlay
unless (null lastPlayOld) $ do
modifySession $ \sess -> sess {slastPlay = []}
LastRecord _ _ k <- getsSession slastRecord
when (k > 0) $ do
modifySession $ \sess -> sess {slastRecord = LastRecord [] [] 0}
promptAdd0 "Macro recording aborted."
srunning <- getsSession srunning
case srunning of
Nothing -> return ()
Just RunParams{runLeader} -> do
side <- getsClient sside
fact <- getsState $ (EM.! side) . sfactionD
arena <- getArenaUI
memA <- getsState $ memActor runLeader arena
when (memA && not (noRunWithMulti fact)) $
updateClientLeader runLeader
modifySession (\sess -> sess {srunning = Nothing})
renderFrames :: MonadClientUI m => LevelId -> Animation -> m PreFrames
renderFrames arena anim = do
report <- getReportUI
let truncRep = [renderReport report]
basicFrame <- drawOverlay ColorFull False truncRep arena
snoAnim <- getsClient $ snoAnim . soptions
return $! if fromMaybe False snoAnim
then [Just basicFrame]
else renderAnim basicFrame anim
animate :: MonadClientUI m => LevelId -> Animation -> m ()
animate arena anim = do
keyPressed <- anyKeyPressed
unless keyPressed $ do
frames <- renderFrames arena anim
displayFrames arena frames
fadeOutOrIn :: MonadClientUI m => Bool -> m ()
fadeOutOrIn out = do
arena <- getArenaUI
CCUI{coscreen} <- getsSession sccui
animMap <- rndToActionForget $ fadeout coscreen out 2
animFrs <- renderFrames arena animMap
displayFrames arena (tail animFrs)