packages feed

venzone-1.0.0.0: src/Screen/Primitives.hs

{-# 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)