{-# LANGUAGE TupleSections #-} -- | Game action monads and basic building blocks for human and computer -- player actions. Has no access to the main action type. module Game.LambdaHack.Common.MonadStateRead ( MonadStateRead(..) , getState, getLevel, nUI , getGameMode, isNoConfirmsGame, getEntryArena, pickWeaponM ) where import Prelude () import Game.LambdaHack.Common.Prelude import qualified Data.EnumMap.Strict as EM import qualified Game.LambdaHack.Common.Ability as Ability import Game.LambdaHack.Common.Actor import Game.LambdaHack.Common.ActorState import Game.LambdaHack.Common.Faction import Game.LambdaHack.Common.Item import Game.LambdaHack.Common.ItemStrongest import qualified Game.LambdaHack.Common.Kind as Kind import Game.LambdaHack.Common.Level import Game.LambdaHack.Common.Request import Game.LambdaHack.Common.State import Game.LambdaHack.Content.ModeKind class (Monad m, Functor m, Applicative m) => MonadStateRead m where getsState :: (State -> a) -> m a getState :: MonadStateRead m => m State getState = getsState id getLevel :: MonadStateRead m => LevelId -> m Level getLevel lid = getsState $ (EM.! lid) . sdungeon nUI :: MonadStateRead m => m Int nUI = do factionD <- getsState sfactionD return $! length $ filter (fhasUI . gplayer) $ EM.elems factionD getGameMode :: MonadStateRead m => m ModeKind getGameMode = do Kind.COps{comode=Kind.Ops{okind}} <- getsState scops t <- getsState sgameModeId return $! okind t isNoConfirmsGame :: MonadStateRead m => m Bool isNoConfirmsGame = do gameMode <- getGameMode return $! maybe False (> 0) $ lookup "no confirms" $ mfreq gameMode getEntryArena :: MonadStateRead m => Faction -> m LevelId getEntryArena fact = do dungeon <- getsState sdungeon let (minD, maxD) = case (EM.minViewWithKey dungeon, EM.maxViewWithKey dungeon) of (Just ((s, _), _), Just ((e, _), _)) -> (s, e) _ -> assert `failure` "empty dungeon" `twith` dungeon f [] = 0 f ((ln, _, _) : _) = ln return $! max minD $ min maxD $ toEnum $ f $ ginitial fact pickWeaponM :: MonadStateRead m => Maybe DiscoveryBenefit -> [(ItemId, ItemFull)] -> Ability.Skills -> ActorAspect -> ActorId -> m [(Int, (ItemId, ItemFull))] pickWeaponM mdiscoBenefit allAssocs actorSk actorAspect source = do sb <- getsState $ getActorBody source localTime <- getsState $ getLocalTime (blid sb) let ar = actorAspect EM.! source calmE = calmEnough sb ar forced = bproj sb permitted = permittedPrecious calmE forced preferredPrecious = either (const False) id . permitted permAssocs = filter (preferredPrecious . snd) allAssocs strongest = strongestMelee mdiscoBenefit localTime permAssocs return $! if | forced -> map (1,) allAssocs | EM.findWithDefault 0 Ability.AbMelee actorSk <= 0 -> [] | otherwise -> strongest