Skip to content

Commit

Permalink
Hide robots for two seconds (#802)
Browse files Browse the repository at this point in the history
- closes #761
  • Loading branch information
xsebek authored Oct 31, 2022
1 parent 7185700 commit 2293f33
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
10 changes: 10 additions & 0 deletions src/Swarm/TUI/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ handleMainEvent ev = do
ControlKey 'g' -> case s ^. uiState . uiGoal of
Just g | g /= [] -> toggleModal (GoalModal g)
_ -> continueWithoutRedraw
MetaKey 'h' -> do
t <- liftIO $ getTime Monotonic
h <- use $ uiState . uiHideRobotsUntil
if h >= t
then -- ignore repeated keypresses
continueWithoutRedraw
else -- hide for two seconds
do
uiState . uiHideRobotsUntil .= t + TimeSpec 2 0
invalidateCacheEntry WorldCache
-- pausing and stepping
ControlKey 'p' | isRunning -> safeTogglePause
ControlKey 'o' | isRunning -> do
Expand Down
11 changes: 11 additions & 0 deletions src/Swarm/TUI/Model.hs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ module Swarm.TUI.Model (
lastInfoTime,
uiShowFPS,
uiShowZero,
uiShowRobots,
uiHideRobotsUntil,
uiInventoryShouldUpdate,
uiTPF,
uiFPS,
Expand Down Expand Up @@ -559,6 +561,7 @@ data UIState = UIState
, _uiGoal :: Maybe [Text]
, _uiShowFPS :: Bool
, _uiShowZero :: Bool
, _uiHideRobotsUntil :: TimeSpec
, _uiInventoryShouldUpdate :: Bool
, _uiTPF :: Double
, _uiFPS :: Double
Expand Down Expand Up @@ -642,6 +645,13 @@ uiShowFPS :: Lens' UIState Bool
-- | A toggle to show or hide inventory items with count 0 by pressing `0`
uiShowZero :: Lens' UIState Bool

-- | Hide robots on the world map.
uiHideRobotsUntil :: Lens' UIState TimeSpec

-- | Whether to show or hide robots on the world map.
uiShowRobots :: Getter UIState Bool
uiShowRobots = to (\ui -> ui ^. lastFrameTime > ui ^. uiHideRobotsUntil)

-- | Whether the Inventory ui panel should update
uiInventoryShouldUpdate :: Lens' UIState Bool

Expand Down Expand Up @@ -830,6 +840,7 @@ initUIState showMainMenu cheatMode = liftIO $ do
, _uiGoal = Nothing
, _uiShowFPS = False
, _uiShowZero = True
, _uiHideRobotsUntil = startTime - 1
, _uiInventoryShouldUpdate = False
, _uiTPF = 0
, _uiFPS = 0
Expand Down
42 changes: 25 additions & 17 deletions src/Swarm/TUI/View.hs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ drawGameUI s =
& addCursorPos
& addClock
)
(drawWorld $ s ^. gameState)
(drawWorld (s ^. uiState . uiShowRobots) (s ^. gameState))
, drawKeyMenu s
, clickable REPLPanel $
panel
Expand All @@ -315,18 +315,20 @@ drawGameUI s =
]
where
addCursorPos = case s ^. uiState . uiWorldCursor of
Just coord -> bottomLabels . leftLabel ?~ padLeftRight 1 (drawWorldCursorInfo (s ^. gameState) coord)
Nothing -> id
Just coord ->
let worlCursorInfo = drawWorldCursorInfo (s ^. uiState . uiShowRobots) (s ^. gameState) coord
in bottomLabels . leftLabel ?~ padLeftRight 1 worlCursorInfo
-- Add clock display in top right of the world view if focused robot
-- has a clock installed
addClock = topLabels . rightLabel ?~ padLeftRight 1 (drawClockDisplay $ s ^. gameState)
fr = s ^. uiState . uiFocusRing
moreTop = s ^. uiState . uiMoreInfoTop
moreBot = s ^. uiState . uiMoreInfoBot

