swarm-0.3.0.0: src/Swarm/TUI/View/CellDisplay.hs
module Swarm.TUI.View.CellDisplay where
import Brick
import Control.Lens
import Data.List.NonEmpty qualified as NE
import Data.Map qualified as M
import Data.Maybe (maybeToList)
import Data.Semigroup (sconcat)
import Swarm.Game.Display
import Swarm.Game.Entity as E
import Swarm.Game.Robot
import Swarm.Game.State
import Swarm.Game.Terrain (terrainMap)
import Swarm.Game.World qualified as W
import Swarm.TUI.Model.Name
-- | Render the 'Display' for a specific location.
drawLoc :: Bool -> GameState -> W.Coords -> Widget Name
drawLoc showRobots g = renderDisplay . displayLoc showRobots g
displayTerrainCell :: GameState -> W.Coords -> Display
displayTerrainCell g coords = terrainMap M.! toEnum (W.lookupTerrain coords (g ^. world))
displayEntityCell, displayRobotCell :: GameState -> W.Coords -> [Display]
displayRobotCell g coords = map (view robotDisplay) (robotsAtLocation (W.coordsToLoc coords) g)
displayEntityCell g coords = maybeToList (displayForEntity <$> W.lookupEntity coords (g ^. world))
where
displayForEntity :: Entity -> Display
displayForEntity e = (if known e then id else hidden) (e ^. entityDisplay)
known e =
e
`hasProperty` Known
|| (e ^. entityName)
`elem` (g ^. knownEntities)
|| case hidingMode g of
HideAllEntities -> False
HideNoEntity -> True
HideEntityUnknownTo ro -> ro `robotKnows` e
-- | Get the 'Display' for a specific location, by combining the
-- 'Display's for the terrain, entity, and robots at the location.
displayLoc :: Bool -> GameState -> W.Coords -> Display
displayLoc showRobots g coords =
sconcat $ terrain NE.:| entity <> robots
where
terrain = displayTerrainCell g coords
entity = displayEntityCell g coords
robots =
if showRobots
then displayRobotCell g coords
else []
data HideEntity = HideAllEntities | HideNoEntity | HideEntityUnknownTo Robot
hidingMode :: GameState -> HideEntity
hidingMode g
| g ^. creativeMode = HideNoEntity
| otherwise = maybe HideAllEntities HideEntityUnknownTo $ focusedRobot g