{-| Module : Game.Werewolf.Command.DevotedServant Description : Devoted Servant commands. Copyright : (c) Henry J. Wylde, 2016 License : BSD3 Maintainer : public@hjwylde.com Devoted Servant commands. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} module Game.Werewolf.Command.DevotedServant ( -- * Commands passCommand, revealCommand, ) where import Control.Lens import Control.Monad.Except import Control.Monad.Extra import Control.Monad.State hiding (state) import Control.Monad.Writer import Data.List import Data.Text (Text) import Game.Werewolf hiding (getVoteResult) import Game.Werewolf.Messages import Game.Werewolf.Util passCommand :: Text -> Command passCommand callerName = Command $ do validateCommand callerName passes %= nub . cons callerName revealCommand :: Text -> Command revealCommand callerName = Command $ do validateCommand callerName target <- head <$> getVoteResult let targetRole = target ^. role let targetName = target ^. name setPlayerRole callerName targetRole setPlayerRole targetName devotedServantRole tell [devotedServantRevealedMessage callerName] resetRole callerName targetRole validateCommand :: (MonadError [Message] m, MonadState Game m) => Text -> m () validateCommand callerName = do validatePlayer callerName callerName unlessM (isPlayerDevotedServant callerName) $ throwError [playerCannotDoThatMessage callerName] unlessM isDevotedServantsTurn $ throwError [playerCannotDoThatRightNowMessage callerName] resetRole :: (MonadState Game m, MonadWriter [Message] m) => Text -> Role -> m () resetRole callerName role | role == jesterRole = jesterRevealed .= False | role == simpleWerewolfRole = do aliveWerewolfNames <- toListOf (players . werewolves . alive . name) <$> get tell $ devotedServantJoinedPackMessages callerName (aliveWerewolfNames \\ [callerName]) | role == wildChildRole = roleModel .= Nothing | role == witchRole = healUsed .= False >> poisonUsed .= False | role == wolfHoundRole = allegianceChosen .= Nothing | otherwise = return ()