drawWorldCursorInfo :: GameState -> W.Coords -> Widget Name
drawWorldCursorInfo g i@(W.Coords (y, x)) =
hBox [drawLoc g i, txt $ " at " <> from (show x) <> " " <> from (show (y * (-1)))]
drawWorldCursorInfo :: Bool -> GameState -> W.Coords -> Widget Name
drawWorldCursorInfo showRobots g i@(W.Coords (y, x)) =
hBox [drawLoc showRobots g i, txt $ " at " <> from (show x) <> " " <> from (show (y * (-1)))]

-- | Format the clock display to be shown in the upper right of the
-- world panel.
Expand Down Expand Up @@ -570,7 +572,7 @@ robotsListWidget s = hCenter table
locWidget = hBox [worldCell, txt $ " " <> locStr]
where
rloc@(V2 x y) = robot ^. robotLocation
worldCell = drawLoc g (W.locToCoords rloc)
worldCell = drawLoc (s ^. uiState . uiShowRobots) g (W.locToCoords rloc)
locStr = from (show x) <> " " <> from (show y)

statusWidget = case robot ^. machine of
Expand Down Expand Up @@ -640,6 +642,7 @@ helpWidget theSeed mport =
, ("Ctrl-z", "decrease speed")
, ("Ctrl-w", "increase speed")
, ("Ctrl-q", "quit the current scenario")
, ("Meta-h", "hide robots for 2s")
, ("Meta-w", "focus on the world map")
, ("Meta-e", "focus on the robot inventory")
, ("Meta-r", "focus on the REPL")
Expand Down Expand Up @@ -785,6 +788,7 @@ drawKeyMenu s =
, Just (NoHighlight, "^p", if isPaused then "unpause" else "pause")
, Just (NoHighlight, "^o", "step")
, Just (NoHighlight, "^zx", "speed")
, Just (if s ^. uiState . uiShowRobots then NoHighlight else Alert, "M-h", "hide robots")
]
may b = if b then Just else const Nothing

Expand Down Expand Up @@ -831,8 +835,8 @@ drawKeyCmd (h, key, cmd) =
------------------------------------------------------------

-- | Draw the current world view.
drawWorld :: GameState -> Widget Name
drawWorld g =
drawWorld :: Bool -> GameState -> Widget Name
drawWorld showRobots g =
center
. cached WorldCache
. reportExtent WorldExtent
Expand All @@ -844,21 +848,25 @@ drawWorld g =
let w = ctx ^. availWidthL
h = ctx ^. availHeightL
ixs = range (viewingRegion g (fromIntegral w, fromIntegral h))
render . vBox . map hBox . chunksOf w . map (drawLoc g) $ ixs
render . vBox . map hBox . chunksOf w . map (drawLoc showRobots g) $ ixs

-- | Render the 'Display' for a specific location.
drawLoc :: GameState -> W.Coords -> Widget Name
drawLoc g = renderDisplay . displayLoc g
drawLoc :: Bool -> GameState -> W.Coords -> Widget Name
drawLoc showRobots g = renderDisplay . displayLoc showRobots g

-- | Get the 'Display' for a specific location, by combining the
-- 'Display's for the terrain, entity, and robots at the location.
displayLoc :: GameState -> W.Coords -> Display
displayLoc g coords =
sconcat . NE.fromList $
[terrainMap M.! toEnum (W.lookupTerrain coords (g ^. world))]
++ maybeToList (displayForEntity <$> W.lookupEntity coords (g ^. world))
++ map (view robotDisplay) (robotsAtLocation (W.coordsToLoc coords) g)
displayLoc :: Bool -> GameState -> W.Coords -> Display
displayLoc showRobots g coords =
sconcat $ terrain NE.:| entity <> robots
where
terrain = terrainMap M.! toEnum (W.lookupTerrain coords (g ^. world))
entity = maybeToList (displayForEntity <$> W.lookupEntity coords (g ^. world))
robots =
if showRobots
then map (view robotDisplay) (robotsAtLocation (W.coordsToLoc coords) g)
else []

displayForEntity :: Entity -> Display
displayForEntity e = (if known e then id else hidden) (e ^. entityDisplay)

Expand Down

0 comments on commit 2293f33

Please sign in to comment.