{-# Language TemplateHaskell #-} {-# Language ScopedTypeVariables #-} module Screen.Primitives where import Plant import Room import Meeple.Operate import Terminal.Game import Lens.Micro.Platform ----------- -- TYPES -- ----------- -- stuff that can change data Screen = Screen { -- "read" part _room :: Room, -- state part: PC/NPCs _meeples :: [Meeple], -- oob check Plant _NeighbourPlant :: Plant } deriving (Eq, Show) makeClassy ''Screen defaultScreen :: Screen defaultScreen = Screen defaultRoom [] defaultPlant ----------------- -- CONVENIENCE -- ----------------- -- convenience lenses -- -- Wrapped in Meeple. Returns Maybe / does nothing if player is dead mplayer :: HasScreen s => Lens' s (Maybe Meeple) mplayer = lens gt st where gt :: HasScreen s => s -> Maybe Meeple gt s = s ^? meeples . each . filtered isPlayer st :: HasScreen s => s -> Maybe Meeple -> s st s (Just m) = s & meeples . each . filtered isPlayer .~ m st s Nothing = s -- same as mplayer, just not wrapped in Meeple player :: HasScreen s => Lens' s (Maybe Player) player = lens (\s -> s ^. mplayer & mapped %~ getPlayer) (\s mp -> s & mplayer .~ fmap MPlayer mp) where getPlayer (MPlayer p) = p getPlayer _ = error "getPlayer on non MPlayer" -- convenience actions -- -- to be abstracted in .Action o .Outcomes if grows playerDie :: HasScreen s => s -> s playerDie s = s & meeples %~ filter (not . isPlayer)