-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A game engine library for roguelike dungeon crawlers
--   
--   LambdaHack is a Haskell game engine library for roguelike games of
--   arbitrary theme, size and complexity, packaged together with a little
--   example dungeon crawler. Try out the browser version of the LambdaHack
--   sample game at <a>https://lambdahack.github.io</a> (It runs fastest on
--   Chrome. Keyboard commands and savefiles are supported only on recent
--   enough versions of browsers. Mouse should work everywhere.)
--   
--   
--   When completed, the engine will let you specify content to be
--   procedurally generated, define the AI behaviour on top of the generic
--   content-independent rules and compile a ready-to-play game binary,
--   using either the supplied or a custom-made main loop. Several
--   frontends are available (SDL2 is the default for desktop and there is
--   a Javascript browser frontend) and many other generic engine
--   components are easily overridden, but the fundamental source of
--   flexibility lies in the strict and type-safe separation of code from
--   the content and of clients (human and AI-controlled) from the server.
--   
--   Please see the changelog file for recent improvements and the issue
--   tracker for short-term plans. Long term vision revolves around
--   procedural content generation and includes in-game content creation,
--   auto-balancing and persistent content modification based on player
--   behaviour. Contributions are welcome.
--   
--   Games known to use the LambdaHack library:
--   
--   <ul>
--   <li>Allure of the Stars, a near-future Sci-Fi game,
--   <a>http://hackage.haskell.org/package/Allure</a></li>
--   <li>Space Privateers, an adventure game set in far future,
--   <a>http://hackage.haskell.org/package/SpacePrivateers</a></li>
--   </ul>
--   
--   Note: All modules in this library are kept visible, to let games
--   override and reuse them. OTOH, to reflect that some modules are
--   implementation details relative to others, the source code adheres to
--   the following convention. If a module has the same name as a
--   directory, the module is the exclusive interface to the directory. No
--   references to the modules in the directory are allowed except from the
--   interface module. This policy is only binding when developing the
--   library --- library users are free to access any modules, since the
--   library authors are in no position to guess their particular needs.
@package LambdaHack
@version 0.7.1.0


-- | Custom Prelude, compatible across many GHC versions.
module Game.LambdaHack.Common.Prelude

-- | A space efficient, packed, unboxed Unicode text type.
data Text :: *
(<+>) :: Text -> Text -> Text

-- | Show and pack the result.
tshow :: Show a => a -> Text

-- | Integer division, rounding up.
divUp :: Integral a => a -> a -> a
infixl 7 `divUp`
(<$$>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
infixl 4 <$$>
partitionM :: Applicative m => (a -> m Bool) -> [a] -> m ([a], [a])

-- | Split the input between the two argument arrows and combine their
--   output. Note that this is in general not a functor.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
(***) :: Arrow a => forall b c b' c'. () => a b c -> a b' c' -> a (b, b') (c, c')
infixr 3 ***

-- | Fanout: send the input to both argument arrows and combine their
--   output.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
(&&&) :: Arrow a => forall b c c'. () => a b c -> a b c' -> a b (c, c')
infixr 3 &&&

-- | Send the first component of the input through the argument arrow, and
--   copy the rest unchanged to the output.
first :: Arrow a => forall b c d. () => a b c -> a (b, d) (c, d)

-- | A mirror image of <a>first</a>.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
second :: Arrow a => forall b c d. () => a b c -> a (d, b) (d, c)


-- | Basic operations on 2D points represented as linear offsets.
module Game.LambdaHack.Common.Point

-- | Spacial dimension for points and vectors.
type X = Int

-- | Spacial dimension for points and vectors.
type Y = Int

-- | 2D points in cartesian representation. Coordinates grow to the right
--   and down, so that the (0, 0) point is in the top-left corner of the
--   screen. Coordinates are never negative.
data Point
Point :: X -> Y -> Point
[px] :: Point -> X
[py] :: Point -> Y

-- | The maximum number of bits for level X and Y dimension (16). The value
--   is chosen to support architectures with 32-bit Ints.
maxLevelDimExponent :: Int

-- | The distance between two points in the chessboard metric.
chessDist :: Point -> Point -> Int

-- | Squared euclidean distance between two points.
euclidDistSq :: Point -> Point -> Int

-- | Checks whether two points are adjacent on the map (horizontally,
--   vertically or diagonally).
adjacent :: Point -> Point -> Bool

-- | Checks that a point belongs to an area.
inside :: Point -> (X, Y, X, Y) -> Bool

-- | Bresenham's line algorithm generalized to arbitrary starting
--   <tt>eps</tt> (<tt>eps</tt> value of 0 gives the standard BLA). Skips
--   the source point and goes through the second point to the edge of the
--   level. GIves <tt>Nothing</tt> if the points are equal. The target is
--   given as <tt>Point</tt> to permit aiming out of the level, e.g., to
--   get uniform distributions of directions for explosions close to the
--   edge of the level.
bla :: X -> Y -> Int -> Point -> Point -> Maybe [Point]

-- | A list of all points on a straight vertical or straight horizontal
--   line between two points. Fails if no such line exists.
fromTo :: Point -> Point -> [Point]
originPoint :: Point

-- | Maximal supported level X and Y dimension. Not checked anywhere. The
--   value is chosen to support architectures with 32-bit Ints.
maxLevelDim :: Int

-- | Bresenham's line algorithm generalized to arbitrary starting
--   <tt>eps</tt> (<tt>eps</tt> value of 0 gives the standard BLA).
--   Includes the source point and goes through the target point to
--   infinity.
blaXY :: Int -> Point -> Point -> [Point]

-- | See
--   <a>http://roguebasin.roguelikedevelopment.org/index.php/Digital_lines</a>.
balancedWord :: Int -> Int -> Int -> [Int]
instance GHC.Generics.Generic Game.LambdaHack.Common.Point.Point
instance GHC.Classes.Ord Game.LambdaHack.Common.Point.Point
instance GHC.Classes.Eq Game.LambdaHack.Common.Point.Point
instance GHC.Show.Show Game.LambdaHack.Common.Point.Point
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Point.Point
instance Control.DeepSeq.NFData Game.LambdaHack.Common.Point.Point
instance GHC.Enum.Enum Game.LambdaHack.Common.Point.Point


-- | Arrays, based on Data.Vector.Unboxed, indexed by <tt>Point</tt>.
module Game.LambdaHack.Common.PointArray

-- | Arrays indexed by <tt>Point</tt>.
data GArray w c
Array :: X -> Y -> Vector w -> GArray w c
[axsize] :: GArray w c -> X
[aysize] :: GArray w c -> Y
[avector] :: GArray w c -> Vector w

-- | Arrays of, effectively, <tt>Word8</tt>, indexed by <tt>Point</tt>.
type Array c = GArray Word8 c
pindex :: X -> Point -> Int
punindex :: X -> Int -> Point

-- | Array lookup.
(!) :: (Unbox w, Enum w, Enum c) => GArray w c -> Point -> c
accessI :: Unbox w => GArray w c -> Int -> w

-- | Construct an array updated with the association list.
(//) :: (Unbox w, Enum w, Enum c) => GArray w c -> [(Point, c)] -> GArray w c
unsafeUpdateA :: (Unbox w, Enum w, Enum c) => GArray w c -> [(Point, c)] -> ()
unsafeWriteA :: (Unbox w, Enum w, Enum c) => GArray w c -> Point -> c -> ()
unsafeWriteManyA :: (Unbox w, Enum w, Enum c) => GArray w c -> [Point] -> c -> ()

-- | Create an array from a replicated element.
replicateA :: (Unbox w, Enum w, Enum c) => X -> Y -> c -> GArray w c

-- | Create an array from a replicated monadic action.
replicateMA :: (Unbox w, Enum w, Enum c, Monad m) => X -> Y -> m c -> m (GArray w c)

-- | Create an array from a function.
generateA :: (Unbox w, Enum w, Enum c) => X -> Y -> (Point -> c) -> GArray w c

-- | Create an array from a monadic function.
generateMA :: (Unbox w, Enum w, Enum c, Monad m) => X -> Y -> (Point -> m c) -> m (GArray w c)
unfoldrNA :: (Unbox w, Enum w, Enum c) => X -> Y -> (b -> (c, b)) -> b -> GArray w c

-- | Content identifiers array size.
sizeA :: GArray w c -> (X, Y)

-- | Fold right over an array.
foldrA :: (Unbox w, Enum w, Enum c) => (c -> a -> a) -> a -> GArray w c -> a

-- | Fold right strictly over an array.
foldrA' :: (Unbox w, Enum w, Enum c) => (c -> a -> a) -> a -> GArray w c -> a

-- | Fold left strictly over an array.
foldlA' :: (Unbox w, Enum w, Enum c) => (a -> c -> a) -> a -> GArray w c -> a

-- | Fold right over an array (function applied to each element and its
--   index).
ifoldrA :: (Unbox w, Enum w, Enum c) => (Point -> c -> a -> a) -> a -> GArray w c -> a

-- | Fold right strictly over an array (function applied to each element
--   and its index).
ifoldrA' :: (Unbox w, Enum w, Enum c) => (Point -> c -> a -> a) -> a -> GArray w c -> a

-- | Fold left strictly over an array (function applied to each element and
--   its index).
ifoldlA' :: (Unbox w, Enum w, Enum c) => (a -> Point -> c -> a) -> a -> GArray w c -> a

-- | Fold monadically strictly over an array.
foldMA' :: (Monad m, Unbox w, Enum w, Enum c) => (a -> c -> m a) -> a -> GArray w c -> m a

-- | Fold monadically strictly over an array (function applied to each
--   element and its index).
ifoldMA' :: (Monad m, Unbox w, Enum w, Enum c) => (a -> Point -> c -> m a) -> a -> GArray w c -> m a

-- | Map over an array.
mapA :: (Unbox w1, Enum w1, Unbox w2, Enum w2, Enum c, Enum d) => (c -> d) -> GArray w1 c -> GArray w2 d

-- | Map over an array (function applied to each element and its index).
imapA :: (Unbox w1, Enum w1, Unbox w2, Enum w2, Enum c, Enum d) => (Point -> c -> d) -> GArray w1 c -> GArray w2 d

-- | Map monadically over an array (function applied to each element and
--   its index) and ignore the results.
imapMA_ :: (Unbox w, Enum w, Enum c, Monad m) => (Point -> c -> m ()) -> GArray w c -> m ()

-- | Set all elements to the given value, in place, if possible.
safeSetA :: (Unbox w, Enum w, Enum c) => c -> GArray w c -> GArray w c

-- | Set all elements to the given value, in place.
unsafeSetA :: (Unbox w, Enum w, Enum c) => c -> GArray w c -> GArray w c

-- | Yield the point coordinates of a minimum element of the array. The
--   array may not be empty.
minIndexA :: (Unbox w, Ord w) => GArray w c -> Point

-- | Yield the point coordinates of the last minimum element of the array.
--   The array may not be empty.
minLastIndexA :: (Unbox w, Ord w) => GArray w c -> Point

-- | Yield the point coordinates of all the minimum elements of the array.
--   The array may not be empty.
minIndexesA :: (Unbox w, Enum w, Ord w) => GArray w c -> [Point]

-- | Yield the point coordinates of the first maximum element of the array.
--   The array may not be empty.
maxIndexA :: (Unbox w, Ord w) => GArray w c -> Point

-- | Yield the point coordinates of the last maximum element of the array.
--   The array may not be empty.
maxLastIndexA :: (Unbox w, Ord w) => GArray w c -> Point

-- | Force the array not to retain any extra memory.
forceA :: Unbox w => GArray w c -> GArray w c
fromListA :: (Unbox w, Enum w, Enum c) => X -> Y -> [c] -> GArray w c
toListA :: (Unbox w, Enum w, Enum c) => GArray w c -> [c]
cnv :: (Enum a, Enum b) => a -> b
instance (GHC.Classes.Eq w, Data.Vector.Unboxed.Base.Unbox w) => GHC.Classes.Eq (Game.LambdaHack.Common.PointArray.GArray w c)
instance GHC.Show.Show (Game.LambdaHack.Common.PointArray.GArray w c)
instance (Data.Vector.Unboxed.Base.Unbox w, Data.Binary.Class.Binary w) => Data.Binary.Class.Binary (Game.LambdaHack.Common.PointArray.GArray w c)


-- | Hacks that haven't found their home yet.
module Game.LambdaHack.Common.Misc

-- | A unique identifier of a faction in a game.
data FactionId

-- | Abstract level identifiers.
data LevelId

-- | A unique identifier of an actor in the dungeon.
data ActorId

-- | Item container type.
data Container
CFloor :: LevelId -> Point -> Container
CEmbed :: LevelId -> Point -> Container
CActor :: ActorId -> CStore -> Container

-- | for bootstrapping actor bodies
CTrunk :: FactionId -> LevelId -> Point -> Container

-- | Actor's item stores.
data CStore
CGround :: CStore
COrgan :: CStore
CEqp :: CStore
CInv :: CStore
CSha :: CStore
data ItemDialogMode
MStore :: CStore -> ItemDialogMode
MOwned :: ItemDialogMode
MStats :: ItemDialogMode
MLoreItem :: ItemDialogMode
MLoreOrgan :: ItemDialogMode
data GroupName a

-- | For each group that the kind belongs to, denoted by a
--   <tt>GroupName</tt> in the first component of a pair, the second
--   component of a pair shows how common the kind is within the group.
type Freqs a = [(GroupName a, Int)]

-- | Rarity on given depths.
type Rarity = [(Double, Int)]

-- | Absolute depth in the dungeon. When used for the maximum depth of the
--   whole dungeon, this can be different than dungeon size, e.g., when the
--   dungeon is branched, and it can even be different than the length of
--   the longest branch, if levels at some depths are missing.
newtype AbsDepth
AbsDepth :: Int -> AbsDepth

-- | Tactic of non-leader actors. Apart of determining AI operation, each
--   tactic implies a skill modifier, that is added to the non-leader
--   skills defined in <tt>fskillsOther</tt> field of <tt>Player</tt>.
data Tactic

-- | if enemy nearby, attack, if no items, etc., explore unknown
TExplore :: Tactic

-- | always follow leader's target or his position if no target
TFollow :: Tactic

-- | follow but don't do any item management nor use
TFollowNoItems :: Tactic

-- | only melee and do ranged combat
TMeleeAndRanged :: Tactic

-- | only melee (or wait)
TMeleeAdjacent :: Tactic

-- | always only wait, even if enemy in melee range
TBlock :: Tactic

-- | if enemy nearby, attack, if no items, etc., roam randomly
TRoam :: Tactic

-- | find an open and uncrowded area, patrol it according to sight radius
--   and fallback temporarily to <tt>TRoam</tt> when enemy is seen by the
--   faction and is within the actor's sight radius
TPatrol :: Tactic
toGroupName :: Text -> GroupName a
validateRarity :: Rarity -> [Text]
describeTactic :: Tactic -> Text

-- | Re-exported English phrase creation functions, applied to default
--   irregular word sets.
makePhrase :: [Part] -> Text

-- | Re-exported English phrase creation functions, applied to default
--   irregular word sets.
makeSentence :: [Part] -> Text

-- | Level bounds.
normalLevelBound :: (Int, Int)

-- | <pre>
--   breturn b a = [a | b]
--   </pre>
breturn :: MonadPlus m => Bool -> a -> m a

-- | Personal data directory for the game. Depends on the OS and the game,
--   e.g., for LambdaHack under Linux it's <tt>~/.LambdaHack/</tt>.
appDataDir :: IO FilePath
xM :: Int -> Int64
xD :: Double -> Double
minusM :: Int64
minusM1 :: Int64
oneM :: Int64
instance GHC.Generics.Generic Game.LambdaHack.Common.Misc.Tactic
instance GHC.Enum.Bounded Game.LambdaHack.Common.Misc.Tactic
instance GHC.Enum.Enum Game.LambdaHack.Common.Misc.Tactic
instance GHC.Classes.Ord Game.LambdaHack.Common.Misc.Tactic
instance GHC.Classes.Eq Game.LambdaHack.Common.Misc.Tactic
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Misc.AbsDepth
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Misc.AbsDepth
instance GHC.Classes.Ord Game.LambdaHack.Common.Misc.AbsDepth
instance GHC.Classes.Eq Game.LambdaHack.Common.Misc.AbsDepth
instance GHC.Show.Show Game.LambdaHack.Common.Misc.AbsDepth
instance GHC.Generics.Generic (Game.LambdaHack.Common.Misc.GroupName a)
instance Data.Binary.Class.Binary (Game.LambdaHack.Common.Misc.GroupName a)
instance Data.Hashable.Class.Hashable (Game.LambdaHack.Common.Misc.GroupName a)
instance GHC.Classes.Ord (Game.LambdaHack.Common.Misc.GroupName a)
instance GHC.Classes.Eq (Game.LambdaHack.Common.Misc.GroupName a)
instance GHC.Read.Read (Game.LambdaHack.Common.Misc.GroupName a)
instance GHC.Generics.Generic Game.LambdaHack.Common.Misc.ItemDialogMode
instance GHC.Classes.Ord Game.LambdaHack.Common.Misc.ItemDialogMode
instance GHC.Classes.Eq Game.LambdaHack.Common.Misc.ItemDialogMode
instance GHC.Read.Read Game.LambdaHack.Common.Misc.ItemDialogMode
instance GHC.Show.Show Game.LambdaHack.Common.Misc.ItemDialogMode
instance GHC.Generics.Generic Game.LambdaHack.Common.Misc.Container
instance GHC.Classes.Ord Game.LambdaHack.Common.Misc.Container
instance GHC.Classes.Eq Game.LambdaHack.Common.Misc.Container
instance GHC.Show.Show Game.LambdaHack.Common.Misc.Container
instance GHC.Generics.Generic Game.LambdaHack.Common.Misc.CStore
instance GHC.Enum.Bounded Game.LambdaHack.Common.Misc.CStore
instance GHC.Enum.Enum Game.LambdaHack.Common.Misc.CStore
instance GHC.Classes.Ord Game.LambdaHack.Common.Misc.CStore
instance GHC.Classes.Eq Game.LambdaHack.Common.Misc.CStore
instance GHC.Read.Read Game.LambdaHack.Common.Misc.CStore
instance GHC.Show.Show Game.LambdaHack.Common.Misc.CStore
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Misc.ActorId
instance GHC.Enum.Enum Game.LambdaHack.Common.Misc.ActorId
instance GHC.Classes.Ord Game.LambdaHack.Common.Misc.ActorId
instance GHC.Classes.Eq Game.LambdaHack.Common.Misc.ActorId
instance GHC.Show.Show Game.LambdaHack.Common.Misc.ActorId
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Misc.LevelId
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Misc.LevelId
instance GHC.Enum.Enum Game.LambdaHack.Common.Misc.LevelId
instance GHC.Classes.Ord Game.LambdaHack.Common.Misc.LevelId
instance GHC.Classes.Eq Game.LambdaHack.Common.Misc.LevelId
instance GHC.Show.Show Game.LambdaHack.Common.Misc.LevelId
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Misc.FactionId
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Misc.FactionId
instance GHC.Enum.Enum Game.LambdaHack.Common.Misc.FactionId
instance GHC.Classes.Ord Game.LambdaHack.Common.Misc.FactionId
instance GHC.Classes.Eq Game.LambdaHack.Common.Misc.FactionId
instance GHC.Show.Show Game.LambdaHack.Common.Misc.FactionId
instance GHC.Show.Show Game.LambdaHack.Common.Misc.Tactic
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Misc.Tactic
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Misc.Tactic
instance Data.String.IsString (Game.LambdaHack.Common.Misc.GroupName a)
instance GHC.Show.Show (Game.LambdaHack.Common.Misc.GroupName a)
instance Control.DeepSeq.NFData (Game.LambdaHack.Common.Misc.GroupName a)
instance Control.DeepSeq.NFData Game.LambdaHack.Common.Misc.ItemDialogMode
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Misc.ItemDialogMode
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Misc.Container
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Misc.CStore
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Misc.CStore
instance Control.DeepSeq.NFData Game.LambdaHack.Common.Misc.CStore
instance (GHC.Enum.Enum k, Data.Binary.Class.Binary k, Data.Binary.Class.Binary e) => Data.Binary.Class.Binary (Data.EnumMap.Strict.EnumMap k e)
instance (GHC.Enum.Enum k, Data.Binary.Class.Binary k) => Data.Binary.Class.Binary (Data.EnumSet.EnumSet k)
instance Data.Binary.Class.Binary Data.Time.Clock.Internal.NominalDiffTime.NominalDiffTime
instance (Data.Hashable.Class.Hashable k, GHC.Classes.Eq k, Data.Binary.Class.Binary k, Data.Binary.Class.Binary v) => Data.Binary.Class.Binary (Data.HashMap.Base.HashMap k v)
instance Data.Key.Zip (Data.EnumMap.Strict.EnumMap k)
instance GHC.Enum.Enum k => Data.Key.ZipWithKey (Data.EnumMap.Strict.EnumMap k)
instance GHC.Enum.Enum k => Data.Key.Keyed (Data.EnumMap.Strict.EnumMap k)
instance GHC.Enum.Enum k => Data.Key.FoldableWithKey (Data.EnumMap.Strict.EnumMap k)
instance GHC.Enum.Enum k => Data.Key.TraversableWithKey (Data.EnumMap.Strict.EnumMap k)
instance GHC.Enum.Enum k => Data.Key.Indexable (Data.EnumMap.Strict.EnumMap k)
instance GHC.Enum.Enum k => Data.Key.Lookup (Data.EnumMap.Strict.EnumMap k)
instance GHC.Enum.Enum k => Data.Key.Adjustable (Data.EnumMap.Strict.EnumMap k)
instance (GHC.Enum.Enum k, Data.Hashable.Class.Hashable k, Data.Hashable.Class.Hashable e) => Data.Hashable.Class.Hashable (Data.EnumMap.Strict.EnumMap k e)
instance Control.DeepSeq.NFData NLP.Miniutter.English.Part
instance Control.DeepSeq.NFData NLP.Miniutter.English.Person
instance Control.DeepSeq.NFData NLP.Miniutter.English.Polarity


-- | Saving/loading to files, with serialization and compression.
module Game.LambdaHack.Common.HSFile

-- | Serialize, compress and save data with an EOF marker. The <tt>OK</tt>
--   is used as an EOF marker to ensure any apparent problems with
--   corrupted files are reported to the user ASAP.
encodeEOF :: Binary a => FilePath -> a -> IO ()

-- | Read, decompress and deserialize data with an EOF marker. The
--   <tt>OK</tt> EOF marker ensures any easily detectable file corruption
--   is discovered and reported before the function returns.
strictDecodeEOF :: Binary a => FilePath -> IO a

-- | Try to create a directory, if it doesn't exist. We catch exceptions in
--   case many clients try to do the same thing at the same time.
tryCreateDir :: FilePath -> IO ()

-- | The operation <a>doesFileExist</a> returns <a>True</a> if the argument
--   file exists and is not a directory, and <a>False</a> otherwise.
doesFileExist :: FilePath -> IO Bool

-- | Try to write a file, given content, if the file not already there. We
--   catch exceptions in case many clients try to do the same thing at the
--   same time.
tryWriteFile :: FilePath -> String -> IO ()

-- | The <a>readFile</a> function reads a file and returns the contents of
--   the file as a string. The file is read lazily, on demand, as with
--   <a>getContents</a>.
readFile :: FilePath -> IO String

-- | <tt><a>renameFile</a> old new</tt> changes the name of an existing
--   file system object from <i>old</i> to <i>new</i>. If the <i>new</i>
--   object already exists, it is atomically replaced by the <i>old</i>
--   object. Neither path may refer to an existing directory. A conformant
--   implementation need not support renaming files in all situations (e.g.
--   renaming across different physical devices), but the constraints must
--   be documented.
--   
--   The operation may fail with:
--   
--   <ul>
--   <li><tt>HardwareFault</tt> A physical I/O error has occurred.
--   <tt>[EIO]</tt></li>
--   <li><tt>InvalidArgument</tt> Either operand is not a valid file name.
--   <tt>[ENAMETOOLONG, ELOOP]</tt></li>
--   <li><a>isDoesNotExistError</a> / <tt>NoSuchThing</tt> The original
--   file does not exist, or there is no path to the target. <tt>[ENOENT,
--   ENOTDIR]</tt></li>
--   <li><a>isPermissionError</a> / <tt>PermissionDenied</tt> The process
--   has insufficient privileges to perform the operation. <tt>[EROFS,
--   EACCES, EPERM]</tt></li>
--   <li><tt>ResourceExhausted</tt> Insufficient resources are available to
--   perform the operation. <tt>[EDQUOT, ENOSPC, ENOMEM, EMLINK]</tt></li>
--   <li><tt>UnsatisfiedConstraints</tt> Implementation-dependent
--   constraints are not satisfied. <tt>[EBUSY]</tt></li>
--   <li><a>UnsupportedOperation</a> The implementation does not support
--   renaming in this situation. <tt>[EXDEV]</tt></li>
--   <li><a>InappropriateType</a> Either path refers to an existing
--   directory. <tt>[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]</tt></li>
--   </ul>
renameFile :: FilePath -> FilePath -> IO ()

-- | Serialize, compress and save data. Note that LBS.writeFile opens the
--   file in binary mode.
encodeData :: Binary a => FilePath -> a -> IO ()


-- | Saving/loading to files, with serialization and compression.
module Game.LambdaHack.Common.File

-- | Serialize, compress and save data with an EOF marker. The <tt>OK</tt>
--   is used as an EOF marker to ensure any apparent problems with
--   corrupted files are reported to the user ASAP.
encodeEOF :: Binary a => FilePath -> a -> IO ()

-- | Read, decompress and deserialize data with an EOF marker. The
--   <tt>OK</tt> EOF marker ensures any easily detectable file corruption
--   is discovered and reported before the function returns.
strictDecodeEOF :: Binary a => FilePath -> IO a

-- | Try to create a directory, if it doesn't exist. We catch exceptions in
--   case many clients try to do the same thing at the same time.
tryCreateDir :: FilePath -> IO ()

-- | The operation <a>doesFileExist</a> returns <a>True</a> if the argument
--   file exists and is not a directory, and <a>False</a> otherwise.
doesFileExist :: FilePath -> IO Bool

-- | Try to write a file, given content, if the file not already there. We
--   catch exceptions in case many clients try to do the same thing at the
--   same time.
tryWriteFile :: FilePath -> String -> IO ()

-- | The <a>readFile</a> function reads a file and returns the contents of
--   the file as a string. The file is read lazily, on demand, as with
--   <a>getContents</a>.
readFile :: FilePath -> IO String

-- | <tt><a>renameFile</a> old new</tt> changes the name of an existing
--   file system object from <i>old</i> to <i>new</i>. If the <i>new</i>
--   object already exists, it is atomically replaced by the <i>old</i>
--   object. Neither path may refer to an existing directory. A conformant
--   implementation need not support renaming files in all situations (e.g.
--   renaming across different physical devices), but the constraints must
--   be documented.
--   
--   The operation may fail with:
--   
--   <ul>
--   <li><tt>HardwareFault</tt> A physical I/O error has occurred.
--   <tt>[EIO]</tt></li>
--   <li><tt>InvalidArgument</tt> Either operand is not a valid file name.
--   <tt>[ENAMETOOLONG, ELOOP]</tt></li>
--   <li><a>isDoesNotExistError</a> / <tt>NoSuchThing</tt> The original
--   file does not exist, or there is no path to the target. <tt>[ENOENT,
--   ENOTDIR]</tt></li>
--   <li><a>isPermissionError</a> / <tt>PermissionDenied</tt> The process
--   has insufficient privileges to perform the operation. <tt>[EROFS,
--   EACCES, EPERM]</tt></li>
--   <li><tt>ResourceExhausted</tt> Insufficient resources are available to
--   perform the operation. <tt>[EDQUOT, ENOSPC, ENOMEM, EMLINK]</tt></li>
--   <li><tt>UnsatisfiedConstraints</tt> Implementation-dependent
--   constraints are not satisfied. <tt>[EBUSY]</tt></li>
--   <li><a>UnsupportedOperation</a> The implementation does not support
--   renaming in this situation. <tt>[EXDEV]</tt></li>
--   <li><a>InappropriateType</a> Either path refers to an existing
--   directory. <tt>[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]</tt></li>
--   </ul>
renameFile :: FilePath -> FilePath -> IO ()


-- | A list of entities with relative frequencies of appearance.
module Game.LambdaHack.Common.Frequency

-- | The frequency distribution type. Not normalized (operations may or may
--   not group the same elements and sum their frequencies). However,
--   elements with zero frequency are removed upon construction.
--   
--   The <tt>Eq</tt> instance compares raw representations, not relative,
--   normalized frequencies, so operations don't need to preserve the
--   expected equalities.
data Frequency a

-- | Uniform discrete frequency distribution.
uniformFreq :: Text -> [a] -> Frequency a

-- | Takes a name and a list of frequencies and items into the frequency
--   distribution.
toFreq :: Text -> [(Int, a)] -> Frequency a

-- | Scale frequency distribution, multiplying it by a positive integer
--   constant.
scaleFreq :: Show a => Int -> Frequency a -> Frequency a

-- | Change the description of the frequency.
renameFreq :: Text -> Frequency a -> Frequency a

-- | Set frequency of an element.
setFreq :: Eq a => Frequency a -> a -> Int -> Frequency a

-- | Test if the frequency distribution is empty.
nullFreq :: Frequency a -> Bool

-- | give acces to raw frequency values
runFrequency :: Frequency a -> [(Int, a)]

-- | short description for debug, etc.
nameFrequency :: Frequency a -> Text
minFreq :: Ord a => Frequency a -> Maybe a
maxFreq :: Ord a => Frequency a -> Maybe a
mostFreq :: Frequency a -> Maybe a

-- | Average value of an <tt>Int</tt> distribution, rounded up to avoid
--   truncating it in the other code higher up, which would equate 1d0 with
--   1d1.
meanFreq :: Frequency Int -> Int
instance GHC.Generics.Generic (Game.LambdaHack.Common.Frequency.Frequency a)
instance Data.Traversable.Traversable Game.LambdaHack.Common.Frequency.Frequency
instance Data.Foldable.Foldable Game.LambdaHack.Common.Frequency.Frequency
instance GHC.Classes.Ord a => GHC.Classes.Ord (Game.LambdaHack.Common.Frequency.Frequency a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Game.LambdaHack.Common.Frequency.Frequency a)
instance GHC.Show.Show a => GHC.Show.Show (Game.LambdaHack.Common.Frequency.Frequency a)
instance GHC.Base.Monad Game.LambdaHack.Common.Frequency.Frequency
instance GHC.Base.Functor Game.LambdaHack.Common.Frequency.Frequency
instance GHC.Base.Applicative Game.LambdaHack.Common.Frequency.Frequency
instance GHC.Base.MonadPlus Game.LambdaHack.Common.Frequency.Frequency
instance GHC.Base.Alternative Game.LambdaHack.Common.Frequency.Frequency
instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Game.LambdaHack.Common.Frequency.Frequency a)
instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Game.LambdaHack.Common.Frequency.Frequency a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Game.LambdaHack.Common.Frequency.Frequency a)


-- | Representation of dice scaled with current level depth.
module Game.LambdaHack.Common.Dice

-- | Multiple dice rolls, some scaled with current level depth, in which
--   case the sum of all rolls is scaled in proportion to current depth
--   divided by maximal dungeon depth.
--   
--   The simple dice should have positive number of rolls and number of
--   sides.
--   
--   The <tt>Num</tt> instance doesn't have <tt>abs</tt> nor
--   <tt>signum</tt> defined, because the functions for computing minimum,
--   maximum and mean dice results would be too costly.
data Dice

-- | Cast dice scaled with current level depth. Note that at the first
--   level, the scaled dice are always ignored.
--   
--   The implementation calls RNG as many times as there are dice rolls,
--   which is costly, so content should prefer to case fewer dice and then
--   multiply them by a constant. If rounded results are not desired (often
--   they are, to limit the number of distinct item varieties in
--   inventory), another dice may be added to the result.
--   
--   A different possible implementation, with dice represented as
--   <tt>Frequency</tt>, makes only one RNG call per dice, but due to lists
--   lengths proportional to the maximal value of the dice, it's is
--   intractable for 1000d1000 and problematic already for 100d100.
castDice :: forall m. Monad m => ((Int, Int) -> m Int) -> AbsDepth -> AbsDepth -> Dice -> m Int

-- | A die, rolled the given number of times. E.g., <tt>1 <a>d</a> 2</tt>
--   rolls 2-sided die one time.
d :: Int -> Int -> Dice

-- | A die rolled the given number of times, with the result scaled with
--   dungeon level depth.
dl :: Int -> Int -> Dice

-- | A die, starting from zero, ending at one less than the bound, rolled
--   the given number of times. E.g., <tt>1 <a>z</a> 1</tt> always rolls
--   zero.
z :: Int -> Int -> Dice

-- | A die, starting from zero, ending at one less than the bound, rolled
--   the given number of times, with the result scaled with dungeon level
--   depth.
zl :: Int -> Int -> Dice
intToDice :: Int -> Dice

-- | Minimal and maximal possible value of the dice.
--   
--   <tt>divUp</tt> in the implementation corresponds to <tt>ceiling</tt>,
--   applied to results of <tt>meanDice</tt> elsewhere in the code, and
--   prevents treating 1d1-power effects (on shallow levels) as null
--   effects.
minmaxDice :: Dice -> (Int, Int)

-- | Maximal value of dice. The scaled part taken assuming median level.
maxDice :: Dice -> Int

-- | Minimal value of dice. The scaled part taken assuming median level.
minDice :: Dice -> Int

-- | Mean value of dice. The scaled part taken assuming median level.
meanDice :: Dice -> Double
reduceDice :: Dice -> Maybe Int

-- | Dice for rolling a pair of integer parameters pertaining to,
--   respectively, the X and Y cartesian 2D coordinates.
data DiceXY
DiceXY :: Dice -> Dice -> DiceXY

-- | Maximal value of DiceXY.
maxDiceXY :: DiceXY -> (Int, Int)

-- | Minimal value of DiceXY.
minDiceXY :: DiceXY -> (Int, Int)

-- | Mean value of DiceXY.
meanDiceXY :: DiceXY -> (Double, Double)
instance GHC.Generics.Generic Game.LambdaHack.Common.Dice.DiceXY
instance GHC.Show.Show Game.LambdaHack.Common.Dice.DiceXY
instance GHC.Generics.Generic Game.LambdaHack.Common.Dice.Dice
instance GHC.Classes.Ord Game.LambdaHack.Common.Dice.Dice
instance GHC.Classes.Eq Game.LambdaHack.Common.Dice.Dice
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Dice.DiceXY
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Dice.DiceXY
instance GHC.Show.Show Game.LambdaHack.Common.Dice.Dice
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Dice.Dice
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Dice.Dice
instance Control.DeepSeq.NFData Game.LambdaHack.Common.Dice.Dice
instance GHC.Num.Num Game.LambdaHack.Common.Dice.Dice


-- | A game requires the engine provided by the library, perhaps
--   customized, and game content, defined completely afresh for the
--   particular game. The general type of the content is
--   <tt>ContentDef</tt> and it has instances for all content kinds, such
--   as items kinds (<a>Game.LambdaHack.Content.ItemKind</a>).
--   
--   The possible kinds are fixed in the library and all defined within the
--   library source code directory. On the other hand, game content, that
--   is the values whose types are <tt>ContentDef</tt> instances, are
--   defined in the directory hosting the particular game definition.
module Game.LambdaHack.Common.ContentDef

-- | The general type of a particular game content, e.g., item kinds.
data ContentDef a
ContentDef :: (a -> Char) -> (a -> Text) -> (a -> Freqs a) -> (a -> [Text]) -> ([a] -> [Text]) -> Vector a -> ContentDef a

-- | symbol, e.g., to print on the map
[getSymbol] :: ContentDef a -> a -> Char

-- | name, e.g., to show to the player
[getName] :: ContentDef a -> a -> Text

-- | frequency within groups
[getFreq] :: ContentDef a -> a -> Freqs a

-- | validate a content item and list all offences
[validateSingle] :: ContentDef a -> a -> [Text]

-- | validate the whole defined content of this type and list all offences
[validateAll] :: ContentDef a -> [a] -> [Text]

-- | all content of this type
[content] :: ContentDef a -> Vector a
contentFromList :: [a] -> Vector a


-- | Colours and text attributes.
module Game.LambdaHack.Common.Color

-- | Colours supported by the major frontends.
data Color
Black :: Color
Red :: Color
Green :: Color
Brown :: Color
Blue :: Color
Magenta :: Color
Cyan :: Color
White :: Color
BrBlack :: Color
BrRed :: Color
BrGreen :: Color
BrYellow :: Color
BrBlue :: Color
BrMagenta :: Color
BrCyan :: Color
BrWhite :: Color

-- | The default colours, to optimize attribute setting.
defFG :: Color

-- | A helper for the terminal frontends that display bright via bold.
isBright :: Color -> Bool

-- | Colour sets.
darkCol :: [Color]

-- | Colour sets.
brightCol :: [Color]

-- | Colour sets.
stdCol :: [Color]

-- | Translationg to heavily modified Linux console color RGB values.
--   
--   Warning: SDL frontend sadly duplicates this code.
colorToRGB :: Color -> Text

-- | Additional map cell highlight, e.g., a colorful square around the cell
--   or a colorful background.
data Highlight
HighlightNone :: Highlight
HighlightRed :: Highlight
HighlightBlue :: Highlight
HighlightYellow :: Highlight
HighlightGrey :: Highlight
HighlightWhite :: Highlight
HighlightMagenta :: Highlight

-- | Text attributes: foreground color and highlight.
data Attr
Attr :: Color -> Highlight -> Attr

-- | foreground colour
[fg] :: Attr -> Color

-- | highlight
[bg] :: Attr -> Highlight

-- | The default attribute, to optimize attribute setting.
defAttr :: Attr

-- | Character to display, with its attribute.
data AttrChar
AttrChar :: Attr -> Char -> AttrChar
[acAttr] :: AttrChar -> Attr
[acChar] :: AttrChar -> Char

-- | Optimized representation of <a>AttrChar</a>.
newtype AttrCharW32
AttrCharW32 :: Word32 -> AttrCharW32
[attrCharW32] :: AttrCharW32 -> Word32
attrCharToW32 :: AttrChar -> AttrCharW32
attrCharFromW32 :: AttrCharW32 -> AttrChar
fgFromW32 :: AttrCharW32 -> Color
bgFromW32 :: AttrCharW32 -> Highlight
charFromW32 :: AttrCharW32 -> Char
attrFromW32 :: AttrCharW32 -> Attr
attrEnumFromW32 :: AttrCharW32 -> Int
spaceAttrW32 :: AttrCharW32
retAttrW32 :: AttrCharW32
attrChar2ToW32 :: Color -> Char -> AttrCharW32
attrChar1ToW32 :: Char -> AttrCharW32
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Color.AttrCharW32
instance GHC.Enum.Enum Game.LambdaHack.Common.Color.AttrCharW32
instance GHC.Classes.Eq Game.LambdaHack.Common.Color.AttrCharW32
instance GHC.Show.Show Game.LambdaHack.Common.Color.AttrCharW32
instance GHC.Classes.Ord Game.LambdaHack.Common.Color.AttrChar
instance GHC.Classes.Eq Game.LambdaHack.Common.Color.AttrChar
instance GHC.Show.Show Game.LambdaHack.Common.Color.AttrChar
instance GHC.Classes.Ord Game.LambdaHack.Common.Color.Attr
instance GHC.Classes.Eq Game.LambdaHack.Common.Color.Attr
instance GHC.Show.Show Game.LambdaHack.Common.Color.Attr
instance GHC.Generics.Generic Game.LambdaHack.Common.Color.Highlight
instance GHC.Enum.Bounded Game.LambdaHack.Common.Color.Highlight
instance GHC.Enum.Enum Game.LambdaHack.Common.Color.Highlight
instance GHC.Classes.Ord Game.LambdaHack.Common.Color.Highlight
instance GHC.Classes.Eq Game.LambdaHack.Common.Color.Highlight
instance GHC.Show.Show Game.LambdaHack.Common.Color.Highlight
instance GHC.Generics.Generic Game.LambdaHack.Common.Color.Color
instance GHC.Enum.Bounded Game.LambdaHack.Common.Color.Color
instance GHC.Enum.Enum Game.LambdaHack.Common.Color.Color
instance GHC.Classes.Ord Game.LambdaHack.Common.Color.Color
instance GHC.Classes.Eq Game.LambdaHack.Common.Color.Color
instance GHC.Show.Show Game.LambdaHack.Common.Color.Color
instance GHC.Enum.Enum Game.LambdaHack.Common.Color.Attr
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Color.Highlight
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Color.Highlight
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Color.Color
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Color.Color


-- | The appearance of in-game items, as communicated to the player.
module Game.LambdaHack.Common.Flavour

-- | The type of item flavours.
data Flavour

-- | Turn a colour set into a flavour set.
zipPlain :: [Color] -> [Flavour]

-- | Turn a colour set into a flavour set.
zipFancy :: [Color] -> [Flavour]

-- | Turn a colour set into a flavour set.
zipLiquid :: [Color] -> [Flavour]

-- | The standard full set of flavours.
stdFlav :: [Flavour]

-- | Get the underlying base colour of a flavour.
flavourToColor :: Flavour -> Color

-- | Construct the full name of a flavour.
flavourToName :: Flavour -> Text

-- | Human-readable names for item colors. The plain set.
colorToPlainName :: Color -> Text

-- | Human-readable names for item colors. The fancy set.
colorToFancyName :: Color -> Text

-- | Simple names for team colors (bright colours preferred).
colorToTeamName :: Color -> Text
data FancyName

-- | Human-readable names for item colors. The liquid set.
colorToLiquidName :: Color -> Text
instance GHC.Generics.Generic Game.LambdaHack.Common.Flavour.Flavour
instance GHC.Classes.Ord Game.LambdaHack.Common.Flavour.Flavour
instance GHC.Classes.Eq Game.LambdaHack.Common.Flavour.Flavour
instance GHC.Show.Show Game.LambdaHack.Common.Flavour.Flavour
instance GHC.Generics.Generic Game.LambdaHack.Common.Flavour.FancyName
instance GHC.Classes.Ord Game.LambdaHack.Common.Flavour.FancyName
instance GHC.Classes.Eq Game.LambdaHack.Common.Flavour.FancyName
instance GHC.Show.Show Game.LambdaHack.Common.Flavour.FancyName
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Flavour.Flavour
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Flavour.Flavour
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Flavour.FancyName
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Flavour.FancyName


-- | AI strategy abilities.
module Game.LambdaHack.Common.Ability

-- | Actor and faction abilities corresponding to client-server requests.
data Ability
AbMove :: Ability
AbMelee :: Ability
AbDisplace :: Ability
AbAlter :: Ability
AbWait :: Ability
AbMoveItem :: Ability
AbProject :: Ability
AbApply :: Ability

-- | Skill level in particular abilities.
--   
--   This representation is sparse, so better than a record when there are
--   more item kinds (with few abilities) than actors (with many
--   abilities), especially if the number of abilities grows as the engine
--   is developed. It's also easier to code and maintain.
type Skills = EnumMap Ability Int
zeroSkills :: Skills
unitSkills :: Skills
addSkills :: Skills -> Skills -> Skills
scaleSkills :: Int -> Skills -> Skills
tacticSkills :: Tactic -> Skills
blockOnly :: Skills
meleeAdjacent :: Skills
meleeAndRanged :: Skills
ignoreItems :: Skills
instance GHC.Enum.Bounded Game.LambdaHack.Common.Ability.Ability
instance GHC.Enum.Enum Game.LambdaHack.Common.Ability.Ability
instance GHC.Generics.Generic Game.LambdaHack.Common.Ability.Ability
instance GHC.Classes.Ord Game.LambdaHack.Common.Ability.Ability
instance GHC.Classes.Eq Game.LambdaHack.Common.Ability.Ability
instance GHC.Show.Show Game.LambdaHack.Common.Ability.Ability
instance Control.DeepSeq.NFData Game.LambdaHack.Common.Ability.Ability
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Ability.Ability
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Ability.Ability


-- | Screen overlays.
module Game.LambdaHack.Client.UI.Overlay

-- | Line of colourful text.
type AttrLine = [AttrCharW32]
emptyAttrLine :: Int -> AttrLine
textToAL :: Text -> AttrLine

-- | Render line of text in the given foreground colour.
fgToAL :: Color -> Text -> AttrLine
stringToAL :: String -> AttrLine
(<+:>) :: AttrLine -> AttrLine -> AttrLine
infixr 6 <+:>

-- | A series of screen lines that either fit the width of the screen or
--   are intended for truncation when displayed. The length of overlay may
--   exceed the length of the screen, unlike in <tt>SingleFrame</tt>. An
--   exception is lines generated from animation, which have to fit in
--   either dimension.
type Overlay = [AttrLine]

-- | Sparse screen overlay representation where only the indicated rows are
--   overlayed and the remaining rows are kept unchanged.
type IntOverlay = [(Int, AttrLine)]

-- | Split a string into lines. Avoids ending the line with a character
--   other than whitespace or punctuation. Space characters are removed
--   from the start, but never from the end of lines. Newlines are
--   respected.
splitAttrLine :: X -> AttrLine -> Overlay
glueLines :: Overlay -> Overlay -> Overlay
updateLines :: Int -> (AttrLine -> AttrLine) -> Overlay -> Overlay

-- | Color mode for the display.
data ColorMode

-- | normal, with full colours
ColorFull :: ColorMode

-- | black and white only
ColorBW :: ColorMode
linesAttr :: AttrLine -> Overlay
splitAttrPhrase :: X -> AttrLine -> Overlay
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Overlay.ColorMode


-- | Screen frames.
module Game.LambdaHack.Client.UI.Frame
type FrameST s = Mutable Vector s Word32 -> ST s ()

-- | Efficiently composable representation of an operation on a frame, that
--   is, on a mutable vector. When the composite operation is eventually
--   performed, the vector is frozen to become a <a>SingleFrame</a>.
newtype FrameForall
FrameForall :: (forall s. FrameST s) -> FrameForall
[unFrameForall] :: FrameForall -> forall s. FrameST s

-- | Representation of an operation of overwriting a frame with a single
--   line at the given row.
writeLine :: Int -> AttrLine -> FrameForall

-- | An overlay that fits on the screen (or is meant to be truncated on
--   display) and is padded to fill the whole screen and is displayed as a
--   single game screen frame.
--   
--   Note that we don't provide a list of color-highlighed positions
--   separately, because overlays need to obscure not only map, but the
--   highlights as well.
newtype SingleFrame
SingleFrame :: GArray Word32 AttrCharW32 -> SingleFrame
[singleFrame] :: SingleFrame -> GArray Word32 AttrCharW32

-- | Sequences of screen frames, including delays.
type Frames = [Maybe FrameForall]
blankSingleFrame :: SingleFrame

-- | Overlays either the game map only or the whole empty screen frame. We
--   assume the lines of the overlay are not too long nor too many.
overlayFrame :: IntOverlay -> FrameForall -> FrameForall
overlayFrameWithLines :: Bool -> Overlay -> FrameForall -> FrameForall

-- | Add a space at the message end, for display overlayed over the level
--   map. Also trim (do not wrap!) too long lines.
truncateAttrLine :: X -> AttrLine -> X -> AttrLine
instance GHC.Show.Show Game.LambdaHack.Client.UI.Frame.SingleFrame
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Frame.SingleFrame


-- | Options that affect the behaviour of the client.
module Game.LambdaHack.Client.ClientOptions

-- | Options that affect the behaviour of the client (but not game rules).
data ClientOptions
ClientOptions :: Maybe Text -> Maybe Text -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Bool -> Maybe Int -> Maybe Int -> Bool -> Maybe Bool -> Bool -> Bool -> Maybe Text -> Maybe FilePath -> String -> Bool -> Bool -> Bool -> Bool -> Maybe Int -> Maybe Int -> ClientOptions

-- | Font family to use for the GTK main game window.
[sgtkFontFamily] :: ClientOptions -> Maybe Text

-- | Font file to use for the SDL2 main game window.
[sdlFontFile] :: ClientOptions -> Maybe Text

-- | Pixels to add to map cells on top of scalable font max glyph height.
[sdlTtfSizeAdd] :: ClientOptions -> Maybe Int

-- | Pixels to add to map cells on top of .fon font max glyph height.
[sdlFonSizeAdd] :: ClientOptions -> Maybe Int

-- | Font size to use for the main game window.
[sfontSize] :: ClientOptions -> Maybe Int

-- | Whether to use bold attribute for colorful characters.
[scolorIsBold] :: ClientOptions -> Maybe Bool

-- | How much to log (e.g., from SDL). 1 is all, 5 is errors, the default.
[slogPriority] :: ClientOptions -> Maybe Int

-- | Maximal frames per second. This is better low and fixed, to avoid
--   jerkiness and delays that tell the player there are many intelligent
--   enemies on the level. That's better than scaling AI sofistication down
--   based on the FPS setting and machine speed.
[smaxFps] :: ClientOptions -> Maybe Int

-- | Never auto-answer all prompts, even if under AI control.
[sdisableAutoYes] :: ClientOptions -> Bool

-- | Don't show any animations.
[snoAnim] :: ClientOptions -> Maybe Bool

-- | Start a new game, overwriting the save file.
[snewGameCli] :: ClientOptions -> Bool

-- | Don't create directories and files and show time stats.
[sbenchmark] :: ClientOptions -> Bool
[stitle] :: ClientOptions -> Maybe Text
[sfontDir] :: ClientOptions -> Maybe FilePath

-- | Prefix of the save game file name.
[ssavePrefixCli] :: ClientOptions -> String

-- | Whether to use the stdout/stdin frontend.
[sfrontendTeletype] :: ClientOptions -> Bool

-- | Whether to use null (no input/output) frontend.
[sfrontendNull] :: ClientOptions -> Bool

-- | Whether to use lazy (output not even calculated) frontend.
[sfrontendLazy] :: ClientOptions -> Bool

-- | Show clients' internal debug messages.
[sdbgMsgCli] :: ClientOptions -> Bool
[sstopAfterSeconds] :: ClientOptions -> Maybe Int
[sstopAfterFrames] :: ClientOptions -> Maybe Int

-- | Default value of client options.
defClientOptions :: ClientOptions
instance GHC.Generics.Generic Game.LambdaHack.Client.ClientOptions.ClientOptions
instance GHC.Classes.Eq Game.LambdaHack.Client.ClientOptions.ClientOptions
instance GHC.Show.Show Game.LambdaHack.Client.ClientOptions.ClientOptions
instance Data.Binary.Class.Binary Game.LambdaHack.Client.ClientOptions.ClientOptions


-- | Breadth first search algorithm.
module Game.LambdaHack.Client.Bfs

-- | Weighted distance between points along shortest paths.
data BfsDistance

-- | State of legality of moves between adjacent points.
data MoveLegal
MoveBlocked :: MoveLegal
MoveToOpen :: MoveLegal
MoveToClosed :: MoveLegal
MoveToUnknown :: MoveLegal

-- | The minimal distance value assigned to paths that don't enter any
--   unknown tiles.
minKnownBfs :: BfsDistance

-- | The distance value that denotes no legal path between points, either
--   due to blocked tiles or pathfinding aborted at earlier tiles, e.g.,
--   due to unknown tiles.
apartBfs :: BfsDistance

-- | Fill out the given BFS array. Unsafe <tt>PointArray</tt> operations
--   are OK here, because the intermediate values of the vector don't leak
--   anywhere outside nor are kept unevaluated and so they can't be
--   overwritten by the unsafe side-effect.
--   
--   When computing move cost, we assume doors openable at no cost, because
--   other actors use them, too, so the cost is shared and the extra
--   visiblity is valuable, too. We treat unknown tiles specially. Whether
--   suspect tiles are considered openable depends on
--   <tt>smarkSuspect</tt>.
fillBfs :: Array Word8 -> Word8 -> Point -> Array BfsDistance -> ()
data AndPath
AndPath :: [Point] -> Point -> Int -> AndPath
[pathList] :: AndPath -> [Point]
[pathGoal] :: AndPath -> Point
[pathLen] :: AndPath -> Int
NoPath :: AndPath

-- | Find a path, without the source position, with the smallest length.
--   The <tt>eps</tt> coefficient determines which direction (of the
--   closest directions available) that path should prefer, where 0 means
--   north-west and 1 means north.
findPathBfs :: Array Word8 -> (Point -> Bool) -> Point -> Point -> Int -> Array BfsDistance -> AndPath

-- | Access a BFS array and interpret the looked up distance value.
accessBfs :: Array BfsDistance -> Point -> Maybe Int

-- | The distance value that denotes that path search was aborted at this
--   tile due to too large actual distance and that the tile was known and
--   not blocked. It is also a true distance value for this tile (shifted
--   by minKnownBfs, as all distances of known tiles).
abortedKnownBfs :: BfsDistance

-- | The distance value that denotes that path search was aborted at this
--   tile due to too large actual distance and that the tile was unknown.
--   It is also a true distance value for this tile.
abortedUnknownBfs :: BfsDistance
instance GHC.Generics.Generic Game.LambdaHack.Client.Bfs.AndPath
instance GHC.Show.Show Game.LambdaHack.Client.Bfs.AndPath
instance GHC.Classes.Eq Game.LambdaHack.Client.Bfs.MoveLegal
instance Data.Bits.Bits Game.LambdaHack.Client.Bfs.BfsDistance
instance GHC.Enum.Bounded Game.LambdaHack.Client.Bfs.BfsDistance
instance GHC.Enum.Enum Game.LambdaHack.Client.Bfs.BfsDistance
instance GHC.Classes.Ord Game.LambdaHack.Client.Bfs.BfsDistance
instance GHC.Classes.Eq Game.LambdaHack.Client.Bfs.BfsDistance
instance GHC.Show.Show Game.LambdaHack.Client.Bfs.BfsDistance
instance Data.Binary.Class.Binary Game.LambdaHack.Client.Bfs.AndPath


-- | AI strategies to direct actors not controlled directly by human
--   players. No operation in this module involves the <tt>State</tt> tyep
--   or any of our client/server monads types.
module Game.LambdaHack.Client.AI.Strategy

-- | A strategy is a choice of (non-empty) frequency tables of possible
--   actions.
data Strategy a
nullStrategy :: Strategy a -> Bool

-- | Strategy where only the actions from the given single frequency table
--   can be picked.
liftFrequency :: Frequency a -> Strategy a

-- | Strategy with the actions from both argument strategies, with original
--   frequencies.
(.|) :: Strategy a -> Strategy a -> Strategy a
infixr 2 .|

-- | Strategy with no actions at all.
reject :: Strategy a

-- | Conditionally accepted strategy.
(.=>) :: Bool -> Strategy a -> Strategy a
infix 3 .=>

-- | Strategy with all actions not satisfying the predicate removed. The
--   remaining actions keep their original relative frequency values.
only :: (a -> Bool) -> Strategy a -> Strategy a

-- | When better choices are towards the start of the list, this is the
--   best frequency of the strategy.
bestVariant :: Strategy a -> Frequency a

-- | Overwrite the description of all frequencies within the strategy.
renameStrategy :: Text -> Strategy a -> Strategy a

-- | Like <a>return</a>, but pick a name of the single frequency.
returN :: Text -> a -> Strategy a
mapStrategyM :: Monad m => (a -> m (Maybe b)) -> Strategy a -> m (Strategy b)
instance Data.Traversable.Traversable Game.LambdaHack.Client.AI.Strategy.Strategy
instance Data.Foldable.Foldable Game.LambdaHack.Client.AI.Strategy.Strategy
instance GHC.Show.Show a => GHC.Show.Show (Game.LambdaHack.Client.AI.Strategy.Strategy a)
instance GHC.Base.Monad Game.LambdaHack.Client.AI.Strategy.Strategy
instance GHC.Base.Functor Game.LambdaHack.Client.AI.Strategy.Strategy
instance GHC.Base.Applicative Game.LambdaHack.Client.AI.Strategy.Strategy
instance GHC.Base.MonadPlus Game.LambdaHack.Client.AI.Strategy.Strategy
instance GHC.Base.Alternative Game.LambdaHack.Client.AI.Strategy.Strategy


-- | Representation of probabilities and random computations.
module Game.LambdaHack.Common.Random

-- | The monad of computations with random generator state.
type Rnd a = State StdGen a

-- | Get a random object within a range with a uniform distribution.
randomR :: (Random a) => (a, a) -> Rnd a

-- | Get a random object of a given type with a uniform distribution.
random :: (Random a) => Rnd a

-- | Get any element of a list with equal probability.
oneOf :: [a] -> Rnd a

-- | Gen an element according to a frequency distribution.
frequency :: Show a => Frequency a -> Rnd a

-- | Fractional chance.
type Chance = Rational

-- | Give <tt>True</tt>, with probability determined by the fraction.
chance :: Chance -> Rnd Bool

-- | Cast dice scaled with current level depth. Note that at the first
--   level, the scaled dice are always ignored.
castDice :: AbsDepth -> AbsDepth -> Dice -> Rnd Int

-- | Cast dice scaled with current level depth and return <tt>True</tt> if
--   the results is greater than 50.
chanceDice :: AbsDepth -> AbsDepth -> Dice -> Rnd Bool

-- | Cast dice, scaled with current level depth, for coordinates.
castDiceXY :: AbsDepth -> AbsDepth -> DiceXY -> Rnd (Int, Int)
foldrM :: Foldable t => (a -> b -> Rnd b) -> b -> t a -> Rnd b
foldlM' :: Foldable t => (b -> a -> Rnd b) -> b -> t a -> Rnd b

-- | Randomly choose an item according to the distribution.
rollFreq :: Show a => Frequency a -> StdGen -> (a, StdGen)


-- | General content types and operations.
module Game.LambdaHack.Common.KindOps

-- | Content identifiers for the content type <tt>c</tt>.
newtype Id c
Id :: Word16 -> Id c

-- | Content operations for the content of type <tt>a</tt>.
data Ops a
Ops :: (Id a -> a) -> (GroupName a -> Id a) -> (GroupName a -> (a -> Bool) -> Rnd (Maybe (Id a))) -> (forall b. (Id a -> a -> b -> b) -> b -> b) -> (forall b. (b -> Id a -> a -> b) -> b -> b) -> (forall b. GroupName a -> (b -> Int -> Id a -> a -> b) -> b -> b) -> Int -> Ops a

-- | content element at given id
[okind] :: Ops a -> Id a -> a

-- | the id of the unique member of a singleton content group
[ouniqGroup] :: Ops a -> GroupName a -> Id a

-- | pick a random id belonging to a group and satisfying a predicate
[opick] :: Ops a -> GroupName a -> (a -> Bool) -> Rnd (Maybe (Id a))

-- | fold over all content elements of <tt>a</tt>
[ofoldrWithKey] :: Ops a -> forall b. (Id a -> a -> b -> b) -> b -> b

-- | fold strictly over all content <tt>a</tt>
[ofoldlWithKey'] :: Ops a -> forall b. (b -> Id a -> a -> b) -> b -> b

-- | fold over the given group only
[ofoldlGroup'] :: Ops a -> forall b. GroupName a -> (b -> Int -> Id a -> a -> b) -> b -> b

-- | size of content <tt>a</tt>
[olength] :: Ops a -> Int
instance Data.Binary.Class.Binary (Game.LambdaHack.Common.KindOps.Id c)
instance GHC.Enum.Bounded (Game.LambdaHack.Common.KindOps.Id c)
instance GHC.Enum.Enum (Game.LambdaHack.Common.KindOps.Id c)
instance GHC.Classes.Ord (Game.LambdaHack.Common.KindOps.Id c)
instance GHC.Classes.Eq (Game.LambdaHack.Common.KindOps.Id c)
instance GHC.Show.Show (Game.LambdaHack.Common.KindOps.Id c)


-- | Screen frames and animations.
module Game.LambdaHack.Client.UI.Animation

-- | Animation is a list of frame modifications to play one by one, where
--   each modification if a map from positions to level map symbols.
data Animation

-- | Render animations on top of a screen frame.
--   
--   Located in this module to keep <tt>Animation</tt> abstract.
renderAnim :: FrameForall -> Animation -> Frames
pushAndDelay :: Animation
blinkColorActor :: Point -> Char -> Color -> Color -> Animation

-- | Attack animation. A part of it also reused for self-damage and
--   healing.
twirlSplash :: (Point, Point) -> Color -> Color -> Animation

-- | Attack that hits through a block.
blockHit :: (Point, Point) -> Color -> Color -> Animation

-- | Attack that is blocked.
blockMiss :: (Point, Point) -> Animation

-- | Death animation for an organic body.
deathBody :: Point -> Animation

-- | Death animation for an organic body, short version (e.g., for
--   enemies).
shortDeathBody :: Point -> Animation

-- | Mark actor location animation.
actorX :: Point -> Animation

-- | Actor teleport animation.
teleport :: (Point, Point) -> Animation

-- | Swap-places animation, both hostile and friendly.
swapPlaces :: (Point, Point) -> Animation
fadeout :: Bool -> Int -> X -> Y -> Rnd Animation
blank :: Maybe AttrCharW32
cSym :: Color -> Char -> Maybe AttrCharW32
mapPosToOffset :: (Point, AttrCharW32) -> (Int, [AttrCharW32])
mzipSingleton :: Point -> Maybe AttrCharW32 -> IntOverlay
mzipPairs :: (Point, Point) -> (Maybe AttrCharW32, Maybe AttrCharW32) -> IntOverlay
instance GHC.Show.Show Game.LambdaHack.Client.UI.Animation.Animation
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Animation.Animation


-- | Ring buffers.
module Game.LambdaHack.Common.RingBuffer

-- | Ring buffers of a size determined at initialization.
data RingBuffer a
empty :: Int -> a -> RingBuffer a
cons :: a -> RingBuffer a -> RingBuffer a
uncons :: RingBuffer a -> Maybe (a, RingBuffer a)
toList :: RingBuffer a -> [a]
length :: RingBuffer a -> Int
instance GHC.Generics.Generic (Game.LambdaHack.Common.RingBuffer.RingBuffer a)
instance GHC.Show.Show a => GHC.Show.Show (Game.LambdaHack.Common.RingBuffer.RingBuffer a)
instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Game.LambdaHack.Common.RingBuffer.RingBuffer a)


-- | Keeping track of forked threads.
module Game.LambdaHack.Common.Thread
forkChild :: MVar [Async ()] -> IO () -> IO ()
waitForChildren :: MVar [Async ()] -> IO ()


-- | Game time and speed.
module Game.LambdaHack.Common.Time

-- | Game time in ticks. The time dimension. One tick is 1 microsecond (one
--   millionth of a second), one turn is 0.5 s.
data Time

-- | Start of the game time, or zero lenght time interval.
timeZero :: Time

-- | An infinitesimal time period.
timeEpsilon :: Time

-- | At least once per clip all moves are resolved and a frame or a frame
--   delay is generated. Currently one clip is 0.05 s, but it may change,
--   and the code should not depend on this fixed value.
timeClip :: Time

-- | One turn is 0.5 s. The code may depend on that. Actors at normal speed
--   (2 m/s) take one turn to move one tile (1 m by 1 m).
timeTurn :: Time

-- | This many ticks fits in a single second. Do not export,
timeSecond :: Time

-- | Absolute time addition, e.g., for summing the total game session time
--   from the times of individual games.
absoluteTimeAdd :: Time -> Time -> Time
absoluteTimeSubtract :: Time -> Time -> Time

-- | Absolute time negation. To be used for reversing time flow, e.g., for
--   comparing absolute times in the reverse order.
absoluteTimeNegate :: Time -> Time

-- | How many time intervals of the latter kind fits in an interval of the
--   former kind.
timeFit :: Time -> Time -> Int

-- | How many time intervals of the latter kind cover an interval of the
--   former kind (rounded up).
timeFitUp :: Time -> Time -> Int

-- | One-dimentional vectors. Introduced to tell apart the 2 uses of Time:
--   as an absolute game time and as an increment.
newtype Delta a
Delta :: a -> Delta a

-- | Shifting an absolute time by a time vector.
timeShift :: Time -> Delta Time -> Time

-- | Time time vector between the second and the first absolute times. The
--   arguments are in the same order as in the underlying scalar
--   subtraction.
timeDeltaToFrom :: Time -> Time -> Delta Time

-- | Time time vector between the second and the first absolute times. The
--   arguments are in the same order as in the underlying scalar
--   subtraction.
timeDeltaSubtract :: Delta Time -> Delta Time -> Delta Time

-- | Reverse a time vector.
timeDeltaReverse :: Delta Time -> Delta Time

-- | Scale the time vector by an <tt>Int</tt> scalar value.
timeDeltaScale :: Delta Time -> Int -> Delta Time

-- | Take the given percent of the time vector.
timeDeltaPercent :: Delta Time -> Int -> Delta Time

-- | Divide a time vector.
timeDeltaDiv :: Delta Time -> Int -> Delta Time

-- | Represent the main 10 thresholds of a time range by digits, given the
--   total length of the time range.
timeDeltaToDigit :: Delta Time -> Delta Time -> Char

-- | Speed in meters per 1 million seconds (m/Ms). Actors at normal speed
--   (2 m/s) take one time turn (0.5 s) to make one step (move one tile,
--   which is 1 m by 1 m).
data Speed

-- | Constructor for content definitions.
toSpeed :: Int -> Speed

-- | Pretty-printing of speed in the format used in content definitions.
fromSpeed :: Speed -> Int

-- | No movement possible at that speed.
speedZero :: Speed

-- | Fast walk speed (2 m/s) that suffices to move one tile in one turn.
speedWalk :: Speed

-- | Limp speed (1 m/s) that suffices to move one tile in two turns. This
--   is the minimal speed for projectiles to fly just one space and drop.
speedLimp :: Speed

-- | Sword thrust speed (10 m/s). Base weapon damages, both melee and
--   ranged, are given assuming this speed and ranged damage is modified
--   accordingly when projectile speeds differ. Differences in melee weapon
--   swing speeds are captured in damage bonuses instead, since many other
--   factors influence total damage.
--   
--   Billiard ball is 25 m<i>s, sword swing at the tip is 35 m</i>s,
--   medieval bow is 70 m<i>s, AK47 is 700 m</i>s.
speedThrust :: Speed

-- | Modify damage when projectiles is at a non-standard speed. Energy and
--   so damage is proportional to the square of speed, hence the formula.
modifyDamageBySpeed :: Int64 -> Speed -> Int64

-- | Scale speed by an <tt>Int</tt> scalar value.
speedScale :: Rational -> Speed -> Speed

-- | Speed addition.
speedAdd :: Speed -> Speed -> Speed

-- | Speed negation.
speedNegate :: Speed -> Speed

-- | The number of time ticks it takes to walk 1 meter at the given speed.
ticksPerMeter :: Speed -> Delta Time

-- | Calculate projectile speed from item weight in grams and velocity
--   percent modifier. See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Item-statistics</a>.
speedFromWeight :: Int -> Int -> Speed

-- | Calculate maximum range taking into account the linger percentage.
rangeFromSpeedAndLinger :: Speed -> Int -> Int

-- | The smallest unit of time. Should not be exported and used elsewhere,
--   because the proportion of turn to tick is an implementation detail.
--   The significance of this detail is only that it determines resolution
--   of the time dimension.
_timeTick :: Time

-- | This many turns fit in a single second.
turnsInSecond :: Int64

-- | Number of seconds in a mega-second.
sInMs :: Int64
minimalSpeed :: Int64

-- | Calculate maximum range in meters of a projectile from its speed. See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Item-statistics</a>.
--   With this formula, each projectile flies for at most 1 second, that is
--   2 turns, and then drops to the ground.
rangeFromSpeed :: Speed -> Int
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Time.Speed
instance GHC.Classes.Ord Game.LambdaHack.Common.Time.Speed
instance GHC.Classes.Eq Game.LambdaHack.Common.Time.Speed
instance GHC.Base.Functor Game.LambdaHack.Common.Time.Delta
instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Game.LambdaHack.Common.Time.Delta a)
instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Game.LambdaHack.Common.Time.Delta a)
instance GHC.Enum.Enum a => GHC.Enum.Enum (Game.LambdaHack.Common.Time.Delta a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Game.LambdaHack.Common.Time.Delta a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Game.LambdaHack.Common.Time.Delta a)
instance GHC.Show.Show a => GHC.Show.Show (Game.LambdaHack.Common.Time.Delta a)
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Time.Time
instance GHC.Enum.Bounded Game.LambdaHack.Common.Time.Time
instance GHC.Enum.Enum Game.LambdaHack.Common.Time.Time
instance GHC.Classes.Ord Game.LambdaHack.Common.Time.Time
instance GHC.Classes.Eq Game.LambdaHack.Common.Time.Time
instance GHC.Show.Show Game.LambdaHack.Common.Time.Time
instance GHC.Show.Show Game.LambdaHack.Common.Time.Speed


-- | Game messages displayed on top of the screen for the player to read
--   and then saved to player history.
module Game.LambdaHack.Client.UI.Msg

-- | The type of a single game message.
data Msg
toMsg :: AttrLine -> Msg
toPrompt :: AttrLine -> Msg
data RepMsgN

-- | The set of messages, with repetitions, to show at the screen at once.
data Report

-- | Empty set of messages.
emptyReport :: Report

-- | Test if the set of messages is empty.
nullReport :: Report -> Bool

-- | Construct a singleton set of messages.
singletonReport :: Msg -> Report

-- | Add a message to the end of report. Deletes old prompt messages.
snocReport :: Report -> Msg -> Report

-- | Add a message to the end of report. Does not delete old prompt
--   messages nor handle repetitions.
consReportNoScrub :: Msg -> Report -> Report

-- | Render a report as a (possibly very long) <a>AttrLine</a>.
renderReport :: Report -> AttrLine
findInReport :: (AttrLine -> Bool) -> Report -> Maybe Msg
incrementInReport :: (AttrLine -> Bool) -> Report -> Maybe Report
lastMsgOfReport :: Report -> (AttrLine, Report)

-- | The history of reports. This is a ring buffer of the given length
data History

-- | Empty history of reports of the given maximal length.
emptyHistory :: Int -> History

-- | Add a report to history, handling repetitions.
addReport :: History -> Time -> Report -> History
lengthHistory :: History -> Int
lastReportOfHistory :: History -> Report
replaceLastReportOfHistory :: Report -> History -> History
splitReportForHistory :: X -> AttrLine -> [AttrLine]

-- | Render history as many lines of text, wrapping if necessary.
renderHistory :: History -> [AttrLine]
type UAttrLine = Vector Word32
uToAttrLine :: UAttrLine -> AttrLine
attrLineToU :: AttrLine -> UAttrLine
renderRepetition :: RepMsgN -> AttrLine
renderTimeReport :: Time -> Report -> AttrLine
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.Msg.History
instance GHC.Show.Show Game.LambdaHack.Client.UI.Msg.History
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.Msg.Report
instance GHC.Show.Show Game.LambdaHack.Client.UI.Msg.Report
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.Msg.RepMsgN
instance GHC.Show.Show Game.LambdaHack.Client.UI.Msg.RepMsgN
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.Msg.Msg
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Msg.Msg
instance GHC.Show.Show Game.LambdaHack.Client.UI.Msg.Msg
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.Msg.History
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.Msg.RepMsgN
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.Msg.Msg


-- | Basic operations on bounded 2D vectors, with an efficient, but not 1-1
--   and not monotonic <tt>Enum</tt> instance.
module Game.LambdaHack.Common.Vector

-- | 2D vectors in cartesian representation. Coordinates grow to the right
--   and down, so that the (1, 1) vector points to the bottom-right corner
--   of the screen.
data Vector
Vector :: X -> Y -> Vector
[vx] :: Vector -> X
[vy] :: Vector -> Y

-- | Tells if a vector has length 1 in the chessboard metric.
isUnit :: Vector -> Bool

-- | Checks whether a unit vector is a diagonal direction, as opposed to
--   cardinal. If the vector is not unit, it checks that the vector is not
--   horizontal nor vertical.
isDiagonal :: Vector -> Bool

-- | Reverse an arbirary vector.
neg :: Vector -> Vector

-- | The lenght of a vector in the chessboard metric, where diagonal moves
--   cost 1.
chessDistVector :: Vector -> Int

-- | Squared euclidean distance between two vectors.
euclidDistSqVector :: Vector -> Vector -> Int

-- | Vectors of all unit moves in the chessboard metric, clockwise,
--   starting north-west.
moves :: [Vector]

-- | Vectors of all cardinal direction unit moves, clockwise, starting
--   north.
movesCardinal :: [Vector]

-- | Vectors of all diagonal direction unit moves, clockwise, starting
--   north.
movesDiagonal :: [Vector]
compassText :: Vector -> Text

-- | All (8 at most) closest neighbours of a point within an area.
vicinity :: X -> Y -> Point -> [Point]
vicinityUnsafe :: Point -> [Point]

-- | All (4 at most) cardinal direction neighbours of a point within an
--   area.
vicinityCardinal :: X -> Y -> Point -> [Point]
vicinityCardinalUnsafe :: Point -> [Point]
squareUnsafeSet :: Point -> EnumSet Point

-- | Translate a point by a vector.
shift :: Point -> Vector -> Point

-- | Translate a point by a vector, but only if the result fits in an area.
shiftBounded :: X -> Y -> Point -> Vector -> Point

-- | A list of points that a list of vectors leads to.
trajectoryToPath :: Point -> [Vector] -> [Point]

-- | A list of points that a list of vectors leads to, bounded by level
--   size.
trajectoryToPathBounded :: X -> Y -> Point -> [Vector] -> [Point]

-- | The vector between the second point and the first. We have
--   
--   <pre>
--   shift pos1 (pos2 `vectorToFrom` pos1) == pos2
--   </pre>
--   
--   The arguments are in the same order as in the underlying scalar
--   subtraction.
vectorToFrom :: Point -> Point -> Vector

-- | A list of vectors between a list of points.
pathToTrajectory :: [Point] -> [Vector]
type RadianAngle = Double

-- | Rotate a vector by the given angle (expressed in radians)
--   counterclockwise and return a unit vector approximately in the
--   resulting direction.
rotate :: RadianAngle -> Vector -> Vector

-- | Given two distinct positions, determine the direction (a unit vector)
--   in which one should move from the first in order to get closer to the
--   second. Ignores obstacles. Of several equally good directions (in the
--   chessboard metric) it picks one of those that visually (in the
--   euclidean metric) maximally align with the vector between the two
--   points.
towards :: Point -> Point -> Vector

-- | Maximal supported vector X and Y coordinates.
maxVectorDim :: Int

-- | Currently unused.
_moveTexts :: [Text]
longMoveTexts :: [Text]

-- | Given a vector of arbitrary non-zero length, produce a unit vector
--   that points in the same direction (in the chessboard metric). Of
--   several equally good directions it picks one of those that visually
--   (in the euclidean metric) maximally align with the original vector.
normalize :: Double -> Double -> Vector
normalizeVector :: Vector -> Vector
instance GHC.Generics.Generic Game.LambdaHack.Common.Vector.Vector
instance GHC.Classes.Ord Game.LambdaHack.Common.Vector.Vector
instance GHC.Classes.Eq Game.LambdaHack.Common.Vector.Vector
instance GHC.Read.Read Game.LambdaHack.Common.Vector.Vector
instance GHC.Show.Show Game.LambdaHack.Common.Vector.Vector
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Vector.Vector
instance GHC.Enum.Enum Game.LambdaHack.Common.Vector.Vector
instance Control.DeepSeq.NFData Game.LambdaHack.Common.Vector.Vector


-- | Frontend-independent keyboard input operations.
module Game.LambdaHack.Client.UI.Key

-- | Frontend-independent datatype to represent keys.
data Key
Esc :: Key
Return :: Key
Space :: Key
Tab :: Key
BackTab :: Key
BackSpace :: Key
PgUp :: Key
PgDn :: Key
Left :: Key
Right :: Key
Up :: Key
Down :: Key
End :: Key
Begin :: Key
Insert :: Key
Delete :: Key
Home :: Key

-- | a keypad key for a character (digits and operators)
KP :: Char -> Key

-- | a single printable character
Char :: Char -> Key

-- | function key
Fun :: Int -> Key

-- | left mouse button pressed
LeftButtonPress :: Key

-- | middle mouse button pressed
MiddleButtonPress :: Key

-- | right mouse button pressed
RightButtonPress :: Key

-- | left mouse button released
LeftButtonRelease :: Key

-- | middle mouse button released
MiddleButtonRelease :: Key

-- | right mouse button released
RightButtonRelease :: Key

-- | mouse wheel rotated north
WheelNorth :: Key

-- | mouse wheel rotated south
WheelSouth :: Key

-- | an unknown key, registered to warn the user
Unknown :: String -> Key
DeadKey :: Key

-- | Our own encoding of modifiers.
data Modifier
NoModifier :: Modifier
Shift :: Modifier
Control :: Modifier
Alt :: Modifier

-- | Key and modifier.
data KM
KM :: Modifier -> Key -> KM
[modifier] :: KM -> Modifier
[key] :: KM -> Key

-- | Key, modifier and position of mouse pointer.
data KMP
KMP :: KM -> Point -> KMP
[kmpKeyMod] :: KMP -> KM
[kmpPointer] :: KMP -> Point

-- | Common and terse names for keys.
showKey :: Key -> String

-- | Show a key with a modifier, if any.
showKM :: KM -> String
escKM :: KM
spaceKM :: KM
safeSpaceKM :: KM
returnKM :: KM
pgupKM :: KM
pgdnKM :: KM
wheelNorthKM :: KM
wheelSouthKM :: KM
upKM :: KM
downKM :: KM
leftKM :: KM
rightKM :: KM
homeKM :: KM
endKM :: KM
backspaceKM :: KM
leftButtonReleaseKM :: KM
rightButtonReleaseKM :: KM
dirAllKey :: Bool -> Bool -> [Key]

-- | Configurable event handler for the direction keys. Used for directed
--   commands such as close door.
handleDir :: Bool -> Bool -> KM -> Maybe Vector

-- | Binding of both sets of movement keys, vi and laptop.
moveBinding :: Bool -> Bool -> (Vector -> a) -> (Vector -> a) -> [(KM, a)]
mkKM :: String -> KM
mkChar :: Char -> KM
mkKP :: Char -> KM

-- | Translate key from a GTK string description to our internal key type.
--   To be used, in particular, for the command bindings and macros in the
--   config file.
--   
--   See
--   <a>https://github.com/twobob/gtk-/blob/master/gdk/keyname-table.h</a>
keyTranslate :: String -> Key

-- | Translate key from a Web API string description
--   (<a>https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key#Key_values</a>)
--   to our internal key type. To be used in web frontends. The argument
--   says whether Shift is pressed.
keyTranslateWeb :: String -> Bool -> Key
dirKeypadKey :: [Key]
dirKeypadShiftChar :: [Char]
dirKeypadShiftKey :: [Key]
dirLaptopKey :: [Key]
dirLaptopShiftKey :: [Key]
dirViChar :: [Char]
dirViKey :: [Key]
dirViShiftKey :: [Key]
dirMoveNoModifier :: Bool -> Bool -> [Key]
dirRunNoModifier :: Bool -> Bool -> [Key]
dirRunControl :: [Key]
dirRunShift :: [Key]
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.Key.KM
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Key.KM
instance GHC.Classes.Ord Game.LambdaHack.Client.UI.Key.KM
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.Key.Modifier
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Key.Modifier
instance GHC.Classes.Ord Game.LambdaHack.Client.UI.Key.Modifier
instance GHC.Show.Show Game.LambdaHack.Client.UI.Key.Modifier
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.Key.Key
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Key.Key
instance GHC.Classes.Ord Game.LambdaHack.Client.UI.Key.Key
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.Key.KM
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.Key.KM
instance GHC.Show.Show Game.LambdaHack.Client.UI.Key.KM
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.Key.Modifier
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.Key.Modifier
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.Key.Key
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.Key.Key


-- | Screen frames and animations.
module Game.LambdaHack.Client.UI.Frontend.Common

-- | Raw frontend definition. The minimal closed set of values that need to
--   depend on the specifics of the chosen frontend.
data RawFrontend
RawFrontend :: (SingleFrame -> IO ()) -> IO () -> MVar () -> TQueue KMP -> RawFrontend
[fdisplay] :: RawFrontend -> SingleFrame -> IO ()
[fshutdown] :: RawFrontend -> IO ()
[fshowNow] :: RawFrontend -> MVar ()
[fchanKey] :: RawFrontend -> TQueue KMP
startupBound :: (MVar RawFrontend -> IO ()) -> IO RawFrontend
createRawFrontend :: (SingleFrame -> IO ()) -> IO () -> IO RawFrontend

-- | Empty the keyboard channel.
resetChanKey :: TQueue KMP -> IO ()
saveKMP :: RawFrontend -> Modifier -> Key -> Point -> IO ()

-- | Translates modifiers to our own encoding.
modifierTranslate :: Bool -> Bool -> Bool -> Bool -> Modifier


-- | Text frontend based on Vty.
module Game.LambdaHack.Client.UI.Frontend.Vty

-- | Starts the main program loop using the frontend input and output.
startup :: ClientOptions -> IO RawFrontend

-- | The name of the frontend.
frontendName :: String


-- | Re-export the operations of the chosen raw frontend (determined at
--   compile time with cabal flags).
module Game.LambdaHack.Client.UI.Frontend.Chosen

-- | Starts the main program loop using the frontend input and output.
startup :: ClientOptions -> IO RawFrontend

-- | The name of the frontend.
frontendName :: String


-- | Line terminal text frontend based on stdin/stdout, intended for
--   logging tests, but may be used on a teletype terminal, or with
--   keyboard and printer.
module Game.LambdaHack.Client.UI.Frontend.Teletype

-- | Set up the frontend input and output.
startup :: ClientOptions -> IO RawFrontend

-- | The name of the frontend.
frontendName :: String


-- | Display game data on the screen and receive user input using one of
--   the available raw frontends and derived operations.
module Game.LambdaHack.Client.UI.Frontend

-- | The instructions sent by clients to the raw frontend, indexed by the
--   returned value.
data FrontReq :: * -> *

-- | Show a frame.
[FrontFrame] :: {frontFrame :: FrameForall} -> FrontReq ()

-- | Perform an explicit delay of the given length.
[FrontDelay] :: Int -> FrontReq ()

-- | Flush frames, display a frame and ask for a keypress.
[FrontKey] :: {frontKeyKeys :: [KM], frontKeyFrame :: FrameForall} -> FrontReq KMP

-- | Inspect the fkeyPressed MVar.
[FrontPressed] :: FrontReq Bool

-- | Discard a key in the queue, if any.
[FrontDiscard] :: FrontReq ()

-- | Add a key to the queue.
[FrontAdd] :: KMP -> FrontReq ()

-- | Set in the frontend that it should auto-answer prompts.
[FrontAutoYes] :: Bool -> FrontReq ()

-- | Shut the frontend down.
[FrontShutdown] :: FrontReq ()

-- | Connection channel between a frontend and a client. Frontend acts as a
--   server, serving keys, etc., when given frames to display.
newtype ChanFrontend
ChanFrontend :: (forall a. FrontReq a -> IO a) -> ChanFrontend

-- | Initialize the frontend chosen by the player via client options.
chanFrontendIO :: ClientOptions -> IO ChanFrontend

-- | The name of the chosen frontend.
frontendName :: String

-- | Machinery allocated for an individual frontend at its startup,
--   unchanged for its lifetime.
data FrontSetup
getKey :: ClientOptions -> FrontSetup -> RawFrontend -> [KM] -> FrameForall -> IO KMP
fchanFrontend :: ClientOptions -> FrontSetup -> RawFrontend -> ChanFrontend
display :: RawFrontend -> FrameForall -> IO ()
defaultMaxFps :: Int
microInSec :: Int
frameTimeoutThread :: Int -> MVar Int -> RawFrontend -> IO ()
lazyStartup :: IO RawFrontend
nullStartup :: IO RawFrontend
seqFrame :: SingleFrame -> IO ()


-- | The type of kinds of weapons, treasure, organs, blasts, etc.
module Game.LambdaHack.Content.ItemKind

-- | Item properties that are fixed for a given kind of items.
data ItemKind
ItemKind :: Char -> Text -> Freqs ItemKind -> [Flavour] -> Dice -> Rarity -> Part -> Int -> [(Int, Dice)] -> [Aspect] -> [Effect] -> [Feature] -> Text -> [(GroupName ItemKind, CStore)] -> ItemKind

-- | map symbol
[isymbol] :: ItemKind -> Char

-- | generic name
[iname] :: ItemKind -> Text

-- | frequency within groups
[ifreq] :: ItemKind -> Freqs ItemKind

-- | possible flavours
[iflavour] :: ItemKind -> [Flavour]

-- | created in that quantity
[icount] :: ItemKind -> Dice

-- | rarity on given depths
[irarity] :: ItemKind -> Rarity

-- | the verb&amp;noun for applying and hit
[iverbHit] :: ItemKind -> Part

-- | weight in grams
[iweight] :: ItemKind -> Int

-- | frequency of basic impact damage
[idamage] :: ItemKind -> [(Int, Dice)]

-- | keep the aspect continuously
[iaspects] :: ItemKind -> [Aspect]

-- | cause the effect when triggered
[ieffects] :: ItemKind -> [Effect]

-- | public properties
[ifeature] :: ItemKind -> [Feature]

-- | description
[idesc] :: ItemKind -> Text

-- | accompanying organs and items
[ikit] :: ItemKind -> [(GroupName ItemKind, CStore)]

-- | Effects of items. Can be invoked by the item wielder to affect another
--   actor or the wielder himself. Many occurences in the same item are
--   possible.
data Effect

-- | secret (learned as effect) name of the item
ELabel :: Text -> Effect

-- | AI and UI flag that leaks item properties
EqpSlot :: EqpSlot -> Effect

-- | burn with this damage
Burn :: Dice -> Effect

-- | explode producing this group of blasts
Explode :: (GroupName ItemKind) -> Effect

-- | modify HP of the actor by this amount
RefillHP :: Int -> Effect

-- | modify Calm of the actor by this amount
RefillCalm :: Int -> Effect

-- | change actor's allegiance
Dominate :: Effect

-- | make actor susceptible to domination
Impress :: Effect

-- | summon the given number of actors of this group
Summon :: (GroupName ItemKind) -> Dice -> Effect

-- | ascend to another level of the dungeon
Ascend :: Bool -> Effect

-- | escape from the dungeon
Escape :: Effect

-- | paralyze for this many game clips
Paralyze :: Dice -> Effect

-- | give free time to actor of this many game turns
InsertMove :: Dice -> Effect

-- | teleport actor across rougly this distance
Teleport :: Dice -> Effect

-- | create an item of the group and insert into the store with the given
--   random timer
CreateItem :: CStore -> (GroupName ItemKind) -> TimerDice -> Effect

-- | make the actor drop items of the given group from the given store; the
--   first integer says how many item kinds to drop, the second, how many
--   copie of each kind to drop
DropItem :: Int -> Int -> CStore -> (GroupName ItemKind) -> Effect

-- | find a suitable (i.e., numerous enough) item, starting from the floor,
--   and polymorph it randomly
PolyItem :: Effect

-- | find a suitable (i.e., not identified) item, starting from the floor,
--   and identify it
Identify :: Effect

-- | detect all on the map in the given radius
Detect :: Int -> Effect

-- | detect actors on the map in the given radius
DetectActor :: Int -> Effect

-- | detect items on the map in the given radius
DetectItem :: Int -> Effect

-- | detect exits on the map in the given radius
DetectExit :: Int -> Effect

-- | detect hidden tiles on the map in the radius
DetectHidden :: Int -> Effect

-- | send an actor flying (push or pull, depending)
SendFlying :: ThrowMod -> Effect

-- | push an actor
PushActor :: ThrowMod -> Effect

-- | pull an actor
PullActor :: ThrowMod -> Effect

-- | make the actor drop its best weapon
DropBestWeapon :: Effect

-- | activate all items with this symbol in inventory; space character
--   means all symbols
ActivateInv :: Char -> Effect

-- | remove all smell on the level
ApplyPerfume :: Effect

-- | trigger one of the effects with equal probability
OneOf :: [Effect] -> Effect

-- | trigger the effect when item smashed (not when applied nor meleed)
OnSmash :: Effect -> Effect

-- | this effect inactive until timeout passes
Recharging :: Effect -> Effect

-- | the item is temporary, vanishes at even void Periodic activation,
--   unless Durable and not Fragile, and shows message with this verb at
--   last copy activation or at each activation unless Durable and Fragile
Temporary :: Text -> Effect

-- | at most one copy can ever be generated
Unique :: Effect

-- | in equipment, triggered as often as <tt>Timeout</tt> permits
Periodic :: Effect

-- | only fire next effect if previous was triggered
Composite :: [Effect] -> Effect

-- | Specification of how to randomly roll a timer at item creation to
--   obtain a fixed timer for the item's lifetime.
data TimerDice
TimerNone :: TimerDice
TimerGameTurn :: Dice -> TimerDice
TimerActorTurn :: Dice -> TimerDice

-- | Aspects of items. Those that are named <tt>Add*</tt> are additive
--   (starting at 0) for all items wielded by an actor and they affect the
--   actor.
data Aspect

-- | some effects disabled until item recharges; expressed in game turns
Timeout :: Dice -> Aspect

-- | percentage damage bonus in melee
AddHurtMelee :: Dice -> Aspect

-- | percentage armor bonus against melee
AddArmorMelee :: Dice -> Aspect

-- | percentage armor bonus against ranged
AddArmorRanged :: Dice -> Aspect

-- | maximal hp
AddMaxHP :: Dice -> Aspect

-- | maximal calm
AddMaxCalm :: Dice -> Aspect

-- | speed in m/10s (not when pushed or pulled)
AddSpeed :: Dice -> Aspect

-- | FOV radius, where 1 means a single tile FOV
AddSight :: Dice -> Aspect

-- | smell radius
AddSmell :: Dice -> Aspect

-- | shine radius
AddShine :: Dice -> Aspect

-- | noctovision radius
AddNocto :: Dice -> Aspect

-- | aggression, e.g., when closing in for melee
AddAggression :: Dice -> Aspect

-- | bonus to an ability
AddAbility :: Ability -> Dice -> Aspect

-- | Parameters modifying a throw of a projectile or flight of pushed
--   actor. Not additive and don't start at 0.
data ThrowMod
ThrowMod :: Int -> Int -> ThrowMod

-- | fly with this percentage of base throw speed
[throwVelocity] :: ThrowMod -> Int

-- | fly for this percentage of 2 turns
[throwLinger] :: ThrowMod -> Int

-- | Features of item. Publicly visible. Affect only the item in question,
--   not the actor, and so not additive in any sense.
data Feature

-- | drop and break at target tile, even if no hit
Fragile :: Feature

-- | drop at target tile, even if no hit
Lobable :: Feature

-- | don't break even when hitting or applying
Durable :: Feature

-- | parameters modifying a throw
ToThrow :: ThrowMod -> Feature

-- | the item starts identified
Identified :: Feature

-- | AI and UI flag: consider applying
Applicable :: Feature

-- | AI and UI flag: consider equipping (independent of <a>EqpSlot</a>,
--   e.g., in case of mixed blessings)
Equipable :: Feature

-- | AI and UI flag: consider meleeing with
Meleeable :: Feature

-- | AI and UI flag: don't risk identifying by use; also, can't throw or
--   apply if not calm enough
Precious :: Feature

-- | overrides actor's tactic
Tactic :: Tactic -> Feature

-- | AI and UI hints about the role of the item.
data EqpSlot
EqpSlotMiscBonus :: EqpSlot
EqpSlotAddHurtMelee :: EqpSlot
EqpSlotAddArmorMelee :: EqpSlot
EqpSlotAddArmorRanged :: EqpSlot
EqpSlotAddMaxHP :: EqpSlot
EqpSlotAddSpeed :: EqpSlot
EqpSlotAddSight :: EqpSlot
EqpSlotLightSource :: EqpSlot
EqpSlotWeapon :: EqpSlot
EqpSlotMiscAbility :: EqpSlot
EqpSlotAbMove :: EqpSlot
EqpSlotAbMelee :: EqpSlot
EqpSlotAbDisplace :: EqpSlot
EqpSlotAbAlter :: EqpSlot
EqpSlotAbProject :: EqpSlot
EqpSlotAbApply :: EqpSlot
EqpSlotAddMaxCalm :: EqpSlot
EqpSlotAddSmell :: EqpSlot
EqpSlotAddNocto :: EqpSlot
EqpSlotAddAggression :: EqpSlot
EqpSlotAbWait :: EqpSlot
EqpSlotAbMoveItem :: EqpSlot
boostItemKindList :: StdGen -> [ItemKind] -> [ItemKind]

-- | Whether the effect has a chance of exhibiting any potentially
--   noticeable behaviour.
forApplyEffect :: Effect -> Bool
forIdEffect :: Effect -> Bool
toDmg :: Dice -> [(Int, Dice)]
toVelocity :: Int -> Feature
toLinger :: Int -> Feature
toOrganGameTurn :: GroupName ItemKind -> Dice -> Effect
toOrganActorTurn :: GroupName ItemKind -> Dice -> Effect
toOrganNone :: GroupName ItemKind -> Effect

-- | Catch invalid item kind definitions.
validateSingleItemKind :: ItemKind -> [Text]

-- | Validate all item kinds.
validateAllItemKind :: [ItemKind] -> [Text]
boostItemKind :: ItemKind -> ItemKind
validateDups :: ItemKind -> Feature -> [Text]
validateDamage :: [(Int, Dice)] -> [Text]
hardwiredItemGroups :: [GroupName ItemKind]
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.ItemKind
instance GHC.Generics.Generic Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Generics.Generic Game.LambdaHack.Content.ItemKind.EqpSlot
instance GHC.Enum.Bounded Game.LambdaHack.Content.ItemKind.EqpSlot
instance GHC.Enum.Enum Game.LambdaHack.Content.ItemKind.EqpSlot
instance GHC.Classes.Ord Game.LambdaHack.Content.ItemKind.EqpSlot
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.EqpSlot
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.EqpSlot
instance GHC.Generics.Generic Game.LambdaHack.Content.ItemKind.Feature
instance GHC.Classes.Ord Game.LambdaHack.Content.ItemKind.Feature
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.Feature
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.Feature
instance GHC.Generics.Generic Game.LambdaHack.Content.ItemKind.ThrowMod
instance GHC.Classes.Ord Game.LambdaHack.Content.ItemKind.ThrowMod
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.ThrowMod
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.ThrowMod
instance GHC.Generics.Generic Game.LambdaHack.Content.ItemKind.Aspect
instance GHC.Classes.Ord Game.LambdaHack.Content.ItemKind.Aspect
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.Aspect
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.Aspect
instance GHC.Generics.Generic Game.LambdaHack.Content.ItemKind.TimerDice
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.TimerDice
instance Control.DeepSeq.NFData Game.LambdaHack.Content.ItemKind.Effect
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.Effect
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.Effect
instance Control.DeepSeq.NFData Game.LambdaHack.Content.ItemKind.EqpSlot
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.EqpSlot
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.EqpSlot
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.Feature
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.Feature
instance Control.DeepSeq.NFData Game.LambdaHack.Content.ItemKind.ThrowMod
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.ThrowMod
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.ThrowMod
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.Aspect
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.Aspect
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.TimerDice
instance Control.DeepSeq.NFData Game.LambdaHack.Content.ItemKind.TimerDice
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.TimerDice
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.TimerDice


-- | The type of game rule sets and assorted game data.
module Game.LambdaHack.Content.RuleKind

-- | The type of game rule sets and assorted game data.
--   
--   In principle, it'se possible to have many rule sets and switch between
--   them during a game session or even a single game.
data RuleKind
RuleKind :: Char -> Text -> Freqs RuleKind -> Text -> FilePath -> Version -> FilePath -> String -> Text -> Bool -> Int -> Int -> FilePath -> Int -> RuleKind

-- | a symbol
[rsymbol] :: RuleKind -> Char

-- | short description
[rname] :: RuleKind -> Text

-- | frequency within groups
[rfreq] :: RuleKind -> Freqs RuleKind

-- | title of the game (not lib)
[rtitle] :: RuleKind -> Text

-- | font directory for the game (not lib)
[rfontDir] :: RuleKind -> FilePath

-- | version of the game
[rexeVersion] :: RuleKind -> Version

-- | name of the UI config file
[rcfgUIName] :: RuleKind -> FilePath

-- | the default UI settings config file
[rcfgUIDefault] :: RuleKind -> String

-- | the ASCII art for the Main Menu
[rmainMenuArt] :: RuleKind -> Text

-- | whether first non-spawner actor death ends the game
[rfirstDeathEnds] :: RuleKind -> Bool

-- | game is saved that often
[rwriteSaveClips] :: RuleKind -> Int

-- | server switches leader level that often
[rleadLevelClips] :: RuleKind -> Int

-- | name of the scores file
[rscoresFile] :: RuleKind -> FilePath

-- | what distance between actors is <tt>nearby</tt>
[rnearby] :: RuleKind -> Int

-- | Catch invalid rule kind definitions.
validateSingleRuleKind :: RuleKind -> [Text]

-- | Since we have only one rule kind, the set of rule kinds is always
--   valid.
validateAllRuleKind :: [RuleKind] -> [Text]
instance GHC.Show.Show Game.LambdaHack.Content.RuleKind.RuleKind


-- | The type of kinds of terrain tiles.
module Game.LambdaHack.Content.TileKind

-- | The type of kinds of terrain tiles. See <tt>Tile.hs</tt> for
--   explanation of the absence of a corresponding type <tt>Tile</tt> that
--   would hold particular concrete tiles in the dungeon. Note that tile
--   names (and any other content names) should not be plural (that would
--   lead to "a stairs"), so "road with cobblestones" is fine, but "granite
--   cobblestones" is wrong.
--   
--   Tile kind for unknown space has the minimal <tt>KindOps.Id</tt> index.
--   The <tt>talter</tt> for unknown space is <tt>1</tt> and no other tile
--   kind has that value.
data TileKind
TileKind :: Char -> Text -> Freqs TileKind -> Color -> Color -> Word8 -> [Feature] -> TileKind

-- | map symbol
[tsymbol] :: TileKind -> Char

-- | short description
[tname] :: TileKind -> Text

-- | frequency within groups
[tfreq] :: TileKind -> Freqs TileKind

-- | map color
[tcolor] :: TileKind -> Color

-- | map color when not in FOV
[tcolor2] :: TileKind -> Color

-- | minimal skill needed to alter the tile
[talter] :: TileKind -> Word8

-- | properties
[tfeature] :: TileKind -> [Feature]

-- | All possible terrain tile features.
data Feature

-- | initially an item of this group is embedded; we assume the item has
--   effects and is supposed to be triggered
Embed :: (GroupName ItemKind) -> Feature

-- | goes from a closed to (randomly closed or) open tile when altered
OpenTo :: (GroupName TileKind) -> Feature

-- | goes from an open to (randomly opened or) closed tile when altered
CloseTo :: (GroupName TileKind) -> Feature

-- | alters tile, but does not change walkability
ChangeTo :: (GroupName TileKind) -> Feature

-- | when hidden, looks as the unique tile of the group
HideAs :: (GroupName TileKind) -> Feature

-- | when generating, may be transformed to the unique tile of the group
BuildAs :: (GroupName TileKind) -> Feature

-- | when generating in opening, can be revealed to belong to the group
RevealAs :: (GroupName TileKind) -> Feature

-- | when generating in solid wall, can be revealed to belong to the group
ObscureAs :: (GroupName TileKind) -> Feature

-- | actors can walk through
Walkable :: Feature

-- | actors can see through
Clear :: Feature

-- | is not lit with an ambient light
Dark :: Feature

-- | initial items often generated there
OftenItem :: Feature

-- | initial actors often generated there
OftenActor :: Feature

-- | no items ever generated there
NoItem :: Feature

-- | no actors ever generated there
NoActor :: Feature

-- | is allowed to have the same look as another tile
Indistinct :: Feature

-- | even if otherwise uninteresting, taken into account for triggering by
--   AI
ConsideredByAI :: Feature

-- | used for visible trails throughout the level
Trail :: Feature

-- | in place normal legend and in override, don't roll a tile kind only
--   once per place, but roll for each position; one non-spicy and at most
--   one spicy is rolled per place and then one of the two is rolled for
--   each position
Spice :: Feature
data TileSpeedup
TileSpeedup :: Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Bool -> Tab Word8 -> Tab Word8 -> TileSpeedup
[isClearTab] :: TileSpeedup -> Tab Bool
[isLitTab] :: TileSpeedup -> Tab Bool
[isWalkableTab] :: TileSpeedup -> Tab Bool
[isDoorTab] :: TileSpeedup -> Tab Bool
[isChangableTab] :: TileSpeedup -> Tab Bool
[isSuspectTab] :: TileSpeedup -> Tab Bool
[isHideAsTab] :: TileSpeedup -> Tab Bool
[consideredByAITab] :: TileSpeedup -> Tab Bool
[isOftenItemTab] :: TileSpeedup -> Tab Bool
[isOftenActorTab] :: TileSpeedup -> Tab Bool
[isNoItemTab] :: TileSpeedup -> Tab Bool
[isNoActorTab] :: TileSpeedup -> Tab Bool
[isEasyOpenTab] :: TileSpeedup -> Tab Bool
[alterMinSkillTab] :: TileSpeedup -> Tab Word8
[alterMinWalkTab] :: TileSpeedup -> Tab Word8
newtype Tab a
Tab :: (Vector a) -> Tab a

-- | Validate a single tile kind.
validateSingleTileKind :: TileKind -> [Text]

-- | Validate all tile kinds.
--   
--   If tiles look the same on the map (symbol and color), their
--   substantial features should be the same, too. Otherwise, the player
--   has to inspect manually all the tiles of that kind, or even experiment
--   with them, to see if any is special. This would be tedious. Note that
--   tiles may freely differ wrt text blurb, dungeon generation, AI
--   preferences, etc.
validateAllTileKind :: [TileKind] -> [Text]

-- | Features of tiles that differentiate them substantially from one
--   another. The intention is the player can easily tell such tiles apart
--   by their behaviour and only looking at the map, not tile name nor
--   description. So if running uses this function, it won't stop at places
--   that the player can't himself tell from other places, and so running
--   does not confer any advantages, except UI convenience. Hashes are
--   accurate enough for our purpose, given that we use arbitrary
--   heuristics anyway.
actionFeatures :: Bool -> TileKind -> IntSet
isUknownSpace :: Id TileKind -> Bool
unknownId :: Id TileKind
isSuspectKind :: TileKind -> Bool
isOpenableKind :: TileKind -> Bool
isClosableKind :: TileKind -> Bool
talterForStairs :: Word8
floorSymbol :: Char
validateDups :: TileKind -> Feature -> [Text]
hardwiredTileGroups :: [GroupName TileKind]
instance GHC.Show.Show Game.LambdaHack.Content.TileKind.TileKind
instance GHC.Generics.Generic Game.LambdaHack.Content.TileKind.Feature
instance GHC.Classes.Ord Game.LambdaHack.Content.TileKind.Feature
instance GHC.Classes.Eq Game.LambdaHack.Content.TileKind.Feature
instance GHC.Show.Show Game.LambdaHack.Content.TileKind.Feature
instance Data.Binary.Class.Binary Game.LambdaHack.Content.TileKind.Feature
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.TileKind.Feature
instance Control.DeepSeq.NFData Game.LambdaHack.Content.TileKind.Feature


-- | The type of kinds of rooms, halls and passages.
module Game.LambdaHack.Content.PlaceKind

-- | Parameters for the generation of small areas within a dungeon level.
data PlaceKind
PlaceKind :: Char -> Text -> Freqs PlaceKind -> Rarity -> Cover -> Fence -> [Text] -> [(Char, GroupName TileKind)] -> PlaceKind

-- | a symbol
[psymbol] :: PlaceKind -> Char

-- | short description
[pname] :: PlaceKind -> Text

-- | frequency within groups
[pfreq] :: PlaceKind -> Freqs PlaceKind

-- | rarity on given depths
[prarity] :: PlaceKind -> Rarity

-- | how to fill whole place based on the corner
[pcover] :: PlaceKind -> Cover

-- | whether to fence place with solid border
[pfence] :: PlaceKind -> Fence

-- | plan of the top-left corner of the place
[ptopLeft] :: PlaceKind -> [Text]

-- | legend override
[poverride] :: PlaceKind -> [(Char, GroupName TileKind)]

-- | A method of filling the whole area (except for CVerbatim and CMirror,
--   which are just placed in the middle of the area) by transforming a
--   given corner.
data Cover

-- | reflect every other corner, overlapping 1 row and column
CAlternate :: Cover

-- | fill symmetrically 4 corners and stretch their borders
CStretch :: Cover

-- | tile separately and symmetrically quarters of the place
CReflect :: Cover

-- | just build the given interior, without filling the area
CVerbatim :: Cover

-- | build the given interior in one of 4 mirrored variants
CMirror :: Cover

-- | The choice of a fence type for the place.
data Fence

-- | put a solid wall fence around the place
FWall :: Fence

-- | leave an empty space, like the rooms floor
FFloor :: Fence

-- | leave an empty space, like the caves ground
FGround :: Fence

-- | skip the fence and fill all with the place proper
FNone :: Fence

-- | Catch invalid place kind definitions. In particular, verify that the
--   top-left corner map is rectangular and not empty.
validateSinglePlaceKind :: PlaceKind -> [Text]

-- | Validate all place kinds. Currently always valid.
validateAllPlaceKind :: [PlaceKind] -> [Text]
instance GHC.Show.Show Game.LambdaHack.Content.PlaceKind.PlaceKind
instance GHC.Classes.Eq Game.LambdaHack.Content.PlaceKind.Fence
instance GHC.Show.Show Game.LambdaHack.Content.PlaceKind.Fence
instance GHC.Classes.Eq Game.LambdaHack.Content.PlaceKind.Cover
instance GHC.Show.Show Game.LambdaHack.Content.PlaceKind.Cover


-- | The type of cave kinds.
module Game.LambdaHack.Content.CaveKind

-- | Parameters for the generation of dungeon levels. Warning: for
--   efficiency, avoid embedded items in any of the common tiles.
data CaveKind
CaveKind :: Char -> Text -> Freqs CaveKind -> X -> Y -> DiceXY -> DiceXY -> DiceXY -> Dice -> Dice -> Rational -> Rational -> Int -> Dice -> Chance -> Chance -> Int -> Int -> Freqs ItemKind -> Dice -> Freqs ItemKind -> Freqs PlaceKind -> Bool -> GroupName TileKind -> GroupName TileKind -> GroupName TileKind -> GroupName TileKind -> GroupName TileKind -> GroupName TileKind -> GroupName TileKind -> Maybe (GroupName PlaceKind) -> Freqs PlaceKind -> Text -> CaveKind

-- | a symbol
[csymbol] :: CaveKind -> Char

-- | short description
[cname] :: CaveKind -> Text

-- | frequency within groups
[cfreq] :: CaveKind -> Freqs CaveKind

-- | X size of the whole cave
[cxsize] :: CaveKind -> X

-- | Y size of the whole cave
[cysize] :: CaveKind -> Y

-- | the dimensions of the grid of places
[cgrid] :: CaveKind -> DiceXY

-- | minimal size of places; for merging
[cminPlaceSize] :: CaveKind -> DiceXY

-- | maximal size of places
[cmaxPlaceSize] :: CaveKind -> DiceXY

-- | the chance a place is dark
[cdarkChance] :: CaveKind -> Dice

-- | the chance the cave is dark
[cnightChance] :: CaveKind -> Dice

-- | a proportion of extra connections
[cauxConnects] :: CaveKind -> Rational

-- | at most this proportion of rooms may be void
[cmaxVoid] :: CaveKind -> Rational

-- | minimal distance between stairs
[cminStairDist] :: CaveKind -> Int

-- | extra stairs on top of from above
[cextraStairs] :: CaveKind -> Dice

-- | the chance of a door in an opening
[cdoorChance] :: CaveKind -> Chance

-- | if there's a door, is it open?
[copenChance] :: CaveKind -> Chance

-- | if not open, hidden one in n times
[chidden] :: CaveKind -> Int

-- | the lower, the more monsters spawn
[cactorCoeff] :: CaveKind -> Int

-- | actor groups to consider
[cactorFreq] :: CaveKind -> Freqs ItemKind

-- | the number of items in the cave
[citemNum] :: CaveKind -> Dice

-- | item groups to consider
[citemFreq] :: CaveKind -> Freqs ItemKind

-- | place groups to consider
[cplaceFreq] :: CaveKind -> Freqs PlaceKind

-- | are passable default tiles permitted
[cpassable] :: CaveKind -> Bool

-- | the default cave tile
[cdefTile] :: CaveKind -> GroupName TileKind

-- | the dark cave corridor tile
[cdarkCorTile] :: CaveKind -> GroupName TileKind

-- | the lit cave corridor tile
[clitCorTile] :: CaveKind -> GroupName TileKind

-- | the filler wall
[cfillerTile] :: CaveKind -> GroupName TileKind

-- | the outer fence wall
[couterFenceTile] :: CaveKind -> GroupName TileKind

-- | the dark place plan legend
[clegendDarkTile] :: CaveKind -> GroupName TileKind

-- | the lit place plan legend
[clegendLitTile] :: CaveKind -> GroupName TileKind

-- | escape, if any
[cescapeGroup] :: CaveKind -> Maybe (GroupName PlaceKind)

-- | place groups to consider for stairs; in this case the rarity of items
--   in the group does not affect group choice
[cstairFreq] :: CaveKind -> Freqs PlaceKind

-- | cave description
[cdesc] :: CaveKind -> Text

-- | Catch caves with not enough space for all the places. Check the size
--   of the cave descriptions to make sure they fit on screen. Etc.
validateSingleCaveKind :: CaveKind -> [Text]

-- | Validate all cave kinds. Note that names don't have to be unique: we
--   can have several variants of a cave with a given name.
validateAllCaveKind :: [CaveKind] -> [Text]
instance GHC.Show.Show Game.LambdaHack.Content.CaveKind.CaveKind


-- | The type of kinds of game modes.
module Game.LambdaHack.Content.ModeKind

-- | Game mode specification.
data ModeKind
ModeKind :: Char -> Text -> Freqs ModeKind -> Roster -> Caves -> Text -> ModeKind

-- | a symbol
[msymbol] :: ModeKind -> Char

-- | short description
[mname] :: ModeKind -> Text

-- | frequency within groups
[mfreq] :: ModeKind -> Freqs ModeKind

-- | players taking part in the game
[mroster] :: ModeKind -> Roster

-- | arena of the game
[mcaves] :: ModeKind -> Caves

-- | description
[mdesc] :: ModeKind -> Text

-- | Requested cave groups for particular levels. The second component is
--   the <tt>Escape</tt> feature on the level. <tt>True</tt> means it's
--   represented by <tt>&lt;</tt>, <tt>False</tt>, by <tt>&gt;</tt>.
type Caves = IntMap (GroupName CaveKind)

-- | The specification of players for the game mode.
data Roster
Roster :: [(Player, [(Int, Dice, GroupName ItemKind)])] -> [(Text, Text)] -> [(Text, Text)] -> Roster

-- | players in the particular team and levels, numbers and groups of their
--   initial members
[rosterList] :: Roster -> [(Player, [(Int, Dice, GroupName ItemKind)])]

-- | the initial enmity matrix
[rosterEnemy] :: Roster -> [(Text, Text)]

-- | the initial aliance matrix
[rosterAlly] :: Roster -> [(Text, Text)]

-- | Outcome of a game.
data Outcome

-- | the faction was eliminated
Killed :: Outcome

-- | the faction lost the game in another way
Defeated :: Outcome

-- | game is supended
Camping :: Outcome

-- | the player won by eliminating all rivals
Conquer :: Outcome

-- | the player escaped the dungeon alive
Escape :: Outcome

-- | game is restarted
Restart :: Outcome

-- | Conditional polynomial representing score calculation for this player.
type HiCondPoly = [HiSummand]
type HiSummand = (HiPolynomial, [Outcome])
type HiPolynomial = [(HiIndeterminant, Double)]
data HiIndeterminant
HiConst :: HiIndeterminant
HiLoot :: HiIndeterminant
HiBlitz :: HiIndeterminant
HiSurvival :: HiIndeterminant
HiKill :: HiIndeterminant
HiLoss :: HiIndeterminant

-- | Properties of a particular player.
data Player
Player :: Text -> [GroupName ItemKind] -> Skills -> Bool -> Bool -> HiCondPoly -> Bool -> Tactic -> LeaderMode -> Bool -> Player

-- | name of the player
[fname] :: Player -> Text

-- | names of actor groups that may naturally fall under player's control,
--   e.g., upon spawning or summoning
[fgroups] :: Player -> [GroupName ItemKind]

-- | fixed skill modifiers to the non-leader actors; also summed with
--   skills implied by ftactic (which is not fixed)
[fskillsOther] :: Player -> Skills

-- | the player can escape the dungeon
[fcanEscape] :: Player -> Bool

-- | the faction declared killed if no actors
[fneverEmpty] :: Player -> Bool

-- | score polynomial for the player
[fhiCondPoly] :: Player -> HiCondPoly

-- | whether actors have gender
[fhasGender] :: Player -> Bool

-- | non-leaders behave according to this tactic; can be changed during the
--   game
[ftactic] :: Player -> Tactic

-- | the mode of switching the leader
[fleaderMode] :: Player -> LeaderMode

-- | does the faction have a UI client (for control or passive observation)
[fhasUI] :: Player -> Bool

-- | If a faction with <tt>LeaderUI</tt> and <tt>LeaderAI</tt> has any
--   actor, it has a leader.
data LeaderMode

-- | faction can have no leader, is whole under AI control
LeaderNull :: LeaderMode

-- | leader under AI control
LeaderAI :: AutoLeader -> LeaderMode

-- | leader under UI control, assumes <tt>fhasUI</tt>
LeaderUI :: AutoLeader -> LeaderMode
data AutoLeader
AutoLeader :: Bool -> Bool -> AutoLeader

-- | leader switching between levels is automatically done by the server
--   and client is not permitted to change to leaders from other levels
--   (the frequency of leader level switching done by the server is
--   controlled by <tt>RuleKind.rleadLevelClips</tt>); if the flag is
--   <tt>False</tt>, server still does a subset of the automatic switching,
--   e.g., when the old leader dies and no other actor of the faction
--   resides on his level, but the client (particularly UI) is expected to
--   do changes as well
[autoDungeon] :: AutoLeader -> Bool

-- | client is discouraged from leader switching (e.g., because non-leader
--   actors have the same skills as leader); server is guaranteed to switch
--   leader within a level very rarely, e.g., when the old leader dies; if
--   the flag is <tt>False</tt>, server still does a subset of the
--   automatic switching, but the client is expected to do more, because
--   it's advantageous for that kind of a faction
[autoLevel] :: AutoLeader -> Bool

-- | Catch invalid game mode kind definitions.
validateSingleModeKind :: ModeKind -> [Text]

-- | Validate game mode kinds together.
validateAllModeKind :: [ModeKind] -> [Text]

-- | Checks, in particular, that there is at least one faction with
--   fneverEmpty or the game would get stuck as soon as the dungeon is
--   devoid of actors.
validateSingleRoster :: Caves -> Roster -> [Text]
validateSinglePlayer :: Player -> [Text]
hardwiredModeGroups :: [GroupName ModeKind]
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.ModeKind
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.Roster
instance GHC.Generics.Generic Game.LambdaHack.Content.ModeKind.Player
instance GHC.Classes.Eq Game.LambdaHack.Content.ModeKind.Player
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.Player
instance GHC.Generics.Generic Game.LambdaHack.Content.ModeKind.LeaderMode
instance GHC.Classes.Ord Game.LambdaHack.Content.ModeKind.LeaderMode
instance GHC.Classes.Eq Game.LambdaHack.Content.ModeKind.LeaderMode
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.LeaderMode
instance GHC.Generics.Generic Game.LambdaHack.Content.ModeKind.AutoLeader
instance GHC.Classes.Ord Game.LambdaHack.Content.ModeKind.AutoLeader
instance GHC.Classes.Eq Game.LambdaHack.Content.ModeKind.AutoLeader
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.AutoLeader
instance GHC.Generics.Generic Game.LambdaHack.Content.ModeKind.HiIndeterminant
instance GHC.Classes.Ord Game.LambdaHack.Content.ModeKind.HiIndeterminant
instance GHC.Classes.Eq Game.LambdaHack.Content.ModeKind.HiIndeterminant
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.HiIndeterminant
instance GHC.Generics.Generic Game.LambdaHack.Content.ModeKind.Outcome
instance GHC.Enum.Bounded Game.LambdaHack.Content.ModeKind.Outcome
instance GHC.Enum.Enum Game.LambdaHack.Content.ModeKind.Outcome
instance GHC.Classes.Ord Game.LambdaHack.Content.ModeKind.Outcome
instance GHC.Classes.Eq Game.LambdaHack.Content.ModeKind.Outcome
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.Outcome
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ModeKind.Player
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ModeKind.LeaderMode
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ModeKind.AutoLeader
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ModeKind.HiIndeterminant
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ModeKind.Outcome


-- | General content types and operations.
module Game.LambdaHack.Common.Kind

-- | Content identifiers for the content type <tt>c</tt>.
data Id c

-- | Content operations for the content of type <tt>a</tt>.
data Ops a
Ops :: (Id a -> a) -> (GroupName a -> Id a) -> (GroupName a -> (a -> Bool) -> Rnd (Maybe (Id a))) -> (forall b. (Id a -> a -> b -> b) -> b -> b) -> (forall b. (b -> Id a -> a -> b) -> b -> b) -> (forall b. GroupName a -> (b -> Int -> Id a -> a -> b) -> b -> b) -> Int -> Ops a

-- | content element at given id
[okind] :: Ops a -> Id a -> a

-- | the id of the unique member of a singleton content group
[ouniqGroup] :: Ops a -> GroupName a -> Id a

-- | pick a random id belonging to a group and satisfying a predicate
[opick] :: Ops a -> GroupName a -> (a -> Bool) -> Rnd (Maybe (Id a))

-- | fold over all content elements of <tt>a</tt>
[ofoldrWithKey] :: Ops a -> forall b. (Id a -> a -> b -> b) -> b -> b

-- | fold strictly over all content <tt>a</tt>
[ofoldlWithKey'] :: Ops a -> forall b. (b -> Id a -> a -> b) -> b -> b

-- | fold over the given group only
[ofoldlGroup'] :: Ops a -> forall b. GroupName a -> (b -> Int -> Id a -> a -> b) -> b -> b

-- | size of content <tt>a</tt>
[olength] :: Ops a -> Int

-- | Operations for all content types, gathered together.
data COps
COps :: Ops CaveKind -> Ops ItemKind -> Ops ModeKind -> Ops PlaceKind -> Ops RuleKind -> Ops TileKind -> TileSpeedup -> COps
[cocave] :: COps -> Ops CaveKind
[coitem] :: COps -> Ops ItemKind
[comode] :: COps -> Ops ModeKind
[coplace] :: COps -> Ops PlaceKind
[corule] :: COps -> Ops RuleKind
[cotile] :: COps -> Ops TileKind
[coTileSpeedup] :: COps -> TileSpeedup

-- | The standard ruleset used for level operations.
stdRuleset :: Ops RuleKind -> RuleKind

-- | Create content operations for type <tt>a</tt> from definition of
--   content of type <tt>a</tt>.
createOps :: forall a. Show a => ContentDef a -> Ops a
instance GHC.Show.Show Game.LambdaHack.Common.Kind.COps
instance GHC.Classes.Eq Game.LambdaHack.Common.Kind.COps


-- | Operations concerning dungeon level tiles.
--   
--   Unlike for many other content types, there is no type <tt>Tile</tt>,
--   of particular concrete tiles in the dungeon, corresponding to
--   <a>TileKind</a> (the type of kinds of terrain tiles). This is because
--   the tiles are too numerous and there's not enough storage space for a
--   well-rounded <tt>Tile</tt> type, on one hand, and on the other hand,
--   tiles are accessed too often in performance critical code to try to
--   compress their representation and/or recompute them. Instead, of
--   defining a <tt>Tile</tt> type, we express various properties of
--   concrete tiles by arrays or sparse EnumMaps, as appropriate.
--   
--   Actors at normal speed (2 m/s) take one turn to move one tile (1 m by
--   1 m).
module Game.LambdaHack.Common.Tile
speedup :: Bool -> Ops TileKind -> TileSpeedup

-- | Whether a tile does not block vision. Essential for efficiency of
--   <a>FOV</a>, hence tabulated.
isClear :: TileSpeedup -> Id TileKind -> Bool

-- | Whether a tile has ambient light --- is lit on its own. Essential for
--   efficiency of <a>Perception</a>, hence tabulated.
isLit :: TileSpeedup -> Id TileKind -> Bool

-- | Whether actors can walk into a tile. Essential for efficiency of
--   pathfinding, hence tabulated.
isWalkable :: TileSpeedup -> Id TileKind -> Bool

-- | Whether a tile is a door, open or closed. Essential for efficiency of
--   pathfinding, hence tabulated.
isDoor :: TileSpeedup -> Id TileKind -> Bool

-- | Whether a tile is changable.
isChangable :: TileSpeedup -> Id TileKind -> Bool

-- | Whether a tile is suspect. Essential for efficiency of pathfinding,
--   hence tabulated.
isSuspect :: TileSpeedup -> Id TileKind -> Bool
isHideAs :: TileSpeedup -> Id TileKind -> Bool
consideredByAI :: TileSpeedup -> Id TileKind -> Bool

-- | Whether one can easily explore a tile, possibly finding a treasure,
--   either spawned there or dropped there by a (dying from poison) foe.
--   Doors can't be explorable since revealing a secret tile should not
--   change it's (walkable and) explorable status. Door status should not
--   depend on whether they are open or not so that a foe opening a door
--   doesn't force us to backtrack to explore it. Still, a foe that digs
--   through a wall will affect our exploration counter and if content lets
--   walls contain threasure, such backtraking makes sense.
isExplorable :: TileSpeedup -> Id TileKind -> Bool
isOftenItem :: TileSpeedup -> Id TileKind -> Bool
isOftenActor :: TileSpeedup -> Id TileKind -> Bool
isNoItem :: TileSpeedup -> Id TileKind -> Bool
isNoActor :: TileSpeedup -> Id TileKind -> Bool

-- | Whether a tile kind (specified by its id) has an OpenTo feature and
--   reasonable alter min skill.
isEasyOpen :: TileSpeedup -> Id TileKind -> Bool
alterMinSkill :: TileSpeedup -> Id TileKind -> Int
alterMinWalk :: TileSpeedup -> Id TileKind -> Int

-- | Whether a tile kind has the given feature.
kindHasFeature :: Feature -> TileKind -> Bool

-- | Whether a tile kind (specified by its id) has the given feature.
hasFeature :: Ops TileKind -> Feature -> Id TileKind -> Bool
openTo :: Ops TileKind -> Id TileKind -> Rnd (Id TileKind)
closeTo :: Ops TileKind -> Id TileKind -> Rnd (Id TileKind)
embeddedItems :: Ops TileKind -> Id TileKind -> [GroupName ItemKind]
revealAs :: Ops TileKind -> Id TileKind -> Rnd (Id TileKind)
obscureAs :: Ops TileKind -> Id TileKind -> Rnd (Id TileKind)
hideAs :: Ops TileKind -> Id TileKind -> Maybe (Id TileKind)
buildAs :: Ops TileKind -> Id TileKind -> Id TileKind
isEasyOpenKind :: TileKind -> Bool

-- | Whether a tile kind (specified by its id) has an OpenTo feature.
isOpenable :: Ops TileKind -> Id TileKind -> Bool

-- | Whether a tile kind (specified by its id) has a CloseTo feature.
isClosable :: Ops TileKind -> Id TileKind -> Bool
createTab :: Unbox a => Ops TileKind -> (TileKind -> a) -> Tab a
createTabWithKey :: Unbox a => Ops TileKind -> (Id TileKind -> TileKind -> a) -> Tab a
accessTab :: Unbox a => Tab a -> Id TileKind -> a
alterMinSkillKind :: Id TileKind -> TileKind -> Word8
alterMinWalkKind :: Id TileKind -> TileKind -> Word8


-- | Weapons, treasure and all the other items in the game.
module Game.LambdaHack.Common.Item

-- | A unique identifier of an item in the dungeon.
data ItemId

-- | Game items in actor possesion or strewn around the dungeon. The fields
--   <tt>jsymbol</tt>, <tt>jname</tt> and <tt>jflavour</tt> make it
--   possible to refer to and draw an unidentified item. Full information
--   about item is available through the <tt>jkindIx</tt> index as soon as
--   the item is identified.
data Item
Item :: ItemKindIx -> LevelId -> Maybe FactionId -> Char -> Text -> Flavour -> [Feature] -> Int -> Dice -> Item

-- | index pointing to the kind of the item
[jkindIx] :: Item -> ItemKindIx

-- | lowest level the item was created at
[jlid] :: Item -> LevelId

-- | the faction that created the item, if any
[jfid] :: Item -> Maybe FactionId

-- | map symbol
[jsymbol] :: Item -> Char

-- | generic name
[jname] :: Item -> Text

-- | flavour
[jflavour] :: Item -> Flavour

-- | public properties
[jfeature] :: Item -> [Feature]

-- | weight in grams, obvious enough
[jweight] :: Item -> Int

-- | impact damage of this particular weapon
[jdamage] :: Item -> Dice

-- | Price an item, taking count into consideration.
itemPrice :: (Item, Int) -> Int
isMelee :: Item -> Bool
goesIntoEqp :: Item -> Bool
goesIntoInv :: Item -> Bool
goesIntoSha :: Item -> Bool

-- | Record of sums of aspect values of an item, container, actor, etc.
data AspectRecord
AspectRecord :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Skills -> AspectRecord
[aTimeout] :: AspectRecord -> Int
[aHurtMelee] :: AspectRecord -> Int
[aArmorMelee] :: AspectRecord -> Int
[aArmorRanged] :: AspectRecord -> Int
[aMaxHP] :: AspectRecord -> Int
[aMaxCalm] :: AspectRecord -> Int
[aSpeed] :: AspectRecord -> Int
[aSight] :: AspectRecord -> Int
[aSmell] :: AspectRecord -> Int
[aShine] :: AspectRecord -> Int
[aNocto] :: AspectRecord -> Int
[aAggression] :: AspectRecord -> Int
[aSkills] :: AspectRecord -> Skills

-- | The map of item ids to item aspects. The full map is known by the
--   server.
type DiscoveryAspect = EnumMap ItemId AspectRecord
emptyAspectRecord :: AspectRecord
sumAspectRecord :: [(AspectRecord, Int)] -> AspectRecord
aspectRecordToList :: AspectRecord -> [Aspect]
meanAspect :: ItemKind -> AspectRecord

-- | An index of the kind identifier of an item. Clients have partial
--   knowledge how these idexes map to kind ids. They gain knowledge by
--   identifying items. The indexes and kind identifiers are 1-1.
data ItemKindIx

-- | A seed for rolling aspects of an item Clients have partial knowledge
--   of how item ids map to the seeds. They gain knowledge by identifying
--   items.
data ItemSeed

-- | The secret part of the information about an item. If a faction knows
--   the aspects of the item (the <a>itemAspect</a> field is not empty),
--   this is a complete secret information/.
data ItemDisco
ItemDisco :: Id ItemKind -> ItemKind -> AspectRecord -> Bool -> Maybe AspectRecord -> ItemDisco
[itemKindId] :: ItemDisco -> Id ItemKind
[itemKind] :: ItemDisco -> ItemKind
[itemAspectMean] :: ItemDisco -> AspectRecord
[itemConst] :: ItemDisco -> Bool
[itemAspect] :: ItemDisco -> Maybe AspectRecord

-- | Full information about an item.
data ItemFull
ItemFull :: Item -> Int -> ItemTimer -> Maybe ItemDisco -> ItemFull
[itemBase] :: ItemFull -> Item
[itemK] :: ItemFull -> Int
[itemTimer] :: ItemFull -> ItemTimer
[itemDisco] :: ItemFull -> Maybe ItemDisco

-- | Partial information about item kinds. These are assigned to each
--   <a>ItemKindIx</a>. There is an item kinda, mean aspect value computed
--   (and here cached) for items of that kind and a flag saying whether the
--   item's aspects are constant rather than random or dependent on dungeon
--   level where the item is created.
data KindMean
KindMean :: Id ItemKind -> AspectRecord -> Bool -> KindMean
[kmKind] :: KindMean -> Id ItemKind
[kmMean] :: KindMean -> AspectRecord
[kmConst] :: KindMean -> Bool

-- | The map of item kind indexes to item kind ids. The full map, as known
--   by the server, is 1-1.
type DiscoveryKind = EnumMap ItemKindIx KindMean

-- | The map of item kind indexes to identifiers of items that have that
--   kind.
type ItemIxMap = EnumMap ItemKindIx [ItemId]

-- | Fields are intentionally kept non-strict, because they are recomputed
--   often, but not used every time. The fields are, in order: 1. whether
--   the item should be kept in equipment (not in pack nor stash) 2. the
--   total benefit from picking the item up (to use or to put in equipment)
--   3. the benefit of applying the item to self 4. the (usually negative)
--   benefit of hitting a foe in meleeing with the item 5. the (usually
--   negative) benefit of flinging an item at an opponent
data Benefit
Benefit :: ~Bool -> ~Double -> ~Double -> ~Double -> ~Double -> Benefit
[benInEqp] :: Benefit -> ~Bool
[benPickup] :: Benefit -> ~Double
[benApply] :: Benefit -> ~Double
[benMelee] :: Benefit -> ~Double
[benFling] :: Benefit -> ~Double
type DiscoveryBenefit = EnumMap ItemId Benefit
itemNoDisco :: (Item, Int) -> ItemFull
itemToFull6 :: COps -> DiscoveryKind -> DiscoveryAspect -> ItemId -> Item -> ItemQuant -> ItemFull
aspectsRandom :: ItemKind -> Bool
seedToAspect :: ItemSeed -> ItemKind -> AbsDepth -> AbsDepth -> AspectRecord
aspectRecordFull :: ItemFull -> AspectRecord
type ItemTimer = [Time]

-- | Number of items in a bag, together with recharging timer, in case of
--   items that need recharging, exists only temporarily or auto-activate
--   at regular intervals.
type ItemQuant = (Int, ItemTimer)

-- | A bag of items, e.g., one of the stores of an actor or the items on a
--   particular floor position or embedded in a particular map tile.
type ItemBag = EnumMap ItemId ItemQuant

-- | All items in the dungeon (including in actor inventories), indexed by
--   item identifier.
type ItemDict = EnumMap ItemId Item
castAspect :: AbsDepth -> AbsDepth -> AspectRecord -> Aspect -> Rnd AspectRecord
addMeanAspect :: AspectRecord -> Aspect -> AspectRecord
ceilingMeanDice :: Dice -> Int
instance GHC.Show.Show Game.LambdaHack.Common.Item.ItemFull
instance GHC.Generics.Generic Game.LambdaHack.Common.Item.Benefit
instance GHC.Show.Show Game.LambdaHack.Common.Item.Benefit
instance GHC.Generics.Generic Game.LambdaHack.Common.Item.KindMean
instance GHC.Classes.Eq Game.LambdaHack.Common.Item.KindMean
instance GHC.Show.Show Game.LambdaHack.Common.Item.KindMean
instance GHC.Show.Show Game.LambdaHack.Common.Item.ItemDisco
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Item.ItemSeed
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Item.ItemSeed
instance GHC.Enum.Enum Game.LambdaHack.Common.Item.ItemSeed
instance GHC.Classes.Ord Game.LambdaHack.Common.Item.ItemSeed
instance GHC.Classes.Eq Game.LambdaHack.Common.Item.ItemSeed
instance GHC.Show.Show Game.LambdaHack.Common.Item.ItemSeed
instance GHC.Generics.Generic Game.LambdaHack.Common.Item.Item
instance GHC.Classes.Eq Game.LambdaHack.Common.Item.Item
instance GHC.Show.Show Game.LambdaHack.Common.Item.Item
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Item.ItemKindIx
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Item.ItemKindIx
instance GHC.Arr.Ix Game.LambdaHack.Common.Item.ItemKindIx
instance GHC.Enum.Enum Game.LambdaHack.Common.Item.ItemKindIx
instance GHC.Classes.Ord Game.LambdaHack.Common.Item.ItemKindIx
instance GHC.Classes.Eq Game.LambdaHack.Common.Item.ItemKindIx
instance GHC.Show.Show Game.LambdaHack.Common.Item.ItemKindIx
instance GHC.Generics.Generic Game.LambdaHack.Common.Item.AspectRecord
instance GHC.Classes.Ord Game.LambdaHack.Common.Item.AspectRecord
instance GHC.Classes.Eq Game.LambdaHack.Common.Item.AspectRecord
instance GHC.Show.Show Game.LambdaHack.Common.Item.AspectRecord
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Item.ItemId
instance GHC.Enum.Enum Game.LambdaHack.Common.Item.ItemId
instance GHC.Classes.Ord Game.LambdaHack.Common.Item.ItemId
instance GHC.Classes.Eq Game.LambdaHack.Common.Item.ItemId
instance GHC.Show.Show Game.LambdaHack.Common.Item.ItemId
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Item.Benefit
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Item.KindMean
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Item.Item
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Item.Item
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Item.AspectRecord
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Item.AspectRecord


-- | Determining the strongest item wrt some property.
module Game.LambdaHack.Common.ItemStrongest
strengthEffect :: (Effect -> [b]) -> ItemFull -> [b]
strengthOnSmash :: ItemFull -> [Effect]
strengthCreateOrgan :: ItemFull -> [GroupName ItemKind]
strengthDropOrgan :: ItemFull -> [GroupName ItemKind]
strengthEqpSlot :: ItemFull -> Maybe EqpSlot
strengthToThrow :: Item -> ThrowMod
strongestSlot :: DiscoveryBenefit -> EqpSlot -> [(ItemId, ItemFull)] -> [(Int, (ItemId, ItemFull))]
computeTrajectory :: Int -> Int -> Int -> [Point] -> ([Vector], (Speed, Int))
itemTrajectory :: Item -> [Point] -> ([Vector], (Speed, Int))
totalRange :: Item -> Int
hasCharge :: Time -> ItemFull -> Bool
damageUsefulness :: Item -> Double
strongestMelee :: Maybe DiscoveryBenefit -> Time -> [(ItemId, ItemFull)] -> [(Double, (ItemId, ItemFull))]
prEqpSlot :: EqpSlot -> AspectRecord -> Int
unknownMeleeBonus :: [ItemFull] -> Bool
filterRecharging :: [Effect] -> [Effect]
stripRecharging :: [Effect] -> [Effect]
stripOnSmash :: [Effect] -> [Effect]
unknownAspect :: (Aspect -> [Dice]) -> ItemFull -> Bool


-- | Possible causes of failure of request.
module Game.LambdaHack.Common.ReqFailure

-- | Possible causes of failure of request.
data ReqFailure
MoveNothing :: ReqFailure
MeleeSelf :: ReqFailure
MeleeDistant :: ReqFailure
DisplaceDistant :: ReqFailure
DisplaceAccess :: ReqFailure
DisplaceProjectiles :: ReqFailure
DisplaceDying :: ReqFailure
DisplaceBraced :: ReqFailure
DisplaceImmobile :: ReqFailure
DisplaceSupported :: ReqFailure
AlterUnskilled :: ReqFailure
AlterUnwalked :: ReqFailure
AlterDistant :: ReqFailure
AlterBlockActor :: ReqFailure
AlterBlockItem :: ReqFailure
AlterNothing :: ReqFailure
EqpOverfull :: ReqFailure
EqpStackFull :: ReqFailure
ApplyUnskilled :: ReqFailure
ApplyRead :: ReqFailure
ApplyOutOfReach :: ReqFailure
ApplyCharging :: ReqFailure
ApplyNoEffects :: ReqFailure
ItemNothing :: ReqFailure
ItemNotCalm :: ReqFailure
NotCalmPrecious :: ReqFailure
ProjectUnskilled :: ReqFailure
ProjectAimOnself :: ReqFailure
ProjectBlockTerrain :: ReqFailure
ProjectBlockActor :: ReqFailure
ProjectLobable :: ReqFailure
ProjectOutOfReach :: ReqFailure
TriggerNothing :: ReqFailure
NoChangeDunLeader :: ReqFailure
impossibleReqFailure :: ReqFailure -> Bool
showReqFailure :: ReqFailure -> Text
permittedPrecious :: Bool -> Bool -> ItemFull -> Either ReqFailure Bool
permittedProject :: Bool -> Int -> Bool -> [Char] -> ItemFull -> Either ReqFailure Bool
permittedProjectAI :: Int -> Bool -> ItemFull -> Bool
permittedApply :: Time -> Int -> Bool -> [Char] -> ItemFull -> Either ReqFailure Bool
permittedPreciousAI :: Bool -> ItemFull -> Bool
instance GHC.Generics.Generic Game.LambdaHack.Common.ReqFailure.ReqFailure
instance GHC.Classes.Eq Game.LambdaHack.Common.ReqFailure.ReqFailure
instance GHC.Show.Show Game.LambdaHack.Common.ReqFailure.ReqFailure
instance Data.Binary.Class.Binary Game.LambdaHack.Common.ReqFailure.ReqFailure


-- | Actors in the game: heroes, monsters, etc.
module Game.LambdaHack.Common.Actor

-- | A unique identifier of an actor in the dungeon.
data ActorId

-- | Actor properties that are changing throughout the game. If they appear
--   dublets of properties of actor kinds, e.g. HP, they may be results of
--   casting the dice specified in their respective actor kind and/or may
--   be modified temporarily, but return to the original value from their
--   respective kind over time.
data Actor
Actor :: ItemId -> Int64 -> ResDelta -> Int64 -> ResDelta -> Point -> Maybe Point -> LevelId -> FactionId -> Maybe ([Vector], Speed) -> ItemBag -> ItemBag -> ItemBag -> Int -> Bool -> Bool -> Actor

-- | the trunk organ of the actor's body
[btrunk] :: Actor -> ItemId

-- | current hit points * 1M
[bhp] :: Actor -> Int64

-- | HP delta this turn * 1M
[bhpDelta] :: Actor -> ResDelta

-- | current calm * 1M
[bcalm] :: Actor -> Int64

-- | calm delta this turn * 1M
[bcalmDelta] :: Actor -> ResDelta

-- | current position
[bpos] :: Actor -> Point

-- | previous position, if any
[boldpos] :: Actor -> Maybe Point

-- | current level
[blid] :: Actor -> LevelId

-- | faction the actor currently belongs to
[bfid] :: Actor -> FactionId

-- | trajectory the actor must travel and his travel speed
[btrajectory] :: Actor -> Maybe ([Vector], Speed)

-- | organs
[borgan] :: Actor -> ItemBag

-- | personal equipment
[beqp] :: Actor -> ItemBag

-- | personal inventory pack
[binv] :: Actor -> ItemBag

-- | number of weapons among eqp and organs
[bweapon] :: Actor -> Int

-- | is the actor waiting right now?
[bwait] :: Actor -> Bool

-- | is a projectile? (shorthand only, this can be deduced from btrunk)
[bproj] :: Actor -> Bool
data ResDelta
ResDelta :: (Int64, Int64) -> (Int64, Int64) -> ResDelta

-- | resource change this player turn
[resCurrentTurn] :: ResDelta -> (Int64, Int64)

-- | resource change last player turn
[resPreviousTurn] :: ResDelta -> (Int64, Int64)
type ActorAspect = EnumMap ActorId AspectRecord
deltaSerious :: ResDelta -> Bool
deltaMild :: ResDelta -> Bool
actorCanMelee :: ActorAspect -> ActorId -> Actor -> Bool
bspeed :: Actor -> AspectRecord -> Speed

-- | Whether an actor is braced for combat this clip.
braced :: Actor -> Bool
actorTemplate :: ItemId -> Int64 -> Int64 -> Point -> LevelId -> FactionId -> Actor
waitedLastTurn :: Actor -> Bool
actorDying :: Actor -> Bool
actorTrunkIsBlast :: Item -> Bool
hpTooLow :: Actor -> AspectRecord -> Bool
calmEnough :: Actor -> AspectRecord -> Bool
hpEnough :: Actor -> AspectRecord -> Bool
checkAdjacent :: Actor -> Actor -> Bool
eqpOverfull :: Actor -> Int -> Bool
eqpFreeN :: Actor -> Int

-- | All actors on the level, indexed by actor identifier.
type ActorDict = EnumMap ActorId Actor

-- | Chance that a new monster is generated. Currently depends on the
--   number of monsters already present, and on the level. In the future,
--   the strength of the character and the strength of the monsters present
--   could further influence the chance, and the chance could also affect
--   which monster is generated. How many and which monsters are generated
--   will also depend on the cave kind used to build the level.
monsterGenChance :: AbsDepth -> AbsDepth -> Int -> Int -> Rnd Bool

-- | How long until an actor's smell vanishes from a tile.
smellTimeout :: Delta Time
instance GHC.Generics.Generic Game.LambdaHack.Common.Actor.Actor
instance GHC.Classes.Eq Game.LambdaHack.Common.Actor.Actor
instance GHC.Show.Show Game.LambdaHack.Common.Actor.Actor
instance GHC.Generics.Generic Game.LambdaHack.Common.Actor.ResDelta
instance GHC.Classes.Eq Game.LambdaHack.Common.Actor.ResDelta
instance GHC.Show.Show Game.LambdaHack.Common.Actor.ResDelta
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Actor.Actor
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Actor.ResDelta


-- | Inhabited dungeon levels and the operations to query and change them
--   as the game progresses.
module Game.LambdaHack.Common.Level

-- | Abstract level identifiers.
data LevelId

-- | Absolute depth in the dungeon. When used for the maximum depth of the
--   whole dungeon, this can be different than dungeon size, e.g., when the
--   dungeon is branched, and it can even be different than the length of
--   the longest branch, if levels at some depths are missing.
data AbsDepth

-- | The complete dungeon is a map from level identifiers to levels.
type Dungeon = EnumMap LevelId Level

-- | Levels in the current branch, one level up (or down) from the current.
ascendInBranch :: Dungeon -> Bool -> LevelId -> [LevelId]

-- | Compute the level identifier and stair position on the new level,
--   after a level change.
--   
--   We assume there is never a staircase up and down at the same position.
whereTo :: LevelId -> Point -> Maybe Bool -> Dungeon -> (LevelId, Point)

-- | Items located on map tiles.
type ItemFloor = EnumMap Point ItemBag

-- | Items located on map tiles.
type ActorMap = EnumMap Point [ActorId]

-- | Tile kinds on the map.
type TileMap = GArray Word16 (Id TileKind)

-- | Current smell on map tiles.
type SmellMap = EnumMap Point Time

-- | A view on single, inhabited dungeon level. <a>Remembered</a> fields
--   carry a subset of the info in the client copies of levels.
data Level
Level :: AbsDepth -> ItemFloor -> ItemFloor -> ActorMap -> TileMap -> X -> Y -> SmellMap -> ([Point], [Point]) -> Int -> Int -> Time -> Int -> Freqs ItemKind -> Int -> Freqs ItemKind -> [Point] -> Bool -> Text -> Text -> Level

-- | absolute depth of the level
[ldepth] :: Level -> AbsDepth

-- | remembered items lying on the floor
[lfloor] :: Level -> ItemFloor

-- | remembered items embedded in the tile
[lembed] :: Level -> ItemFloor

-- | seen actors at positions on the level
[lactor] :: Level -> ActorMap

-- | remembered level map
[ltile] :: Level -> TileMap

-- | width of the level
[lxsize] :: Level -> X

-- | height of the level
[lysize] :: Level -> Y

-- | remembered smells on the level
[lsmell] :: Level -> SmellMap

-- | positions of (up, down) stairs
[lstair] :: Level -> ([Point], [Point])

-- | currently remembered clear tiles
[lseen] :: Level -> Int

-- | total number of explorable tiles
[lexplorable] :: Level -> Int

-- | local time on the level (possibly frozen)
[ltime] :: Level -> Time

-- | the lower, the more monsters spawn
[lactorCoeff] :: Level -> Int

-- | frequency of spawned actors; [] for clients
[lactorFreq] :: Level -> Freqs ItemKind

-- | number of initial items, 0 for clients
[litemNum] :: Level -> Int

-- | frequency of initial items; [] for clients
[litemFreq] :: Level -> Freqs ItemKind

-- | positions of IK.Escape tiles
[lescape] :: Level -> [Point]

-- | whether the level is covered in darkness
[lnight] :: Level -> Bool

-- | level name
[lname] :: Level -> Text

-- | level description
[ldesc] :: Level -> Text
updateFloor :: (ItemFloor -> ItemFloor) -> Level -> Level
updateEmbed :: (ItemFloor -> ItemFloor) -> Level -> Level
updateActorMap :: (ActorMap -> ActorMap) -> Level -> Level
updateTile :: (TileMap -> TileMap) -> Level -> Level
updateSmell :: (SmellMap -> SmellMap) -> Level -> Level

-- | Query for tile kinds on the map.
at :: Level -> Point -> Id TileKind

-- | Find a random position on the map satisfying a predicate.
findPoint :: X -> Y -> (Point -> Maybe Point) -> Rnd Point

-- | Find a random position on the map satisfying a predicate.
findPos :: TileMap -> (Point -> Id TileKind -> Bool) -> Rnd Point

-- | Try to find a random position on the map satisfying conjunction of the
--   mandatory and an optional predicate. If the permitted number of
--   attempts is not enough, try again the same number of times without the
--   next optional predicate, and fall back to trying as many times, as
--   needed, with only the mandatory predicate.
findPosTry :: Int -> TileMap -> (Point -> Id TileKind -> Bool) -> [Point -> Id TileKind -> Bool] -> Rnd Point
findPosTry2 :: Int -> TileMap -> (Point -> Id TileKind -> Bool) -> [Point -> Id TileKind -> Bool] -> (Point -> Id TileKind -> Bool) -> [Point -> Id TileKind -> Bool] -> Rnd Point
assertSparseItems :: ItemFloor -> ItemFloor
assertSparseActors :: ActorMap -> ActorMap
instance GHC.Classes.Eq Game.LambdaHack.Common.Level.Level
instance GHC.Show.Show Game.LambdaHack.Common.Level.Level
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Level.Level


-- | Description of effects.
module Game.LambdaHack.Client.UI.EffectDescription

-- | Suffix to append to a basic content name if the content causes the
--   effect.
--   
--   We show absolute time in seconds, not <tt>moves</tt>, because actors
--   can have different speeds (and actions can potentially take different
--   time intervals). We call the time taken by one player move, when
--   walking, a <tt>move</tt>. <tt>Turn</tt> and <tt>clip</tt> are used
--   mostly internally, the former as an absolute time unit. We show
--   distances in <tt>steps</tt>, because one step, from a tile to another
--   tile, is always 1 meter. We don't call steps <tt>tiles</tt>, reserving
--   that term for the context of terrain kinds or units of area.
effectToSuffix :: Effect -> Text
slotToSentence :: EqpSlot -> Text
slotToName :: EqpSlot -> Text
slotToDesc :: EqpSlot -> Text
slotToDecorator :: EqpSlot -> Actor -> Int -> Text
statSlots :: [EqpSlot]
kindAspectToSuffix :: Aspect -> Text
featureToSuff :: Feature -> Text
featureToSentence :: Feature -> Maybe Text
affixDice :: Dice -> Text
tmodToSuff :: Text -> ThrowMod -> Text
affixBonus :: Int -> Text
wrapInParens :: Text -> Text
wrapInChevrons :: Text -> Text


-- | Factions taking part in the game, e.g., a hero faction, a monster
--   faction and an animal faction.
module Game.LambdaHack.Common.Faction

-- | A unique identifier of a faction in a game.
data FactionId

-- | All factions in the game, indexed by faction identifier.
type FactionDict = EnumMap FactionId Faction

-- | The faction datatype.
data Faction
Faction :: Text -> Color -> Player -> [(Int, Int, GroupName ItemKind)] -> Dipl -> Maybe Status -> Maybe ActorId -> ItemBag -> EnumMap (Id ItemKind) Int -> EnumMap (Id ModeKind) (IntMap (EnumMap (Id ItemKind) Int)) -> Faction

-- | individual name
[gname] :: Faction -> Text

-- | color of actors or their frames
[gcolor] :: Faction -> Color

-- | the player spec for this faction
[gplayer] :: Faction -> Player

-- | initial actors
[ginitial] :: Faction -> [(Int, Int, GroupName ItemKind)]

-- | diplomatic mode
[gdipl] :: Faction -> Dipl

-- | cause of game end/exit
[gquit] :: Faction -> Maybe Status

-- | the leader of the faction; don't use in place of sleader on clients
[_gleader] :: Faction -> Maybe ActorId

-- | faction's shared inventory
[gsha] :: Faction -> ItemBag

-- | members killed
[gvictims] :: Faction -> EnumMap (Id ItemKind) Int

-- | members killed in the past, by game mode and difficulty level
[gvictimsD] :: Faction -> EnumMap (Id ModeKind) (IntMap (EnumMap (Id ItemKind) Int))

-- | Diplomacy states. Higher overwrite lower in case of asymmetric
--   content.
data Diplomacy
Unknown :: Diplomacy
Neutral :: Diplomacy
Alliance :: Diplomacy
War :: Diplomacy

-- | Current game status.
data Status
Status :: Outcome -> Int -> Maybe (GroupName ModeKind) -> Status

-- | current game outcome
[stOutcome] :: Status -> Outcome

-- | depth of the final encounter
[stDepth] :: Status -> Int

-- | new game group to start, if any
[stNewGame] :: Status -> Maybe (GroupName ModeKind)

-- | The type of na actor target.
data Target

-- | target an actor; cycle only trough seen foes, unless the flag is set
TEnemy :: ActorId -> Bool -> Target

-- | target a concrete spot
TPoint :: TGoal -> LevelId -> Point -> Target

-- | target position relative to actor
TVector :: Vector -> Target

-- | The goal of an actor.
data TGoal

-- | last seen position of the targeted actor
TEnemyPos :: ActorId -> Bool -> TGoal

-- | embedded item that can be triggered; in <tt>TPoint (TEmbed bag p) _
--   q</tt> usually <tt>bag</tt> is embbedded in <tt>p</tt> and <tt>q</tt>
--   is an adjacent open tile
TEmbed :: ItemBag -> Point -> TGoal

-- | item lying on the ground
TItem :: ItemBag -> TGoal

-- | smell potentially left by enemies
TSmell :: TGoal

-- | an unknown tile to be explored
TUnknown :: TGoal

-- | a known tile to be patrolled
TKnown :: TGoal

-- | an unspecified goal
TAny :: TGoal
data Challenge
Challenge :: Int -> Bool -> Bool -> Challenge

-- | game difficulty level (HP bonus or malus)
[cdiff] :: Challenge -> Int

-- | lone wolf challenge (only one starting character)
[cwolf] :: Challenge -> Bool

-- | cold fish challenge (no healing from enemies)
[cfish] :: Challenge -> Bool
gleader :: Faction -> Maybe ActorId
tgtKindDescription :: Target -> Text

-- | Tell whether the faction consists of summoned horrors only.
--   
--   Horror player is special, for summoned actors that don't belong to any
--   of the main players of a given game. E.g., animals summoned during a
--   skirmish game between two hero factions land in the horror faction. In
--   every game, either all factions for which summoning items exist should
--   be present or a horror player should be added to host them.
isHorrorFact :: Faction -> Bool
nameOfHorrorFact :: GroupName ItemKind
noRunWithMulti :: Faction -> Bool
isAIFact :: Faction -> Bool
autoDungeonLevel :: Faction -> (Bool, Bool)
automatePlayer :: Bool -> Player -> Player

-- | Check if factions are at war. Assumes symmetry.
isAtWar :: Faction -> FactionId -> Bool

-- | Check if factions are allied. Assumes symmetry.
isAllied :: Faction -> FactionId -> Bool
difficultyBound :: Int
difficultyDefault :: Int
difficultyCoeff :: Int -> Int
difficultyInverse :: Int -> Int
defaultChallenge :: Challenge
type Dipl = EnumMap FactionId Diplomacy
instance GHC.Generics.Generic Game.LambdaHack.Common.Faction.Challenge
instance GHC.Classes.Ord Game.LambdaHack.Common.Faction.Challenge
instance GHC.Classes.Eq Game.LambdaHack.Common.Faction.Challenge
instance GHC.Show.Show Game.LambdaHack.Common.Faction.Challenge
instance GHC.Generics.Generic Game.LambdaHack.Common.Faction.Target
instance GHC.Classes.Ord Game.LambdaHack.Common.Faction.Target
instance GHC.Classes.Eq Game.LambdaHack.Common.Faction.Target
instance GHC.Show.Show Game.LambdaHack.Common.Faction.Target
instance GHC.Generics.Generic Game.LambdaHack.Common.Faction.TGoal
instance GHC.Classes.Ord Game.LambdaHack.Common.Faction.TGoal
instance GHC.Classes.Eq Game.LambdaHack.Common.Faction.TGoal
instance GHC.Show.Show Game.LambdaHack.Common.Faction.TGoal
instance GHC.Generics.Generic Game.LambdaHack.Common.Faction.Faction
instance GHC.Classes.Eq Game.LambdaHack.Common.Faction.Faction
instance GHC.Show.Show Game.LambdaHack.Common.Faction.Faction
instance GHC.Generics.Generic Game.LambdaHack.Common.Faction.Status
instance GHC.Classes.Ord Game.LambdaHack.Common.Faction.Status
instance GHC.Classes.Eq Game.LambdaHack.Common.Faction.Status
instance GHC.Show.Show Game.LambdaHack.Common.Faction.Status
instance GHC.Generics.Generic Game.LambdaHack.Common.Faction.Diplomacy
instance GHC.Enum.Enum Game.LambdaHack.Common.Faction.Diplomacy
instance GHC.Classes.Ord Game.LambdaHack.Common.Faction.Diplomacy
instance GHC.Classes.Eq Game.LambdaHack.Common.Faction.Diplomacy
instance GHC.Show.Show Game.LambdaHack.Common.Faction.Diplomacy
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.Challenge
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.Target
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.TGoal
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.Faction
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.Status
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.Diplomacy


-- | Actors perceiving other actors and the dungeon level.
--   
--   Visibility works according to KISS. Everything that player sees is
--   real. There are no unmarked hidden tiles and only solid tiles can be
--   marked, so there are no invisible walls and to pass through an
--   illusory wall, you have to use a turn bumping into it first. Only
--   tiles marked with Suspect can turn out to be another tile. (So, if all
--   tiles are marked with Suspect, the player knows nothing for sure, but
--   this should be avoided, because searching becomes too time-consuming.)
--   Each actor sees adjacent tiles, even when blind, so adjacent tiles are
--   known, so the actor can decide accurately whether to pass thorugh or
--   alter, etc.
--   
--   Items are always real and visible. Actors are real, but can be
--   invisible. Invisible actors in walls can't be hit, but are hinted at
--   when altering the tile, so the player can flee or block. Invisible
--   actors in open space can be hit.
module Game.LambdaHack.Common.Perception

-- | Visible positions.
newtype PerVisible
PerVisible :: EnumSet Point -> PerVisible
[pvisible] :: PerVisible -> EnumSet Point

-- | Smelled positions.
newtype PerSmelled
PerSmelled :: EnumSet Point -> PerSmelled
[psmelled] :: PerSmelled -> EnumSet Point

-- | The type representing the perception of a faction on a level.
data Perception
Perception :: PerVisible -> PerSmelled -> Perception
[psight] :: Perception -> PerVisible
[psmell] :: Perception -> PerSmelled

-- | Perception of a single faction, indexed by level identifier.
type PerLid = EnumMap LevelId Perception

-- | Perception indexed by faction identifier. This can't be added to
--   <tt>FactionDict</tt>, because clients can't see it for other factions.
type PerFid = EnumMap FactionId PerLid

-- | The set of tiles visible by at least one hero.
totalVisible :: Perception -> EnumSet Point

-- | The set of tiles smelt by at least one hero.
totalSmelled :: Perception -> EnumSet Point
emptyPer :: Perception
nullPer :: Perception -> Bool
addPer :: Perception -> Perception -> Perception
diffPer :: Perception -> Perception -> Perception
instance GHC.Generics.Generic Game.LambdaHack.Common.Perception.Perception
instance GHC.Classes.Eq Game.LambdaHack.Common.Perception.Perception
instance GHC.Show.Show Game.LambdaHack.Common.Perception.Perception
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Perception.PerSmelled
instance GHC.Classes.Eq Game.LambdaHack.Common.Perception.PerSmelled
instance GHC.Show.Show Game.LambdaHack.Common.Perception.PerSmelled
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Perception.PerVisible
instance GHC.Classes.Eq Game.LambdaHack.Common.Perception.PerVisible
instance GHC.Show.Show Game.LambdaHack.Common.Perception.PerVisible
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Perception.Perception


-- | High score table operations.
module Game.LambdaHack.Common.HighScore

-- | The list of scores, in decreasing order.
data ScoreTable

-- | A dictionary from game mode IDs to scores tables.
type ScoreDict = EnumMap (Id ModeKind) ScoreTable

-- | Empty score table
empty :: ScoreDict

-- | Register a new score in a score table.
register :: ScoreTable -> Int -> Time -> Status -> POSIXTime -> Challenge -> Text -> EnumMap (Id ItemKind) Int -> EnumMap (Id ItemKind) Int -> HiCondPoly -> (Bool, (ScoreTable, Int))

-- | Show a single high score, from the given ranking in the high score
--   table.
showScore :: TimeZone -> (Int, ScoreRecord) -> [Text]
getTable :: Id ModeKind -> ScoreDict -> ScoreTable
getRecord :: Int -> ScoreTable -> ScoreRecord

-- | Generate a slideshow with the current and previous scores.
highSlideshow :: ScoreTable -> Int -> Text -> TimeZone -> (Text, [[Text]])

-- | A single score record. Records are ordered in the highscore table,
--   from the best to the worst, in lexicographic ordering wrt the fields
--   below.
data ScoreRecord

-- | Insert a new score into the table, Return new table and the ranking.
--   Make sure the table doesn't grow too large.
insertPos :: ScoreRecord -> ScoreTable -> (ScoreTable, Int)

-- | Show a screenful of the high scores table. Parameter height is the
--   number of (3-line) scores to be shown.
showTable :: TimeZone -> ScoreTable -> Int -> Int -> [Text]

-- | Produce a couple of renderings of the high scores table.
showNearbyScores :: TimeZone -> Int -> ScoreTable -> Int -> [[Text]]
instance Data.Binary.Class.Binary Game.LambdaHack.Common.HighScore.ScoreTable
instance GHC.Classes.Eq Game.LambdaHack.Common.HighScore.ScoreTable
instance GHC.Generics.Generic Game.LambdaHack.Common.HighScore.ScoreRecord
instance GHC.Classes.Ord Game.LambdaHack.Common.HighScore.ScoreRecord
instance GHC.Classes.Eq Game.LambdaHack.Common.HighScore.ScoreRecord
instance GHC.Show.Show Game.LambdaHack.Common.HighScore.ScoreRecord
instance GHC.Show.Show Game.LambdaHack.Common.HighScore.ScoreTable
instance Data.Binary.Class.Binary Game.LambdaHack.Common.HighScore.ScoreRecord


-- | The common server and client basic game state type and its operations.
module Game.LambdaHack.Common.State

-- | View on the basic game state. The <tt>remembered</tt> fields, in
--   client copies of the state, carry only a subset of the full
--   information that the server keeps. Clients never directly change their
--   <tt>State</tt>, but apply atomic actions sent by the server to do so
--   (and/or the server applies the actions to each client state in turn).
data State
sdungeon :: State -> Dungeon
stotalDepth :: State -> AbsDepth
sactorD :: State -> ActorDict
sitemD :: State -> ItemDict
sitemIxMap :: State -> ItemIxMap
sfactionD :: State -> FactionDict
stime :: State -> Time
scops :: State -> COps
shigh :: State -> ScoreDict
sgameModeId :: State -> Id ModeKind
sdiscoKind :: State -> DiscoveryKind
sdiscoAspect :: State -> DiscoveryAspect
sactorAspect :: State -> ActorAspect

-- | Initial complete global game state.
defStateGlobal :: Dungeon -> AbsDepth -> FactionDict -> COps -> ScoreDict -> Id ModeKind -> DiscoveryKind -> State

-- | Initial empty state.
emptyState :: COps -> State

-- | Local state created by removing secret information from global state
--   components.
localFromGlobal :: State -> State

-- | Update dungeon data within state.
updateDungeon :: (Dungeon -> Dungeon) -> State -> State

-- | Update dungeon depth.
updateDepth :: (AbsDepth -> AbsDepth) -> State -> State

-- | Update the actor dictionary.
updateActorD :: (ActorDict -> ActorDict) -> State -> State

-- | Update the item dictionary.
updateItemD :: (ItemDict -> ItemDict) -> State -> State

-- | Update the item kind index map.
updateItemIxMap :: (ItemIxMap -> ItemIxMap) -> State -> State

-- | Update faction data within state.
updateFactionD :: (FactionDict -> FactionDict) -> State -> State

-- | Update global time within state.
updateTime :: (Time -> Time) -> State -> State

-- | Update content data within state.
updateCOps :: (COps -> COps) -> State -> State
updateDiscoKind :: (DiscoveryKind -> DiscoveryKind) -> State -> State
updateDiscoAspect :: (DiscoveryAspect -> DiscoveryAspect) -> State -> State
updateActorAspect :: (ActorAspect -> ActorAspect) -> State -> State
getItemBody :: ItemId -> State -> Item
aspectRecordFromItem :: ItemId -> Item -> State -> AspectRecord
aspectRecordFromIid :: ItemId -> State -> AspectRecord
aspectRecordFromActor :: Actor -> State -> AspectRecord
actorAspectInDungeon :: State -> ActorAspect
unknownLevel :: COps -> AbsDepth -> X -> Y -> Text -> Text -> ([Point], [Point]) -> Int -> [Point] -> Bool -> Level
unknownTileMap :: Id TileKind -> Int -> Int -> TileMap
instance GHC.Classes.Eq Game.LambdaHack.Common.State.State
instance GHC.Show.Show Game.LambdaHack.Common.State.State
instance Data.Binary.Class.Binary Game.LambdaHack.Common.State.State


-- | Descripitons of items.
module Game.LambdaHack.Client.UI.ItemDescription

-- | The part of speech describing the item.
partItem :: FactionId -> FactionDict -> CStore -> Time -> ItemFull -> (Bool, Bool, Part, Part)
partItemShort :: FactionId -> FactionDict -> CStore -> Time -> ItemFull -> (Bool, Bool, Part, Part)
partItemHigh :: FactionId -> FactionDict -> CStore -> Time -> ItemFull -> (Bool, Bool, Part, Part)
partItemWs :: FactionId -> FactionDict -> Int -> CStore -> Time -> ItemFull -> Part
partItemWsRanged :: FactionId -> FactionDict -> Int -> CStore -> Time -> ItemFull -> Part
partItemShortAW :: FactionId -> FactionDict -> CStore -> Time -> ItemFull -> Part
partItemMediumAW :: FactionId -> FactionDict -> CStore -> Time -> ItemFull -> Part
partItemShortWownW :: FactionId -> FactionDict -> Part -> CStore -> Time -> ItemFull -> Part
viewItem :: Item -> AttrCharW32
itemDesc :: FactionId -> FactionDict -> Int -> CStore -> Time -> ItemFull -> AttrLine
show64With2 :: Int64 -> Text

-- | The part of speech describing the item parameterized by the number of
--   effects/aspects to show..
partItemN :: FactionId -> FactionDict -> Bool -> Int -> Int -> CStore -> Time -> ItemFull -> (Bool, Bool, Part, Part)
textAllAE :: Int -> Bool -> CStore -> ItemFull -> ([Text], [Text])
partItemWsR :: FactionId -> FactionDict -> Bool -> Int -> CStore -> Time -> ItemFull -> Part


-- | UI aspects of actors.
module Game.LambdaHack.Client.UI.ActorUI
data ActorUI
ActorUI :: Char -> Text -> Text -> Color -> ActorUI

-- | individual map symbol
[bsymbol] :: ActorUI -> Char

-- | individual name
[bname] :: ActorUI -> Text

-- | individual pronoun
[bpronoun] :: ActorUI -> Text

-- | individual map color
[bcolor] :: ActorUI -> Color
type ActorDictUI = EnumMap ActorId ActorUI
keySelected :: (ActorId, Actor, ActorUI) -> (Bool, Bool, Char, Color, ActorId)

-- | The part of speech describing the actor.
partActor :: ActorUI -> Part

-- | The part of speech containing the actor pronoun.
partPronoun :: ActorUI -> Part
ppContainer :: Container -> Text
ppCStore :: CStore -> (Text, Text)
ppCStoreIn :: CStore -> Text
ppCStoreWownW :: Bool -> CStore -> Part -> [Part]
ppContainerWownW :: (ActorId -> Part) -> Bool -> Container -> [Part]
verbCStore :: CStore -> Text
tryFindActor :: State -> (ActorId -> Actor -> Bool) -> Maybe (ActorId, Actor)
tryFindHeroK :: ActorDictUI -> FactionId -> Int -> State -> Maybe (ActorId, Actor)
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.ActorUI.ActorUI
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.ActorUI.ActorUI
instance GHC.Show.Show Game.LambdaHack.Client.UI.ActorUI.ActorUI
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.ActorUI.ActorUI


-- | Abstract syntax of requests.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Client.Request

-- | Requests sent by AI clients to the server. If faction leader is to be
--   changed, it's included as the second component.
type RequestAI = (ReqAI, Maybe ActorId)

-- | Possible forms of requests sent by AI clients.
data ReqAI
ReqAINop :: ReqAI
ReqAITimed :: RequestAnyAbility -> ReqAI

-- | Requests sent by UI clients to the server. If faction leader is to be
--   changed, it's included as the second component.
type RequestUI = (ReqUI, Maybe ActorId)

-- | Possible forms of requests sent by UI clients.
data ReqUI
ReqUINop :: ReqUI
ReqUITimed :: RequestAnyAbility -> ReqUI
ReqUIGameRestart :: (GroupName ModeKind) -> Challenge -> ReqUI
ReqUIGameExit :: ReqUI
ReqUIGameSave :: ReqUI
ReqUITactic :: Tactic -> ReqUI
ReqUIAutomate :: ReqUI

-- | Basic form of requests, sent by both AI and UI clients to the server.
data RequestAnyAbility
RequestAnyAbility :: (RequestTimed a) -> RequestAnyAbility

-- | Requests that take game time, indexed by actor ability that is needed
--   for performing the corresponding actions.
data RequestTimed :: Ability -> *
[ReqMove] :: Vector -> RequestTimed  'AbMove
[ReqMelee] :: ActorId -> ItemId -> CStore -> RequestTimed  'AbMelee
[ReqDisplace] :: ActorId -> RequestTimed  'AbDisplace
[ReqAlter] :: Point -> RequestTimed  'AbAlter
[ReqWait] :: RequestTimed  'AbWait
[ReqWait10] :: RequestTimed  'AbWait
[ReqMoveItems] :: [(ItemId, Int, CStore, CStore)] -> RequestTimed  'AbMoveItem
[ReqProject] :: Point -> Int -> ItemId -> CStore -> RequestTimed  'AbProject
[ReqApply] :: ItemId -> CStore -> RequestTimed  'AbApply
instance GHC.Show.Show Game.LambdaHack.Client.Request.ReqAI
instance GHC.Show.Show Game.LambdaHack.Client.Request.ReqUI
instance GHC.Show.Show Game.LambdaHack.Client.Request.RequestAnyAbility
instance GHC.Show.Show (Game.LambdaHack.Client.Request.RequestTimed a)


-- | Actor preferences for targets and actions, based on actor attributes.
module Game.LambdaHack.Client.Preferences

-- | Compute the whole <a>Benefit</a> structure, containing various facets
--   of AI item preference, for an item with the given effects and aspects.
--   
--   Note: result has non-strict fields, so arguments are forced to avoid
--   leaks. When AI looks at items (including organs) more often, force the
--   fields.
totalUsefulness :: COps -> Faction -> [Effect] -> AspectRecord -> Item -> Benefit

-- | How much AI benefits from applying the effect. The first component is
--   benefit when applied to self, the second is benefit (preferably
--   negative) when applied to enemy. This represents benefit from using
--   the effect every <tt>avgItemDelay</tt> turns, so if the item is not
--   durable, the value is adjusted down elsewhere. The benefit includes
--   the drawback of having to use the actor's turn, except when there is
--   battle and item is a weapon and so there is usually nothing better to
--   do than to melee, or when the actor is stuck or idle or laying in wait
--   or luring an enemy from a safe distance. So there is less than
--   <tt>averageTurnValue</tt> included in each benefit, so in case when
--   turn is not spent, e.g, periodic or temporary effects, the difference
--   in value is only slight.
effectToBenefit :: COps -> Faction -> Effect -> (Double, Double)
averageTurnValue :: Double
avgItemDelay :: Double
avgItemLife :: Double
durabilityMult :: Double
organBenefit :: Double -> GroupName ItemKind -> COps -> Faction -> (Double, Int)
recBenefit :: GroupName ItemKind -> COps -> Faction -> (Double, Int)
fakeItem :: ItemKind -> Item
aspectToBenefit :: Aspect -> Double
recordToBenefit :: AspectRecord -> [Double]


-- | Operations on the <a>Actor</a> type, and related, that need the
--   <a>State</a> type, but not our custom monad types.
module Game.LambdaHack.Common.ActorState
fidActorNotProjAssocs :: FactionId -> State -> [(ActorId, Actor)]
actorAssocs :: (FactionId -> Bool) -> LevelId -> State -> [(ActorId, Actor)]
actorRegularAssocs :: (FactionId -> Bool) -> LevelId -> State -> [(ActorId, Actor)]
warActorRegularList :: FactionId -> LevelId -> State -> [Actor]
friendlyActorRegularList :: FactionId -> LevelId -> State -> [Actor]
fidActorRegularIds :: FactionId -> LevelId -> State -> [ActorId]
bagAssocs :: State -> ItemBag -> [(ItemId, Item)]
bagAssocsK :: State -> ItemBag -> [(ItemId, (Item, ItemQuant))]
posToAidsLvl :: Point -> Level -> [ActorId]
posToAids :: Point -> LevelId -> State -> [ActorId]
posToAssocs :: Point -> LevelId -> State -> [(ActorId, Actor)]
nearbyFreePoints :: (Id TileKind -> Bool) -> Point -> LevelId -> State -> [Point]

-- | Calculate loot's worth for a given faction.
calculateTotal :: FactionId -> State -> (ItemBag, Int)
mergeItemQuant :: ItemQuant -> ItemQuant -> ItemQuant
sharedInv :: FactionId -> State -> ItemBag
sharedEqp :: FactionId -> State -> ItemBag
sharedAllOwned :: FactionId -> State -> ItemBag
sharedAllOwnedFid :: Bool -> FactionId -> State -> ItemBag
findIid :: ActorId -> FactionId -> ItemId -> State -> [(ActorId, (Actor, CStore))]
getActorBody :: ActorId -> State -> Actor
getActorAspect :: ActorId -> State -> AspectRecord
getCarriedAssocs :: Actor -> State -> [(ItemId, Item)]
getCarriedIidCStore :: Actor -> [(ItemId, CStore)]
getContainerBag :: Container -> State -> ItemBag
getFloorBag :: LevelId -> Point -> State -> ItemBag
getEmbedBag :: LevelId -> Point -> State -> ItemBag
getBodyStoreBag :: Actor -> CStore -> State -> ItemBag
mapActorItems_ :: Monad m => (CStore -> ItemId -> ItemQuant -> m a) -> Actor -> State -> m ()
getActorAssocs :: ActorId -> CStore -> State -> [(ItemId, Item)]
getActorAssocsK :: ActorId -> CStore -> State -> [(ItemId, (Item, ItemQuant))]

-- | Checks if the actor is present on the current level. The order of
--   argument here and in other functions is set to allow
--   
--   <pre>
--   b &lt;- getsState (memActor a)
--   </pre>
memActor :: ActorId -> LevelId -> State -> Bool

-- | Get current time from the dungeon data.
getLocalTime :: LevelId -> State -> Time
regenCalmDelta :: Actor -> AspectRecord -> State -> Int64
actorInAmbient :: Actor -> State -> Bool
canDeAmbientList :: Actor -> State -> [Point]
actorSkills :: Maybe ActorId -> ActorId -> State -> Skills
dispEnemy :: ActorId -> ActorId -> Skills -> State -> Bool
itemToFull :: State -> ItemId -> ItemQuant -> ItemFull
fullAssocs :: ActorId -> [CStore] -> State -> [(ItemId, ItemFull)]
storeFromC :: Container -> CStore
aidFromC :: Container -> Maybe ActorId

-- | Determine the dungeon level of the container. If the item is in a
--   shared stash, the level depends on which actor asks.
lidFromC :: Container -> State -> LevelId
posFromC :: Container -> State -> Point
isEscape :: LevelId -> Point -> State -> Bool
isStair :: LevelId -> Point -> State -> Bool

-- | Require that any non-dying foe is adjacent. We include even
--   projectiles that explode when stricken down, because they can be
--   caught and then they don't explode, so it makes sense to focus on
--   handling them. If there are many projectiles in a single adjacent
--   position, we only test the first one, the one that would be hit in
--   melee (this is not optimal if the actor would need to flee instead of
--   meleeing, but fleeing with *many* projectiles adjacent is a possible
--   waste of a move anyway).
anyFoeAdj :: ActorId -> State -> Bool
actorAdjacentAssocs :: Actor -> State -> [(ActorId, Actor)]
armorHurtBonus :: ActorId -> ActorId -> State -> Int
inMelee :: Actor -> State -> Bool


-- | Game state reading monad and basic operations.
module Game.LambdaHack.Common.MonadStateRead

-- | Monad for reading game state. A state monad with state modification
--   disallowed (another constraint is needed to permit that). The basic
--   server and client monads are like that, because server and clients
--   freely modify their internal session data, but don't modify the main
--   game state, except in very restricted and synchronized way.
class (Monad m, Functor m, Applicative m) => MonadStateRead m
getsState :: MonadStateRead m => (State -> a) -> m a
getState :: MonadStateRead m => m State
getLevel :: MonadStateRead m => LevelId -> m Level
nUI :: MonadStateRead m => m Int
getGameMode :: MonadStateRead m => m ModeKind
isNoConfirmsGame :: MonadStateRead m => m Bool
getEntryArena :: MonadStateRead m => Faction -> m LevelId
pickWeaponM :: MonadStateRead m => Maybe DiscoveryBenefit -> [(ItemId, ItemFull)] -> Skills -> ActorId -> m [(Double, (ItemId, ItemFull))]


-- | Item slots for UI and AI item collections.
module Game.LambdaHack.Client.UI.ItemSlot

-- | Slot label. Usually just a character. Sometimes with a numerical
--   prefix.
data SlotChar
SlotChar :: Int -> Char -> SlotChar
[slotPrefix] :: SlotChar -> Int
[slotChar] :: SlotChar -> Char

-- | Mapping from slot labels to item identifiers.
data ItemSlots
ItemSlots :: EnumMap SlotChar ItemId -> EnumMap SlotChar ItemId -> ItemSlots
[itemSlots] :: ItemSlots -> EnumMap SlotChar ItemId
[organSlots] :: ItemSlots -> EnumMap SlotChar ItemId
allSlots :: Int -> [SlotChar]
allZeroSlots :: [SlotChar]
intSlots :: [SlotChar]
slotLabel :: SlotChar -> Text

-- | Assigns a slot to an item, for inclusion in the inventory of a hero.
--   Tries to to use the requested slot, if any.
assignSlot :: CStore -> Item -> FactionId -> Maybe Actor -> ItemSlots -> SlotChar -> State -> SlotChar
instance GHC.Show.Show Game.LambdaHack.Client.UI.ItemSlot.ItemSlots
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.ItemSlot.SlotChar
instance GHC.Show.Show Game.LambdaHack.Client.UI.ItemSlot.SlotChar
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.ItemSlot.ItemSlots
instance GHC.Classes.Ord Game.LambdaHack.Client.UI.ItemSlot.SlotChar
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.ItemSlot.SlotChar
instance GHC.Enum.Enum Game.LambdaHack.Client.UI.ItemSlot.SlotChar


-- | Slideshows.
module Game.LambdaHack.Client.UI.Slideshow

-- | A key or an item slot label at a given position on the screen.
type KYX = (Either [KM] SlotChar, (Y, X, X))

-- | An Overlay of text with an associated list of keys or slots that
--   activated when the specified screen position is pointed at. The list
--   should be sorted wrt rows and then columns.
type OKX = (Overlay, [KYX])

-- | A list of active screenfulls to be shown one after another. Each
--   screenful has an independent numbering of rows and columns.
data Slideshow
emptySlideshow :: Slideshow
unsnoc :: Slideshow -> Maybe (Slideshow, OKX)
toSlideshow :: [OKX] -> Slideshow
menuToSlideshow :: OKX -> Slideshow
wrapOKX :: Y -> X -> X -> [(KM, String)] -> OKX
splitOverlay :: X -> Y -> Report -> [KM] -> OKX -> Slideshow
splitOKX :: X -> Y -> AttrLine -> [KM] -> OKX -> [OKX]
moreMsg :: String
endMsg :: String
keysOKX :: Y -> X -> X -> [KM] -> OKX
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Slideshow.Slideshow
instance GHC.Show.Show Game.LambdaHack.Client.UI.Slideshow.Slideshow


-- | The monad for writing to the main game state.
module Game.LambdaHack.Atomic.MonadStateWrite

-- | The monad for writing to the main game state. Atomic updates
--   (<tt>UpdAtomic</tt>) are given semantics in this monad.
class MonadStateRead m => MonadStateWrite m
modifyState :: MonadStateWrite m => (State -> State) -> m ()

-- | Exception signifying that atomic action failed because the information
--   it carries is inconsistent with the client's state, (e.g., because the
--   client knows too little to understand the command or already deduced
--   the state change from earlier commands or is confused, amnesiac or
--   sees illusory actors or tiles). Whenever we know the failure is
--   logically impossible, we don't throw the <tt>AtomicFail</tt>
--   exception, but insert a normal assertion or <tt>error</tt> call, which
--   are never caught nor handled.
newtype AtomicFail
AtomicFail :: String -> AtomicFail
atomicFail :: String -> a
putState :: MonadStateWrite m => State -> m ()
updateLevel :: MonadStateWrite m => LevelId -> (Level -> Level) -> m ()
updateActor :: MonadStateWrite m => ActorId -> (Actor -> Actor) -> m ()
updateFaction :: MonadStateWrite m => FactionId -> (Faction -> Faction) -> m ()
moveActorMap :: MonadStateWrite m => ActorId -> Actor -> Actor -> m ()
insertBagContainer :: MonadStateWrite m => ItemBag -> Container -> m ()
insertItemContainer :: MonadStateWrite m => ItemId -> ItemQuant -> Container -> m ()
insertItemActor :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> CStore -> m ()
deleteBagContainer :: MonadStateWrite m => ItemBag -> Container -> m ()
deleteItemContainer :: MonadStateWrite m => ItemId -> ItemQuant -> Container -> m ()
deleteItemActor :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> CStore -> m ()
addAis :: MonadStateWrite m => [(ItemId, Item)] -> m ()
itemsMatch :: Item -> Item -> Bool
addItemToActor :: MonadStateWrite m => ItemId -> Item -> Int -> ActorId -> m ()
resetActorAspect :: MonadStateWrite m => m ()
insertItemFloor :: MonadStateWrite m => ItemId -> ItemQuant -> LevelId -> Point -> m ()
insertItemEmbed :: MonadStateWrite m => ItemId -> ItemQuant -> LevelId -> Point -> m ()
insertItemOrgan :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> m ()
insertItemEqp :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> m ()
insertItemInv :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> m ()
insertItemSha :: MonadStateWrite m => ItemId -> ItemQuant -> FactionId -> m ()
deleteItemFloor :: MonadStateWrite m => ItemId -> ItemQuant -> LevelId -> Point -> m ()
deleteItemEmbed :: MonadStateWrite m => ItemId -> ItemQuant -> LevelId -> Point -> m ()
deleteItemOrgan :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> m ()
deleteItemEqp :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> m ()
deleteItemInv :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> m ()
deleteItemSha :: MonadStateWrite m => ItemId -> ItemQuant -> FactionId -> m ()
rmFromBag :: ItemQuant -> ItemId -> ItemBag -> ItemBag
instance GHC.Show.Show Game.LambdaHack.Atomic.MonadStateWrite.AtomicFail
instance GHC.Exception.Exception Game.LambdaHack.Atomic.MonadStateWrite.AtomicFail


-- | Abstract syntax of human player commands.
module Game.LambdaHack.Client.UI.HumanCmd
data CmdCategory
CmdMainMenu :: CmdCategory
CmdItemMenu :: CmdCategory
CmdMove :: CmdCategory
CmdItem :: CmdCategory
CmdAim :: CmdCategory
CmdMeta :: CmdCategory
CmdMouse :: CmdCategory
CmdInternal :: CmdCategory
CmdNoHelp :: CmdCategory
CmdDebug :: CmdCategory
CmdMinimal :: CmdCategory
categoryDescription :: CmdCategory -> Text

-- | Symbolic representation of areas of the screen used to define the
--   meaning of mouse button presses relative to where the mouse points to.
data CmdArea
CaMessage :: CmdArea
CaMapLeader :: CmdArea
CaMapParty :: CmdArea
CaMap :: CmdArea
CaLevelNumber :: CmdArea
CaArenaName :: CmdArea
CaPercentSeen :: CmdArea
CaXhairDesc :: CmdArea
CaSelected :: CmdArea
CaCalmGauge :: CmdArea
CaHPGauge :: CmdArea
CaTargetDesc :: CmdArea
areaDescription :: CmdArea -> Text

-- | This triple of command categories, description and the command term
--   itself defines the meaning of a human command as entered via a
--   keypress, mouse click or chosen from a menu.
type CmdTriple = ([CmdCategory], Text, HumanCmd)

-- | Abstract syntax of human player commands.
data HumanCmd
Macro :: [String] -> HumanCmd
ByArea :: [(CmdArea, HumanCmd)] -> HumanCmd
ByAimMode :: HumanCmd -> HumanCmd -> HumanCmd
[exploration] :: HumanCmd -> HumanCmd
[aiming] :: HumanCmd -> HumanCmd
ByItemMode :: [Trigger] -> HumanCmd -> HumanCmd -> HumanCmd
[ts] :: HumanCmd -> [Trigger]
[notChosen] :: HumanCmd -> HumanCmd
[chosen] :: HumanCmd -> HumanCmd
ComposeIfLocal :: HumanCmd -> HumanCmd -> HumanCmd
ComposeUnlessError :: HumanCmd -> HumanCmd -> HumanCmd
Compose2ndLocal :: HumanCmd -> HumanCmd -> HumanCmd
LoopOnNothing :: HumanCmd -> HumanCmd
Wait :: HumanCmd
Wait10 :: HumanCmd
MoveDir :: Vector -> HumanCmd
RunDir :: Vector -> HumanCmd
RunOnceAhead :: HumanCmd
MoveOnceToXhair :: HumanCmd
RunOnceToXhair :: HumanCmd
ContinueToXhair :: HumanCmd
MoveItem :: [CStore] -> CStore -> (Maybe Part) -> Bool -> HumanCmd
Project :: [Trigger] -> HumanCmd
Apply :: [Trigger] -> HumanCmd
AlterDir :: [Trigger] -> HumanCmd
AlterWithPointer :: [Trigger] -> HumanCmd
Help :: HumanCmd
ItemMenu :: HumanCmd
MainMenu :: HumanCmd
GameDifficultyIncr :: HumanCmd
GameWolfToggle :: HumanCmd
GameFishToggle :: HumanCmd
GameScenarioIncr :: HumanCmd
GameRestart :: HumanCmd
GameExit :: HumanCmd
GameSave :: HumanCmd
Tactic :: HumanCmd
Automate :: HumanCmd
Clear :: HumanCmd
SortSlots :: HumanCmd
ChooseItem :: ItemDialogMode -> HumanCmd
ChooseItemMenu :: ItemDialogMode -> HumanCmd
ChooseItemProject :: [Trigger] -> HumanCmd
ChooseItemApply :: [Trigger] -> HumanCmd
PickLeader :: Int -> HumanCmd
PickLeaderWithPointer :: HumanCmd
MemberCycle :: HumanCmd
MemberBack :: HumanCmd
SelectActor :: HumanCmd
SelectNone :: HumanCmd
SelectWithPointer :: HumanCmd
Repeat :: Int -> HumanCmd
Record :: HumanCmd
History :: HumanCmd
MarkVision :: HumanCmd
MarkSmell :: HumanCmd
MarkSuspect :: HumanCmd
SettingsMenu :: HumanCmd
ChallengesMenu :: HumanCmd
Cancel :: HumanCmd
Accept :: HumanCmd
TgtClear :: HumanCmd
ItemClear :: HumanCmd
MoveXhair :: Vector -> Int -> HumanCmd
AimTgt :: HumanCmd
AimFloor :: HumanCmd
AimEnemy :: HumanCmd
AimItem :: HumanCmd
AimAscend :: Int -> HumanCmd
EpsIncr :: Bool -> HumanCmd
XhairUnknown :: HumanCmd
XhairItem :: HumanCmd
XhairStair :: Bool -> HumanCmd
XhairPointerFloor :: HumanCmd
XhairPointerEnemy :: HumanCmd
AimPointerFloor :: HumanCmd
AimPointerEnemy :: HumanCmd

-- | Description of how item manipulation is triggered and communicated to
--   the player.
data Trigger
ApplyItem :: Part -> Part -> Char -> Trigger
[verb] :: Trigger -> Part
[object] :: Trigger -> Part
[symbol] :: Trigger -> Char
AlterFeature :: Part -> Part -> Feature -> Trigger
[verb] :: Trigger -> Part
[object] :: Trigger -> Part
[feature] :: Trigger -> Feature
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.HumanCmd.HumanCmd
instance GHC.Classes.Ord Game.LambdaHack.Client.UI.HumanCmd.HumanCmd
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.HumanCmd.HumanCmd
instance GHC.Read.Read Game.LambdaHack.Client.UI.HumanCmd.HumanCmd
instance GHC.Show.Show Game.LambdaHack.Client.UI.HumanCmd.HumanCmd
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.HumanCmd.Trigger
instance GHC.Classes.Ord Game.LambdaHack.Client.UI.HumanCmd.Trigger
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.HumanCmd.Trigger
instance GHC.Show.Show Game.LambdaHack.Client.UI.HumanCmd.Trigger
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.HumanCmd.CmdArea
instance GHC.Classes.Ord Game.LambdaHack.Client.UI.HumanCmd.CmdArea
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.HumanCmd.CmdArea
instance GHC.Read.Read Game.LambdaHack.Client.UI.HumanCmd.CmdArea
instance GHC.Show.Show Game.LambdaHack.Client.UI.HumanCmd.CmdArea
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.HumanCmd.CmdCategory
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.HumanCmd.CmdCategory
instance GHC.Read.Read Game.LambdaHack.Client.UI.HumanCmd.CmdCategory
instance GHC.Show.Show Game.LambdaHack.Client.UI.HumanCmd.CmdCategory
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.HumanCmd.HumanCmd
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.HumanCmd.HumanCmd
instance GHC.Read.Read Game.LambdaHack.Client.UI.HumanCmd.Trigger
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.HumanCmd.Trigger
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.HumanCmd.Trigger
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.HumanCmd.CmdArea
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.HumanCmd.CmdArea
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.HumanCmd.CmdCategory
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.HumanCmd.CmdCategory


-- | UI client options.
module Game.LambdaHack.Client.UI.UIOptions

-- | Options that affect the UI of the client.
data UIOptions
UIOptions :: [(KM, CmdTriple)] -> [(Int, (Text, Text))] -> Bool -> Bool -> Text -> Text -> Int -> Int -> Int -> Bool -> Int -> Int -> Bool -> Bool -> [String] -> UIOptions
[uCommands] :: UIOptions -> [(KM, CmdTriple)]
[uHeroNames] :: UIOptions -> [(Int, (Text, Text))]

-- | the option for Vi keys takes precendence
[uVi] :: UIOptions -> Bool

-- | because the laptop keys are the default
[uLaptop] :: UIOptions -> Bool
[uGtkFontFamily] :: UIOptions -> Text
[uSdlFontFile] :: UIOptions -> Text
[uSdlTtfSizeAdd] :: UIOptions -> Int
[uSdlFonSizeAdd] :: UIOptions -> Int
[uFontSize] :: UIOptions -> Int
[uColorIsBold] :: UIOptions -> Bool
[uHistoryMax] :: UIOptions -> Int
[uMaxFps] :: UIOptions -> Int
[uNoAnim] :: UIOptions -> Bool
[uRunStopMsgs] :: UIOptions -> Bool

-- | Hardwired commandline arguments to process.
[uCmdline] :: UIOptions -> [String]

-- | Read and parse UI config file.
mkUIOptions :: COps -> Bool -> IO UIOptions

-- | Modify client options with UI options.
applyUIOptions :: COps -> UIOptions -> ClientOptions -> ClientOptions
parseConfig :: Config -> UIOptions
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.UIOptions.UIOptions
instance GHC.Show.Show Game.LambdaHack.Client.UI.UIOptions.UIOptions
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.UIOptions.UIOptions
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.UIOptions.UIOptions


-- | The type of definitions of key-command mappings to be used for the UI
--   and shorthands for specifying command triples in the content files.
module Game.LambdaHack.Client.UI.Content.KeyKind

-- | Key-command mappings to be specified in content and used for the UI.
newtype KeyKind

-- | default client UI commands
KeyKind :: [(KM, CmdTriple)] -> KeyKind
evalKeyDef :: (String, CmdTriple) -> (KM, CmdTriple)
addCmdCategory :: CmdCategory -> CmdTriple -> CmdTriple
replaceDesc :: Text -> CmdTriple -> CmdTriple
moveItemTriple :: [CStore] -> CStore -> Part -> Bool -> CmdTriple
repeatTriple :: Int -> CmdTriple
mouseLMB :: CmdTriple
mouseMMB :: CmdTriple
mouseRMB :: CmdTriple
goToCmd :: HumanCmd
runToAllCmd :: HumanCmd
autoexploreCmd :: HumanCmd
autoexplore25Cmd :: HumanCmd
aimFlingCmd :: HumanCmd
projectI :: [Trigger] -> CmdTriple
projectA :: [Trigger] -> CmdTriple
flingTs :: [Trigger]
applyIK :: [Trigger] -> CmdTriple
applyI :: [Trigger] -> CmdTriple
grabItems :: Text -> CmdTriple
dropItems :: Text -> CmdTriple
descTs :: [Trigger] -> Text
defaultHeroSelect :: Int -> (String, CmdTriple)
replaceCmd :: HumanCmd -> CmdTriple -> CmdTriple
projectICmd :: [Trigger] -> HumanCmd
grabCmd :: HumanCmd
dropCmd :: HumanCmd


-- | Verifying, aggregating and displaying binding of keys to commands.
module Game.LambdaHack.Client.UI.KeyBindings

-- | Bindings and other information about human player commands.
data Binding
Binding :: Map KM CmdTriple -> [(KM, CmdTriple)] -> Map HumanCmd [KM] -> Binding

-- | binding of keys to commands
[bcmdMap] :: Binding -> Map KM CmdTriple

-- | the properly ordered list of commands for the help menu
[bcmdList] :: Binding -> [(KM, CmdTriple)]

-- | and from commands to their keys
[brevMap] :: Binding -> Map HumanCmd [KM]

-- | Create binding of keys to movement and other standard commands, as
--   well as commands defined in the config file.
stdBinding :: KeyKind -> UIOptions -> Binding

-- | Produce a set of help/menu screens from the key bindings.
keyHelp :: Binding -> Int -> [(Text, OKX)]

-- | Turn the specified portion of bindings into a menu.
okxsN :: Binding -> Int -> Int -> (HumanCmd -> Bool) -> CmdCategory -> [Text] -> [Text] -> OKX


-- | The client UI session state.
module Game.LambdaHack.Client.UI.SessionUI

-- | The information that is used across a client playing session,
--   including many consecutive games in a single session. Some of it is
--   saved, some is reset when a new playing session starts. An important
--   component is the frontend session.
data SessionUI
SessionUI :: Target -> ActorDictUI -> ItemSlots -> SlotChar -> Maybe (CStore, CStore) -> ChanFrontend -> Binding -> UIOptions -> Maybe AimMode -> Bool -> Maybe (CStore, ItemId) -> EnumSet ActorId -> Maybe RunParams -> Report -> History -> Point -> LastRecord -> [KM] -> EnumSet ActorId -> Int -> Bool -> Bool -> Map String Int -> Bool -> KeysHintMode -> POSIXTime -> POSIXTime -> Time -> Int -> Int -> SessionUI

-- | the common xhair
[sxhair] :: SessionUI -> Target

-- | assigned actor UI presentations
[sactorUI] :: SessionUI -> ActorDictUI

-- | map from slots to items
[sslots] :: SessionUI -> ItemSlots

-- | last used slot
[slastSlot] :: SessionUI -> SlotChar

-- | last item move stores
[slastItemMove] :: SessionUI -> Maybe (CStore, CStore)

-- | connection with the frontend
[schanF] :: SessionUI -> ChanFrontend

-- | binding of keys to commands
[sbinding] :: SessionUI -> Binding

-- | UI options as set by the player
[sUIOptions] :: SessionUI -> UIOptions

-- | aiming mode
[saimMode] :: SessionUI -> Maybe AimMode

-- | last mouse aiming not vacuus
[sxhairMoused] :: SessionUI -> Bool

-- | selected item, if any
[sitemSel] :: SessionUI -> Maybe (CStore, ItemId)

-- | the set of currently selected actors
[sselected] :: SessionUI -> EnumSet ActorId

-- | parameters of the current run, if any
[srunning] :: SessionUI -> Maybe RunParams

-- | current messages
[_sreport] :: SessionUI -> Report

-- | history of messages
[shistory] :: SessionUI -> History

-- | mouse pointer position
[spointer] :: SessionUI -> Point

-- | state of key sequence recording
[slastRecord] :: SessionUI -> LastRecord

-- | state of key sequence playback
[slastPlay] :: SessionUI -> [KM]

-- | actors that just got out of sight
[slastLost] :: SessionUI -> EnumSet ActorId

-- | player just waited this many times
[swaitTimes] :: SessionUI -> Int

-- | mark leader and party FOV
[smarkVision] :: SessionUI -> Bool

-- | mark smell, if the leader can smell
[smarkSmell] :: SessionUI -> Bool

-- | indices of last used menu items
[smenuIxMap] :: SessionUI -> Map String Int

-- | current level needs displaying
[sdisplayNeeded] :: SessionUI -> Bool

-- | how to show keys hints when no messages
[skeysHintMode] :: SessionUI -> KeysHintMode

-- | this session start time
[sstart] :: SessionUI -> POSIXTime

-- | this game start time
[sgstart] :: SessionUI -> POSIXTime

-- | clips from start of session to current game start
[sallTime] :: SessionUI -> Time

-- | this game current frame count
[snframes] :: SessionUI -> Int

-- | frame count from start of session to current game start
[sallNframes] :: SessionUI -> Int

-- | Current aiming mode of a client.
newtype AimMode
AimMode :: LevelId -> AimMode
[aimLevelId] :: AimMode -> LevelId

-- | Parameters of the current run.
data RunParams
RunParams :: ActorId -> [ActorId] -> Bool -> Maybe Text -> Int -> RunParams

-- | the original leader from run start
[runLeader] :: RunParams -> ActorId

-- | the list of actors that take part
[runMembers] :: RunParams -> [ActorId]

-- | initial run continuation by any run participant, including run leader
[runInitial] :: RunParams -> Bool

-- | message with the next stop reason
[runStopMsg] :: RunParams -> Maybe Text

-- | waiting for others to move out of the way
[runWaiting] :: RunParams -> Int

-- | State of last recorded and currently being recorded key sequences.
data LastRecord
LastRecord :: [KM] -> [KM] -> Int -> LastRecord

-- | accumulated keys of the current command
[currentKeys] :: LastRecord -> [KM]

-- | keys of the rest of the recorded command batch
[previousKeys] :: LastRecord -> [KM]

-- | space left for commands to record in this batch
[freeSpace] :: LastRecord -> Int
data KeysHintMode
KeysHintBlocked :: KeysHintMode
KeysHintAbsent :: KeysHintMode
KeysHintPresent :: KeysHintMode
sreport :: SessionUI -> Report
emptySessionUI :: UIOptions -> SessionUI
toggleMarkVision :: SessionUI -> SessionUI
toggleMarkSmell :: SessionUI -> SessionUI
getActorUI :: ActorId -> SessionUI -> ActorUI
instance GHC.Enum.Bounded Game.LambdaHack.Client.UI.SessionUI.KeysHintMode
instance GHC.Enum.Enum Game.LambdaHack.Client.UI.SessionUI.KeysHintMode
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.SessionUI.KeysHintMode
instance GHC.Show.Show Game.LambdaHack.Client.UI.SessionUI.RunParams
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.SessionUI.AimMode
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.SessionUI.AimMode
instance GHC.Show.Show Game.LambdaHack.Client.UI.SessionUI.AimMode
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.SessionUI.SessionUI
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.SessionUI.RunParams


-- | A set of atomic commands shared by client and server. These are the
--   largest building blocks that have no components that can be observed
--   in isolation.
--   
--   We try to make atomic commands respect the laws of energy and mass
--   conservation, unless they really can't, e.g., monster spawning. For
--   example item removal from inventory is not an atomic command, but item
--   dropped from the inventory to the ground is. This makes it easier to
--   undo the commands. In principle, the commands are the only way to
--   affect the basic game state (<a>State</a>).
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Atomic.CmdAtomic

-- | Abstract syntax of atomic commands, that is, atomic game state
--   transformations.
data CmdAtomic

-- | atomic updates
UpdAtomic :: UpdAtomic -> CmdAtomic

-- | atomic special effects
SfxAtomic :: SfxAtomic -> CmdAtomic

-- | Abstract syntax of atomic updates, that is, atomic commands that
--   really change the <a>State</a>. Most of them are an encoding of a game
--   state diff, though they also carry some intentional hints that help
--   clients determine whether and how to communicate it to players.
data UpdAtomic
UpdCreateActor :: ActorId -> Actor -> [(ItemId, Item)] -> UpdAtomic
UpdDestroyActor :: ActorId -> Actor -> [(ItemId, Item)] -> UpdAtomic
UpdCreateItem :: ItemId -> Item -> ItemQuant -> Container -> UpdAtomic
UpdDestroyItem :: ItemId -> Item -> ItemQuant -> Container -> UpdAtomic
UpdSpotActor :: ActorId -> Actor -> [(ItemId, Item)] -> UpdAtomic
UpdLoseActor :: ActorId -> Actor -> [(ItemId, Item)] -> UpdAtomic
UpdSpotItem :: Bool -> ItemId -> Item -> ItemQuant -> Container -> UpdAtomic
UpdLoseItem :: Bool -> ItemId -> Item -> ItemQuant -> Container -> UpdAtomic
UpdSpotItemBag :: Container -> ItemBag -> [(ItemId, Item)] -> UpdAtomic
UpdLoseItemBag :: Container -> ItemBag -> [(ItemId, Item)] -> UpdAtomic
UpdMoveActor :: ActorId -> Point -> Point -> UpdAtomic
UpdWaitActor :: ActorId -> Bool -> UpdAtomic
UpdDisplaceActor :: ActorId -> ActorId -> UpdAtomic
UpdMoveItem :: ItemId -> Int -> ActorId -> CStore -> CStore -> UpdAtomic
UpdRefillHP :: ActorId -> Int64 -> UpdAtomic
UpdRefillCalm :: ActorId -> Int64 -> UpdAtomic
UpdTrajectory :: ActorId -> (Maybe ([Vector], Speed)) -> (Maybe ([Vector], Speed)) -> UpdAtomic
UpdQuitFaction :: FactionId -> (Maybe Status) -> (Maybe Status) -> UpdAtomic
UpdLeadFaction :: FactionId -> (Maybe ActorId) -> (Maybe ActorId) -> UpdAtomic
UpdDiplFaction :: FactionId -> FactionId -> Diplomacy -> Diplomacy -> UpdAtomic
UpdTacticFaction :: FactionId -> Tactic -> Tactic -> UpdAtomic
UpdAutoFaction :: FactionId -> Bool -> UpdAtomic
UpdRecordKill :: ActorId -> (Id ItemKind) -> Int -> UpdAtomic
UpdAlterTile :: LevelId -> Point -> (Id TileKind) -> (Id TileKind) -> UpdAtomic
UpdAlterExplorable :: LevelId -> Int -> UpdAtomic
UpdSearchTile :: ActorId -> Point -> (Id TileKind) -> UpdAtomic
UpdHideTile :: ActorId -> Point -> (Id TileKind) -> UpdAtomic
UpdSpotTile :: LevelId -> [(Point, Id TileKind)] -> UpdAtomic
UpdLoseTile :: LevelId -> [(Point, Id TileKind)] -> UpdAtomic
UpdAlterSmell :: LevelId -> Point -> Time -> Time -> UpdAtomic
UpdSpotSmell :: LevelId -> [(Point, Time)] -> UpdAtomic
UpdLoseSmell :: LevelId -> [(Point, Time)] -> UpdAtomic
UpdTimeItem :: ItemId -> Container -> ItemTimer -> ItemTimer -> UpdAtomic
UpdAgeGame :: [LevelId] -> UpdAtomic
UpdUnAgeGame :: [LevelId] -> UpdAtomic
UpdDiscover :: Container -> ItemId -> (Id ItemKind) -> ItemSeed -> UpdAtomic
UpdCover :: Container -> ItemId -> (Id ItemKind) -> ItemSeed -> UpdAtomic
UpdDiscoverKind :: Container -> ItemKindIx -> (Id ItemKind) -> UpdAtomic
UpdCoverKind :: Container -> ItemKindIx -> (Id ItemKind) -> UpdAtomic
UpdDiscoverSeed :: Container -> ItemId -> ItemSeed -> UpdAtomic
UpdCoverSeed :: Container -> ItemId -> ItemSeed -> UpdAtomic
UpdDiscoverServer :: ItemId -> AspectRecord -> UpdAtomic
UpdCoverServer :: ItemId -> AspectRecord -> UpdAtomic
UpdPerception :: LevelId -> Perception -> Perception -> UpdAtomic
UpdRestart :: FactionId -> PerLid -> State -> Challenge -> ClientOptions -> UpdAtomic
UpdRestartServer :: State -> UpdAtomic
UpdResume :: FactionId -> PerLid -> UpdAtomic
UpdResumeServer :: State -> UpdAtomic
UpdKillExit :: FactionId -> UpdAtomic
UpdWriteSave :: UpdAtomic

-- | Abstract syntax of atomic special effects, that is, atomic commands
--   that only display special effects and don't change <a>State</a>.
data SfxAtomic
SfxStrike :: ActorId -> ActorId -> ItemId -> CStore -> SfxAtomic
SfxRecoil :: ActorId -> ActorId -> ItemId -> CStore -> SfxAtomic
SfxSteal :: ActorId -> ActorId -> ItemId -> CStore -> SfxAtomic
SfxRelease :: ActorId -> ActorId -> ItemId -> CStore -> SfxAtomic
SfxProject :: ActorId -> ItemId -> CStore -> SfxAtomic
SfxReceive :: ActorId -> ItemId -> CStore -> SfxAtomic
SfxApply :: ActorId -> ItemId -> CStore -> SfxAtomic
SfxCheck :: ActorId -> ItemId -> CStore -> SfxAtomic
SfxTrigger :: ActorId -> Point -> SfxAtomic
SfxShun :: ActorId -> Point -> SfxAtomic
SfxEffect :: FactionId -> ActorId -> Effect -> Int64 -> SfxAtomic
SfxMsgFid :: FactionId -> SfxMsg -> SfxAtomic
SfxSortSlots :: SfxAtomic

-- | Symbolic representation of text messages sent by server to clients and
--   shown to players.
data SfxMsg
SfxUnexpected :: ReqFailure -> SfxMsg
SfxLoudUpd :: Bool -> UpdAtomic -> SfxMsg
SfxLoudStrike :: Bool -> (Id ItemKind) -> Int -> SfxMsg
SfxLoudSummon :: Bool -> (GroupName ItemKind) -> Dice -> SfxMsg
SfxFizzles :: SfxMsg
SfxNothingHappens :: SfxMsg
SfxVoidDetection :: SfxMsg
SfxSummonLackCalm :: ActorId -> SfxMsg
SfxLevelNoMore :: SfxMsg
SfxLevelPushed :: SfxMsg
SfxBracedImmune :: ActorId -> SfxMsg
SfxEscapeImpossible :: SfxMsg
SfxTransImpossible :: SfxMsg
SfxIdentifyNothing :: SfxMsg
SfxPurposeNothing :: CStore -> SfxMsg
SfxPurposeTooFew :: Int -> Int -> SfxMsg
SfxPurposeUnique :: SfxMsg
SfxColdFish :: SfxMsg
SfxTimerExtended :: ActorId -> ItemId -> CStore -> SfxMsg
undoUpdAtomic :: UpdAtomic -> Maybe UpdAtomic
undoSfxAtomic :: SfxAtomic -> SfxAtomic
undoCmdAtomic :: CmdAtomic -> Maybe CmdAtomic
instance GHC.Generics.Generic Game.LambdaHack.Atomic.CmdAtomic.CmdAtomic
instance GHC.Classes.Eq Game.LambdaHack.Atomic.CmdAtomic.CmdAtomic
instance GHC.Show.Show Game.LambdaHack.Atomic.CmdAtomic.CmdAtomic
instance GHC.Generics.Generic Game.LambdaHack.Atomic.CmdAtomic.SfxAtomic
instance GHC.Classes.Eq Game.LambdaHack.Atomic.CmdAtomic.SfxAtomic
instance GHC.Show.Show Game.LambdaHack.Atomic.CmdAtomic.SfxAtomic
instance GHC.Generics.Generic Game.LambdaHack.Atomic.CmdAtomic.SfxMsg
instance GHC.Classes.Eq Game.LambdaHack.Atomic.CmdAtomic.SfxMsg
instance GHC.Show.Show Game.LambdaHack.Atomic.CmdAtomic.SfxMsg
instance GHC.Generics.Generic Game.LambdaHack.Atomic.CmdAtomic.UpdAtomic
instance GHC.Classes.Eq Game.LambdaHack.Atomic.CmdAtomic.UpdAtomic
instance GHC.Show.Show Game.LambdaHack.Atomic.CmdAtomic.UpdAtomic
instance Data.Binary.Class.Binary Game.LambdaHack.Atomic.CmdAtomic.CmdAtomic
instance Data.Binary.Class.Binary Game.LambdaHack.Atomic.CmdAtomic.SfxAtomic
instance Data.Binary.Class.Binary Game.LambdaHack.Atomic.CmdAtomic.SfxMsg
instance Data.Binary.Class.Binary Game.LambdaHack.Atomic.CmdAtomic.UpdAtomic


-- | Representation and computation of visiblity of atomic commands by
--   clients.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Atomic.PosAtomicRead

-- | The type representing visibility of atomic commands to factions, based
--   on the position of the command, etc. Note that the server sees and
--   smells all positions.
data PosAtomic

-- | whomever sees all the positions, notices
PosSight :: LevelId -> [Point] -> PosAtomic

-- | observers and the faction notice
PosFidAndSight :: [FactionId] -> LevelId -> [Point] -> PosAtomic

-- | whomever smells all the positions, notices
PosSmell :: LevelId -> [Point] -> PosAtomic

-- | only the faction notices, server doesn't
PosFid :: FactionId -> PosAtomic

-- | faction and server notices
PosFidAndSer :: (Maybe LevelId) -> FactionId -> PosAtomic

-- | only the server notices
PosSer :: PosAtomic

-- | everybody notices
PosAll :: PosAtomic

-- | never broadcasted, but sent manually
PosNone :: PosAtomic

-- | Produce the positions where the atomic update takes place or, more
--   generally, the conditions under which the update can be noticed by a
--   client.
--   
--   The goal of this mechanics is to ensure that atomic commands involving
--   some positions visible by a client convey similar information as the
--   client would get by directly observing the changes of the portion of
--   server state limited to the visible positions. Consequently, when the
--   visible commands are later applied to the client's state, the state
--   stays consistent --- in sync with the server state and correctly
--   limited by visiblity. There is some wiggle room both in what "in sync"
--   and "visible" means and how they propagate through time.
--   
--   E.g., <tt>UpdDisplaceActor</tt> in a black room between two enemy
--   actors, with only one actor carrying a 0-radius light would not be
--   distinguishable by looking at the state (or the screen) from
--   <tt>UpdMoveActor</tt> of the illuminated actor, hence such
--   <tt>UpdDisplaceActor</tt> should not be observable, but
--   <tt>UpdMoveActor</tt> in similar cotext would be (or the former should
--   be perceived as the latter). However, to simplify, we assign as strict
--   visibility requirements to <tt>UpdMoveActor</tt> as to
--   <tt>UpdDisplaceActor</tt> and fall back to <tt>UpdSpotActor</tt>
--   (which provides minimal information that does not contradict state) if
--   the visibility is lower.
posUpdAtomic :: MonadStateRead m => UpdAtomic -> m PosAtomic

-- | Produce the positions where the atomic special effect takes place.
posSfxAtomic :: MonadStateRead m => SfxAtomic -> m PosAtomic

-- | Decompose an atomic action that is outside a client's visiblity. The
--   decomposed actions give less information that the original command,
--   but some of them may fall within the visibility range of the client.
--   The original action may give more information than even the total sum
--   of all actions it's broken into. E.g., <tt>UpdMoveActor</tt> informs
--   about the continued existence of the actor between moves vs popping
--   out of existence and then back in.
--   
--   This is computed in server's <tt>State</tt> from before performing the
--   command.
breakUpdAtomic :: MonadStateRead m => UpdAtomic -> m [UpdAtomic]

-- | Given the client, its perception and an atomic command, determine if
--   the client notices the command.
seenAtomicCli :: Bool -> FactionId -> Perception -> PosAtomic -> Bool

-- | Determine whether the server would see a command that has the given
--   visibilty conditions.
seenAtomicSer :: PosAtomic -> Bool
posProjBody :: Actor -> PosAtomic
singleAid :: MonadStateRead m => ActorId -> m PosAtomic
doubleAid :: MonadStateRead m => ActorId -> ActorId -> m PosAtomic
singleContainer :: MonadStateRead m => Container -> m PosAtomic
instance GHC.Classes.Eq Game.LambdaHack.Atomic.PosAtomicRead.PosAtomic
instance GHC.Show.Show Game.LambdaHack.Atomic.PosAtomicRead.PosAtomic


-- | Semantics of atomic commands shared by client and server.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Atomic.HandleAtomicWrite

-- | The game-state semantics of atomic game commands. There is no
--   corresponding definition for special effects (<a>SfxAtomic</a>),
--   because they don't modify <a>State</a>.
--   
--   For each of the commands, we are guaranteed that the client, the
--   command is addressed to, perceives all the positions the command
--   affects (as computed by <a>posUpdAtomic</a>). In the code for each
--   semantic function we additonally verify the client is aware of any
--   relevant items and/or actors and we throw the <tt>AtomicFail</tt>
--   exception if it's not. The server keeps copies of all clients' states
--   and, before sending a command to a client, applies it to the client's
--   state copy. If <tt>AtomicFail</tt> is signalled, the command is
--   ignored for that client. This enables simpler server code that
--   addresses commands to all clients that can see it, even though not all
--   are able to process it.
handleUpdAtomic :: MonadStateWrite m => UpdAtomic -> m ()
updCreateActor :: MonadStateWrite m => ActorId -> Actor -> [(ItemId, Item)] -> m ()
updDestroyActor :: MonadStateWrite m => ActorId -> Actor -> [(ItemId, Item)] -> m ()
updCreateItem :: MonadStateWrite m => ItemId -> Item -> ItemQuant -> Container -> m ()
updDestroyItem :: MonadStateWrite m => ItemId -> Item -> ItemQuant -> Container -> m ()
updSpotItemBag :: MonadStateWrite m => Container -> ItemBag -> [(ItemId, Item)] -> m ()
updLoseItemBag :: MonadStateWrite m => Container -> ItemBag -> [(ItemId, Item)] -> m ()
updMoveActor :: MonadStateWrite m => ActorId -> Point -> Point -> m ()
updWaitActor :: MonadStateWrite m => ActorId -> Bool -> m ()
updDisplaceActor :: MonadStateWrite m => ActorId -> ActorId -> m ()
updMoveItem :: MonadStateWrite m => ItemId -> Int -> ActorId -> CStore -> CStore -> m ()
updRefillHP :: MonadStateWrite m => ActorId -> Int64 -> m ()
updRefillCalm :: MonadStateWrite m => ActorId -> Int64 -> m ()
updTrajectory :: MonadStateWrite m => ActorId -> Maybe ([Vector], Speed) -> Maybe ([Vector], Speed) -> m ()
updQuitFaction :: MonadStateWrite m => FactionId -> Maybe Status -> Maybe Status -> m ()
updLeadFaction :: MonadStateWrite m => FactionId -> Maybe ActorId -> Maybe ActorId -> m ()
updDiplFaction :: MonadStateWrite m => FactionId -> FactionId -> Diplomacy -> Diplomacy -> m ()
updTacticFaction :: MonadStateWrite m => FactionId -> Tactic -> Tactic -> m ()
updAutoFaction :: MonadStateWrite m => FactionId -> Bool -> m ()
updRecordKill :: MonadStateWrite m => ActorId -> Id ItemKind -> Int -> m ()
updAlterTile :: MonadStateWrite m => LevelId -> Point -> Id TileKind -> Id TileKind -> m ()
updAlterExplorable :: MonadStateWrite m => LevelId -> Int -> m ()
updSearchTile :: MonadStateWrite m => ActorId -> Point -> Id TileKind -> m ()
updSpotTile :: MonadStateWrite m => LevelId -> [(Point, Id TileKind)] -> m ()
updLoseTile :: MonadStateWrite m => LevelId -> [(Point, Id TileKind)] -> m ()
updAlterSmell :: MonadStateWrite m => LevelId -> Point -> Time -> Time -> m ()
updSpotSmell :: MonadStateWrite m => LevelId -> [(Point, Time)] -> m ()
updLoseSmell :: MonadStateWrite m => LevelId -> [(Point, Time)] -> m ()
updTimeItem :: MonadStateWrite m => ItemId -> Container -> ItemTimer -> ItemTimer -> m ()
updAgeGame :: MonadStateWrite m => [LevelId] -> m ()
updUnAgeGame :: MonadStateWrite m => [LevelId] -> m ()
ageLevel :: MonadStateWrite m => Delta Time -> LevelId -> m ()
updDiscover :: MonadStateWrite m => Container -> ItemId -> Id ItemKind -> ItemSeed -> m ()
updCover :: Container -> ItemId -> Id ItemKind -> ItemSeed -> m ()
updDiscoverKind :: MonadStateWrite m => Container -> ItemKindIx -> Id ItemKind -> m ()
discoverKind :: MonadStateWrite m => ItemKindIx -> Id ItemKind -> m KindMean
updCoverKind :: Container -> ItemKindIx -> Id ItemKind -> m ()
updDiscoverSeed :: MonadStateWrite m => Container -> ItemId -> ItemSeed -> m ()
discoverSeed :: MonadStateWrite m => ItemId -> ItemSeed -> m ()
updCoverSeed :: Container -> ItemId -> ItemSeed -> m ()
updDiscoverServer :: MonadStateWrite m => ItemId -> AspectRecord -> m ()
updCoverServer :: MonadStateWrite m => ItemId -> AspectRecord -> m ()
updRestart :: MonadStateWrite m => State -> m ()
updRestartServer :: MonadStateWrite m => State -> m ()
updResumeServer :: MonadStateWrite m => State -> m ()


-- | Atomic game state transformations, their representation and semantics.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Atomic

-- | Abstract syntax of atomic commands, that is, atomic game state
--   transformations.
data CmdAtomic

-- | atomic updates
UpdAtomic :: UpdAtomic -> CmdAtomic

-- | atomic special effects
SfxAtomic :: SfxAtomic -> CmdAtomic

-- | Abstract syntax of atomic updates, that is, atomic commands that
--   really change the <a>State</a>. Most of them are an encoding of a game
--   state diff, though they also carry some intentional hints that help
--   clients determine whether and how to communicate it to players.
data UpdAtomic
UpdCreateActor :: ActorId -> Actor -> [(ItemId, Item)] -> UpdAtomic
UpdDestroyActor :: ActorId -> Actor -> [(ItemId, Item)] -> UpdAtomic
UpdCreateItem :: ItemId -> Item -> ItemQuant -> Container -> UpdAtomic
UpdDestroyItem :: ItemId -> Item -> ItemQuant -> Container -> UpdAtomic
UpdSpotActor :: ActorId -> Actor -> [(ItemId, Item)] -> UpdAtomic
UpdLoseActor :: ActorId -> Actor -> [(ItemId, Item)] -> UpdAtomic
UpdSpotItem :: Bool -> ItemId -> Item -> ItemQuant -> Container -> UpdAtomic
UpdLoseItem :: Bool -> ItemId -> Item -> ItemQuant -> Container -> UpdAtomic
UpdSpotItemBag :: Container -> ItemBag -> [(ItemId, Item)] -> UpdAtomic
UpdLoseItemBag :: Container -> ItemBag -> [(ItemId, Item)] -> UpdAtomic
UpdMoveActor :: ActorId -> Point -> Point -> UpdAtomic
UpdWaitActor :: ActorId -> Bool -> UpdAtomic
UpdDisplaceActor :: ActorId -> ActorId -> UpdAtomic
UpdMoveItem :: ItemId -> Int -> ActorId -> CStore -> CStore -> UpdAtomic
UpdRefillHP :: ActorId -> Int64 -> UpdAtomic
UpdRefillCalm :: ActorId -> Int64 -> UpdAtomic
UpdTrajectory :: ActorId -> (Maybe ([Vector], Speed)) -> (Maybe ([Vector], Speed)) -> UpdAtomic
UpdQuitFaction :: FactionId -> (Maybe Status) -> (Maybe Status) -> UpdAtomic
UpdLeadFaction :: FactionId -> (Maybe ActorId) -> (Maybe ActorId) -> UpdAtomic
UpdDiplFaction :: FactionId -> FactionId -> Diplomacy -> Diplomacy -> UpdAtomic
UpdTacticFaction :: FactionId -> Tactic -> Tactic -> UpdAtomic
UpdAutoFaction :: FactionId -> Bool -> UpdAtomic
UpdRecordKill :: ActorId -> (Id ItemKind) -> Int -> UpdAtomic
UpdAlterTile :: LevelId -> Point -> (Id TileKind) -> (Id TileKind) -> UpdAtomic
UpdAlterExplorable :: LevelId -> Int -> UpdAtomic
UpdSearchTile :: ActorId -> Point -> (Id TileKind) -> UpdAtomic
UpdHideTile :: ActorId -> Point -> (Id TileKind) -> UpdAtomic
UpdSpotTile :: LevelId -> [(Point, Id TileKind)] -> UpdAtomic
UpdLoseTile :: LevelId -> [(Point, Id TileKind)] -> UpdAtomic
UpdAlterSmell :: LevelId -> Point -> Time -> Time -> UpdAtomic
UpdSpotSmell :: LevelId -> [(Point, Time)] -> UpdAtomic
UpdLoseSmell :: LevelId -> [(Point, Time)] -> UpdAtomic
UpdTimeItem :: ItemId -> Container -> ItemTimer -> ItemTimer -> UpdAtomic
UpdAgeGame :: [LevelId] -> UpdAtomic
UpdUnAgeGame :: [LevelId] -> UpdAtomic
UpdDiscover :: Container -> ItemId -> (Id ItemKind) -> ItemSeed -> UpdAtomic
UpdCover :: Container -> ItemId -> (Id ItemKind) -> ItemSeed -> UpdAtomic
UpdDiscoverKind :: Container -> ItemKindIx -> (Id ItemKind) -> UpdAtomic
UpdCoverKind :: Container -> ItemKindIx -> (Id ItemKind) -> UpdAtomic
UpdDiscoverSeed :: Container -> ItemId -> ItemSeed -> UpdAtomic
UpdCoverSeed :: Container -> ItemId -> ItemSeed -> UpdAtomic
UpdDiscoverServer :: ItemId -> AspectRecord -> UpdAtomic
UpdCoverServer :: ItemId -> AspectRecord -> UpdAtomic
UpdPerception :: LevelId -> Perception -> Perception -> UpdAtomic
UpdRestart :: FactionId -> PerLid -> State -> Challenge -> ClientOptions -> UpdAtomic
UpdRestartServer :: State -> UpdAtomic
UpdResume :: FactionId -> PerLid -> UpdAtomic
UpdResumeServer :: State -> UpdAtomic
UpdKillExit :: FactionId -> UpdAtomic
UpdWriteSave :: UpdAtomic

-- | Abstract syntax of atomic special effects, that is, atomic commands
--   that only display special effects and don't change <a>State</a>.
data SfxAtomic
SfxStrike :: ActorId -> ActorId -> ItemId -> CStore -> SfxAtomic
SfxRecoil :: ActorId -> ActorId -> ItemId -> CStore -> SfxAtomic
SfxSteal :: ActorId -> ActorId -> ItemId -> CStore -> SfxAtomic
SfxRelease :: ActorId -> ActorId -> ItemId -> CStore -> SfxAtomic
SfxProject :: ActorId -> ItemId -> CStore -> SfxAtomic
SfxReceive :: ActorId -> ItemId -> CStore -> SfxAtomic
SfxApply :: ActorId -> ItemId -> CStore -> SfxAtomic
SfxCheck :: ActorId -> ItemId -> CStore -> SfxAtomic
SfxTrigger :: ActorId -> Point -> SfxAtomic
SfxShun :: ActorId -> Point -> SfxAtomic
SfxEffect :: FactionId -> ActorId -> Effect -> Int64 -> SfxAtomic
SfxMsgFid :: FactionId -> SfxMsg -> SfxAtomic
SfxSortSlots :: SfxAtomic

-- | Symbolic representation of text messages sent by server to clients and
--   shown to players.
data SfxMsg
SfxUnexpected :: ReqFailure -> SfxMsg
SfxLoudUpd :: Bool -> UpdAtomic -> SfxMsg
SfxLoudStrike :: Bool -> (Id ItemKind) -> Int -> SfxMsg
SfxLoudSummon :: Bool -> (GroupName ItemKind) -> Dice -> SfxMsg
SfxFizzles :: SfxMsg
SfxNothingHappens :: SfxMsg
SfxVoidDetection :: SfxMsg
SfxSummonLackCalm :: ActorId -> SfxMsg
SfxLevelNoMore :: SfxMsg
SfxLevelPushed :: SfxMsg
SfxBracedImmune :: ActorId -> SfxMsg
SfxEscapeImpossible :: SfxMsg
SfxTransImpossible :: SfxMsg
SfxIdentifyNothing :: SfxMsg
SfxPurposeNothing :: CStore -> SfxMsg
SfxPurposeTooFew :: Int -> Int -> SfxMsg
SfxPurposeUnique :: SfxMsg
SfxColdFish :: SfxMsg
SfxTimerExtended :: ActorId -> ItemId -> CStore -> SfxMsg

-- | The game-state semantics of atomic game commands. There is no
--   corresponding definition for special effects (<a>SfxAtomic</a>),
--   because they don't modify <a>State</a>.
--   
--   For each of the commands, we are guaranteed that the client, the
--   command is addressed to, perceives all the positions the command
--   affects (as computed by <a>posUpdAtomic</a>). In the code for each
--   semantic function we additonally verify the client is aware of any
--   relevant items and/or actors and we throw the <tt>AtomicFail</tt>
--   exception if it's not. The server keeps copies of all clients' states
--   and, before sending a command to a client, applies it to the client's
--   state copy. If <tt>AtomicFail</tt> is signalled, the command is
--   ignored for that client. This enables simpler server code that
--   addresses commands to all clients that can see it, even though not all
--   are able to process it.
handleUpdAtomic :: MonadStateWrite m => UpdAtomic -> m ()

-- | The type representing visibility of atomic commands to factions, based
--   on the position of the command, etc. Note that the server sees and
--   smells all positions.
data PosAtomic

-- | whomever sees all the positions, notices
PosSight :: LevelId -> [Point] -> PosAtomic

-- | observers and the faction notice
PosFidAndSight :: [FactionId] -> LevelId -> [Point] -> PosAtomic

-- | whomever smells all the positions, notices
PosSmell :: LevelId -> [Point] -> PosAtomic

-- | only the faction notices, server doesn't
PosFid :: FactionId -> PosAtomic

-- | faction and server notices
PosFidAndSer :: (Maybe LevelId) -> FactionId -> PosAtomic

-- | only the server notices
PosSer :: PosAtomic

-- | everybody notices
PosAll :: PosAtomic

-- | never broadcasted, but sent manually
PosNone :: PosAtomic

-- | Produce the positions where the atomic update takes place or, more
--   generally, the conditions under which the update can be noticed by a
--   client.
--   
--   The goal of this mechanics is to ensure that atomic commands involving
--   some positions visible by a client convey similar information as the
--   client would get by directly observing the changes of the portion of
--   server state limited to the visible positions. Consequently, when the
--   visible commands are later applied to the client's state, the state
--   stays consistent --- in sync with the server state and correctly
--   limited by visiblity. There is some wiggle room both in what "in sync"
--   and "visible" means and how they propagate through time.
--   
--   E.g., <tt>UpdDisplaceActor</tt> in a black room between two enemy
--   actors, with only one actor carrying a 0-radius light would not be
--   distinguishable by looking at the state (or the screen) from
--   <tt>UpdMoveActor</tt> of the illuminated actor, hence such
--   <tt>UpdDisplaceActor</tt> should not be observable, but
--   <tt>UpdMoveActor</tt> in similar cotext would be (or the former should
--   be perceived as the latter). However, to simplify, we assign as strict
--   visibility requirements to <tt>UpdMoveActor</tt> as to
--   <tt>UpdDisplaceActor</tt> and fall back to <tt>UpdSpotActor</tt>
--   (which provides minimal information that does not contradict state) if
--   the visibility is lower.
posUpdAtomic :: MonadStateRead m => UpdAtomic -> m PosAtomic

-- | Produce the positions where the atomic special effect takes place.
posSfxAtomic :: MonadStateRead m => SfxAtomic -> m PosAtomic

-- | Decompose an atomic action that is outside a client's visiblity. The
--   decomposed actions give less information that the original command,
--   but some of them may fall within the visibility range of the client.
--   The original action may give more information than even the total sum
--   of all actions it's broken into. E.g., <tt>UpdMoveActor</tt> informs
--   about the continued existence of the actor between moves vs popping
--   out of existence and then back in.
--   
--   This is computed in server's <tt>State</tt> from before performing the
--   command.
breakUpdAtomic :: MonadStateRead m => UpdAtomic -> m [UpdAtomic]

-- | Given the client, its perception and an atomic command, determine if
--   the client notices the command.
seenAtomicCli :: Bool -> FactionId -> Perception -> PosAtomic -> Bool

-- | Determine whether the server would see a command that has the given
--   visibilty conditions.
seenAtomicSer :: PosAtomic -> Bool

-- | The monad for writing to the main game state. Atomic updates
--   (<tt>UpdAtomic</tt>) are given semantics in this monad.
class MonadStateRead m => MonadStateWrite m
modifyState :: MonadStateWrite m => (State -> State) -> m ()

-- | Exception signifying that atomic action failed because the information
--   it carries is inconsistent with the client's state, (e.g., because the
--   client knows too little to understand the command or already deduced
--   the state change from earlier commands or is confused, amnesiac or
--   sees illusory actors or tiles). Whenever we know the failure is
--   logically impossible, we don't throw the <tt>AtomicFail</tt>
--   exception, but insert a normal assertion or <tt>error</tt> call, which
--   are never caught nor handled.
newtype AtomicFail
AtomicFail :: String -> AtomicFail
putState :: MonadStateWrite m => State -> m ()


-- | Client-specific game state components.
module Game.LambdaHack.Client.State

-- | Client state, belonging to a single faction.
data StateClient
StateClient :: Int -> EnumMap ActorId TgtAndPath -> EnumSet LevelId -> EnumMap ActorId BfsAndPath -> [CmdAtomic] -> DiscoveryBenefit -> PerLid -> AlterLid -> StdGen -> Maybe ActorId -> FactionId -> Bool -> Challenge -> Challenge -> Int -> Int -> EnumMap LevelId (Maybe Bool) -> EnumMap (Id ModeKind) (Map Challenge Int) -> ClientOptions -> StateClient

-- | a parameter of the aiming digital line
[seps] :: StateClient -> Int

-- | targets of our actors in the dungeon
[stargetD] :: StateClient -> EnumMap ActorId TgtAndPath

-- | the set of fully explored levels
[sexplored] :: StateClient -> EnumSet LevelId

-- | pathfinding data for our actors
[sbfsD] :: StateClient -> EnumMap ActorId BfsAndPath

-- | atomic commands performed to date
[sundo] :: StateClient -> [CmdAtomic]

-- | remembered AI benefits of items
[sdiscoBenefit] :: StateClient -> DiscoveryBenefit

-- | faction perception indexed by level
[sfper] :: StateClient -> PerLid

-- | cached alter ability data for positions
[salter] :: StateClient -> AlterLid

-- | current random generator
[srandom] :: StateClient -> StdGen

-- | candidate new leader of the faction; Faction.gleader is the old leader
[_sleader] :: StateClient -> Maybe ActorId

-- | faction controlled by the client
[_sside] :: StateClient -> FactionId

-- | exit the game loop
[squit] :: StateClient -> Bool

-- | current game challenge setup
[scurChal] :: StateClient -> Challenge

-- | next game challenge setup
[snxtChal] :: StateClient -> Challenge

-- | next game scenario number
[snxtScenario] :: StateClient -> Int

-- | whether to mark suspect features
[smarkSuspect] :: StateClient -> Int

-- | last in-melee condition for each level
[scondInMelee] :: StateClient -> EnumMap LevelId (Maybe Bool)

-- | won games at particular difficulty lvls
[svictories] :: StateClient -> EnumMap (Id ModeKind) (Map Challenge Int)

-- | client options
[soptions] :: StateClient -> ClientOptions
type AlterLid = EnumMap LevelId (Array Word8)

-- | Pathfinding distances to all reachable positions of an actor and a
--   shortest paths to some of the positions.
data BfsAndPath
BfsInvalid :: BfsAndPath
BfsAndPath :: Array BfsDistance -> EnumMap Point AndPath -> BfsAndPath
[bfsArr] :: BfsAndPath -> Array BfsDistance
[bfsPath] :: BfsAndPath -> EnumMap Point AndPath

-- | Actor's target and a path to it, if any.
data TgtAndPath
TgtAndPath :: Target -> AndPath -> TgtAndPath
[tapTgt] :: TgtAndPath -> Target
[tapPath] :: TgtAndPath -> AndPath

-- | Initial empty game client state.
emptyStateClient :: FactionId -> StateClient

-- | Cycle the <a>smarkSuspect</a> setting.
cycleMarkSuspect :: StateClient -> StateClient

-- | Update target parameters within client state.
updateTarget :: ActorId -> (Maybe Target -> Maybe Target) -> StateClient -> StateClient

-- | Get target parameters from client state.
getTarget :: ActorId -> StateClient -> Maybe Target

-- | Update picked leader within state. Verify actor's faction.
updateLeader :: ActorId -> State -> StateClient -> StateClient
sside :: StateClient -> FactionId
sleader :: StateClient -> Maybe ActorId
instance GHC.Show.Show Game.LambdaHack.Client.State.StateClient
instance GHC.Generics.Generic Game.LambdaHack.Client.State.TgtAndPath
instance GHC.Show.Show Game.LambdaHack.Client.State.TgtAndPath
instance GHC.Show.Show Game.LambdaHack.Client.State.BfsAndPath
instance Data.Binary.Class.Binary Game.LambdaHack.Client.State.StateClient
instance Data.Binary.Class.Binary Game.LambdaHack.Client.State.TgtAndPath


-- | Basic client monad and related operations.
module Game.LambdaHack.Client.MonadClient

-- | Monad for writing to client state.
class MonadStateRead m => MonadClient m
getsClient :: MonadClient m => (StateClient -> a) -> m a
modifyClient :: MonadClient m => (StateClient -> StateClient) -> m ()
liftIO :: MonadClient m => IO a -> m a
getClient :: MonadClient m => m StateClient
putClient :: MonadClient m => StateClient -> m ()
debugPossiblyPrint :: MonadClient m => Text -> m ()

-- | Invoke pseudo-random computation with the generator kept in the state.
rndToAction :: MonadClient m => Rnd a -> m a

-- | Invoke pseudo-random computation, don't change generator kept in
--   state.
rndToActionForget :: MonadClient m => Rnd a -> m a


-- | Common client monad operations.
module Game.LambdaHack.Client.CommonM

-- | Get the current perception of a client.
getPerFid :: MonadClient m => LevelId -> m Perception

-- | Calculate the position of an actor's target.
aidTgtToPos :: MonadStateRead m => ActorId -> LevelId -> Target -> m (Maybe Point)

-- | Counts the number of steps until the projectile would hit an actor or
--   obstacle. Starts searching with the given eps and returns the first
--   found eps for which the number reaches the distance between actor and
--   target position, or Nothing if none can be found.
makeLine :: MonadStateRead m => Bool -> Actor -> Point -> Int -> m (Maybe Int)
maxActorSkillsClient :: MonadClient m => ActorId -> m Skills
currentSkillsClient :: MonadClient m => ActorId -> m Skills
pickWeaponClient :: MonadClient m => ActorId -> ActorId -> m (Maybe (RequestTimed  'AbMelee))
updateSalter :: MonadClient m => LevelId -> [(Point, Id TileKind)] -> m ()
createSalter :: State -> AlterLid


-- | Breadth first search and related algorithms using the client monad.
module Game.LambdaHack.Client.BfsM
invalidateBfsAid :: MonadClient m => ActorId -> m ()
invalidateBfsLid :: MonadClient m => LevelId -> m ()
invalidateBfsAll :: MonadClient m => m ()
createBfs :: MonadClient m => Bool -> Word8 -> ActorId -> m (Array BfsDistance)

-- | Get cached BFS array and path or, if not stored, generate and store
--   first.
getCacheBfsAndPath :: forall m. MonadClient m => ActorId -> Point -> m (Array BfsDistance, AndPath)

-- | Get cached BFS array or, if not stored, generate and store first.
getCacheBfs :: MonadClient m => ActorId -> m (Array BfsDistance)

-- | Get cached BFS path or, if not stored, generate and store first.
getCachePath :: MonadClient m => ActorId -> Point -> m AndPath
createPath :: MonadClient m => ActorId -> Target -> m TgtAndPath
condBFS :: MonadClient m => ActorId -> m (Bool, Word8)

-- | Furthest (wrt paths) known position.
furthestKnown :: MonadClient m => ActorId -> m Point

-- | Closest reachable unknown tile position, if any.
--   
--   Note: some of these tiles are behind suspect tiles and they are chosen
--   in preference to more distant directly accessible unknown tiles. This
--   is in principle OK, but in dungeons with few hidden doors AI is at a
--   disadvantage (and with many hidden doors, it fares as well as a human
--   that deduced the dungeon properties). Changing Bfs to accomodate all
--   dungeon styles would be complex and would slow down the engine.
--   
--   If the level has inaccessible open areas (at least from the stairs AI
--   used) the level will be nevertheless here finally marked explored, to
--   enable transition to other levels. We should generally avoid such
--   levels, because digging and/or trying to find other stairs leading to
--   disconnected areas is not KISS so we don't do this in AI, so AI is at
--   a disadvantage.
closestUnknown :: MonadClient m => ActorId -> m (Maybe Point)

-- | Finds smells closest to the actor, except under the actor, because
--   actors consume smell only moving over them, not standing. Of the
--   closest, prefers the newest smell.
closestSmell :: MonadClient m => ActorId -> m [(Int, (Point, Time))]
data FleeViaStairsOrEscape
ViaStairs :: FleeViaStairsOrEscape
ViaStairsUp :: FleeViaStairsOrEscape
ViaStairsDown :: FleeViaStairsOrEscape
ViaEscape :: FleeViaStairsOrEscape
ViaNothing :: FleeViaStairsOrEscape
ViaAnything :: FleeViaStairsOrEscape
embedBenefit :: MonadClient m => FleeViaStairsOrEscape -> ActorId -> [(Point, ItemBag)] -> m [(Double, (Point, ItemBag))]

-- | Closest (wrt paths) AI-triggerable tiles with embedded items. In AI,
--   the level the actor is on is either explored or the actor already has
--   a weapon equipped, so no need to explore further, he tries to find
--   enemies on other levels, but before that, he triggers other tiles in
--   hope of some loot or beneficial effect to enter next level with.
closestTriggers :: MonadClient m => FleeViaStairsOrEscape -> ActorId -> m [(Int, (Point, (Point, ItemBag)))]

-- | Check whether the actor has enough gear to go look for enemies. We
--   assume weapons in equipment are better than any among organs or at
--   least provide some essential diversity. Disabled if, due to tactic,
--   actors follow leader and so would repeatedly move towards and away
--   form stairs at leader change, depending on current leader's gear.
--   Number of items of a single kind is ignored, because variety is
--   needed.
condEnoughGearM :: MonadClient m => ActorId -> m Bool

-- | Closest (wrt paths) items.
closestItems :: MonadClient m => ActorId -> m [(Int, (Point, ItemBag))]

-- | Closest (wrt paths) enemy actors.
closestFoes :: MonadClient m => [(ActorId, Actor)] -> ActorId -> m [(Int, (ActorId, Actor))]
unexploredDepth :: MonadClient m => Bool -> LevelId -> m Bool
updatePathFromBfs :: MonadClient m => Bool -> BfsAndPath -> ActorId -> Point -> m (Array BfsDistance, AndPath)
instance GHC.Classes.Eq Game.LambdaHack.Client.BfsM.FleeViaStairsOrEscape
instance GHC.Show.Show Game.LambdaHack.Client.BfsM.FleeViaStairsOrEscape


-- | Assorted conditions used later on in AI logic.
module Game.LambdaHack.Client.AI.ConditionM

-- | Require that the target enemy is visible by the party.
condAimEnemyPresentM :: MonadClient m => ActorId -> m Bool

-- | Require that the target enemy is remembered on the actor's level.
condAimEnemyRememberedM :: MonadClient m => ActorId -> m Bool

-- | Check if the target is nonmoving.
condTgtNonmovingM :: MonadClient m => ActorId -> m Bool

-- | Require that any non-dying foe is adjacent, except projectiles that
--   (possibly) explode upon contact.
condAnyFoeAdjM :: MonadStateRead m => ActorId -> m Bool

-- | Require the actor stands adjacent to a triggerable tile (e.g.,
--   stairs).
condAdjTriggerableM :: MonadStateRead m => ActorId -> m Bool

-- | Produce the chess-distance-sorted list of non-low-HP, melee-cabable
--   foes on the level. We don't consider path-distance, because we are
--   interested in how soon the foe can close in to hit us, which can
--   diverge greately from path distance for short distances, e.g., when
--   terrain gets revealed. We don't consider non-moving actors, because
--   they can't chase us and also because they can't be aggresive so to
--   resolve the stalemate, the opposing AI has to be aggresive by ignoring
--   them and then when melee is started, it's usually too late to retreat.
meleeThreatDistList :: MonadStateRead m => ActorId -> m [(Int, (ActorId, Actor))]

-- | Require the actor blocks the paths of any of his party members.
condBlocksFriendsM :: MonadClient m => ActorId -> m Bool

-- | Require the actor stands over a weapon that would be auto-equipped.
condFloorWeaponM :: MonadStateRead m => ActorId -> m Bool

-- | Check whether the actor has no weapon in equipment.
condNoEqpWeaponM :: MonadStateRead m => ActorId -> m Bool

-- | Require that the actor can project any items.
condCanProjectM :: MonadClient m => Int -> ActorId -> m Bool
condProjectListM :: MonadClient m => Int -> ActorId -> m [(Maybe Benefit, CStore, ItemId, ItemFull)]

-- | Produce the list of items with a given property available to the actor
--   and the items' values.
benAvailableItems :: MonadClient m => ActorId -> [CStore] -> m [(Maybe Benefit, CStore, ItemId, ItemFull)]
hinders :: Bool -> Bool -> Bool -> Bool -> Actor -> AspectRecord -> ItemFull -> Bool

-- | Require that the actor stands over a desirable item.
condDesirableFloorItemM :: MonadClient m => ActorId -> m Bool

-- | Produce the list of items on the ground beneath the actor that are
--   worth picking up.
benGroundItems :: MonadClient m => ActorId -> m [(Maybe Benefit, CStore, ItemId, ItemFull)]
desirableItem :: Bool -> Maybe Double -> Item -> Bool
condSupport :: MonadClient m => Int -> ActorId -> m Bool

-- | Require that the actor stands in the dark and so would be betrayed by
--   his own equipped light,
condShineWouldBetrayM :: MonadStateRead m => ActorId -> m Bool

-- | Produce a list of acceptable adjacent points to flee to.
fleeList :: MonadClient m => ActorId -> m ([(Int, Point)], [(Int, Point)])


-- | Let AI pick the best target for an actor.
module Game.LambdaHack.Client.AI.PickTargetM

-- | Verify and possibly change the target of an actor. This function both
--   updates the target in the client state and returns the new target
--   explicitly.
refreshTarget :: MonadClient m => (ActorId, Actor) -> m (Maybe TgtAndPath)

-- | AI proposes possible targets for the actor. Never empty.
targetStrategy :: forall m. MonadClient m => ActorId -> m (Strategy TgtAndPath)


-- | Picking the AI actor to move and refreshing leader and non-leader
--   targets.
module Game.LambdaHack.Client.AI.PickActorM

-- | Pick a new leader from among the actors on the current level. Refresh
--   the target of the new leader, even if unchanged.
pickActorToMove :: MonadClient m => Maybe ActorId -> m ActorId

-- | Inspect the tactics of the actor and set his target according to it.
setTargetFromTactics :: MonadClient m => ActorId -> m ()


-- | AI procedure for picking the best action for an actor.
module Game.LambdaHack.Client.AI.HandleAbilityM

-- | Pick the most desirable AI ation for the actor.
pickAction :: MonadClient m => ActorId -> Bool -> m RequestAnyAbility
actionStrategy :: forall m. MonadClient m => ActorId -> Bool -> m (Strategy RequestAnyAbility)
waitBlockNow :: MonadClient m => m (Strategy (RequestTimed  'AbWait))
pickup :: MonadClient m => ActorId -> Bool -> m (Strategy (RequestTimed  'AbMoveItem))
equipItems :: MonadClient m => ActorId -> m (Strategy (RequestTimed  'AbMoveItem))
toShare :: EqpSlot -> Bool
yieldUnneeded :: MonadClient m => ActorId -> m (Strategy (RequestTimed  'AbMoveItem))
unEquipItems :: MonadClient m => ActorId -> m (Strategy (RequestTimed  'AbMoveItem))
groupByEqpSlot :: [(ItemId, ItemFull)] -> EnumMap EqpSlot [(ItemId, ItemFull)]
bestByEqpSlot :: DiscoveryBenefit -> [(ItemId, ItemFull)] -> [(ItemId, ItemFull)] -> [(ItemId, ItemFull)] -> [(EqpSlot, ([(Int, (ItemId, ItemFull))], [(Int, (ItemId, ItemFull))], [(Int, (ItemId, ItemFull))]))]
harmful :: DiscoveryBenefit -> ItemId -> Bool
meleeBlocker :: MonadClient m => ActorId -> m (Strategy (RequestTimed  'AbMelee))
meleeAny :: MonadClient m => ActorId -> m (Strategy (RequestTimed  'AbMelee))
trigger :: MonadClient m => ActorId -> FleeViaStairsOrEscape -> m (Strategy (RequestTimed  'AbAlter))
projectItem :: MonadClient m => ActorId -> m (Strategy (RequestTimed  'AbProject))
data ApplyItemGroup
applyItem :: MonadClient m => ActorId -> ApplyItemGroup -> m (Strategy (RequestTimed  'AbApply))
flee :: MonadClient m => ActorId -> [(Int, Point)] -> m (Strategy RequestAnyAbility)
displaceFoe :: MonadClient m => ActorId -> m (Strategy RequestAnyAbility)
displaceBlocker :: MonadClient m => ActorId -> Bool -> m (Strategy RequestAnyAbility)
displaceTowards :: MonadClient m => ActorId -> Point -> Bool -> m (Strategy Vector)
chase :: MonadClient m => ActorId -> Bool -> Bool -> m (Strategy RequestAnyAbility)
moveTowards :: MonadClient m => ActorId -> Point -> Point -> Bool -> m (Strategy Vector)
moveOrRunAid :: MonadClient m => ActorId -> Vector -> m (Maybe RequestAnyAbility)
instance GHC.Classes.Eq Game.LambdaHack.Client.AI.HandleAbilityM.ApplyItemGroup


-- | Ways for the client to use AI to produce server requests, based on the
--   client's view of the game state.
module Game.LambdaHack.Client.AI

-- | Handle the move of an actor under AI control (regardless if the whole
--   faction is under human or computer control).
queryAI :: MonadClient m => ActorId -> m RequestAI

-- | Pick an actor to move and an action for him to perform, given an
--   optional previous candidate actor and action and the server-proposed
--   actor.
pickActorAndAction :: MonadClient m => Maybe (ActorId, RequestAnyAbility) -> ActorId -> m (ActorId, RequestAnyAbility)

-- | Check if any non-dying foe (projectile or not) is adjacent to any of
--   our normal actors (whether they can melee or just need to flee, in
--   which case alert is needed so that they are not slowed down by others)
--   and record this per-level. This is needed only by AI and computed as
--   lazily as possible before each round of AI deliberations.
udpdateCondInMelee :: MonadClient m => ActorId -> m ()


-- | Abstract syntax of responses.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Client.Response

-- | Abstract syntax of responses sent by server to an AI or UI client (or
--   a universal client that can handle both roles, which is why this type
--   is not separated into distinct AI and UI types). A response tells a
--   client how to update game state or what information to send to the
--   server.
data Response

-- | change <tt>State</tt> by performing this atomic update
RespUpdAtomicNoState :: UpdAtomic -> Response

-- | put the given <tt>State</tt>, which results from performing the atomic
--   update
RespUpdAtomic :: State -> UpdAtomic -> Response

-- | compute an AI move for the actor and send (the semantics of) it
RespQueryAI :: ActorId -> Response

-- | perform special effects (animations, messages, etc.)
RespSfxAtomic :: SfxAtomic -> Response

-- | prompt the human player for a command and send (the semantics of) it
RespQueryUI :: Response
instance GHC.Show.Show Game.LambdaHack.Client.Response.Response


-- | Handle atomic commands received by the client.
module Game.LambdaHack.Client.HandleAtomicM

-- | Client monad for saving and restarting games.
class MonadClient m => MonadClientSetup m
saveClient :: MonadClientSetup m => m ()
restartClient :: MonadClientSetup m => m ()

-- | Effect of atomic actions on client state. It is calculated with the
--   global state from after the command is executed (except where the
--   supplied <tt>oldState</tt> is used).
cmdAtomicSemCli :: MonadClientSetup m => State -> UpdAtomic -> m ()
wipeBfsIfItemAffectsSkills :: MonadClient m => [CStore] -> ActorId -> m ()
tileChangeAffectsBfs :: COps -> Id TileKind -> Id TileKind -> Bool
createActor :: MonadClient m => ActorId -> Actor -> [(ItemId, Item)] -> m ()
destroyActor :: MonadClient m => ActorId -> Actor -> Bool -> m ()
addItemToDiscoBenefit :: MonadClient m => ItemId -> Item -> m ()
perception :: MonadClient m => LevelId -> Perception -> Perception -> m ()
discoverKind :: MonadClient m => Container -> ItemKindIx -> Id ItemKind -> m ()
coverKind :: Container -> ItemKindIx -> Id ItemKind -> m ()
discoverSeed :: MonadClient m => Container -> ItemId -> ItemSeed -> m ()
coverSeed :: Container -> ItemId -> ItemSeed -> m ()
killExit :: MonadClient m => m ()


-- | Rectangular areas of levels and their basic operations.
module Game.LambdaHack.Server.DungeonGen.Area

-- | The type of areas. The bottom left and the top right points.
data Area

-- | Checks if it's an area with at least one field.
toArea :: (X, Y, X, Y) -> Maybe Area
fromArea :: Area -> (X, Y, X, Y)
trivialArea :: Point -> Area
isTrivialArea :: Area -> Bool
mkFixed :: (X, Y) -> Area -> Point -> Area
data SpecialArea
SpecialArea :: Area -> SpecialArea
SpecialFixed :: Point -> (GroupName PlaceKind) -> Area -> SpecialArea
SpecialMerged :: SpecialArea -> Point -> SpecialArea

-- | Divide uniformly a larger area into the given number of smaller areas
--   overlapping at the edges.
--   
--   When a list of fixed centers (some important points inside) of
--   (non-overlapping) areas is given, incorporate those, with as little
--   disruption, as possible.
grid :: EnumMap Point (GroupName PlaceKind) -> [Point] -> (X, Y) -> Area -> ((X, Y), EnumMap Point SpecialArea)

-- | Shrink the given area on all fours sides by the amount.
shrink :: Area -> Maybe Area
expand :: Area -> Area
sumAreas :: Area -> Area -> Area
instance GHC.Show.Show Game.LambdaHack.Server.DungeonGen.Area.SpecialArea
instance GHC.Classes.Eq Game.LambdaHack.Server.DungeonGen.Area.Area
instance GHC.Show.Show Game.LambdaHack.Server.DungeonGen.Area.Area
instance Data.Binary.Class.Binary Game.LambdaHack.Server.DungeonGen.Area.Area


-- | Operations on the <a>Area</a> type that involve random numbers.
module Game.LambdaHack.Server.DungeonGen.AreaRnd

-- | Pick a random point within an area.
xyInArea :: Area -> Rnd Point

-- | Create a void room, i.e., a single point area within the designated
--   area.
mkVoidRoom :: Area -> Rnd Area

-- | Create a random room according to given parameters.
mkRoom :: (X, Y) -> (X, Y) -> Area -> Rnd Area

-- | Pick a subset of connections between adjacent areas within a grid
--   until there is only one connected component in the graph of all areas.
connectGrid :: EnumSet Point -> (X, Y) -> Rnd [(Point, Point)]

-- | Pick a single random connection between adjacent areas within a grid.
randomConnection :: (X, Y) -> Rnd (Point, Point)

-- | The choice of horizontal and vertical orientation.
data HV
Horiz :: HV
Vert :: HV

-- | The coordinates of consecutive fields of a corridor.
type Corridor = [Point]

-- | Try to connect two interiors of places with a corridor. Choose
--   entrances some steps away from the edges, if the place is big enough.
--   Note that with <tt>pfence == FNone</tt>, the inner area considered is
--   the strict interior of the place, without the outermost tiles.
--   
--   The corridor connects (touches) the inner areas and the turning point
--   of the corridor (if any) is outside of the outer areas and inside the
--   grid areas.
connectPlaces :: (Area, Fence, Area) -> (Area, Fence, Area) -> Rnd (Maybe Corridor)
connectGrid' :: EnumSet Point -> (X, Y) -> EnumSet Point -> EnumSet Point -> [(Point, Point)] -> Rnd [(Point, Point)]

-- | Sort the sequence of two points, in the derived lexicographic order.
sortPoint :: (Point, Point) -> (Point, Point)

-- | Create a corridor, either horizontal or vertical, with a possible
--   intermediate part that is in the opposite direction. There might not
--   always exist a good intermediate point if the places are allowed to be
--   close together and then we let the intermediate part degenerate.
mkCorridor :: HV -> Point -> Bool -> Point -> Bool -> Area -> Rnd Corridor
borderPlace :: Area -> Fence -> (Area, Area)
instance GHC.Classes.Eq Game.LambdaHack.Server.DungeonGen.AreaRnd.HV


-- | Generation of places from place kinds.
module Game.LambdaHack.Server.DungeonGen.Place

-- | The parameters of a place. All are immutable and rolled and fixed at
--   the time when a place is generated.
data Place
Place :: Id PlaceKind -> Area -> Bool -> GroupName TileKind -> Id TileKind -> Id TileKind -> Id TileKind -> Place
[qkind] :: Place -> Id PlaceKind
[qarea] :: Place -> Area
[qseen] :: Place -> Bool
[qlegend] :: Place -> GroupName TileKind
[qFWall] :: Place -> Id TileKind
[qFFloor] :: Place -> Id TileKind
[qFGround] :: Place -> Id TileKind

-- | The map of tile kinds in a place (and generally anywhere in a cave).
--   The map is sparse. The default tile that eventually fills the empty
--   spaces is specified in the cave kind specification with
--   <tt>cdefTile</tt>.
type TileMapEM = EnumMap Point (Id TileKind)

-- | For <tt>CAlternate</tt> tiling, require the place be comprised of an
--   even number of whole corners, with exactly one square overlap between
--   consecutive coners and no trimming. For other tiling methods, check
--   that the area is large enough for tiling the corner twice in each
--   direction, with a possible one row/column overlap.
placeCheck :: Area -> PlaceKind -> Bool

-- | Given a few parameters, roll and construct a <a>Place</a>
--   datastructure and fill a cave section acccording to it.
buildPlace :: COps -> CaveKind -> Bool -> Id TileKind -> Id TileKind -> AbsDepth -> AbsDepth -> Int -> Area -> Maybe (GroupName PlaceKind) -> Rnd (TileMapEM, Place)
isChancePos :: Int -> Int -> Point -> Bool

-- | Construct a fence around an area, with the given tile group.
buildFenceRnd :: COps -> GroupName TileKind -> Area -> Rnd TileMapEM

-- | Calculate interior room area according to fence type, based on the
--   total area for the room and it's fence. This is used for checking if
--   the room fits in the area, for digging up the place and the fence and
--   for deciding if the room is dark or lit later in the dungeon
--   generation process.
interiorArea :: PlaceKind -> Area -> Maybe Area

-- | Roll a legend of a place plan: a map from plan symbols to tile kinds.
olegend :: COps -> GroupName TileKind -> Rnd (EnumMap Char (Int, Id TileKind), EnumMap Char (Id TileKind))
ooverride :: COps -> [(Char, GroupName TileKind)] -> Rnd (EnumMap Char (Int, Id TileKind), EnumMap Char (Id TileKind))

-- | Construct a fence around an area, with the given tile kind.
buildFence :: Id TileKind -> Area -> TileMapEM

-- | Create a place by tiling patterns.
tilePlace :: Area -> PlaceKind -> Rnd (EnumMap Point Char)
instance GHC.Show.Show Game.LambdaHack.Server.DungeonGen.Place.Place
instance Data.Binary.Class.Binary Game.LambdaHack.Server.DungeonGen.Place.Place


-- | Generation of caves (not yet inhabited dungeon levels) from cave
--   kinds.
module Game.LambdaHack.Server.DungeonGen.Cave

-- | The type of caves (not yet inhabited dungeon levels).
data Cave
Cave :: Id CaveKind -> Int -> TileMapEM -> [Place] -> Bool -> Cave

-- | the kind of the cave
[dkind] :: Cave -> Id CaveKind

-- | secret tile seed
[dsecret] :: Cave -> Int

-- | tile kinds in the cave
[dmap] :: Cave -> TileMapEM

-- | places generated in the cave
[dplaces] :: Cave -> [Place]

-- | whether the cave is dark
[dnight] :: Cave -> Bool
bootFixedCenters :: CaveKind -> [Point]

-- | Generate a cave using an algorithm inspired by the original Rogue, as
--   follows (in gross simplification):
--   
--   <ul>
--   <li>The available area is divided into a grid, e.g, 3 by 3, where each
--   of the 9 grid cells has approximately the same size.</li>
--   <li>In some of the 9 grid cells a room is placed at a random position
--   and with a random size, but larger than the minimum size, e.g, 2 by 2
--   floor tiles.</li>
--   <li>Rooms that are on horizontally or vertically adjacent grid cells
--   may be connected by a corridor. Corridors consist of 3 segments of
--   straight lines (either "horizontal, vertical, horizontal" or
--   "vertical, horizontal, vertical"). They end in openings in the walls
--   of the room they connect. It is possible that one or two of the 3
--   segments have length 0, such that the resulting corridor is L-shaped
--   or even a single straight line.</li>
--   <li>Corridors are generated randomly in such a way that at least every
--   room on the grid is connected, and a few more might be. It is not
--   sufficient to always connect all adjacent rooms, because not each cell
--   holds a room.</li>
--   </ul>
buildCave :: COps -> AbsDepth -> AbsDepth -> Int -> Id CaveKind -> EnumMap Point (GroupName PlaceKind) -> Rnd Cave
pickOpening :: COps -> CaveKind -> TileMapEM -> Id TileKind -> Int -> Point -> (Id TileKind, Id TileKind) -> Rnd (Id TileKind)
digCorridors :: Id TileKind -> Corridor -> TileMapEM
instance GHC.Show.Show Game.LambdaHack.Server.DungeonGen.Cave.Cave


-- | The dungeon generation routine. It creates empty dungeons, without
--   actors and without items, either lying on the floor or embedded inside
--   tiles.
module Game.LambdaHack.Server.DungeonGen

-- | Freshly generated and not yet populated dungeon.
data FreshDungeon
FreshDungeon :: Dungeon -> AbsDepth -> FreshDungeon

-- | maps for all levels
[freshDungeon] :: FreshDungeon -> Dungeon

-- | absolute dungeon depth
[freshTotalDepth] :: FreshDungeon -> AbsDepth

-- | Generate the dungeon for a new game.
dungeonGen :: COps -> Caves -> Rnd FreshDungeon
convertTileMaps :: COps -> Bool -> Rnd (Id TileKind) -> Maybe (Rnd (Id TileKind)) -> Int -> Int -> TileMapEM -> Rnd TileMap
buildTileMap :: COps -> Cave -> Rnd TileMap
buildLevel :: COps -> Int -> GroupName CaveKind -> Int -> AbsDepth -> [Point] -> Rnd (Level, [Point])
placeDownStairs :: CaveKind -> [Point] -> Rnd Point
levelFromCaveKind :: COps -> CaveKind -> AbsDepth -> TileMap -> ([Point], [Point]) -> Int -> [Point] -> Bool -> Level


-- | DFOV (Digital Field of View) implemented according to specification at
--   <a>http://roguebasin.roguelikedevelopment.org/index.php?title=Digital_field_of_view_implementation</a>.
--   This fast version of the algorithm, based on <a>PFOV</a>, has AFAIK
--   never been described nor implemented before.
module Game.LambdaHack.Server.FovDigital

-- | Calculates the list of tiles, in <tt>Bump</tt> coordinates, visible
--   from (0, 0), within the given sight range.
scan :: EnumSet Point -> Distance -> Array Bool -> (Bump -> Point) -> EnumSet Point

-- | Rotated and translated coordinates of 2D points, so that the points
--   fit in a single quadrant area (e, g., quadrant I for Permissive FOV,
--   hence both coordinates positive; adjacent diagonal halves of quadrant
--   I and II for Digital FOV, hence y positive). The special coordinates
--   are written using the standard mathematical coordinate setup, where
--   quadrant I, with x and y positive, is on the upper right.
data Bump
B :: Int -> Int -> Bump
[bx] :: Bump -> Int
[by] :: Bump -> Int

-- | Distance from the (0, 0) point where FOV originates.
type Distance = Int

-- | Progress along an arc with a constant distance from (0, 0).
type Progress = Int

-- | Straight line between points.
data Line
Line :: Bump -> Bump -> Line

-- | Convex hull represented as a list of points.
type ConvexHull = [Bump]

-- | An edge (comprising of a line and a convex hull) of the area to be
--   scanned.
type Edge = (Line, ConvexHull)

-- | The area left to be scanned, delimited by edges.
type EdgeInterval = (Edge, Edge)

-- | Check if the line from the second point to the first is more steep
--   than the line from the third point to the first. This is related to
--   the formal notion of gradient (or angle), but hacked wrt signs to work
--   fast in this particular setup. Returns True for ill-defined lines.
steeper :: Bump -> Bump -> Bump -> Ordering

-- | Extends a convex hull of bumps with a new bump. Nothing needs to be
--   done if the new bump already lies within the hull. The first argument
--   is typically <a>steeper</a>, optionally negated, applied to the second
--   argument.
addHull :: (Bump -> Bump -> Ordering) -> Bump -> ConvexHull -> ConvexHull

-- | Create a line from two points. Debug: check if well-defined.
dline :: Bump -> Bump -> Line

-- | Compare steepness of <tt>(p1, f)</tt> and <tt>(p2, f)</tt>. Debug:
--   Verify that the results of 2 independent checks are equal.
dsteeper :: Bump -> Bump -> Bump -> Ordering

-- | The X coordinate, represented as a fraction, of the intersection of a
--   given line and the line of diagonals of diamonds at distance
--   <tt>d</tt> from (0, 0).
intersect :: Line -> Distance -> (Int, Int)

-- | Debug functions for DFOV:
--   
--   Debug: calculate steeper for DFOV in another way and compare results.
_debugSteeper :: Bump -> Bump -> Bump -> Ordering

-- | Debug: check if a view border line for DFOV is legal.
_debugLine :: Line -> (Bool, String)
instance GHC.Show.Show Game.LambdaHack.Server.FovDigital.Line
instance GHC.Show.Show Game.LambdaHack.Server.FovDigital.Bump


-- | Field Of View scanning.
--   
--   See <a>https://github.com/LambdaHack/LambdaHack/wiki/Fov-and-los</a>
--   for discussion.
module Game.LambdaHack.Server.Fov
data FovValid a
FovValid :: a -> FovValid a
FovInvalid :: FovValid a

-- | Main perception validity map, for all factions.
type PerValidFid = EnumMap FactionId (EnumMap LevelId Bool)

-- | Visually reachable positions (light passes through them to the actor).
--   They need to be intersected with lucid positions to obtain visible
--   positions.
newtype PerReachable
PerReachable :: EnumSet Point -> PerReachable
[preachable] :: PerReachable -> EnumSet Point
data CacheBeforeLucid
CacheBeforeLucid :: PerReachable -> PerVisible -> PerSmelled -> CacheBeforeLucid
[creachable] :: CacheBeforeLucid -> PerReachable
[cnocto] :: CacheBeforeLucid -> PerVisible
[csmell] :: CacheBeforeLucid -> PerSmelled
type PerActor = EnumMap ActorId (FovValid CacheBeforeLucid)
data PerceptionCache
PerceptionCache :: FovValid CacheBeforeLucid -> PerActor -> PerceptionCache
[ptotal] :: PerceptionCache -> FovValid CacheBeforeLucid
[perActor] :: PerceptionCache -> PerActor

-- | Server cache of perceptions of a single faction, indexed by level
--   identifier.
type PerCacheLid = EnumMap LevelId PerceptionCache

-- | Server cache of perceptions, indexed by faction identifier.
type PerCacheFid = EnumMap FactionId PerCacheLid

-- | Map from level positions that currently hold item or actor(s) with
--   shine to the maximum of radiuses of the shining lights.
--   
--   Note that floor and (many projectile) actors light on a single tile
--   should be additive for <tt>FovShine</tt> to be incrementally updated.
--   
--   <tt>FovShine</tt> should not even be kept in <tt>StateServer</tt>,
--   because it's cheap to compute, compared to <tt>FovLucid</tt> and
--   invalidated almost as often (not invalidated only by
--   <tt>UpdAlterTile</tt>).
newtype FovShine
FovShine :: EnumMap Point Int -> FovShine
[fovShine] :: FovShine -> EnumMap Point Int

-- | Level positions with either ambient light or shining items or actors.
newtype FovLucid
FovLucid :: EnumSet Point -> FovLucid
[fovLucid] :: FovLucid -> EnumSet Point
type FovLucidLid = EnumMap LevelId (FovValid FovLucid)

-- | Level positions that pass through light and vision.
newtype FovClear
FovClear :: Array Bool -> FovClear
[fovClear] :: FovClear -> Array Bool
type FovClearLid = EnumMap LevelId FovClear

-- | Level positions with tiles that have ambient light.
newtype FovLit
FovLit :: EnumSet Point -> FovLit
[fovLit] :: FovLit -> EnumSet Point
type FovLitLid = EnumMap LevelId FovLit

-- | Compute positions visible (reachable and seen) by the party. A
--   position is lucid, if it's lit by an ambient light or by a weak,
--   portable light source, e.g,, carried by an actor. A reachable and
--   lucid position is visible. Additionally, positions directly adjacent
--   to an actor are assumed to be visible to him (through sound, touch,
--   noctovision, whatever).
perceptionFromPTotal :: FovLucid -> CacheBeforeLucid -> Perception
perActorFromLevel :: PerActor -> (ActorId -> Actor) -> ActorAspect -> FovClear -> PerActor
boundSightByCalm :: Int -> Int64 -> Int
totalFromPerActor :: PerActor -> CacheBeforeLucid

-- | Update lights on the level. This is needed every (even enemy) actor
--   move to show thrown torches. We need to update lights even if cmd
--   doesn't change any perception, so that for next cmd that does, but
--   doesn't change lights, and operates on the same level, the lights are
--   up to date. We could make lights lazy to ensure no computation is
--   wasted, but it's rare that cmd changed them, but not the perception
--   (e.g., earthquake in an uninhabited corner of the active arena, but
--   the we'd probably want some feedback, at least sound).
lucidFromLevel :: FovClearLid -> FovLitLid -> State -> LevelId -> Level -> FovLucid

-- | Calculate the perception and its caches for the whole dungeon.
perFidInDungeon :: State -> (FovLitLid, FovClearLid, FovLucidLid, PerValidFid, PerCacheFid, PerFid)

-- | Compute positions reachable by the actor. Reachable are all fields on
--   a visually unblocked path from the actor position. Also compute
--   positions seen by noctovision and perceived by smell.
cacheBeforeLucidFromActor :: FovClear -> Actor -> AspectRecord -> CacheBeforeLucid
shineFromLevel :: State -> LevelId -> Level -> FovShine
floorLightSources :: DiscoveryAspect -> Level -> [(Point, Int)]

-- | Compute all dynamically lit positions on a level, whether lit by
--   actors or shining floor items. Note that an actor can be blind, in
--   which case he doesn't see his own light (but others, from his or other
--   factions, possibly do).
lucidFromItems :: FovClear -> [(Point, Int)] -> [FovLucid]
litFromLevel :: COps -> Level -> FovLit
litInDungeon :: State -> FovLitLid
clearFromLevel :: COps -> Level -> FovClear
clearInDungeon :: State -> FovClearLid
lucidInDungeon :: FovClearLid -> FovLitLid -> State -> FovLucidLid

-- | Calculate perception of a faction.
perLidFromFaction :: FovLucidLid -> FovClearLid -> FactionId -> State -> (PerLid, PerCacheLid)
perceptionCacheFromLevel :: FovClearLid -> FactionId -> LevelId -> State -> PerceptionCache
type Matrix = (Int, Int, Int, Int)

-- | Perform a full scan for a given position. Returns the positions that
--   are currently in the field of view. The Field of View algorithm to use
--   is passed in the second argument. The actor's own position is
--   considred reachable by him.
fullscan :: FovClear -> Int -> Point -> EnumSet Point
instance GHC.Classes.Eq Game.LambdaHack.Server.Fov.FovLit
instance GHC.Show.Show Game.LambdaHack.Server.Fov.FovLit
instance GHC.Classes.Eq Game.LambdaHack.Server.Fov.FovClear
instance GHC.Show.Show Game.LambdaHack.Server.Fov.FovClear
instance GHC.Classes.Eq Game.LambdaHack.Server.Fov.FovLucid
instance GHC.Show.Show Game.LambdaHack.Server.Fov.FovLucid
instance GHC.Classes.Eq Game.LambdaHack.Server.Fov.FovShine
instance GHC.Show.Show Game.LambdaHack.Server.Fov.FovShine
instance GHC.Classes.Eq Game.LambdaHack.Server.Fov.PerceptionCache
instance GHC.Show.Show Game.LambdaHack.Server.Fov.PerceptionCache
instance GHC.Classes.Eq Game.LambdaHack.Server.Fov.CacheBeforeLucid
instance GHC.Show.Show Game.LambdaHack.Server.Fov.CacheBeforeLucid
instance GHC.Classes.Eq Game.LambdaHack.Server.Fov.PerReachable
instance GHC.Show.Show Game.LambdaHack.Server.Fov.PerReachable
instance GHC.Classes.Eq a => GHC.Classes.Eq (Game.LambdaHack.Server.Fov.FovValid a)
instance GHC.Show.Show a => GHC.Show.Show (Game.LambdaHack.Server.Fov.FovValid a)


-- | Creation of items on the server. Types and operations that don't
--   involve server state nor our custom monads.
module Game.LambdaHack.Server.ItemRev

-- | The essential item properties, used for the <tt>ItemRev</tt> hash
--   table from items to their ids, needed to assign ids to newly generated
--   items. All the other meaningul properties can be derived from them.
--   Note 1: <tt>jlid</tt> is not meaningful; it gets forgotten if items
--   from different levels roll the same random properties and so are
--   merged. However, the first item generated by the server wins, which is
--   most of the time the lower <tt>jlid</tt> item, which makes sense for
--   the client. Note 2: <tt>ItemSeed</tt> instead of <tt>AspectRecord</tt>
--   is not enough, becaused different seeds may result in the same
--   <tt>AspectRecord</tt> and we don't want such items to be distinct in
--   UI and elsewhere.
type ItemKnown = (ItemKindIx, AspectRecord, Dice, Maybe FactionId)

-- | Reverse item map, for item creation, to keep items and item
--   identifiers in bijection.
type ItemRev = HashMap ItemKnown ItemId
type UniqueSet = EnumSet (Id ItemKind)

-- | Build an item with the given stats.
buildItem :: FlavourMap -> DiscoveryKindRev -> Id ItemKind -> ItemKind -> LevelId -> Dice -> Item

-- | Generate an item based on level.
newItem :: COps -> FlavourMap -> DiscoveryKind -> DiscoveryKindRev -> UniqueSet -> Freqs ItemKind -> Int -> LevelId -> AbsDepth -> AbsDepth -> Rnd (Maybe (ItemKnown, ItemFull, ItemDisco, ItemSeed, GroupName ItemKind))

-- | The reverse map to <tt>DiscoveryKind</tt>, needed for item creation.
type DiscoveryKindRev = EnumMap (Id ItemKind) ItemKindIx

-- | The map of item ids to item seeds, needed for item creation.
type ItemSeedDict = EnumMap ItemId ItemSeed
serverDiscos :: COps -> Rnd (DiscoveryKind, DiscoveryKindRev)

-- | Flavours assigned by the server to item kinds, in this particular
--   game.
data FlavourMap
emptyFlavourMap :: FlavourMap

-- | Randomly chooses flavour for all item kinds for this game.
dungeonFlavourMap :: COps -> Rnd FlavourMap
instance Data.Binary.Class.Binary Game.LambdaHack.Server.ItemRev.FlavourMap
instance GHC.Show.Show Game.LambdaHack.Server.ItemRev.FlavourMap


-- | Saving and restoring game state, used by both server and clients.
module Game.LambdaHack.Common.Save
type ChanSave a = MVar (Maybe a)
saveToChan :: ChanSave a -> a -> IO ()
wrapInSaves :: Binary a => COps -> (a -> FilePath) -> (ChanSave a -> IO ()) -> IO ()

-- | Restore a saved game, if it exists. Initialize directory structure and
--   copy over data files, if needed.
restoreGame :: Binary a => COps -> FilePath -> IO (Maybe a)
saveNameCli :: COps -> FactionId -> String
saveNameSer :: COps -> String

-- | Repeatedly save serialized snapshots of current state.
loopSave :: Binary a => COps -> (a -> FilePath) -> ChanSave a -> IO ()
vExevLib :: COps -> (Version, Version)
showVersion2 :: (Version, Version) -> Text
delayPrint :: Text -> IO ()


-- | Client monad for interacting with a human through UI.
module Game.LambdaHack.Client.UI.MonadClientUI

-- | The monad that gives the client access to UI operations.
class MonadClient m => MonadClientUI m
getsSession :: MonadClientUI m => (SessionUI -> a) -> m a
modifySession :: MonadClientUI m => (SessionUI -> SessionUI) -> m ()
liftIO :: MonadClientUI m => IO a -> m a
clientPrintUI :: MonadClientUI m => Text -> m ()

-- | The row where the dungeon map starts.
mapStartY :: Y
getSession :: MonadClientUI m => m SessionUI
putSession :: MonadClientUI m => SessionUI -> m ()

-- | Push frames or delays to the frame queue. The frames depict the
--   <tt>lid</tt> level.
displayFrames :: MonadClientUI m => LevelId -> Frames -> m ()

-- | Write <a>FrontKey</a> UI request to the frontend, read the reply, set
--   pointer, return key.
connFrontendFrontKey :: MonadClientUI m => [KM] -> FrameForall -> m KM
setFrontAutoYes :: MonadClientUI m => Bool -> m ()
frontendShutdown :: MonadClientUI m => m ()

-- | Initialize the frontend chosen by the player via client options.
chanFrontend :: MonadClientUI m => ClientOptions -> m ChanFrontend
anyKeyPressed :: MonadClientUI m => m Bool
discardPressedKey :: MonadClientUI m => m ()
addPressedEsc :: MonadClientUI m => m ()
getReportUI :: MonadClientUI m => m Report
getLeaderUI :: MonadClientUI m => m ActorId
getArenaUI :: MonadClientUI m => m LevelId
viewedLevelUI :: MonadClientUI m => m LevelId
leaderTgtToPos :: MonadClientUI m => m (Maybe Point)
xhairToPos :: MonadClientUI m => m (Maybe Point)
clearXhair :: MonadClientUI m => m ()
clearAimMode :: MonadClientUI m => m ()
scoreToSlideshow :: MonadClientUI m => Int -> Status -> m Slideshow
defaultHistory :: MonadClientUI m => Int -> m History
tellAllClipPS :: MonadClientUI m => m ()
tellGameClipPS :: MonadClientUI m => m ()
elapsedSessionTimeGT :: MonadClientUI m => Int -> m Bool
resetSessionStart :: MonadClientUI m => m ()
resetGameStart :: MonadClientUI m => m ()

-- | The part of speech describing the actor or "you" if a leader of the
--   client's faction. The actor may be not present in the dungeon.
partActorLeader :: MonadClientUI m => ActorId -> ActorUI -> m Part
partActorLeaderFun :: MonadClientUI m => m (ActorId -> Part)

-- | The part of speech with the actor's pronoun or "you" if a leader of
--   the client's faction. The actor may be not present in the dungeon.
partPronounLeader :: MonadClient m => ActorId -> ActorUI -> m Part

-- | The part of speech describing the actor (designated by actor id and
--   present in the dungeon) or a special name if a leader of the
--   observer's faction.
partAidLeader :: MonadClientUI m => ActorId -> m Part

-- | Try to read saved client game state from the file system.
tryRestore :: MonadClientUI m => m (Maybe (StateClient, Maybe SessionUI))
leaderSkillsClientUI :: MonadClientUI m => m Skills

-- | Write a UI request to the frontend and read a corresponding reply.
connFrontend :: MonadClientUI m => FrontReq a -> m a
displayFrame :: MonadClientUI m => Maybe FrameForall -> m ()
addPressedKey :: MonadClientUI m => KMP -> m ()


-- | Running and disturbance.
--   
--   The general rule is: whatever is behind you (and so ignored
--   previously), determines what you ignore moving forward. This is
--   calcaulated separately for the tiles to the left, to the right and in
--   the middle along the running direction. So, if you want to ignore
--   something start running when you stand on it (or to the right or left,
--   respectively) or by entering it (or passing to the right or left,
--   respectively).
--   
--   Some things are never ignored, such as: enemies seen, imporant
--   messages heard, solid tiles and actors in the way.
module Game.LambdaHack.Client.UI.RunM

-- | Continue running in the given direction.
continueRun :: MonadClientUI m => LevelId -> RunParams -> m (Either Text RequestAnyAbility)

-- | This function implements the actual logic of running. It checks if we
--   have to stop running because something interesting cropped up, it
--   ajusts the direction given by the vector if we reached a corridor's
--   corner (we never change direction except in corridors) and it
--   increments the counter of traversed tiles.
--   
--   Note that while goto-xhair commands ignore items on the way, here we
--   stop wnenever we touch an item. Running is more cautious to compensate
--   that the player cannot specify the end-point of running. It's also
--   more suited to open, already explored terrain. Goto-xhair works better
--   with unknown terrain, e.g., it stops whenever an item is spotted, but
--   then ignores the item, leaving it to the player to mark the item
--   position as a goal of the next goto.
continueRunDir :: MonadClientUI m => RunParams -> m (Either Text Vector)
enterableDir :: COps -> Level -> Point -> Vector -> Bool
tryTurning :: MonadClient m => ActorId -> m (Either Text Vector)
checkAndRun :: MonadClient m => ActorId -> Vector -> m (Either Text Vector)


-- | Monadic operations on game messages.
module Game.LambdaHack.Client.UI.MsgM

-- | Add a message to the current report.
msgAdd :: MonadClientUI m => Text -> m ()

-- | Add a prompt to the current report.
promptAdd :: MonadClientUI m => Text -> m ()

-- | Add a prompt with basic keys description.
promptMainKeys :: MonadClientUI m => m ()

-- | Add a prompt to the current report.
promptAddAttr :: MonadClientUI m => AttrLine -> m ()

-- | Store current report in the history and reset report.
recordHistory :: MonadClientUI m => m ()


-- | Display game data on the screen using one of the available frontends
--   (determined at compile time with cabal flags).
module Game.LambdaHack.Client.UI.DrawM
targetDescLeader :: MonadClientUI m => ActorId -> m (Maybe Text, Maybe Text)

-- | Draw the whole screen: level map and status area.
drawBaseFrame :: MonadClientUI m => ColorMode -> LevelId -> m FrameForall
targetDesc :: MonadClientUI m => Maybe Target -> m (Maybe Text, Maybe Text)
targetDescXhair :: MonadClientUI m => m (Text, Maybe Text)
drawFrameTerrain :: forall m. MonadClientUI m => LevelId -> m FrameForall
drawFrameContent :: forall m. MonadClientUI m => LevelId -> m FrameForall
drawFramePath :: forall m. MonadClientUI m => LevelId -> m FrameForall
drawFrameActor :: forall m. MonadClientUI m => LevelId -> m FrameForall
drawFrameExtra :: forall m. MonadClientUI m => ColorMode -> LevelId -> m FrameForall
drawFrameStatus :: MonadClientUI m => LevelId -> m AttrLine
drawArenaStatus :: Bool -> Level -> Int -> AttrLine
drawLeaderStatus :: MonadClient m => Int -> m AttrLine
drawLeaderDamage :: MonadClientUI m => Int -> m AttrLine
drawSelected :: MonadClientUI m => LevelId -> Int -> EnumSet ActorId -> m (Int, AttrLine)


-- | A set of Frame monad operations.
module Game.LambdaHack.Client.UI.FrameM

-- | Push the frame depicting the current level to the frame queue. Only
--   one line of the report is shown, as in animations, because it may not
--   be our turn, so we can't clear the message to see what is underneath.
pushFrame :: MonadClientUI m => m ()
promptGetKey :: MonadClientUI m => ColorMode -> Overlay -> Bool -> [KM] -> m KM
stopPlayBack :: MonadClientUI m => m ()

-- | Render and display animations on top of the current screen frame.
animate :: MonadClientUI m => LevelId -> Animation -> m ()
fadeOutOrIn :: MonadClientUI m => Bool -> m ()

-- | Draw the current level with the overlay on top. If the overlay is too
--   long, it's truncated. Similarly, for each line of the overlay, if it's
--   too wide, it's truncated.
drawOverlay :: MonadClientUI m => ColorMode -> Bool -> Overlay -> LevelId -> m FrameForall

-- | Render animations on top of the current screen frame.
renderFrames :: MonadClientUI m => LevelId -> Animation -> m Frames


-- | Monadic operations on slideshows and related data.
module Game.LambdaHack.Client.UI.SlideshowM

-- | Add current report to the overlay, split the result and produce,
--   possibly, many slides.
overlayToSlideshow :: MonadClientUI m => Y -> [KM] -> OKX -> m Slideshow

-- | Split current report into a slideshow.
reportToSlideshow :: MonadClientUI m => [KM] -> m Slideshow

-- | Split current report into a slideshow. Keep report unchanged.
reportToSlideshowKeep :: MonadClientUI m => [KM] -> m Slideshow

-- | Display a message. Return value indicates if the player wants to
--   continue. Feature: if many pages, only the last SPACE exits (but first
--   ESC).
displaySpaceEsc :: MonadClientUI m => ColorMode -> Text -> m Bool

-- | Display a message. Ignore keypresses. Feature: if many pages, only the
--   last SPACE exits (but first ESC).
displayMore :: MonadClientUI m => ColorMode -> Text -> m ()
displayMoreKeep :: MonadClientUI m => ColorMode -> Text -> m ()

-- | Print a yes/no question and return the player's answer. Use black and
--   white colours to turn player's attention to the choice.
displayYesNo :: MonadClientUI m => ColorMode -> Text -> m Bool
getConfirms :: MonadClientUI m => ColorMode -> [KM] -> Slideshow -> m KM

-- | Display a, potentially, multi-screen menu and return the chosen key or
--   item slot label (and the index in the whole menu so that the cursor
--   can again be placed at that spot next time menu is displayed).
--   
--   This function is the only source of menus and so, effectively, UI
--   modes.
displayChoiceScreen :: forall m. MonadClientUI m => ColorMode -> Bool -> Int -> Slideshow -> [KM] -> m (Either KM SlotChar, Int)


-- | Helper functions for both inventory management and human commands.
module Game.LambdaHack.Client.UI.HandleHelperM

-- | Message describing the cause of failure of human command.
data FailError
showFailError :: FailError -> Text
type MError = Maybe FailError
mergeMError :: MError -> MError -> MError
type FailOrCmd a = Either FailError a
failWith :: MonadClientUI m => Text -> m (FailOrCmd a)
failSer :: MonadClientUI m => ReqFailure -> m (FailOrCmd a)
failMsg :: MonadClientUI m => Text -> m MError
weaveJust :: FailOrCmd a -> Either MError a
sortSlots :: MonadClientUI m => FactionId -> Maybe Actor -> m ()

-- | Switches current member to the next on the level, if any, wrapping.
memberCycle :: MonadClientUI m => Bool -> m MError

-- | Switches current member to the previous in the whole dungeon,
--   wrapping.
memberBack :: MonadClientUI m => Bool -> m MError
partyAfterLeader :: MonadClientUI m => ActorId -> m [(ActorId, Actor, ActorUI)]

-- | Select a faction leader. False, if nothing to do.
pickLeader :: MonadClientUI m => Bool -> ActorId -> m Bool
pickLeaderWithPointer :: MonadClientUI m => m MError
itemOverlay :: MonadClientUI m => CStore -> LevelId -> ItemBag -> m OKX
statsOverlay :: MonadClient m => ActorId -> m OKX
pickNumber :: MonadClientUI m => Bool -> Int -> m (Either MError Int)

-- | Produces a textual description of the terrain and items at an already
--   explored position. Mute for unknown positions. The detailed variant is
--   for use in the aiming mode.
lookAt :: MonadClientUI m => Bool -> Text -> Bool -> Point -> ActorId -> Text -> m Text
instance GHC.Show.Show Game.LambdaHack.Client.UI.HandleHelperM.FailError


-- | UI of inventory management.
module Game.LambdaHack.Client.UI.InventoryM
data Suitability
SuitsEverything :: Suitability
SuitsSomething :: (ItemFull -> Bool) -> Suitability

-- | Let the human player choose a single, preferably suitable, item from a
--   list of items. Don't display stores empty for all actors. Start with a
--   non-empty store.
getFull :: MonadClientUI m => m Suitability -> (Actor -> ActorUI -> AspectRecord -> ItemDialogMode -> Text) -> (Actor -> ActorUI -> AspectRecord -> ItemDialogMode -> Text) -> [CStore] -> [CStore] -> Bool -> Bool -> m (Either Text ([(ItemId, ItemFull)], (ItemDialogMode, Either KM SlotChar)))

-- | Let a human player choose any item from a given group. Note that this
--   does not guarantee the chosen item belongs to the group, as the player
--   can override the choice. Used e.g., for applying and projecting.
getGroupItem :: MonadClientUI m => m Suitability -> Text -> Text -> [CStore] -> [CStore] -> m (Either Text ((ItemId, ItemFull), (ItemDialogMode, Either KM SlotChar)))

-- | Display all items from a store and let the human player choose any or
--   switch to any other store. Used, e.g., for viewing inventory and item
--   descriptions.
getStoreItem :: MonadClientUI m => (Actor -> ActorUI -> AspectRecord -> ItemDialogMode -> Text) -> ItemDialogMode -> m (Either Text (ItemId, ItemFull), (ItemDialogMode, Either KM SlotChar))
ppItemDialogMode :: ItemDialogMode -> (Text, Text)
ppItemDialogModeFrom :: ItemDialogMode -> Text
storeFromMode :: ItemDialogMode -> CStore
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.InventoryM.ItemDialogState
instance GHC.Show.Show Game.LambdaHack.Client.UI.InventoryM.ItemDialogState


-- | Semantics of <a>Game.LambdaHack.Client.UI.HumanCmd</a> client commands
--   that do not return server requests,, but only change internal client
--   state. None of such commands takes game time.
module Game.LambdaHack.Client.UI.HandleHumanLocalM
macroHuman :: MonadClientUI m => [String] -> m ()

-- | Clear current messages, cycle key hints mode.
clearHuman :: MonadClientUI m => m ()
sortSlotsHuman :: MonadClientUI m => m ()

-- | Display items from a given container store and possibly let the user
--   chose one.
chooseItemHuman :: MonadClientUI m => ItemDialogMode -> m MError
chooseItemDialogMode :: MonadClientUI m => ItemDialogMode -> m (FailOrCmd ItemDialogMode)
chooseItemProjectHuman :: forall m. MonadClientUI m => [Trigger] -> m MError
chooseItemApplyHuman :: forall m. MonadClientUI m => [Trigger] -> m MError
psuitReq :: MonadClientUI m => [Trigger] -> m (Either Text (ItemFull -> Either ReqFailure (Point, Bool)))
triggerSymbols :: [Trigger] -> [Char]
permittedApplyClient :: MonadClientUI m => [Char] -> m (ItemFull -> Either ReqFailure Bool)
pickLeaderHuman :: MonadClientUI m => Int -> m MError
pickLeaderWithPointerHuman :: MonadClientUI m => m MError

-- | Switch current member to the next on the viewed level, if any,
--   wrapping.
memberCycleHuman :: MonadClientUI m => m MError

-- | Switch current member to the previous in the whole dungeon, wrapping.
memberBackHuman :: MonadClientUI m => m MError
selectActorHuman :: MonadClientUI m => m ()
selectNoneHuman :: MonadClientUI m => m ()
selectWithPointerHuman :: MonadClientUI m => m MError
repeatHuman :: MonadClientUI m => Int -> m ()
recordHuman :: MonadClientUI m => m ()
historyHuman :: forall m. MonadClientUI m => m ()
markVisionHuman :: MonadClientUI m => m ()
markSmellHuman :: MonadClientUI m => m ()
markSuspectHuman :: MonadClientUI m => m ()

-- | End aiming mode, rejecting the current position.
cancelHuman :: MonadClientUI m => m ()

-- | Accept the current x-hair position as target, ending aiming mode, if
--   active.
acceptHuman :: MonadClientUI m => m ()
tgtClearHuman :: MonadClientUI m => m ()
itemClearHuman :: MonadClientUI m => m ()

-- | Move the xhair. Assumes aiming mode.
moveXhairHuman :: MonadClientUI m => Vector -> Int -> m MError

-- | Start aiming.
aimTgtHuman :: MonadClientUI m => m MError

-- | Cycle aiming mode. Do not change position of the xhair, switch among
--   things at that position.
aimFloorHuman :: MonadClientUI m => m ()
aimEnemyHuman :: MonadClientUI m => m ()
aimItemHuman :: MonadClientUI m => m ()

-- | Change the displayed level in aiming mode to (at most) k levels
--   shallower. Enters aiming mode, if not already in one.
aimAscendHuman :: MonadClientUI m => Int -> m MError

-- | Tweak the <tt>eps</tt> parameter of the aiming digital line.
epsIncrHuman :: MonadClientUI m => Bool -> m ()
xhairUnknownHuman :: MonadClientUI m => m MError
xhairItemHuman :: MonadClientUI m => m MError
xhairStairHuman :: MonadClientUI m => Bool -> m MError
xhairPointerFloorHuman :: MonadClientUI m => m ()
xhairPointerEnemyHuman :: MonadClientUI m => m ()
aimPointerFloorHuman :: MonadClientUI m => m ()
aimPointerEnemyHuman :: MonadClientUI m => m ()
permittedProjectClient :: MonadClientUI m => [Char] -> m (ItemFull -> Either ReqFailure Bool)
projectCheck :: MonadClientUI m => Point -> m (Maybe ReqFailure)

-- | Check whether one is permitted to aim (for projecting) at a target
--   (this is only checked for actor targets so that the player doesn't
--   miss enemy getting out of sight; but for positions we let player shoot
--   at obstacles, e.g., to destroy them, and shoot at a lying item and
--   then at its posision, after enemy picked up the item). Returns a
--   different <tt>seps</tt> if needed to reach the target actor.
--   
--   Note: Perception is not enough for the check, because the target actor
--   can be obscured by a glass wall or be out of sight range, but in
--   weapon range.
xhairLegalEps :: MonadClientUI m => m (Either Text Int)
posFromXhair :: MonadClientUI m => m (Either Text Point)
selectAid :: MonadClientUI m => ActorId -> m ()

-- | End aiming mode, accepting the current position.
endAiming :: MonadClientUI m => m ()
endAimingMsg :: MonadClientUI m => m ()

-- | Perform look around in the current position of the xhair. Does nothing
--   outside aiming mode.
doLook :: MonadClientUI m => m ()
flashAiming :: MonadClientUI m => m ()
xhairPointerFloor :: MonadClientUI m => Bool -> m ()
xhairPointerEnemy :: MonadClientUI m => Bool -> m ()


-- | Display atomic commands received by the client.
module Game.LambdaHack.Client.UI.DisplayAtomicM

-- | Visualize atomic updates sent to the client. This is done in the
--   global state after the command is executed and after the client state
--   is modified by the command.
displayRespUpdAtomicUI :: MonadClientUI m => Bool -> UpdAtomic -> m ()

-- | Display special effects (text, animation) sent to the client.
displayRespSfxAtomicUI :: MonadClientUI m => Bool -> SfxAtomic -> m ()
updateItemSlot :: MonadClientUI m => CStore -> Maybe ActorId -> ItemId -> m SlotChar
markDisplayNeeded :: MonadClientUI m => LevelId -> m ()
updateItemSlotSide :: MonadClientUI m => CStore -> ActorId -> ItemId -> m SlotChar
lookAtMove :: MonadClientUI m => ActorId -> m ()
actorVerbMU :: MonadClientUI m => ActorId -> ActorUI -> Part -> m ()
aidVerbMU :: MonadClientUI m => ActorId -> Part -> m ()
itemVerbMU :: MonadClientUI m => ItemId -> ItemQuant -> Part -> Container -> m ()
itemAidVerbMU :: MonadClientUI m => ActorId -> Part -> ItemId -> Either (Maybe Int) Int -> CStore -> m ()
msgDuplicateScrap :: MonadClientUI m => m Bool
createActorUI :: MonadClientUI m => Bool -> ActorId -> Actor -> m ()
destroyActorUI :: MonadClientUI m => Bool -> ActorId -> Actor -> m ()
spotItem :: MonadClientUI m => Bool -> ItemId -> ItemQuant -> Container -> m ()
moveActor :: MonadClientUI m => ActorId -> Point -> Point -> m ()
displaceActorUI :: MonadClientUI m => ActorId -> ActorId -> m ()
moveItemUI :: MonadClientUI m => ItemId -> Int -> ActorId -> CStore -> CStore -> m ()
quitFactionUI :: MonadClientUI m => FactionId -> Maybe Status -> m ()
discover :: MonadClientUI m => Container -> ItemId -> m ()
ppSfxMsg :: MonadClientUI m => SfxMsg -> m Text
setLastSlot :: MonadClientUI m => ActorId -> ItemId -> CStore -> m ()
strike :: MonadClientUI m => Bool -> ActorId -> ActorId -> ItemId -> CStore -> m ()


-- | Semantics of <a>Game.LambdaHack.Client.UI.HumanCmd</a> client commands
--   that return server requests. A couple of them do not take time, the
--   rest does. Here prompts and menus are displayed, but any feedback
--   resulting from the commands (e.g., from inventory manipulation) is
--   generated later on, by the server, for all clients that witness the
--   results of the commands.
module Game.LambdaHack.Client.UI.HandleHumanGlobalM

-- | Pick command depending on area the mouse pointer is in. The first
--   matching area is chosen. If none match, only interrupt.
byAreaHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> [(CmdArea, HumanCmd)] -> m (Either MError ReqUI)
byAimModeHuman :: MonadClientUI m => m (Either MError ReqUI) -> m (Either MError ReqUI) -> m (Either MError ReqUI)
byItemModeHuman :: MonadClientUI m => [Trigger] -> m (Either MError ReqUI) -> m (Either MError ReqUI) -> m (Either MError ReqUI)
composeIfLocalHuman :: MonadClientUI m => m (Either MError ReqUI) -> m (Either MError ReqUI) -> m (Either MError ReqUI)
composeUnlessErrorHuman :: MonadClientUI m => m (Either MError ReqUI) -> m (Either MError ReqUI) -> m (Either MError ReqUI)
compose2ndLocalHuman :: MonadClientUI m => m (Either MError ReqUI) -> m (Either MError ReqUI) -> m (Either MError ReqUI)
loopOnNothingHuman :: MonadClientUI m => m (Either MError ReqUI) -> m (Either MError ReqUI)

-- | Leader waits a turn (and blocks, etc.).
waitHuman :: MonadClientUI m => m (RequestTimed  'AbWait)

-- | Leader waits a 1/10th of a turn (and doesn't block, etc.).
waitHuman10 :: MonadClientUI m => m (RequestTimed  'AbWait)
moveRunHuman :: MonadClientUI m => Bool -> Bool -> Bool -> Bool -> Vector -> m (FailOrCmd RequestAnyAbility)
runOnceAheadHuman :: MonadClientUI m => m (Either MError ReqUI)
moveOnceToXhairHuman :: MonadClientUI m => m (FailOrCmd RequestAnyAbility)
runOnceToXhairHuman :: MonadClientUI m => m (FailOrCmd RequestAnyAbility)
continueToXhairHuman :: MonadClientUI m => m (FailOrCmd RequestAnyAbility)
moveItemHuman :: forall m. MonadClientUI m => [CStore] -> CStore -> Maybe Part -> Bool -> m (FailOrCmd (RequestTimed  'AbMoveItem))
projectHuman :: MonadClientUI m => [Trigger] -> m (FailOrCmd (RequestTimed  'AbProject))
applyHuman :: MonadClientUI m => [Trigger] -> m (FailOrCmd (RequestTimed  'AbApply))

-- | Ask for a direction and alter a tile in the specified way, if
--   possible.
alterDirHuman :: MonadClientUI m => [Trigger] -> m (FailOrCmd (RequestTimed  'AbAlter))

-- | Try to alter a tile using a feature under the pointer.
alterWithPointerHuman :: MonadClientUI m => [Trigger] -> m (FailOrCmd (RequestTimed  'AbAlter))

-- | Display command help.
helpHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> m (Either MError ReqUI)
itemMenuHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> m (Either MError ReqUI)
chooseItemMenuHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> ItemDialogMode -> m (Either MError ReqUI)

-- | Display the main menu.
mainMenuHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> m (Either MError ReqUI)

-- | Display the settings menu.
settingsMenuHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> m (Either MError ReqUI)

-- | Display the challenges menu.
challengesMenuHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> m (Either MError ReqUI)
gameScenarioIncr :: MonadClientUI m => m ()
gameDifficultyIncr :: MonadClientUI m => m ()
gameWolfToggle :: MonadClientUI m => m ()
gameFishToggle :: MonadClientUI m => m ()
gameRestartHuman :: MonadClientUI m => m (FailOrCmd ReqUI)
gameExitHuman :: MonadClientUI m => m ReqUI
gameSaveHuman :: MonadClientUI m => m ReqUI
tacticHuman :: MonadClientUI m => m (FailOrCmd ReqUI)
automateHuman :: MonadClientUI m => m (FailOrCmd ReqUI)
areaToRectangles :: MonadClientUI m => CmdArea -> m [(X, Y, X, Y)]

-- | Actor attacks an enemy actor or his own projectile.
meleeAid :: MonadClientUI m => ActorId -> m (FailOrCmd (RequestTimed  'AbMelee))

-- | Actor swaps position with another.
displaceAid :: MonadClientUI m => ActorId -> m (FailOrCmd (RequestTimed  'AbDisplace))

-- | Leader moves or searches or alters. No visible actor at the position.
moveSearchAlter :: MonadClientUI m => Vector -> m (FailOrCmd RequestAnyAbility)
goToXhair :: MonadClientUI m => Bool -> Bool -> m (FailOrCmd RequestAnyAbility)
multiActorGoTo :: MonadClientUI m => LevelId -> Point -> RunParams -> m (FailOrCmd (Bool, Vector))
selectItemsToMove :: forall m. MonadClientUI m => [CStore] -> CStore -> Maybe Part -> Bool -> m (FailOrCmd (CStore, [(ItemId, ItemFull)]))
moveItems :: forall m. MonadClientUI m => [CStore] -> (CStore, [(ItemId, ItemFull)]) -> CStore -> m (FailOrCmd (RequestTimed  'AbMoveItem))
projectItem :: MonadClientUI m => [Trigger] -> (CStore, (ItemId, ItemFull)) -> m (FailOrCmd (RequestTimed  'AbProject))
applyItem :: MonadClientUI m => [Trigger] -> (CStore, (ItemId, ItemFull)) -> m (FailOrCmd (RequestTimed  'AbApply))

-- | Try to alter a tile using a feature in the given direction.
alterTile :: MonadClientUI m => [Trigger] -> Vector -> m (FailOrCmd (RequestTimed  'AbAlter))

-- | Try to alter a tile using a feature at the given position.
alterTileAtPos :: MonadClientUI m => [Trigger] -> Point -> Text -> m (FailOrCmd (RequestTimed  'AbAlter))

-- | Verify important effects, such as fleeing the dungeon.
--   
--   This is contrived for now, the embedded items are not analyzed, but
--   only recognized by name.
verifyAlters :: MonadClientUI m => LevelId -> Point -> m (FailOrCmd ())
verifyEscape :: MonadClientUI m => m (FailOrCmd ())

-- | Guess and report why the bump command failed.
guessAlter :: COps -> [Trigger] -> Id TileKind -> Text
artWithVersion :: MonadClientUI m => m [String]
generateMenu :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> [(KM, (Text, HumanCmd))] -> [String] -> String -> m (Either MError ReqUI)
nxtGameMode :: COps -> Int -> ModeKind


-- | Semantics of human player commands.
module Game.LambdaHack.Client.UI.HandleHumanM

-- | The semantics of human player commands in terms of the client monad.
--   
--   Some time cosuming commands are enabled even in aiming mode, but
--   cannot be invoked in aiming mode on a remote level (level different
--   than the level of the leader), which is caught here.
cmdHumanSem :: MonadClientUI m => HumanCmd -> m (Either MError ReqUI)

-- | Commands that are forbidden on a remote level, because they would
--   usually take time when invoked on one, but not necessarily do what the
--   player expects. Note that some commands that normally take time are
--   not included, because they don't take time in aiming mode or their
--   individual sanity conditions include a remote level check.
noRemoteHumanCmd :: HumanCmd -> Bool
cmdAction :: MonadClientUI m => HumanCmd -> m (Either MError ReqUI)
addNoError :: Monad m => m () -> m (Either MError ReqUI)
fmapTimedToUI :: Monad m => m (RequestTimed a) -> m ReqUI


-- | Ways for the client to use player input via UI to produce server
--   requests, based on the client's view (visualized for the player) of
--   the game state.
module Game.LambdaHack.Client.UI

-- | Handle the move of a human player.
queryUI :: MonadClientUI m => m RequestUI

-- | The monad that gives the client access to UI operations.
class MonadClient m => MonadClientUI m
getsSession :: MonadClientUI m => (SessionUI -> a) -> m a
modifySession :: MonadClientUI m => (SessionUI -> SessionUI) -> m ()
liftIO :: MonadClientUI m => IO a -> m a

-- | The information that is used across a client playing session,
--   including many consecutive games in a single session. Some of it is
--   saved, some is reset when a new playing session starts. An important
--   component is the frontend session.
data SessionUI
SessionUI :: Target -> ActorDictUI -> ItemSlots -> SlotChar -> Maybe (CStore, CStore) -> ChanFrontend -> Binding -> UIOptions -> Maybe AimMode -> Bool -> Maybe (CStore, ItemId) -> EnumSet ActorId -> Maybe RunParams -> Report -> History -> Point -> LastRecord -> [KM] -> EnumSet ActorId -> Int -> Bool -> Bool -> Map String Int -> Bool -> KeysHintMode -> POSIXTime -> POSIXTime -> Time -> Int -> Int -> SessionUI

-- | the common xhair
[sxhair] :: SessionUI -> Target

-- | assigned actor UI presentations
[sactorUI] :: SessionUI -> ActorDictUI

-- | map from slots to items
[sslots] :: SessionUI -> ItemSlots

-- | last used slot
[slastSlot] :: SessionUI -> SlotChar

-- | last item move stores
[slastItemMove] :: SessionUI -> Maybe (CStore, CStore)

-- | connection with the frontend
[schanF] :: SessionUI -> ChanFrontend

-- | binding of keys to commands
[sbinding] :: SessionUI -> Binding

-- | UI options as set by the player
[sUIOptions] :: SessionUI -> UIOptions

-- | aiming mode
[saimMode] :: SessionUI -> Maybe AimMode

-- | last mouse aiming not vacuus
[sxhairMoused] :: SessionUI -> Bool

-- | selected item, if any
[sitemSel] :: SessionUI -> Maybe (CStore, ItemId)

-- | the set of currently selected actors
[sselected] :: SessionUI -> EnumSet ActorId

-- | parameters of the current run, if any
[srunning] :: SessionUI -> Maybe RunParams

-- | current messages
[_sreport] :: SessionUI -> Report

-- | history of messages
[shistory] :: SessionUI -> History

-- | mouse pointer position
[spointer] :: SessionUI -> Point

-- | state of key sequence recording
[slastRecord] :: SessionUI -> LastRecord

-- | state of key sequence playback
[slastPlay] :: SessionUI -> [KM]

-- | actors that just got out of sight
[slastLost] :: SessionUI -> EnumSet ActorId

-- | player just waited this many times
[swaitTimes] :: SessionUI -> Int

-- | mark leader and party FOV
[smarkVision] :: SessionUI -> Bool

-- | mark smell, if the leader can smell
[smarkSmell] :: SessionUI -> Bool

-- | indices of last used menu items
[smenuIxMap] :: SessionUI -> Map String Int

-- | current level needs displaying
[sdisplayNeeded] :: SessionUI -> Bool

-- | how to show keys hints when no messages
[skeysHintMode] :: SessionUI -> KeysHintMode

-- | this session start time
[sstart] :: SessionUI -> POSIXTime

-- | this game start time
[sgstart] :: SessionUI -> POSIXTime

-- | clips from start of session to current game start
[sallTime] :: SessionUI -> Time

-- | this game current frame count
[snframes] :: SessionUI -> Int

-- | frame count from start of session to current game start
[sallNframes] :: SessionUI -> Int

-- | Visualize atomic updates sent to the client. This is done in the
--   global state after the command is executed and after the client state
--   is modified by the command.
displayRespUpdAtomicUI :: MonadClientUI m => Bool -> UpdAtomic -> m ()

-- | Display special effects (text, animation) sent to the client.
displayRespSfxAtomicUI :: MonadClientUI m => Bool -> SfxAtomic -> m ()

-- | Key-command mappings to be specified in content and used for the UI.
data KeyKind

-- | Options that affect the UI of the client.
data UIOptions

-- | Modify client options with UI options.
applyUIOptions :: COps -> UIOptions -> ClientOptions -> ClientOptions

-- | Hardwired commandline arguments to process.
uCmdline :: UIOptions -> [String]

-- | Read and parse UI config file.
mkUIOptions :: COps -> Bool -> IO UIOptions

-- | Connection channel between a frontend and a client. Frontend acts as a
--   server, serving keys, etc., when given frames to display.
data ChanFrontend

-- | Initialize the frontend chosen by the player via client options.
chanFrontend :: MonadClientUI m => ClientOptions -> m ChanFrontend

-- | Add a message to the current report.
msgAdd :: MonadClientUI m => Text -> m ()

-- | Try to read saved client game state from the file system.
tryRestore :: MonadClientUI m => m (Maybe (StateClient, Maybe SessionUI))

-- | Create binding of keys to movement and other standard commands, as
--   well as commands defined in the config file.
stdBinding :: KeyKind -> UIOptions -> Binding

-- | Let the human player issue commands until any command takes time.
humanCommand :: forall m. MonadClientUI m => m ReqUI


-- | Semantics of responses sent by the server to clients.
module Game.LambdaHack.Client.HandleResponseM

-- | Client monad in which one can send requests to the client.
class MonadClient m => MonadClientWriteRequest m
sendRequestAI :: MonadClientWriteRequest m => RequestAI -> m ()
sendRequestUI :: MonadClientWriteRequest m => RequestUI -> m ()
clientHasUI :: MonadClientWriteRequest m => m Bool

-- | Monad for executing atomic game state transformations on a client.
class MonadClient m => MonadClientAtomic m

-- | Execute an atomic update that changes the client's <a>State</a>.
execUpdAtomic :: MonadClientAtomic m => UpdAtomic -> m ()

-- | Put state that is intended to be the result of performing an atomic
--   update by the server on its copy of the client's <a>State</a>.
execPutState :: MonadClientAtomic m => State -> m ()

-- | Handle server responses.
--   
--   Note that for clients communicating with the server over the net,
--   <tt>RespUpdAtomicNoState</tt> should be used, because executing a
--   single command is cheaper than sending the whole state over the net.
--   However, for the standalone exe mode, with clients in the same process
--   as the server, a pointer to the state set with <tt>execPutState</tt>
--   is cheaper.
handleResponse :: (MonadClientSetup m, MonadClientUI m, MonadClientAtomic m, MonadClientWriteRequest m) => Response -> m ()


-- | The main loop of the client, processing human and computer player
--   moves turn by turn.
module Game.LambdaHack.Client.LoopM

-- | Client monad in which one can receive responses from the server.
class MonadClient m => MonadClientReadResponse m
receiveResponse :: MonadClientReadResponse m => m Response

-- | The main game loop for an AI or UI client. It receives responses from
--   the server, changes internal client state accordingly, analyzes
--   ensuing human or AI commands and sends resulting requests to the
--   server. Depending on whether it's an AI or UI client, it sends AI or
--   human player requests.
--   
--   The loop is started in client state that is empty except for the
--   <tt>sside</tt> and <tt>seps</tt> fields, see <a>emptyStateClient</a>.
loopCli :: (MonadClientSetup m, MonadClientUI m, MonadClientAtomic m, MonadClientReadResponse m, MonadClientWriteRequest m) => KeyKind -> UIOptions -> ClientOptions -> m ()
initAI :: MonadClient m => m ()
initUI :: MonadClientUI m => KeyKind -> UIOptions -> m ()


-- | Semantics of responses that are sent from server to clients, in terms
--   of client state transformations, and semantics of human commands and
--   AI moves, in terms of requests to be sent from the client to the
--   server.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Client

-- | The main game loop for an AI or UI client. It receives responses from
--   the server, changes internal client state accordingly, analyzes
--   ensuing human or AI commands and sends resulting requests to the
--   server. Depending on whether it's an AI or UI client, it sends AI or
--   human player requests.
--   
--   The loop is started in client state that is empty except for the
--   <tt>sside</tt> and <tt>seps</tt> fields, see <a>emptyStateClient</a>.
loopCli :: (MonadClientSetup m, MonadClientUI m, MonadClientAtomic m, MonadClientReadResponse m, MonadClientWriteRequest m) => KeyKind -> UIOptions -> ClientOptions -> m ()

-- | Requests sent by AI clients to the server. If faction leader is to be
--   changed, it's included as the second component.
type RequestAI = (ReqAI, Maybe ActorId)

-- | Possible forms of requests sent by AI clients.
data ReqAI
ReqAINop :: ReqAI
ReqAITimed :: RequestAnyAbility -> ReqAI

-- | Requests sent by UI clients to the server. If faction leader is to be
--   changed, it's included as the second component.
type RequestUI = (ReqUI, Maybe ActorId)

-- | Possible forms of requests sent by UI clients.
data ReqUI
ReqUINop :: ReqUI
ReqUITimed :: RequestAnyAbility -> ReqUI
ReqUIGameRestart :: (GroupName ModeKind) -> Challenge -> ReqUI
ReqUIGameExit :: ReqUI
ReqUIGameSave :: ReqUI
ReqUITactic :: Tactic -> ReqUI
ReqUIAutomate :: ReqUI

-- | Basic form of requests, sent by both AI and UI clients to the server.
data RequestAnyAbility
RequestAnyAbility :: (RequestTimed a) -> RequestAnyAbility

-- | Requests that take game time, indexed by actor ability that is needed
--   for performing the corresponding actions.
data RequestTimed :: Ability -> *
[ReqMove] :: Vector -> RequestTimed  'AbMove
[ReqMelee] :: ActorId -> ItemId -> CStore -> RequestTimed  'AbMelee
[ReqDisplace] :: ActorId -> RequestTimed  'AbDisplace
[ReqAlter] :: Point -> RequestTimed  'AbAlter
[ReqWait] :: RequestTimed  'AbWait
[ReqWait10] :: RequestTimed  'AbWait
[ReqMoveItems] :: [(ItemId, Int, CStore, CStore)] -> RequestTimed  'AbMoveItem
[ReqProject] :: Point -> Int -> ItemId -> CStore -> RequestTimed  'AbProject
[ReqApply] :: ItemId -> CStore -> RequestTimed  'AbApply

-- | Abstract syntax of responses sent by server to an AI or UI client (or
--   a universal client that can handle both roles, which is why this type
--   is not separated into distinct AI and UI types). A response tells a
--   client how to update game state or what information to send to the
--   server.
data Response

-- | change <tt>State</tt> by performing this atomic update
RespUpdAtomicNoState :: UpdAtomic -> Response

-- | put the given <tt>State</tt>, which results from performing the atomic
--   update
RespUpdAtomic :: State -> UpdAtomic -> Response

-- | compute an AI move for the actor and send (the semantics of) it
RespQueryAI :: ActorId -> Response

-- | perform special effects (animations, messages, etc.)
RespSfxAtomic :: SfxAtomic -> Response

-- | prompt the human player for a command and send (the semantics of) it
RespQueryUI :: Response

-- | Options that affect the behaviour of the client (but not game rules).
data ClientOptions

-- | Default value of client options.
defClientOptions :: ClientOptions

-- | Don't create directories and files and show time stats.
sbenchmark :: ClientOptions -> Bool

-- | Key-command mappings to be specified in content and used for the UI.
data KeyKind

-- | Options that affect the UI of the client.
data UIOptions

-- | Modify client options with UI options.
applyUIOptions :: COps -> UIOptions -> ClientOptions -> ClientOptions

-- | Hardwired commandline arguments to process.
uCmdline :: UIOptions -> [String]

-- | Read and parse UI config file.
mkUIOptions :: COps -> Bool -> IO UIOptions


-- | Server and client game state types and operations.
module Game.LambdaHack.Server.ServerOptions

-- | Options that affect the behaviour of the server (including game
--   rules).
data ServerOptions
ServerOptions :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe (GroupName ModeKind) -> Bool -> Bool -> Maybe StdGen -> Maybe StdGen -> Bool -> Challenge -> Bool -> String -> Bool -> ClientOptions -> ServerOptions
[sknowMap] :: ServerOptions -> Bool
[sknowEvents] :: ServerOptions -> Bool
[sknowItems] :: ServerOptions -> Bool
[sniff] :: ServerOptions -> Bool
[sallClear] :: ServerOptions -> Bool
[sboostRandomItem] :: ServerOptions -> Bool
[sgameMode] :: ServerOptions -> Maybe (GroupName ModeKind)
[sautomateAll] :: ServerOptions -> Bool
[skeepAutomated] :: ServerOptions -> Bool
[sdungeonRng] :: ServerOptions -> Maybe StdGen
[smainRng] :: ServerOptions -> Maybe StdGen
[snewGameSer] :: ServerOptions -> Bool
[scurChalSer] :: ServerOptions -> Challenge
[sdumpInitRngs] :: ServerOptions -> Bool
[ssavePrefixSer] :: ServerOptions -> String
[sdbgMsgSer] :: ServerOptions -> Bool
[sclientOptions] :: ServerOptions -> ClientOptions
data RNGs
RNGs :: Maybe StdGen -> Maybe StdGen -> RNGs
[dungeonRandomGenerator] :: RNGs -> Maybe StdGen
[startingRandomGenerator] :: RNGs -> Maybe StdGen

-- | Default value of server options.
defServerOptions :: ServerOptions
instance GHC.Show.Show Game.LambdaHack.Server.ServerOptions.ServerOptions
instance GHC.Show.Show Game.LambdaHack.Server.ServerOptions.RNGs
instance Data.Binary.Class.Binary Game.LambdaHack.Server.ServerOptions.RNGs
instance Data.Binary.Class.Binary Game.LambdaHack.Server.ServerOptions.ServerOptions


-- | Server and client game state types and operations.
module Game.LambdaHack.Server.State

-- | State with server-specific data, including a copy of each client's
--   basic game state, but not the server's basic state.
data StateServer
StateServer :: ActorTime -> DiscoveryKindRev -> UniqueSet -> ItemSeedDict -> ItemRev -> FlavourMap -> ActorId -> ItemId -> EnumMap LevelId Int -> [CmdAtomic] -> EnumMap FactionId State -> PerFid -> PerValidFid -> PerCacheFid -> FovLucidLid -> FovClearLid -> FovLitLid -> [LevelId] -> Bool -> StdGen -> RNGs -> Bool -> Bool -> ServerOptions -> ServerOptions -> StateServer

-- | absolute times of next actions
[sactorTime] :: StateServer -> ActorTime

-- | reverse map, used for item creation
[sdiscoKindRev] :: StateServer -> DiscoveryKindRev

-- | already generated unique items
[suniqueSet] :: StateServer -> UniqueSet

-- | map from item ids to item seeds
[sitemSeedD] :: StateServer -> ItemSeedDict

-- | reverse id map, used for item creation
[sitemRev] :: StateServer -> ItemRev

-- | association of flavour to items
[sflavour] :: StateServer -> FlavourMap

-- | stores next actor index
[sacounter] :: StateServer -> ActorId

-- | stores next item index
[sicounter] :: StateServer -> ItemId
[snumSpawned] :: StateServer -> EnumMap LevelId Int

-- | atomic commands performed to date
[sundo] :: StateServer -> [CmdAtomic]

-- | each faction state, as seen by clients
[sclientStates] :: StateServer -> EnumMap FactionId State

-- | perception of all factions
[sperFid] :: StateServer -> PerFid

-- | perception validity for all factions
[sperValidFid] :: StateServer -> PerValidFid

-- | perception cache of all factions
[sperCacheFid] :: StateServer -> PerCacheFid

-- | ambient or shining light positions
[sfovLucidLid] :: StateServer -> FovLucidLid

-- | clear tiles positions
[sfovClearLid] :: StateServer -> FovClearLid

-- | ambient light positions
[sfovLitLid] :: StateServer -> FovLitLid

-- | active arenas
[sarenas] :: StateServer -> [LevelId]

-- | whether active arenas valid
[svalidArenas] :: StateServer -> Bool

-- | current random generator
[srandom] :: StateServer -> StdGen

-- | initial random generators
[srngs] :: StateServer -> RNGs

-- | exit the game loop
[squit] :: StateServer -> Bool

-- | write savegame to a file now
[swriteSave] :: StateServer -> Bool

-- | current commandline options
[soptions] :: StateServer -> ServerOptions

-- | options for the next game
[soptionsNxt] :: StateServer -> ServerOptions

-- | Position in time for each actor, grouped by level and by faction.
type ActorTime = EnumMap FactionId (EnumMap LevelId (EnumMap ActorId Time))

-- | Initial, empty game server state.
emptyStateServer :: StateServer
updateActorTime :: FactionId -> LevelId -> ActorId -> Time -> ActorTime -> ActorTime
ageActor :: FactionId -> LevelId -> ActorId -> Delta Time -> ActorTime -> ActorTime
instance GHC.Show.Show Game.LambdaHack.Server.State.StateServer
instance Data.Binary.Class.Binary Game.LambdaHack.Server.State.StateServer


-- | Parsing of commandline arguments.
module Game.LambdaHack.Server.Commandline

-- | Parser for server options from commandline arguments.
serverOptionsPI :: ParserInfo ServerOptions
serverOptionsP :: Parser ServerOptions


-- | Basic server monads and related operations.
module Game.LambdaHack.Server.MonadServer
class MonadStateRead m => MonadServer m
getsServer :: MonadServer m => (StateServer -> a) -> m a
modifyServer :: MonadServer m => (StateServer -> StateServer) -> m ()
chanSaveServer :: MonadServer m => m (ChanSave (State, StateServer))
liftIO :: MonadServer m => IO a -> m a

-- | The monad for executing atomic game state transformations.
class MonadServer m => MonadServerAtomic m

-- | Execute an atomic command that changes the state on the server and on
--   all clients that can notice it.
execUpdAtomic :: MonadServerAtomic m => UpdAtomic -> m ()

-- | Execute an atomic command that changes the state on the server only.
execUpdAtomicSer :: MonadServerAtomic m => UpdAtomic -> m Bool

-- | Execute an atomic command that changes the state on the given single
--   client only.
execUpdAtomicFid :: MonadServerAtomic m => FactionId -> UpdAtomic -> m ()

-- | Execute an atomic command that changes the state on the given single
--   client only. Catch <a>AtomicFail</a> and indicate if it was in fact
--   raised.
execUpdAtomicFidCatch :: MonadServerAtomic m => FactionId -> UpdAtomic -> m Bool

-- | Execute an atomic command that only displays special effects.
execSfxAtomic :: MonadServerAtomic m => SfxAtomic -> m ()
execSendPer :: MonadServerAtomic m => FactionId -> LevelId -> Perception -> Perception -> Perception -> m ()
getServer :: MonadServer m => m StateServer
putServer :: MonadServer m => StateServer -> m ()
debugPossiblyPrint :: MonadServer m => Text -> m ()
debugPossiblyPrintAndExit :: MonadServer m => Text -> m ()
serverPrint :: MonadServer m => Text -> m ()
saveServer :: MonadServer m => m ()

-- | Dumps to stdout the RNG states from the start of the game.
dumpRngs :: MonadServer m => RNGs -> m ()

-- | Read the high scores dictionary. Return the empty table if no file.
restoreScore :: forall m. MonadServer m => COps -> m ScoreDict

-- | Generate a new score, register it and save.
registerScore :: MonadServer m => Status -> FactionId -> m ()

-- | Invoke pseudo-random computation with the generator kept in the state.
rndToAction :: MonadServer m => Rnd a -> m a

-- | Gets a random generator from the user-submitted options or, if not
--   present, generates one.
getSetGen :: MonadServer m => Maybe StdGen -> m StdGen


-- | Server operations for items.
module Game.LambdaHack.Server.ItemM
registerItem :: MonadServerAtomic m => ItemFull -> ItemKnown -> ItemSeed -> Container -> Bool -> m ItemId
embedItem :: MonadServerAtomic m => LevelId -> Point -> Id TileKind -> m ()
rollItem :: MonadServerAtomic m => Int -> LevelId -> Freqs ItemKind -> m (Maybe (ItemKnown, ItemFull, ItemDisco, ItemSeed, GroupName ItemKind))
rollAndRegisterItem :: MonadServerAtomic m => LevelId -> Freqs ItemKind -> Container -> Bool -> Maybe Int -> m (Maybe (ItemId, (ItemFull, GroupName ItemKind)))
placeItemsInDungeon :: forall m. MonadServerAtomic m => m ()
embedItemsInDungeon :: MonadServerAtomic m => m ()

-- | Mapping over actor's items from a give store.
mapActorCStore_ :: MonadServer m => CStore -> (ItemId -> ItemQuant -> m a) -> Actor -> m ()
onlyRegisterItem :: MonadServerAtomic m => ItemKnown -> ItemSeed -> m ItemId
createLevelItem :: MonadServerAtomic m => Point -> LevelId -> m ()


-- | Handle atomic commands on the server, after they are executed to
--   change server <a>State</a> and before they are sent to clients.
module Game.LambdaHack.Server.HandleAtomicM

-- | Effect of atomic actions on server state is calculated with the global
--   state from after the command is executed (except where the supplied
--   <tt>oldState</tt> is used).
cmdAtomicSemSer :: MonadServer m => State -> UpdAtomic -> m ()
invalidateArenas :: MonadServer m => m ()
updateSclear :: MonadServer m => LevelId -> Point -> Id TileKind -> Id TileKind -> m Bool
updateSlit :: MonadServer m => LevelId -> Point -> Id TileKind -> Id TileKind -> m Bool
invalidateLucidLid :: MonadServer m => LevelId -> m ()
invalidateLucidAid :: MonadServer m => ActorId -> m ()
actorHasShine :: ActorAspect -> ActorId -> Bool
itemAffectsShineRadius :: DiscoveryAspect -> ItemId -> [CStore] -> Bool
itemAffectsPerRadius :: DiscoveryAspect -> ItemId -> Bool
addPerActor :: MonadServer m => ActorId -> Actor -> m ()
addPerActorAny :: MonadServer m => ActorId -> Actor -> m ()
deletePerActor :: MonadServer m => ActorAspect -> ActorId -> Actor -> m ()
deletePerActorAny :: MonadServer m => ActorId -> Actor -> m ()
invalidatePerActor :: MonadServer m => ActorId -> m ()
reconsiderPerActor :: MonadServer m => ActorId -> m ()
invalidatePerLid :: MonadServer m => LevelId -> m ()


-- | Debug output for requests and responses.
module Game.LambdaHack.Server.DebugM
debugResponse :: MonadServer m => FactionId -> Response -> m ()
debugRequestAI :: MonadServer m => ActorId -> m ()
debugRequestUI :: MonadServer m => ActorId -> m ()
debugShow :: Show a => a -> Text
debugPretty :: MonadServer m => FactionId -> Text -> UpdAtomic -> m ()
debugPlain :: MonadServer m => FactionId -> Text -> UpdAtomic -> m ()
data DebugAid
DebugAid :: Text -> ActorId -> FactionId -> LevelId -> Int64 -> Time -> Time -> DebugAid
[label] :: DebugAid -> Text
[aid] :: DebugAid -> ActorId
[faction] :: DebugAid -> FactionId
[lid] :: DebugAid -> LevelId
[bHP] :: DebugAid -> Int64
[btime] :: DebugAid -> Time
[time] :: DebugAid -> Time
debugAid :: MonadServer m => ActorId -> Text -> m Text
instance GHC.Show.Show Game.LambdaHack.Server.DebugM.DebugAid


-- | The server definitions for the server-client communication protocol.
module Game.LambdaHack.Server.ProtocolM
type CliSerQueue = MVar

-- | Connection information for all factions, indexed by faction
--   identifier.
type ConnServerDict = EnumMap FactionId ChanServer

-- | Connection channel between the server and a single client.
data ChanServer
ChanServer :: CliSerQueue Response -> CliSerQueue RequestAI -> Maybe (CliSerQueue RequestUI) -> ChanServer
[responseS] :: ChanServer -> CliSerQueue Response
[requestAIS] :: ChanServer -> CliSerQueue RequestAI
[requestUIS] :: ChanServer -> Maybe (CliSerQueue RequestUI)

-- | The server monad with the ability to communicate with clients.
class MonadServer m => MonadServerReadRequest m
getsDict :: MonadServerReadRequest m => (ConnServerDict -> a) -> m a
modifyDict :: MonadServerReadRequest m => (ConnServerDict -> ConnServerDict) -> m ()
liftIO :: MonadServerReadRequest m => IO a -> m a
putDict :: MonadServerReadRequest m => ConnServerDict -> m ()

-- | If the <tt>AtomicFail</tt> conditions hold, send a command to client,
--   otherwise do nothing.
sendUpdate :: (MonadServerAtomic m, MonadServerReadRequest m) => FactionId -> UpdAtomic -> m ()

-- | Send a command to client, crashing if the <tt>AtomicFail</tt>
--   conditions don't hold when executed on the client's state.
sendUpdateCheck :: (MonadServerAtomic m, MonadServerReadRequest m) => FactionId -> UpdAtomic -> m ()
sendUpdNoState :: MonadServerReadRequest m => FactionId -> UpdAtomic -> m ()
sendSfx :: MonadServerReadRequest m => FactionId -> SfxAtomic -> m ()
sendQueryAI :: MonadServerReadRequest m => FactionId -> ActorId -> m RequestAI
sendQueryUI :: (MonadServerAtomic m, MonadServerReadRequest m) => FactionId -> ActorId -> m RequestUI
killAllClients :: (MonadServerAtomic m, MonadServerReadRequest m) => m ()
childrenServer :: MVar [Async ()]

-- | Update connections to the new definition of factions. Connect to
--   clients in old or newly spawned threads that read and write directly
--   to the channels.
updateConn :: (MonadServerAtomic m, MonadServerReadRequest m) => (Bool -> FactionId -> ChanServer -> IO ()) -> m ()
tryRestore :: MonadServerReadRequest m => m (Maybe (State, StateServer))
writeQueue :: MonadServerReadRequest m => Response -> CliSerQueue Response -> m ()
readQueueAI :: MonadServerReadRequest m => CliSerQueue RequestAI -> m RequestAI
readQueueUI :: MonadServerReadRequest m => CliSerQueue RequestUI -> m RequestUI
newQueue :: IO (CliSerQueue a)


-- | Sending atomic commands to clients and executing them on the server.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Server.BroadcastAtomic

-- | Send an atomic action to all clients that can see it.
handleAndBroadcast :: (MonadServerAtomic m, MonadServerReadRequest m) => PosAtomic -> [UpdAtomic] -> CmdAtomic -> m ()
sendPer :: (MonadServerAtomic m, MonadServerReadRequest m) => FactionId -> LevelId -> Perception -> Perception -> Perception -> m ()
handleCmdAtomicServer :: MonadServerAtomic m => UpdAtomic -> m (PosAtomic, [UpdAtomic], Bool)

-- | Messages for some unseen atomic commands.
loudUpdAtomic :: MonadStateRead m => Bool -> UpdAtomic -> m (Maybe SfxMsg)

-- | Messages for some unseen sfx.
loudSfxAtomic :: MonadStateRead m => Bool -> SfxAtomic -> m (Maybe SfxMsg)
atomicForget :: FactionId -> LevelId -> Perception -> State -> [UpdAtomic]
atomicRemember :: LevelId -> Perception -> State -> State -> [UpdAtomic]


-- | Server operations common to many modules.
module Game.LambdaHack.Server.CommonM
execFailure :: MonadServerAtomic m => ActorId -> RequestTimed a -> ReqFailure -> m ()
revealItems :: MonadServerAtomic m => Maybe FactionId -> m ()
moveStores :: MonadServerAtomic m => Bool -> ActorId -> CStore -> CStore -> m ()

-- | Generate the atomic updates that jointly perform a given item move.
generalMoveItem :: MonadStateRead m => Bool -> ItemId -> Int -> Container -> Container -> m [UpdAtomic]
deduceQuits :: MonadServerAtomic m => FactionId -> Status -> m ()
deduceKilled :: MonadServerAtomic m => ActorId -> m ()
electLeader :: MonadServerAtomic m => FactionId -> LevelId -> ActorId -> m ()
supplantLeader :: MonadServerAtomic m => FactionId -> ActorId -> m ()
updatePer :: MonadServerAtomic m => FactionId -> LevelId -> m ()
recomputeCachePer :: MonadServer m => FactionId -> LevelId -> m Perception
projectFail :: MonadServerAtomic m => ActorId -> Point -> Int -> ItemId -> CStore -> Bool -> m (Maybe ReqFailure)
addActor :: MonadServerAtomic m => GroupName ItemKind -> FactionId -> Point -> LevelId -> (Actor -> Actor) -> Time -> m (Maybe ActorId)
registerActor :: MonadServerAtomic m => ItemKnown -> ItemFull -> ItemSeed -> FactionId -> Point -> LevelId -> (Actor -> Actor) -> Time -> m (Maybe ActorId)
addActorIid :: MonadServerAtomic m => ItemId -> ItemFull -> Bool -> FactionId -> Point -> LevelId -> (Actor -> Actor) -> Time -> m (Maybe ActorId)
discoverIfNoEffects :: MonadServerAtomic m => Container -> ItemId -> ItemFull -> m ()
pickWeaponServer :: MonadServer m => ActorId -> m (Maybe (ItemId, CStore))
currentSkillsServer :: MonadServer m => ActorId -> m Skills
containerMoveItem :: MonadStateRead m => Bool -> ItemId -> Int -> Container -> Container -> m [UpdAtomic]
quitF :: MonadServerAtomic m => Status -> FactionId -> m ()

-- | Tell whether a faction that we know is still in game, keeps arena.
--   Keeping arena means, if the faction is still in game, it always has a
--   leader in the dungeon somewhere. So, leaderless factions and spawner
--   factions do not keep an arena, even though the latter usually has a
--   leader for most of the game.
keepArenaFact :: Faction -> Bool
anyActorsAlive :: MonadServer m => FactionId -> ActorId -> m Bool
projectBla :: MonadServerAtomic m => ActorId -> Point -> [Point] -> ItemId -> CStore -> Bool -> m ()
addProjectile :: MonadServerAtomic m => Point -> [Point] -> ItemId -> ItemQuant -> LevelId -> FactionId -> Time -> Bool -> m ()
getCacheLucid :: MonadServer m => LevelId -> m FovLucid
getCacheTotal :: MonadServer m => FactionId -> LevelId -> m CacheBeforeLucid


-- | Operations for starting and restarting the game.
module Game.LambdaHack.Server.StartM
initPer :: MonadServer m => m ()
reinitGame :: MonadServerAtomic m => m ()
gameReset :: MonadServer m => ServerOptions -> Maybe (GroupName ModeKind) -> Maybe StdGen -> m State

-- | Apply options that don't need a new game.
applyDebug :: MonadServer m => m ()
mapFromFuns :: (Bounded a, Enum a, Ord b) => [a -> b] -> Map b a
resetFactions :: FactionDict -> Id ModeKind -> Int -> AbsDepth -> Roster -> Rnd FactionDict
populateDungeon :: MonadServerAtomic m => m ()

-- | Find starting postions for all factions. Try to make them distant from
--   each other. Place as many of the factions, as possible, over stairs,
--   starting from the end of the list, including placing the last factions
--   over escapes (we assume they are guardians of the escapes). This
--   implies the inital factions (if any) start far from escapes.
findEntryPoss :: COps -> LevelId -> Level -> Int -> Rnd [Point]


-- | Server operations performed periodically in the game loop and related
--   operations.
module Game.LambdaHack.Server.PeriodicM

-- | Spawn, possibly, a monster according to the level's actor groups. We
--   assume heroes are never spawned.
spawnMonster :: MonadServerAtomic m => m ()
addAnyActor :: MonadServerAtomic m => Freqs ItemKind -> LevelId -> Time -> Maybe Point -> m (Maybe ActorId)

-- | Advance the move time for the given actor
advanceTime :: MonadServerAtomic m => ActorId -> Int -> m ()

-- | Add communication overhead time delta to all non-projectile, non-dying
--   faction's actors, except the leader. Effectively, this limits moves of
--   a faction on a level to 10, regardless of the number of actors and
--   their speeds. To avoid animals suddenly acting extremely sluggish
--   whenever monster's leader visits a distant arena that has a crowd of
--   animals, overhead applies only to actors on the same level. Since the
--   number of active levels is limited, this bounds the total moves per
--   turn of each faction as well.
--   
--   Leader is immune from overhead and so he is faster than other faction
--   members and of equal speed to leaders of other factions (of equal base
--   speed) regardless how numerous the faction is. Thanks to this, there
--   is no problem with leader of a numerous faction having very long UI
--   turns, introducing UI lag.
overheadActorTime :: MonadServerAtomic m => FactionId -> LevelId -> m ()

-- | Swap the relative move times of two actors (e.g., when switching a UI
--   leader).
swapTime :: MonadServerAtomic m => ActorId -> ActorId -> m ()
udpateCalm :: MonadServerAtomic m => ActorId -> Int64 -> m ()
leadLevelSwitch :: MonadServerAtomic m => m ()
rollSpawnPos :: COps -> EnumSet Point -> Bool -> LevelId -> Level -> FactionId -> State -> Rnd Point


-- | Handle effects. They are most often caused by requests sent by clients
--   but sometimes also caused by projectiles or periodically activated
--   items.
module Game.LambdaHack.Server.HandleEffectM
applyItem :: MonadServerAtomic m => ActorId -> ItemId -> CStore -> m ()
meleeEffectAndDestroy :: MonadServerAtomic m => ActorId -> ActorId -> ItemId -> Container -> m ()
effectAndDestroy :: MonadServerAtomic m => Bool -> ActorId -> ActorId -> ItemId -> Container -> Bool -> [Effect] -> ItemFull -> m ()
itemEffectEmbedded :: MonadServerAtomic m => ActorId -> Point -> ItemBag -> m ()

-- | Drop a single actor's item. Note that if there are multiple copies, at
--   most one explodes to avoid excessive carnage and UI clutter (let's
--   say, the multiple explosions interfere with each other or perhaps
--   larger quantities of explosives tend to be packaged more safely).
dropCStoreItem :: MonadServerAtomic m => Bool -> CStore -> ActorId -> Actor -> Int -> ItemId -> ItemQuant -> m ()
dominateFidSfx :: MonadServerAtomic m => FactionId -> ActorId -> m Bool
pickDroppable :: MonadStateRead m => ActorId -> Actor -> m Container
refillHP :: MonadServerAtomic m => Bool -> ActorId -> Actor -> Int64 -> m ()
cutCalm :: MonadServerAtomic m => ActorId -> m ()
applyMeleeDamage :: MonadServerAtomic m => ActorId -> ActorId -> ItemId -> m Bool
imperishableKit :: [Effect] -> Bool -> ItemTimer -> ItemFull -> (Bool, ItemQuant)

-- | The source actor affects the target actor, with a given item. If any
--   of the effects fires up, the item gets identified. This function is
--   mutually recursive with <tt>effect</tt> and so it's a part of
--   <tt>Effect</tt> semantics.
--   
--   Note that if we activate a durable item, e.g., armor, from the ground,
--   it will get identified, which is perfectly fine, until we want to add
--   sticky armor that can't be easily taken off (and, e.g., has some
--   maluses).
itemEffectDisco :: MonadServerAtomic m => ActorId -> ActorId -> ItemId -> Container -> Bool -> Bool -> [Effect] -> m Bool

-- | The source actor affects the target actor, with a given effect and
--   power. Both actors are on the current level and can be the same actor.
--   The item may or may not still be in the container. The boolean result
--   indicates if the effect actually fired up, as opposed to fizzled.
effectSem :: MonadServerAtomic m => ActorId -> ActorId -> ItemId -> Container -> Bool -> Bool -> Effect -> m Bool
effectBurn :: MonadServerAtomic m => Dice -> ActorId -> ActorId -> m Bool
effectExplode :: MonadServerAtomic m => m () -> GroupName ItemKind -> ActorId -> m Bool
effectRefillHP :: MonadServerAtomic m => Int -> ActorId -> ActorId -> m Bool
effectRefillCalm :: MonadServerAtomic m => m () -> Int -> ActorId -> ActorId -> m Bool
effectDominate :: MonadServerAtomic m => (Effect -> m Bool) -> ActorId -> ActorId -> m Bool
dominateFid :: MonadServerAtomic m => FactionId -> ActorId -> m Bool
effectImpress :: MonadServerAtomic m => (Effect -> m Bool) -> m () -> ActorId -> ActorId -> m Bool
effectSummon :: MonadServerAtomic m => m () -> GroupName ItemKind -> Dice -> ItemId -> ActorId -> ActorId -> Bool -> m Bool
effectAscend :: MonadServerAtomic m => (Effect -> m Bool) -> m () -> Bool -> ActorId -> ActorId -> Point -> m Bool
findStairExit :: MonadStateRead m => FactionId -> Bool -> LevelId -> Point -> m Point
switchLevels1 :: MonadServerAtomic m => (ActorId, Actor) -> m (Maybe ActorId)
switchLevels2 :: MonadServerAtomic m => LevelId -> Point -> (ActorId, Actor) -> Time -> Maybe ActorId -> m ()

-- | The faction leaves the dungeon.
effectEscape :: MonadServerAtomic m => ActorId -> ActorId -> m Bool

-- | Advance target actor time by this many time clips. Not by actor moves,
--   to hurt fast actors more.
effectParalyze :: MonadServerAtomic m => m () -> Dice -> ActorId -> m Bool

-- | Give target actor the given number of extra moves. Don't give an
--   absolute amount of time units, to benefit slow actors more.
effectInsertMove :: MonadServerAtomic m => m () -> Dice -> ActorId -> m Bool

-- | Teleport the target actor. Note that projectiles can be teleported,
--   too, for extra fun.
effectTeleport :: MonadServerAtomic m => m () -> Dice -> ActorId -> ActorId -> m Bool
effectCreateItem :: MonadServerAtomic m => Maybe FactionId -> Maybe Int -> ActorId -> CStore -> GroupName ItemKind -> TimerDice -> m Bool

-- | Make the target actor drop all items in a store from the given group
--   (not just a random single item, or cluttering equipment with rubbish
--   would be beneficial).
effectDropItem :: MonadServerAtomic m => m () -> Int -> Int -> CStore -> GroupName ItemKind -> ActorId -> m Bool
allGroupItems :: MonadServerAtomic m => CStore -> GroupName ItemKind -> ActorId -> m [(ItemId, ItemQuant)]
effectPolyItem :: MonadServerAtomic m => m () -> ActorId -> ActorId -> m Bool
effectIdentify :: MonadServerAtomic m => m () -> ItemId -> ActorId -> ActorId -> m Bool
identifyIid :: MonadServerAtomic m => ItemId -> Container -> Id ItemKind -> m ()
effectDetect :: MonadServerAtomic m => m () -> Int -> ActorId -> m Bool
effectDetectX :: MonadServerAtomic m => (Point -> Bool) -> ([Point] -> m Bool) -> m () -> Int -> ActorId -> m Bool
effectDetectActor :: MonadServerAtomic m => m () -> Int -> ActorId -> m Bool
effectDetectItem :: MonadServerAtomic m => m () -> Int -> ActorId -> m Bool
effectDetectExit :: MonadServerAtomic m => m () -> Int -> ActorId -> m Bool
effectDetectHidden :: MonadServerAtomic m => m () -> Int -> ActorId -> Point -> m Bool

-- | Send the target actor flying like a projectile. The arguments
--   correspond to <tt>ToThrow</tt> and <tt>Linger</tt> properties of
--   items. If the actors are adjacent, the vector is directed outwards, if
--   no, inwards, if it's the same actor, boldpos is used, if it can't, a
--   random outward vector of length 10 is picked.
effectSendFlying :: MonadServerAtomic m => m () -> ThrowMod -> ActorId -> ActorId -> Maybe Bool -> m Bool
sendFlyingVector :: MonadServerAtomic m => ActorId -> ActorId -> Maybe Bool -> m Vector

-- | Make the target actor drop his best weapon (stack).
effectDropBestWeapon :: MonadServerAtomic m => m () -> ActorId -> m Bool

-- | Activate all items with the given symbol in the target actor's
--   equipment (there's no variant that activates a random one, to avoid
--   the incentive for carrying garbage). Only one item of each stack is
--   activated (and possibly consumed).
effectActivateInv :: MonadServerAtomic m => m () -> ActorId -> Char -> m Bool
effectTransformEqp :: forall m. MonadServerAtomic m => m () -> ActorId -> Char -> CStore -> (ItemId -> ItemQuant -> m ()) -> m Bool
effectApplyPerfume :: MonadServerAtomic m => m () -> ActorId -> m Bool
effectOneOf :: MonadServerAtomic m => (Effect -> m Bool) -> [Effect] -> m Bool
effectRecharging :: MonadServerAtomic m => (Effect -> m Bool) -> Effect -> Bool -> m Bool
effectTemporary :: MonadServerAtomic m => m () -> ActorId -> ItemId -> Container -> m Bool
effectComposite :: MonadServerAtomic m => (Effect -> m Bool) -> [Effect] -> m Bool


-- | Semantics of requests . A couple of them do not take time, the rest
--   does. Note that since the results are atomic commands, which are
--   executed only later (on the server and some of the clients), all
--   condition are checkd by the semantic functions in the context of the
--   state before the server command. Even if one or more atomic actions
--   are already issued by the point an expression is evaluated, they do
--   not influence the outcome of the evaluation.
module Game.LambdaHack.Server.HandleRequestM

-- | The semantics of server commands. AI always takes time and so doesn't
--   loop.
handleRequestAI :: MonadServerAtomic m => ReqAI -> m (Maybe RequestAnyAbility)

-- | The semantics of server commands. Only the first two cases affect
--   time.
handleRequestUI :: MonadServerAtomic m => FactionId -> ActorId -> ReqUI -> m (Maybe RequestAnyAbility)
handleRequestTimed :: MonadServerAtomic m => FactionId -> ActorId -> RequestTimed a -> m Bool
switchLeader :: MonadServerAtomic m => FactionId -> ActorId -> m ()

-- | Actor moves or attacks. Note that client may not be able to see an
--   invisible monster so it's the server that determines if melee took
--   place, etc. Also, only the server is authorized to check if a move is
--   legal and it needs full context for that, e.g., the initial actor
--   position to check if melee attack does not try to reach to a distant
--   tile.
reqMove :: MonadServerAtomic m => ActorId -> Vector -> m ()

-- | Actor tries to swap positions with another.
reqDisplace :: MonadServerAtomic m => ActorId -> ActorId -> m ()
reqGameExit :: MonadServerAtomic m => ActorId -> m ()

-- | This is a shorthand. Instead of setting <tt>bwait</tt> in
--   <tt>ReqWait</tt> and unsetting in all other requests, we call this
--   once before executing a request.
setBWait :: MonadServerAtomic m => RequestTimed a -> ActorId -> Actor -> m (Maybe Bool)

-- | Clear deltas for Calm and HP for proper UI display and AI hints.
managePerRequest :: MonadServerAtomic m => ActorId -> m ()
handleRequestTimedCases :: MonadServerAtomic m => ActorId -> RequestTimed a -> m ()

-- | Add a smell trace for the actor to the level. For now, only actors
--   with gender leave strong and unique enough smell. If smell already
--   there and the actor can smell, remove smell. Projectiles are ignored.
--   As long as an actor can smell, he doesn't leave any smell ever.
affectSmell :: MonadServerAtomic m => ActorId -> m ()

-- | Resolves the result of an actor moving into another. Actors on blocked
--   positions can be attacked without any restrictions. For instance, an
--   actor embedded in a wall can be attacked from an adjacent position.
--   This function is analogous to projectGroupItem, but for melee and not
--   using up the weapon. No problem if there are many projectiles at the
--   spot. We just attack the one specified.
reqMelee :: MonadServerAtomic m => ActorId -> ActorId -> ItemId -> CStore -> m ()

-- | Search and/or alter the tile.
reqAlter :: MonadServerAtomic m => ActorId -> Point -> m ()

-- | Do nothing.
--   
--   Something is sometimes done in <a>setBWait</a>.
reqWait :: MonadServerAtomic m => ActorId -> m ()
reqMoveItems :: MonadServerAtomic m => ActorId -> [(ItemId, Int, CStore, CStore)] -> m ()
reqMoveItem :: MonadServerAtomic m => ActorId -> Bool -> (ItemId, Int, CStore, CStore) -> m ()
computeRndTimeout :: Time -> ItemId -> ItemFull -> Rnd (Maybe Time)
reqProject :: MonadServerAtomic m => ActorId -> Point -> Int -> ItemId -> CStore -> m ()
reqApply :: MonadServerAtomic m => ActorId -> ItemId -> CStore -> m ()
reqGameRestart :: MonadServerAtomic m => ActorId -> GroupName ModeKind -> Challenge -> m ()
reqGameSave :: MonadServer m => m ()
reqTactic :: MonadServerAtomic m => FactionId -> Tactic -> m ()
reqAutomate :: MonadServerAtomic m => FactionId -> m ()


-- | Server operations used when ending game and deciding whether to end.
module Game.LambdaHack.Server.EndM

-- | Continue or exit or restart the game.
endOrLoop :: (MonadServerAtomic m, MonadServerReadRequest m) => m () -> (Maybe (GroupName ModeKind) -> m ()) -> m () -> m ()
dieSer :: MonadServerAtomic m => ActorId -> Actor -> m ()

-- | Save game on server and all clients.
writeSaveAll :: MonadServerAtomic m => Bool -> m ()
gameExit :: (MonadServerAtomic m, MonadServerReadRequest m) => m ()

-- | Drop all actor's items.
dropAllItems :: MonadServerAtomic m => ActorId -> Actor -> m ()


-- | The main loop of the server, processing human and computer player
--   moves turn by turn.
module Game.LambdaHack.Server.LoopM

-- | Start a game session, including the clients, and then loop,
--   communicating with the clients.
--   
--   The loop is started in server state that is empty, see
--   <a>emptyStateServer</a>.
loopSer :: (MonadServerAtomic m, MonadServerReadRequest m) => ServerOptions -> (Bool -> FactionId -> ChanServer -> IO ()) -> m ()
factionArena :: MonadStateRead m => Faction -> m (Maybe LevelId)
arenasForLoop :: MonadStateRead m => m [LevelId]
handleFidUpd :: (MonadServerAtomic m, MonadServerReadRequest m) => Bool -> (FactionId -> m ()) -> FactionId -> Faction -> m Bool

-- | Handle a clip (the smallest fraction of a game turn for which a frame
--   may potentially be generated). Run the leader and other actors moves.
--   Eventually advance the time and repeat.
loopUpd :: forall m. (MonadServerAtomic m, MonadServerReadRequest m) => m () -> m ()

-- | Handle the end of every clip. Do whatever has to be done every fixed
--   number of clips, e.g., monster generation. Advance time. Perform
--   periodic saves, if applicable.
endClip :: forall m. MonadServerAtomic m => (FactionId -> m ()) -> m ()

-- | Check if the given actor is dominated and update his calm.
manageCalmAndDomination :: MonadServerAtomic m => ActorId -> Actor -> m ()

-- | Trigger periodic items for all actors on the given level.
applyPeriodicLevel :: MonadServerAtomic m => m ()
handleTrajectories :: MonadServerAtomic m => LevelId -> FactionId -> m ()
hTrajectories :: MonadServerAtomic m => (ActorId, Actor) -> m ()

-- | Manage trajectory of a projectile.
--   
--   Colliding with a wall or actor doesn't take time, because the
--   projectile does not move (the move is blocked). Not advancing time
--   forces dead projectiles to be destroyed ASAP. Otherwise, with some
--   timings, it can stay on the game map dead, blocking path of
--   human-controlled actors and alarming the hapless human.
setTrajectory :: MonadServerAtomic m => ActorId -> m ()
handleActors :: (MonadServerAtomic m, MonadServerReadRequest m) => LevelId -> FactionId -> m Bool
hActors :: forall m. (MonadServerAtomic m, MonadServerReadRequest m) => FactionId -> [(ActorId, Actor)] -> m Bool
restartGame :: MonadServerAtomic m => m () -> m () -> Maybe (GroupName ModeKind) -> m ()


-- | Semantics of requests that are sent by clients to the server, in terms
--   of game state changes and responses to be sent to the clients.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Server

-- | Start a game session, including the clients, and then loop,
--   communicating with the clients.
--   
--   The loop is started in server state that is empty, see
--   <a>emptyStateServer</a>.
loopSer :: (MonadServerAtomic m, MonadServerReadRequest m) => ServerOptions -> (Bool -> FactionId -> ChanServer -> IO ()) -> m ()

-- | Connection channel between the server and a single client.
data ChanServer
ChanServer :: CliSerQueue Response -> CliSerQueue RequestAI -> Maybe (CliSerQueue RequestUI) -> ChanServer
[responseS] :: ChanServer -> CliSerQueue Response
[requestAIS] :: ChanServer -> CliSerQueue RequestAI
[requestUIS] :: ChanServer -> Maybe (CliSerQueue RequestUI)

-- | Parser for server options from commandline arguments.
serverOptionsPI :: ParserInfo ServerOptions

-- | Options that affect the behaviour of the server (including game
--   rules).
data ServerOptions
ServerOptions :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe (GroupName ModeKind) -> Bool -> Bool -> Maybe StdGen -> Maybe StdGen -> Bool -> Challenge -> Bool -> String -> Bool -> ClientOptions -> ServerOptions
[sknowMap] :: ServerOptions -> Bool
[sknowEvents] :: ServerOptions -> Bool
[sknowItems] :: ServerOptions -> Bool
[sniff] :: ServerOptions -> Bool
[sallClear] :: ServerOptions -> Bool
[sboostRandomItem] :: ServerOptions -> Bool
[sgameMode] :: ServerOptions -> Maybe (GroupName ModeKind)
[sautomateAll] :: ServerOptions -> Bool
[skeepAutomated] :: ServerOptions -> Bool
[sdungeonRng] :: ServerOptions -> Maybe StdGen
[smainRng] :: ServerOptions -> Maybe StdGen
[snewGameSer] :: ServerOptions -> Bool
[scurChalSer] :: ServerOptions -> Challenge
[sdumpInitRngs] :: ServerOptions -> Bool
[ssavePrefixSer] :: ServerOptions -> String
[sdbgMsgSer] :: ServerOptions -> Bool
[sclientOptions] :: ServerOptions -> ClientOptions


-- | The implementation of our custom game client monads. Just as any other
--   component of the library, this implementation can be substituted.
module Game.LambdaHack.SampleImplementation.SampleMonadClient

-- | Run the main client loop, with the given arguments and empty initial
--   states, in the <tt>IO</tt> monad.
executorCli :: KeyKind -> UIOptions -> ClientOptions -> COps -> Bool -> FactionId -> ChanServer -> IO ()
data CliState
CliState :: State -> StateClient -> Maybe SessionUI -> ChanServer -> ChanSave (StateClient, Maybe SessionUI) -> CliState

-- | current global state
[cliState] :: CliState -> State

-- | current client state
[cliClient] :: CliState -> StateClient

-- | UI state, empty for AI clients
[cliSession] :: CliState -> Maybe SessionUI

-- | this client connection information
[cliDict] :: CliState -> ChanServer

-- | connection to the save thread
[cliToSave] :: CliState -> ChanSave (StateClient, Maybe SessionUI)

-- | Client state transformation monad.
newtype CliImplementation a
CliImplementation :: StateT CliState IO a -> CliImplementation a
[runCliImplementation] :: CliImplementation a -> StateT CliState IO a
instance GHC.Base.Applicative Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance GHC.Base.Functor Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance GHC.Base.Monad Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance Game.LambdaHack.Common.MonadStateRead.MonadStateRead Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance Game.LambdaHack.Atomic.MonadStateWrite.MonadStateWrite Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance Game.LambdaHack.Client.MonadClient.MonadClient Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance Game.LambdaHack.Client.HandleAtomicM.MonadClientSetup Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance Game.LambdaHack.Client.UI.MonadClientUI.MonadClientUI Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance Game.LambdaHack.Client.LoopM.MonadClientReadResponse Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance Game.LambdaHack.Client.HandleResponseM.MonadClientWriteRequest Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation
instance Game.LambdaHack.Client.HandleResponseM.MonadClientAtomic Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation


-- | The implementation of our custom game server monads. Just as any other
--   component of the library, this implementation can be substituted.
module Game.LambdaHack.SampleImplementation.SampleMonadServer

-- | Run the main server loop, with the given arguments and empty initial
--   states, in the <tt>IO</tt> monad.
executorSer :: COps -> KeyKind -> ServerOptions -> IO ()
data SerState
SerState :: State -> StateServer -> ConnServerDict -> ChanSave (State, StateServer) -> SerState

-- | current global state
[serState] :: SerState -> State

-- | current server state
[serServer] :: SerState -> StateServer

-- | client-server connection information
[serDict] :: SerState -> ConnServerDict

-- | connection to the save thread
[serToSave] :: SerState -> ChanSave (State, StateServer)

-- | Server state transformation monad.
newtype SerImplementation a
SerImplementation :: StateT SerState IO a -> SerImplementation a
[runSerImplementation] :: SerImplementation a -> StateT SerState IO a
instance GHC.Base.Applicative Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
instance GHC.Base.Functor Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
instance GHC.Base.Monad Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
instance Game.LambdaHack.Common.MonadStateRead.MonadStateRead Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
instance Game.LambdaHack.Atomic.MonadStateWrite.MonadStateWrite Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
instance Game.LambdaHack.Server.MonadServer.MonadServer Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
instance Game.LambdaHack.Server.ProtocolM.MonadServerReadRequest Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
instance Game.LambdaHack.Server.MonadServer.MonadServerAtomic Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
