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


-- | A game engine library for roguelike dungeon crawlers
--   
--   LambdaHack is a game engine library for roguelike games of arbitrary
--   theme, size and complexity, packaged together with a small example
--   dungeon crawler.
--   
--   
--   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 (GTK is the default) 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.
--   
--   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.5.0.0


-- | Common definitions for the Field of View algorithms. See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Fov-and-los</a> for
--   some more context and references.
module Game.LambdaHack.Server.Fov.Common

-- | 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

-- | 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

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

-- | Maximal element of a non-empty list. Prefers elements from the rear,
--   which is essential for PFOV, to avoid ill-defined lines.
maximal :: (a -> a -> Bool) -> [a] -> a

-- | 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 -> Bool

-- | 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 -> Bool) -> Bump -> ConvexHull -> ConvexHull
instance GHC.Show.Show Game.LambdaHack.Server.Fov.Common.Line
instance GHC.Show.Show Game.LambdaHack.Server.Fov.Common.Bump


-- | A restrictive variant of Recursive Shadow Casting FOV with infinite
--   range. It's not designed for dungeons with diagonal walls and so here
--   they block visibility, though they don't block movement. The main
--   advantage of the algorithm is that it's very simple and fast.
module Game.LambdaHack.Server.Fov.Shadow

-- | Rotated and translated coordinates of 2D points, so that they fit in
--   the same single octant area.
type SBump = (Progress, Distance)

-- | The area left to be scanned, delimited by fractions of the original
--   arc. Interval <tt>(0, 1)</tt> means the whole 45 degrees arc of the
--   processed octant is to be scanned.
type Interval = (Rational, Rational)

-- | Calculates the list of tiles, in <tt>SBump</tt> coordinates, visible
--   from (0, 0).
scan :: (SBump -> Bool) -> Distance -> Interval -> [SBump]


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


-- | Ring buffers.
module Game.LambdaHack.Common.RingBuffer
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]
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)


-- | 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]
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.Read.Read 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 Array c

-- | Array lookup.
(!) :: Enum c => Array c -> Point -> c

-- | Construct an array updated with the association list.
(//) :: Enum c => Array c -> [(Point, c)] -> Array c

-- | Create an array from a replicated element.
replicateA :: Enum c => X -> Y -> c -> Array c

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

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

-- | Create an array from a monadic function.
generateMA :: Enum c => Monad m => X -> Y -> (Point -> m c) -> m (Array c)

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

-- | Fold left strictly over an array.
foldlA :: Enum c => (a -> c -> a) -> a -> Array c -> a

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

-- | Map over an array.
mapA :: (Enum c, Enum d) => (c -> d) -> Array c -> Array d

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

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

-- | Set all elements to the given value, in place, if possible.
safeSetA :: Enum c => c -> Array c -> Array c

-- | Set all elements to the given value, in place.
unsafeSetA :: Enum c => c -> Array c -> Array c
unsafeUpdateA :: Enum c => Array c -> [(Point, c)] -> Array c

-- | Yield the point coordinates of a minimum element of the array. The
--   array may not be empty.
minIndexA :: Enum c => Array c -> Point

-- | Yield the point coordinates of the last minimum element of the array.
--   The array may not be empty.
minLastIndexA :: Enum c => Array c -> Point

-- | Yield the point coordinates of all the minimum elements of the array.
--   The array may not be empty.
minIndexesA :: Enum c => Array c -> [Point]

-- | Yield the point coordinates of the first maximum element of the array.
--   The array may not be empty.
maxIndexA :: Enum c => Array c -> Point

-- | Yield the point coordinates of the last maximum element of the array.
--   The array may not be empty.
maxLastIndexA :: Enum c => Array c -> Point

-- | Force the array not to retain any extra memory.
forceA :: Enum c => Array c -> Array c
instance GHC.Classes.Eq (Game.LambdaHack.Common.PointArray.Array c)
instance GHC.Show.Show (Game.LambdaHack.Common.PointArray.Array c)
instance Data.Binary.Class.Binary (Game.LambdaHack.Common.PointArray.Array c)


-- | Basic operations on 2D vectors represented in an efficient, but not
--   unique, way.
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]

-- | All (4 at most) cardinal direction neighbours of a point within an
--   area.
vicinityCardinal :: X -> Y -> Point -> [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
instance GHC.Generics.Generic Game.LambdaHack.Common.Vector.Vector
instance GHC.Read.Read Game.LambdaHack.Common.Vector.Vector
instance GHC.Show.Show Game.LambdaHack.Common.Vector.Vector
instance GHC.Classes.Ord Game.LambdaHack.Common.Vector.Vector
instance GHC.Classes.Eq 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


-- | 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

-- | Divide uniformly a larger area into the given number of smaller areas
--   overlapping at the edges.
grid :: (X, Y) -> Area -> [(Point, Area)]

-- | Enlarge (or shrink) the given area on all fours sides by the amount.
shrink :: Area -> Maybe Area
instance GHC.Show.Show Game.LambdaHack.Server.DungeonGen.Area.Area
instance Data.Binary.Class.Binary Game.LambdaHack.Server.DungeonGen.Area.Area


-- | 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

-- | 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

-- | 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
data CStore
CGround :: CStore
COrgan :: CStore
CEqp :: CStore
CInv :: CStore
CSha :: CStore
data ItemDialogMode
MStore :: CStore -> ItemDialogMode
MOwned :: ItemDialogMode
MStats :: ItemDialogMode

-- | Level bounds. TODO: query terminal size instead and scroll view.
normalLevelBound :: (Int, Int)

-- | Integer division, rounding up.
divUp :: Integral a => a -> a -> a
infixl 7 `divUp`
data GroupName a
toGroupName :: Text -> 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)]

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

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

-- | 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 TODO (currently the
--   same as TExplore; should it chase targets too (TRoam) and only switch
--   to TPatrol when none?)
TPatrol :: Tactic
isRight :: Either a b -> Bool
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 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 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.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 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 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.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.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 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.Read.Read (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 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 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 Control.DeepSeq.NFData Game.LambdaHack.Common.Misc.ItemDialogMode
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 (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 k, Data.Binary.Class.Binary v, GHC.Classes.Eq k, Data.Hashable.Class.Hashable k) => 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


-- | 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

-- | At least once per clip all moves are resolved and a frame or a frame
--   delay is generated. Currently one clip is 0.1 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

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

-- | Absolute time addition, e.g., for summing the total game session time
--   from the times of individual games.
absoluteTimeAdd :: 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

-- | 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

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

-- | 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

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

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

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

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

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

-- | 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 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

-- | Calculate maximum range taking into account the linger percentage.
rangeFromSpeedAndLinger :: Speed -> Int -> 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


-- | 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.
--   
--   For now the rules are immutable througout the game, so there is no
--   type <tt>Rule</tt> to hold any changing parameters, just
--   <tt>RuleKind</tt> for the fixed set. However, in the future, if the
--   rules can get changed during gameplay based on data mining of player
--   behaviour, we may add such a type and then <tt>RuleKind</tt> will
--   become just a starting template, analogously as for the other content.
--   
--   The <tt>raccessible</tt> field holds extra conditions that have to be
--   met for a tile to be accessible, on top of being an open tile (or
--   openable, in some contexts). The <tt>raccessibleDoor</tt> field
--   contains yet additional conditions concerning tiles that are doors,
--   whether open or closed. Precondition: the two positions are next to
--   each other. We assume the predicate is symmetric.
data RuleKind
RuleKind :: !Char -> !Text -> !(Freqs RuleKind) -> !(Maybe (Point -> Point -> Bool)) -> !(Maybe (Point -> Point -> Bool)) -> !Text -> (FilePath -> IO FilePath) -> !Version -> !FilePath -> !String -> !Text -> !Bool -> !FovMode -> !Int -> !Int -> !FilePath -> !String -> !Int -> RuleKind

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

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

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

-- | see above
[raccessible] :: RuleKind -> !(Maybe (Point -> Point -> Bool))

-- | see above
[raccessibleDoor] :: RuleKind -> !(Maybe (Point -> Point -> Bool))

-- | the title of the game
[rtitle] :: RuleKind -> !Text

-- | the path to data files
[rpathsDataFile] :: RuleKind -> FilePath -> IO FilePath

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

-- | base 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

-- | FOV calculation mode
[rfovMode] :: RuleKind -> !FovMode

-- | 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

-- | name of the savefile prefix
[rsavePrefix] :: RuleKind -> !String

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

-- | Field Of View scanning mode.
data FovMode

-- | restrictive shadow casting (not symmetric!)
Shadow :: FovMode

-- | permissive FOV
Permissive :: FovMode

-- | digital FOV
Digital :: FovMode

-- | Catch invalid rule kind definitions. In particular, this validates the
--   ASCII art format (TODO).
validateSingleRuleKind :: RuleKind -> [Text]

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


-- | 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.Fov.Digital

-- | Calculates the list of tiles, in <tt>Bump</tt> coordinates, visible
--   from (0, 0), within the given sight range.
scan :: Distance -> (Bump -> Bool) -> [Bump]

-- | 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 -> Bool

-- | 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 -> Bool

-- | Debug: check if a view border line for DFOV is legal.
_debugLine :: Line -> (Bool, String)


-- | PFOV (Permissive Field of View) clean-room reimplemented based on the
--   algorithm described in
--   <a>http://roguebasin.roguelikedevelopment.org/index.php?title=Precise_Permissive_Field_of_View</a>,
--   though the general structure is more influenced by recursive shadow
--   casting, as implemented in Shadow.hs. In the result, this algorithm is
--   much faster than the original algorithm on dense maps, since it does
--   not scan areas blocked by shadows.
module Game.LambdaHack.Server.Fov.Permissive

-- | Calculates the list of tiles, in <tt>Bump</tt> coordinates, visible
--   from (0, 0).
scan :: (Bump -> Bool) -> [Bump]

-- | 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 -> Bool

-- | The Y coordinate, represented as a fraction, of the intersection of a
--   given line and the line of diagonals of squares at distance <tt>d</tt>
--   from (0, 0).
intersect :: Line -> Distance -> (Int, Int)

-- | Debug functions for PFOV:
--   
--   Debug: calculate steeper for PFOV in another way and compare results.
debugSteeper :: Bump -> Bump -> Bump -> Bool

-- | Debug: checks postconditions of borderLine.
debugLine :: Line -> (Bool, String)


-- | Queues implemented with two stacks to ensure fast writes.
module Game.LambdaHack.Common.LQueue

-- | Queues implemented with two stacks.
type LQueue a = ([a], [a])

-- | Create a new empty mutable queue.
newLQueue :: LQueue a

-- | Check if the queue is empty.
nullLQueue :: LQueue a -> Bool

-- | The length of the queue.
lengthLQueue :: LQueue a -> Int

-- | Try reading a queue. Return <tt>Nothing</tt> if empty.
tryReadLQueue :: LQueue a -> Maybe (a, LQueue a)

-- | Write to the queue. Faster than reading.
writeLQueue :: LQueue a -> a -> LQueue a

-- | Remove all but the last written non-<tt>Nothing</tt> element of the
--   queue.
trimLQueue :: LQueue (Maybe a) -> LQueue (Maybe a)

-- | Remove frames up to and including the first segment of
--   <tt>Nothing</tt> frames. | If the resulting queue is empty, apply
--   trimLQueue instead.
dropStartLQueue :: LQueue (Maybe a) -> LQueue (Maybe a)

-- | Dump all but the last written non-<tt>Nothing</tt> element of the
--   queue, if any.
lastLQueue :: LQueue (Maybe a) -> Maybe a
toListLQueue :: LQueue a -> [a]


-- | Saving/loading 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 ()

-- | Try to copy over data files, if not already there. We catch exceptions
--   in case many clients try to do the same thing at the same time.
tryCopyDataFiles :: FilePath -> (FilePath -> IO FilePath) -> [(FilePath, FilePath)] -> IO ()

-- | 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


-- | 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 (<tt>Game.LambdaHack.Content.ItemKind</tt>). The
--   possible kinds are fixed in the library and all defined in the same
--   directory. On the other hand, game content, that is all elements of
--   <tt>ContentDef</tt> instances, are defined in a directory of the game
--   code proper, with names corresponding to their kinds.
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]) -> ![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 the defined content of this type
[content] :: ContentDef a -> ![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.
defBG :: Color

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

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

-- | Due to the limitation of the curses library used in the curses
--   frontend, only these are legal backgrounds.
legalBG :: [Color]

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

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

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

-- | Translationg to heavily modified Linux console color RGB values.
colorToRGB :: Color -> String

-- | Text attributes: foreground and backgroud colors.
data Attr
Attr :: !Color -> !Color -> Attr

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

-- | backgroud color
[bg] :: Attr -> !Color

-- | The default attribute, to optimize attribute setting.
defAttr :: Attr
data AttrChar
AttrChar :: !Attr -> !Char -> AttrChar
[acAttr] :: AttrChar -> !Attr
[acChar] :: AttrChar -> !Char
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.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 Data.Hashable.Class.Hashable Game.LambdaHack.Common.Color.Color
instance GHC.Enum.Enum Game.LambdaHack.Common.Color.Attr
instance GHC.Enum.Enum Game.LambdaHack.Common.Color.AttrChar
instance Data.Binary.Class.Binary 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]

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

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

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

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

-- | Simple names for team colors (bright colours preferred).
colorToTeamName :: Color -> 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
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.FancyName
instance Data.Binary.Class.Binary 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


-- | Game messages displayed on top of the screen for the player to read.
module Game.LambdaHack.Common.Msg

-- | 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

-- | The type of a single message.
type Msg = Text

-- | An infix synonym for <a>mappend</a>.
(<>) :: Monoid m => m -> m -> m
infixr 6 <>
(<+>) :: Text -> Text -> Text
infixr 6 <+>
tshow :: Show a => a -> Text
toWidth :: Int -> Text -> Text

-- | The "press something to see more" mark.
moreMsg :: Msg

-- | The "end of screenfuls of text" mark.
endMsg :: Msg

-- | The confirmation request message.
yesnoMsg :: Msg

-- | Add a space at the message end, for display overlayed over the level
--   map. Also trims (does not wrap!) too long lines. In case of newlines,
--   displays only the first line, but marks the message as partial.
truncateMsg :: X -> Text -> Text

-- | The type of a set of messages 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 message to the end of report.
addMsg :: Report -> Msg -> Report
prependMsg :: Msg -> Report -> Report

-- | Split a messages into chunks that fit in one line. We assume the width
--   of the messages line is the same as of level map.
splitReport :: X -> Report -> Overlay

-- | Render a report as a (possibly very long) string.
renderReport :: Report -> Text
findInReport :: (ByteString -> Bool) -> Report -> Maybe ByteString
lastMsgOfReport :: Report -> (ByteString, 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
lengthHistory :: History -> Int

-- | Add a report to history, handling repetitions.
addReport :: History -> Time -> Report -> History

-- | Render history as many lines of text, wrapping if necessary.
renderHistory :: History -> Overlay
lastReportOfHistory :: History -> Maybe Report

-- | A series of screen lines that may or may not fit the width nor height
--   of the screen. An overlay may be transformed by adding the first line
--   and/or by splitting into a slideshow of smaller overlays.
data Overlay
emptyOverlay :: Overlay
truncateToOverlay :: Text -> Overlay
toOverlay :: [Text] -> Overlay

-- | A few overlays, displayed one by one upon keypress. When displayed,
--   they are trimmed, not wrapped and any lines below the lower screen
--   edge are not visible. If the first pair element is not
--   <tt>Nothing</tt>, the overlay is displayed over a blank screen,
--   including the bottom lines. The boolean flag then indicates whether to
--   start at the topmost screenful or bottommost.
data Slideshow

-- | Split an overlay into a slideshow in which each overlay, prefixed by
--   <tt>msg</tt> and postfixed by <tt>moreMsg</tt> except for the last
--   one, fits on the screen wrt height (but lines may be too wide).
splitOverlay :: Maybe Bool -> Y -> Overlay -> Overlay -> Slideshow

-- | Declare the list of raw overlays to be fit for display on the screen.
--   In particular, current <tt>Report</tt> is eiter empty or unimportant
--   or contained in the overlays and if any vertical or horizontal
--   trimming of the overlays happens, this is intended.
toSlideshow :: Maybe Bool -> [[Text]] -> Slideshow
encodeLine :: [AttrChar] -> ScreenLine
encodeOverlay :: [[AttrChar]] -> Overlay
type ScreenLine = Vector Int32
toScreenLine :: Text -> ScreenLine

-- | 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.
splitText :: X -> Text -> [Text]
instance GHC.Classes.Eq Game.LambdaHack.Common.Msg.Slideshow
instance GHC.Show.Show Game.LambdaHack.Common.Msg.Slideshow
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Msg.Overlay
instance GHC.Classes.Eq Game.LambdaHack.Common.Msg.Overlay
instance GHC.Show.Show Game.LambdaHack.Common.Msg.Overlay
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Msg.History
instance GHC.Show.Show Game.LambdaHack.Common.Msg.History
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Msg.Report
instance GHC.Show.Show Game.LambdaHack.Common.Msg.Report
instance GHC.Base.Monoid Game.LambdaHack.Common.Msg.Slideshow


-- | A list of items 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, unless they do some kind of normalization (see
--   <tt>Dice</tt>).
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.; keep it lazy, because it's rarely
--   used
nameFrequency :: Frequency a -> Text
maxFreq :: Ord a => Frequency a -> Maybe a
minFreq :: Ord a => 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.Read.Read a => GHC.Read.Read (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 for parameters scaled with current level depth.
module Game.LambdaHack.Common.Dice

-- | Dice for parameters scaled with current level depth. To the result of
--   rolling the first set of dice we add the second, scaled in proportion
--   to current depth divided by maximal dungeon depth. The result if then
--   multiplied by the scale --- to be used to ensure that dice results are
--   multiples of, e.g., 10. The scale is set with <tt>|*|</tt>.
data Dice
diceConst :: Dice -> SimpleDice
diceLevel :: Dice -> SimpleDice
diceMult :: Dice -> Int

-- | Multiplying the dice, after all randomness is resolved, by a constant.
--   Infix declaration ensures that <tt>1 + 2 |*| 3</tt> parses as <tt>(1 +
--   2) |*| 3</tt>.
(|*|) :: Dice -> Int -> Dice
infixl 5 |*|

-- | A single simple dice.
d :: Int -> Dice

-- | Dice scaled with level.
ds :: Int -> Dice
dl :: Int -> Dice
intToDice :: Int -> Dice

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

-- | Minimal value of dice. The scaled part ignored.
minDice :: Dice -> Int

-- | Mean value of dice. The level-dependent part is taken assuming the
--   highest level, because that's where the game is the hardest. Assumes
--   the frequencies are not null.
meanDice :: Dice -> Int
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 -> (Int, Int)
type SimpleDice = Frequency Int
instance GHC.Generics.Generic Game.LambdaHack.Common.Dice.DiceXY
instance GHC.Classes.Ord Game.LambdaHack.Common.Dice.DiceXY
instance GHC.Classes.Eq 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 GHC.Read.Read Game.LambdaHack.Common.Dice.Dice
instance GHC.Num.Num Game.LambdaHack.Common.Dice.SimpleDice
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
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Dice.DiceXY
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Dice.DiceXY


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

-- | The monad of computations with random generator state. The lazy state
--   monad is OK here: the state is small and regularly forced.
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)


-- | 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 random room according to given parameters.
mkRoom :: (X, Y) -> (X, Y) -> Area -> Rnd Area

-- | Create a void room, i.e., a single point area within the designated
--   area.
mkVoidRoom :: 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 :: (X, Y) -> Rnd [(Point, Point)]

-- | Pick a single random connection between adjacent areas within a grid.
randomConnection :: (X, Y) -> Rnd (Point, Point)

-- | The coordinates of consecutive fields of a corridor.
type Corridor = [Point]

-- | Try to connect two interiors of places with a corridor. Choose
--   entrances at least 4 or 3 tiles distant from the edges, if the place
--   is big enough. Note that with <tt>pfence == FNone</tt>, the area
--   considered is the strict interior of the place, without the outermost
--   tiles.
connectPlaces :: (Area, Area) -> (Area, Area) -> Rnd Corridor


-- | Saving and restoring server game state.
module Game.LambdaHack.Common.Save
type ChanSave a = MVar (Maybe a)
saveToChan :: ChanSave a -> a -> IO ()
wrapInSaves :: Binary a => (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 => String -> [(FilePath, FilePath)] -> (FilePath -> IO FilePath) -> IO (Maybe a)
delayPrint :: Text -> IO ()


-- | Screen frames and animations.
module Game.LambdaHack.Common.ClientOptions
data DebugModeCli
DebugModeCli :: !(Maybe String) -> !(Maybe Bool) -> !(Maybe Int) -> !Bool -> !Bool -> !(Maybe Bool) -> !Bool -> !Bool -> !(Maybe String) -> !Bool -> !Bool -> !Bool -> DebugModeCli

-- | Font to use for the main game window.
[sfont] :: DebugModeCli -> !(Maybe String)

-- | Whether to use bold attribute for colorful characters.
[scolorIsBold] :: DebugModeCli -> !(Maybe Bool)

-- | 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] :: DebugModeCli -> !(Maybe Int)

-- | Don't maintain any requested delays between frames, e.g., for
--   screensaver.
[snoDelay] :: DebugModeCli -> !Bool

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

-- | Don't show any animations.
[snoAnim] :: DebugModeCli -> !(Maybe Bool)

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

-- | Don't create directories and files and show time stats.
[sbenchmark] :: DebugModeCli -> !Bool

-- | Prefix of the save game file.
[ssavePrefixCli] :: DebugModeCli -> !(Maybe String)

-- | Whether to use the stdout/stdin frontend for all clients.
[sfrontendStd] :: DebugModeCli -> !Bool

-- | Whether to use void (no input/output) frontend for all clients.
[sfrontendNull] :: DebugModeCli -> !Bool

-- | Show clients' internal debug messages.
[sdbgMsgCli] :: DebugModeCli -> !Bool
defDebugModeCli :: DebugModeCli
instance GHC.Generics.Generic Game.LambdaHack.Common.ClientOptions.DebugModeCli
instance GHC.Classes.Eq Game.LambdaHack.Common.ClientOptions.DebugModeCli
instance GHC.Show.Show Game.LambdaHack.Common.ClientOptions.DebugModeCli
instance Data.Binary.Class.Binary Game.LambdaHack.Common.ClientOptions.DebugModeCli


-- | 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
AbTrigger :: Ability
type Skills = EnumMap Ability Int
zeroSkills :: Skills
unitSkills :: Skills
addSkills :: Skills -> Skills -> Skills
scaleSkills :: Int -> Skills -> 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.Read.Read Game.LambdaHack.Common.Ability.Ability
instance GHC.Show.Show 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


-- | The type of kinds of weapons, treasure, organs, blasts and actors.
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 -> ![Aspect Dice] -> ![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 for applying and melee
[iverbHit] :: ItemKind -> !Part

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

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

-- | 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. Constructors are sorted vs increasing impact/danger.
data Effect
NoEffect :: !Text -> Effect
Hurt :: !Dice -> Effect
Burn :: !Dice -> Effect

-- | explode, producing this group of blasts
Explode :: !(GroupName ItemKind) -> Effect
RefillHP :: !Int -> Effect
OverfillHP :: !Int -> Effect
RefillCalm :: !Int -> Effect
OverfillCalm :: !Int -> Effect
Dominate :: Effect
Impress :: Effect
CallFriend :: !Dice -> Effect
Summon :: !(Freqs ItemKind) -> !Dice -> Effect
Ascend :: !Int -> Effect

-- | the Int says if can be placed on last level, etc.
Escape :: !Int -> Effect
Paralyze :: !Dice -> Effect
InsertMove :: !Dice -> Effect
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

-- | <tt>DropItem CGround x True</tt> means stomp on items
DropItem :: !CStore -> !(GroupName ItemKind) -> !Bool -> Effect
PolyItem :: Effect
Identify :: Effect
SendFlying :: !ThrowMod -> Effect
PushActor :: !ThrowMod -> Effect
PullActor :: !ThrowMod -> Effect
DropBestWeapon :: Effect

-- | symbol <tt>' '</tt> means all
ActivateInv :: !Char -> Effect
ApplyPerfume :: Effect
OneOf :: ![Effect] -> Effect

-- | trigger if item smashed (not 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
Temporary :: !Text -> Effect
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 a

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

-- | in equipment, apply as often as <tt>Timeout</tt> permits
Periodic :: Aspect a

-- | some effects will be disabled until item recharges
Timeout :: !a -> Aspect a

-- | percentage damage bonus in melee
AddHurtMelee :: !a -> Aspect a

-- | percentage damage bonus in ranged
AddHurtRanged :: !a -> Aspect a

-- | percentage armor bonus against melee
AddArmorMelee :: !a -> Aspect a

-- | percentage armor bonus against ranged
AddArmorRanged :: !a -> Aspect a

-- | maximal hp
AddMaxHP :: !a -> Aspect a

-- | maximal calm
AddMaxCalm :: !a -> Aspect a

-- | speed in m/10s
AddSpeed :: !a -> Aspect a

-- | skills in particular abilities
AddSkills :: !Skills -> Aspect a

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

-- | smell radius, where 1 means a single tile
AddSmell :: !a -> Aspect a

-- | light radius, where 1 means a single tile
AddLight :: !a -> Aspect a

-- | Parameters modifying a throw. 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. 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

-- | 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: goes to inventory
EqpSlot :: !EqpSlot -> !Text -> Feature

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

-- | overrides actor's tactic (TODO)
Tactic :: !Tactic -> Feature
data EqpSlot
EqpSlotPeriodic :: EqpSlot
EqpSlotTimeout :: EqpSlot
EqpSlotAddHurtMelee :: EqpSlot
EqpSlotAddArmorMelee :: EqpSlot
EqpSlotAddHurtRanged :: EqpSlot
EqpSlotAddArmorRanged :: EqpSlot
EqpSlotAddMaxHP :: EqpSlot
EqpSlotAddMaxCalm :: EqpSlot
EqpSlotAddSpeed :: EqpSlot
EqpSlotAddSkills :: Ability -> EqpSlot
EqpSlotAddSight :: EqpSlot
EqpSlotAddSmell :: EqpSlot
EqpSlotAddLight :: EqpSlot

-- | a hack exclusively for AI that shares weapons
EqpSlotWeapon :: EqpSlot
slotName :: EqpSlot -> Text
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]
instance GHC.Generics.Generic Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Classes.Ord Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Read.Read Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.ItemKind
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.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.ThrowMod
instance GHC.Classes.Ord Game.LambdaHack.Content.ItemKind.ThrowMod
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.ThrowMod
instance GHC.Read.Read Game.LambdaHack.Content.ItemKind.ThrowMod
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.ThrowMod
instance Data.Traversable.Traversable Game.LambdaHack.Content.ItemKind.Aspect
instance Data.Foldable.Foldable Game.LambdaHack.Content.ItemKind.Aspect
instance GHC.Base.Functor Game.LambdaHack.Content.ItemKind.Aspect
instance GHC.Generics.Generic (Game.LambdaHack.Content.ItemKind.Aspect a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Game.LambdaHack.Content.ItemKind.Aspect a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Game.LambdaHack.Content.ItemKind.Aspect a)
instance GHC.Read.Read a => GHC.Read.Read (Game.LambdaHack.Content.ItemKind.Aspect a)
instance GHC.Show.Show a => GHC.Show.Show (Game.LambdaHack.Content.ItemKind.Aspect a)
instance GHC.Generics.Generic Game.LambdaHack.Content.ItemKind.TimerDice
instance GHC.Classes.Ord Game.LambdaHack.Content.ItemKind.TimerDice
instance GHC.Classes.Eq Game.LambdaHack.Content.ItemKind.TimerDice
instance GHC.Read.Read Game.LambdaHack.Content.ItemKind.TimerDice
instance Control.DeepSeq.NFData Game.LambdaHack.Content.ItemKind.Effect
instance GHC.Show.Show Game.LambdaHack.Content.ItemKind.TimerDice
instance Control.DeepSeq.NFData Game.LambdaHack.Content.ItemKind.TimerDice
instance Control.DeepSeq.NFData Game.LambdaHack.Content.ItemKind.ThrowMod
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.Effect
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.TimerDice
instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Game.LambdaHack.Content.ItemKind.Aspect a)
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.ThrowMod
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.Feature
instance Data.Hashable.Class.Hashable Game.LambdaHack.Content.ItemKind.EqpSlot
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.Effect
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.TimerDice
instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Game.LambdaHack.Content.ItemKind.Aspect a)
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.ThrowMod
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.Feature
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ItemKind.EqpSlot


-- | Description of effects. No operation in this module involves state or
--   monad types.
module Game.LambdaHack.Common.EffectDescription
effectToSuffix :: Effect -> Text
aspectToSuffix :: Aspect Int -> Text
featureToSuff :: Feature -> Text
kindEffectToSuffix :: Effect -> Text
kindAspectToSuffix :: Aspect Dice -> Text


-- | 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.
data TileKind
TileKind :: !Char -> !Text -> !(Freqs TileKind) -> !Color -> !Color -> ![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

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

-- | All possible terrain tile features.
data Feature

-- | embed an item of this group, to cause effects (WIP)
Embed :: !(GroupName ItemKind) -> Feature

-- | causes the effect when triggered; more succint than <tt>Embed</tt>,
--   but will probably get supplanted by <tt>Embed</tt>
Cause :: !Effect -> Feature

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

-- | goes from an open to a closed tile when altered
CloseTo :: !(GroupName TileKind) -> Feature

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

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

-- | if secret, can be revealed to belong to the group
RevealAs :: !(GroupName TileKind) -> Feature

-- | actors can walk through
Walkable :: Feature

-- | actors can see through
Clear :: Feature

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

-- | may not be what it seems (clients only)
Suspect :: Feature

-- | can never be excavated nor seen through
Impenetrable :: Feature

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

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

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

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

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

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

-- | Validate all tile kinds.
--   
--   If tiles look the same on the map, the description and the 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 iiles may
--   freely differ wrt dungeon generation, AI preferences, etc.
validateAllTileKind :: [TileKind] -> [Text]

-- | Features of tiles that differentiate them substantially from one
--   another. By tile content validation condition, this means the player
--   can tell such tile apart, and only looking at the map, not tile name.
--   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
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.Read.Read 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, which is
--   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

-- | 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 layout 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 -> !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) -> 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
[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 void
[cmaxVoid] :: CaveKind -> !Rational

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

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

-- | 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

-- | 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, Maybe Bool)

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

-- | players in the particular team
[rosterList] :: Roster -> ![Player Dice]

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

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

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

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

-- | name of the monster group to control
[fgroup] :: Player a -> !(GroupName ItemKind)

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

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

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

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

-- | whether actors have numbers, not symbols
[fhasNumbers] :: Player a -> !Bool

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

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

-- | level where the initial members start
[fentryLevel] :: Player a -> !a

-- | number of initial members
[finitialActors] :: Player a -> !a

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

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

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

-- | a symbol (matches the keypress, if any)
[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

-- | 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

-- | leader switching within a level is automatically done by the server
--   and client is not permitted to change leaders (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 permitted to do more
[autoLevel] :: AutoLeader -> !Bool

-- | 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
data HiIndeterminant
HiConst :: HiIndeterminant
HiLoot :: HiIndeterminant
HiBlitz :: HiIndeterminant
HiSurvival :: HiIndeterminant
HiKill :: HiIndeterminant
HiLoss :: HiIndeterminant

-- | Conditional polynomial representing score calculation for this player.
type HiCondPoly = [HiSummand]
type HiSummand = (HiPolynomial, [Outcome])
type HiPolynomial = [(HiIndeterminant, Double)]

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

-- | Validate all game mode kinds. Currently always valid.
validateAllModeKind :: [ModeKind] -> [Text]
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.ModeKind
instance GHC.Classes.Eq Game.LambdaHack.Content.ModeKind.Roster
instance GHC.Show.Show Game.LambdaHack.Content.ModeKind.Roster
instance GHC.Generics.Generic (Game.LambdaHack.Content.ModeKind.Player a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Game.LambdaHack.Content.ModeKind.Player a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Game.LambdaHack.Content.ModeKind.Player a)
instance GHC.Show.Show a => GHC.Show.Show (Game.LambdaHack.Content.ModeKind.Player a)
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.Outcome
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ModeKind.HiIndeterminant
instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Game.LambdaHack.Content.ModeKind.Player a)
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ModeKind.LeaderMode
instance Data.Binary.Class.Binary Game.LambdaHack.Content.ModeKind.AutoLeader


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

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

-- | Type family for auxiliary data structures for speeding up content
--   operations.

-- | 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. GroupName a -> (Int -> Id a -> a -> b -> b) -> b -> b) -> !(Id a, Id a) -> !(Maybe (Speedup a)) -> Ops a

-- | the 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 over the given group only
[ofoldrGroup] :: Ops a -> forall b. GroupName a -> (Int -> Id a -> a -> b -> b) -> b -> b

-- | bounds of identifiers of content <tt>a</tt>
[obounds] :: Ops a -> !(Id a, Id a)

-- | auxiliary speedup components
[ospeedup] :: Ops a -> !(Maybe (Speedup a))

-- | Operations for all content types, gathered together.
data COps
COps :: !(Ops CaveKind) -> !(Ops ItemKind) -> !(Ops ModeKind) -> !(Ops PlaceKind) -> !(Ops RuleKind) -> !(Ops TileKind) -> 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)

-- | 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

-- | The standard ruleset used for level operations.
stdRuleset :: Ops RuleKind -> RuleKind
instance Data.Binary.Class.Binary (Game.LambdaHack.Common.Kind.Id c)
instance GHC.Enum.Bounded (Game.LambdaHack.Common.Kind.Id c)
instance GHC.Enum.Enum (Game.LambdaHack.Common.Kind.Id c)
instance GHC.Arr.Ix (Game.LambdaHack.Common.Kind.Id c)
instance GHC.Classes.Ord (Game.LambdaHack.Common.Kind.Id c)
instance GHC.Classes.Eq (Game.LambdaHack.Common.Kind.Id c)
instance GHC.Show.Show (Game.LambdaHack.Common.Kind.Id c)
instance GHC.Show.Show Game.LambdaHack.Common.Kind.COps
instance GHC.Classes.Eq Game.LambdaHack.Common.Kind.COps


-- | Weapons, treasure and all the other items in the game. No operation in
--   this module involves the state or any of our custom monads.
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 -> !Char -> !Text -> !Flavour -> ![Feature] -> !Int -> Item

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

-- | the level on which item was created
[jlid] :: Item -> !LevelId

-- | 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
seedToAspectsEffects :: ItemSeed -> ItemKind -> AbsDepth -> AbsDepth -> ItemAspectEffect

-- | An index of the kind id of an item. Clients have partial knowledge how
--   these idexes map to kind ids. They gain knowledge by identifying
--   items.
data ItemKindIx

-- | The map of item kind indexes to item kind ids. The full map, as known
--   by the server, is a bijection.
type DiscoveryKind = EnumMap ItemKindIx (Id ItemKind)

-- | A seed for rolling aspects and effects of an item Clients have partial
--   knowledge of how item ids map to the seeds. They gain knowledge by
--   identifying items.
data ItemSeed
data ItemAspectEffect
ItemAspectEffect :: ![Aspect Int] -> ![Effect] -> ItemAspectEffect

-- | the aspects of the item
[jaspects] :: ItemAspectEffect -> ![Aspect Int]

-- | the effects when applied
[jeffects] :: ItemAspectEffect -> ![Effect]

-- | The map of item ids to item aspects and effects. The full map is known
--   by the server.
type DiscoveryEffect = EnumMap ItemId ItemAspectEffect
data ItemFull
ItemFull :: !Item -> !Int -> !ItemTimer -> !(Maybe ItemDisco) -> ItemFull
[itemBase] :: ItemFull -> !Item
[itemK] :: ItemFull -> !Int
[itemTimer] :: ItemFull -> !ItemTimer
[itemDisco] :: ItemFull -> !(Maybe ItemDisco)
data ItemDisco
ItemDisco :: !(Id ItemKind) -> !ItemKind -> !(Maybe ItemAspectEffect) -> ItemDisco
[itemKindId] :: ItemDisco -> !(Id ItemKind)
[itemKind] :: ItemDisco -> !ItemKind
[itemAE] :: ItemDisco -> !(Maybe ItemAspectEffect)
itemNoDisco :: (Item, Int) -> ItemFull
itemNoAE :: ItemFull -> ItemFull
type ItemTimer = [Time]
type ItemQuant = (Int, ItemTimer)
type ItemBag = EnumMap ItemId ItemQuant

-- | All items in the dungeon (including in actor inventories), indexed by
--   item identifier.
type ItemDict = EnumMap ItemId Item

-- | 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 the two.
--   Note that <tt>jlid</tt> is not meaningful; it gets forgotten if items
--   from different levels roll the same random properties and so are
--   merged.
type ItemKnown = (ItemKindIx, ItemAspectEffect)
instance GHC.Show.Show Game.LambdaHack.Common.Item.ItemFull
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 GHC.Show.Show Game.LambdaHack.Common.Item.ItemDisco
instance GHC.Generics.Generic Game.LambdaHack.Common.Item.ItemAspectEffect
instance GHC.Classes.Eq Game.LambdaHack.Common.Item.ItemAspectEffect
instance GHC.Show.Show Game.LambdaHack.Common.Item.ItemAspectEffect
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 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 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.ItemAspectEffect
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Item.ItemAspectEffect
instance Data.Hashable.Class.Hashable Game.LambdaHack.Common.Item.Item
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Item.Item


-- | Determining the strongest item wrt some property. No operation in this
--   module involves the state or any of our custom monads.
module Game.LambdaHack.Common.ItemStrongest
strengthOnSmash :: ItemFull -> [Effect]
strengthCreateOrgan :: ItemFull -> [GroupName ItemKind]
strengthDropOrgan :: ItemFull -> [GroupName ItemKind]
strengthToThrow :: Item -> ThrowMod
strengthEqpSlot :: Item -> Maybe (EqpSlot, Text)
strengthFromEqpSlot :: EqpSlot -> ItemFull -> Maybe Int
strengthEffect :: (Effect -> [b]) -> ItemFull -> [b]
strongestSlotNoFilter :: EqpSlot -> [(ItemId, ItemFull)] -> [(Int, (ItemId, ItemFull))]
strongestSlot :: EqpSlot -> [(ItemId, ItemFull)] -> [(Int, (ItemId, ItemFull))]
sumSlotNoFilter :: EqpSlot -> [ItemFull] -> Int
sumSkills :: [ItemFull] -> Skills
totalRange :: Item -> Int
computeTrajectory :: Int -> Int -> Int -> [Point] -> ([Vector], (Speed, Int))
itemTrajectory :: Item -> [Point] -> ([Vector], (Speed, Int))
unknownMelee :: [ItemFull] -> Bool
allRecharging :: [Effect] -> [Effect]
stripRecharging :: [Effect] -> [Effect]
stripOnSmash :: [Effect] -> [Effect]


-- | Actors in the game: heroes, monsters, etc. No operation in this module
--   involves the <tt>State</tt> or <tt>Action</tt> type.
module Game.LambdaHack.Common.Actor

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

-- | 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

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

-- | The part of speech containing the actor pronoun.
partPronoun :: Actor -> Part

-- | Actor properties that are changing throughout the game. If they are
--   dublets of properties from <tt>ActorKind</tt>, they are usually
--   modified temporarily, but tend to return to the original value from
--   <tt>ActorKind</tt> over time. E.g., HP.
data Actor
Actor :: !ItemId -> !Char -> !Text -> !Text -> !Color -> !Time -> !Int64 -> !ResDelta -> !Int64 -> !ResDelta -> !Point -> !(Maybe Point) -> !LevelId -> !LevelId -> !FactionId -> !FactionId -> !FactionId -> !(Maybe ([Vector], Speed)) -> !ItemBag -> !ItemBag -> !ItemBag -> !Bool -> !Bool -> Actor
[btrunk] :: Actor -> !ItemId

-- | individual map symbol
[bsymbol] :: Actor -> !Char

-- | individual name
[bname] :: Actor -> !Text

-- | individual pronoun
[bpronoun] :: Actor -> !Text

-- | individual map color
[bcolor] :: Actor -> !Color

-- | absolute time of next action
[btime] :: Actor -> !Time

-- | 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

-- | previous level
[boldlid] :: Actor -> !LevelId

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

-- | the faction actor is attracted to
[bfidImpressed] :: Actor -> !FactionId

-- | the original faction of the actor
[bfidOriginal] :: 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
[binv] :: Actor -> !ItemBag

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

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

-- | resource change this player turn
[resCurrentTurn] :: ResDelta -> !Int64

-- | resource change last player turn
[resPreviousTurn] :: ResDelta -> !Int64
deltaSerious :: ResDelta -> Bool
deltaMild :: ResDelta -> Bool
xM :: Int -> Int64
minusM :: Int64
minusTwoM :: Int64
oneM :: Int64
bspeed :: Actor -> [ItemFull] -> Speed

-- | A template for a new actor.
actorTemplate :: ItemId -> Char -> Text -> Text -> Color -> Int64 -> Int64 -> Point -> LevelId -> Time -> FactionId -> Actor

-- | Whether an actor is braced for combat this clip.
braced :: Actor -> Bool

-- | The actor waited last turn.
waitedLastTurn :: Actor -> Bool
actorDying :: Actor -> Bool
actorNewBorn :: Actor -> Bool

-- | Checks for the presence of actors in a position. Does not check if the
--   tile is walkable.
unoccupied :: [Actor] -> Point -> Bool
hpTooLow :: Actor -> [ItemFull] -> Bool
hpHuge :: Actor -> Bool
calmEnough :: Actor -> [ItemFull] -> Bool
calmEnough10 :: Actor -> [ItemFull] -> Bool
hpEnough :: Actor -> [ItemFull] -> Bool
hpEnough10 :: Actor -> [ItemFull] -> Bool

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

-- | How long until an actor's smell vanishes from a tile.
smellTimeout :: Delta Time
checkAdjacent :: Actor -> Actor -> Bool
keySelected :: (ActorId, Actor) -> (Bool, Bool, Char, Color, ActorId)
ppContainer :: Container -> Text
ppCStore :: CStore -> (Text, Text)
ppCStoreIn :: CStore -> Text
verbCStore :: CStore -> Text
instance GHC.Classes.Eq Game.LambdaHack.Common.Actor.Actor
instance GHC.Show.Show Game.LambdaHack.Common.Actor.Actor
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


-- | Factions taking part in the game: e.g., two human players controlling
--   the hero faction battling the monster and the animal factions.
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
data Faction
Faction :: !Text -> !Color -> !(Player Int) -> !Dipl -> !(Maybe Status) -> !(Maybe (ActorId, Maybe Target)) -> !ItemBag -> !(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 Int)

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

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

-- | the leader of the faction and his target
[gleader] :: Faction -> !(Maybe (ActorId, Maybe Target))

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

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

-- | Diplomacy states. Higher overwrite lower in case of assymetric
--   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

-- | last seen position of the targeted actor
TEnemyPos :: !ActorId -> !LevelId -> !Point -> !Bool -> Target

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

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

-- | 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. Actors
--   that can be summoned should have "horror" in their <tt>ifreq</tt> set.
isHorrorFact :: Faction -> Bool
noRunWithMulti :: Faction -> Bool
isAIFact :: Faction -> Bool
autoDungeonLevel :: Faction -> (Bool, Bool)
automatePlayer :: Bool -> Player a -> Player a

-- | 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
type Dipl = EnumMap FactionId Diplomacy
instance GHC.Classes.Ord 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.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.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.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.Faction
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.Diplomacy
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.Status
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Faction.Target


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

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

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

-- | Empty score table
empty :: ScoreDict

-- | Register a new score in a score table.
register :: ScoreTable -> Int -> Time -> Status -> ClockTime -> Int -> 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 :: (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 -> Slideshow

-- | 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
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.Show.Show Game.LambdaHack.Common.HighScore.ScoreRecord
instance GHC.Classes.Ord Game.LambdaHack.Common.HighScore.ScoreRecord
instance GHC.Classes.Eq Game.LambdaHack.Common.HighScore.ScoreRecord
instance Data.Binary.Class.Binary System.Time.ClockTime
instance Data.Binary.Class.Binary Game.LambdaHack.Common.HighScore.ScoreRecord
instance GHC.Show.Show Game.LambdaHack.Common.HighScore.ScoreTable


-- | Descripitons of items.
module Game.LambdaHack.Common.ItemDescription

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

-- | The part of speech describing the item.
partItem :: CStore -> Time -> ItemFull -> (Bool, Part, Part)
partItemWs :: Int -> CStore -> Time -> ItemFull -> Part
partItemAW :: CStore -> Time -> ItemFull -> Part
partItemMediumAW :: CStore -> Time -> ItemFull -> Part
partItemWownW :: Part -> CStore -> Time -> ItemFull -> Part
itemDesc :: CStore -> Time -> ItemFull -> Overlay
textAllAE :: Int -> Bool -> CStore -> ItemFull -> [Text]
viewItem :: Item -> (Char, Attr)


-- | 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

-- | The last time a hero left a smell in a given tile. To be used by
--   monsters that hunt by smell.
type SmellTime = Time

-- | 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

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

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

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

-- | Whether actors can walk into a tile, perhaps opening a door first,
--   perhaps a hidden door. Essential for efficiency of pathfinding, hence
--   tabulated.
isPassable :: Ops TileKind -> Id TileKind -> Bool

-- | Whether actors can walk into a tile, perhaps opening a door first,
--   perhaps a hidden door. Essential for efficiency of pathfinding, hence
--   tabulated.
isPassableNoSuspect :: Ops TileKind -> Id TileKind -> Bool

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

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

-- | Whether one can easily explore a tile, possibly finding a treasure or
--   a clue. 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.
isExplorable :: Ops TileKind -> Id TileKind -> Bool

-- | The player can't tell one tile from the other.
lookSimilar :: TileKind -> TileKind -> Bool
speedup :: Bool -> Ops TileKind -> TileSpeedup
openTo :: Ops TileKind -> Id TileKind -> Rnd (Id TileKind)
closeTo :: Ops TileKind -> Id TileKind -> Rnd (Id TileKind)
embedItems :: Ops TileKind -> Id TileKind -> [GroupName ItemKind]
causeEffects :: Ops TileKind -> Id TileKind -> [Effect]
revealAs :: Ops TileKind -> Id TileKind -> Rnd (Id TileKind)
hideAs :: Ops TileKind -> Id TileKind -> Id TileKind

-- | 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

-- | Whether a tile kind (specified by its id) has a ChangeTo feature.
--   Essential for efficiency of pathfinding, hence tabulated.
isChangeable :: Ops TileKind -> Id TileKind -> Bool
isEscape :: Ops TileKind -> Id TileKind -> Bool
isStair :: Ops TileKind -> Id TileKind -> Bool
ascendTo :: Ops TileKind -> Id TileKind -> [Int]
data TileSpeedup
TileSpeedup :: !Tab -> !Tab -> !Tab -> !Tab -> !Tab -> !Tab -> !Tab -> !Tab -> TileSpeedup
[isClearTab] :: TileSpeedup -> !Tab
[isLitTab] :: TileSpeedup -> !Tab
[isWalkableTab] :: TileSpeedup -> !Tab
[isPassableTab] :: TileSpeedup -> !Tab
[isPassableNoSuspectTab] :: TileSpeedup -> !Tab
[isDoorTab] :: TileSpeedup -> !Tab
[isSuspectTab] :: TileSpeedup -> !Tab
[isChangeableTab] :: TileSpeedup -> !Tab
data Tab
createTab :: Ops TileKind -> (TileKind -> Bool) -> Tab
accessTab :: Tab -> Id TileKind -> Bool


-- | 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 names to levels.
type Dungeon = EnumMap LevelId Level

-- | Levels in the current branch, <tt>k</tt> levels shallower than the
--   current.
ascendInBranch :: Dungeon -> Int -> LevelId -> [LevelId]

-- | 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 -> !ActorPrio -> !ItemFloor -> !ItemFloor -> !TileMap -> !X -> !Y -> !SmellMap -> !Text -> !([Point], [Point]) -> !Int -> !Int -> !Time -> !Int -> !(Freqs ItemKind) -> !Int -> !(Freqs ItemKind) -> !Int -> !Int -> ![Point] -> Level

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

-- | remembered actor times on the level
[lprio] :: Level -> !ActorPrio

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

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

-- | 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

-- | level description
[ldesc] :: Level -> !Text

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

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

-- | total number of initially clear tiles
[lclear] :: Level -> !Int

-- | date of the last activity on the level
[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)

-- | secret tile seed
[lsecret] :: Level -> !Int

-- | secret tile density
[lhidden] :: Level -> !Int

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

-- | Actor time priority queue.
type ActorPrio = EnumMap Time [ActorId]

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

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

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

-- | Query for tile kinds on the map.
at :: Level -> Point -> Id TileKind
checkAccess :: COps -> Level -> Maybe (Point -> Point -> Bool)
checkDoorAccess :: COps -> Level -> Maybe (Point -> Point -> Bool)

-- | Check whether one position is accessible from another, using the
--   formula from the standard ruleset. Precondition: the two positions are
--   next to each other.
accessible :: COps -> Level -> Point -> Point -> Bool

-- | Check whether one position is accessible from another, using the
--   formula from the standard ruleset, but additionally treating unknown
--   tiles as walkable. Precondition: the two positions are next to each
--   other.
accessibleUnknown :: COps -> Level -> Point -> Point -> Bool

-- | Check whether actors can move from a position along a unit vector,
--   using the formula from the standard ruleset.
accessibleDir :: COps -> Level -> Point -> Vector -> Bool
knownLsecret :: Level -> Bool
isSecretPos :: Level -> Point -> Bool
hideTile :: COps -> Level -> Point -> Id TileKind

-- | 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 the conjunction of
--   the list of predicates. If the permitted number of attempts is not
--   enough, try again the same number of times without the first
--   predicate, then without the first two, etc., until only one predicate
--   remains, at which point try as many times, as needed.
findPosTry :: Int -> TileMap -> (Point -> Id TileKind -> Bool) -> [Point -> Id TileKind -> Bool] -> Rnd Point
mapLevelActors_ :: Monad m => (ActorId -> m a) -> Level -> m ()
mapDungeonActors_ :: Monad m => (ActorId -> m a) -> Dungeon -> m ()
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


-- | 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 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

-- | The type representing the perception of a faction on a level.
data Perception
Perception :: !PerceptionVisible -> !PerceptionVisible -> Perception
newtype PerceptionVisible
PerceptionVisible :: EnumSet Point -> PerceptionVisible

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

-- | The set of tiles smelled by at least one hero.
smellVisible :: Perception -> EnumSet Point
nullPer :: Perception -> Bool
addPer :: Perception -> Perception -> Perception
diffPer :: Perception -> Perception -> Perception

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

-- | Perception indexed by faction identifier. This can't be added to
--   <tt>FactionDict</tt>, because clients can't see it.
type Pers = EnumMap FactionId FactionPers
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.PerceptionVisible
instance GHC.Classes.Eq Game.LambdaHack.Common.Perception.PerceptionVisible
instance GHC.Show.Show Game.LambdaHack.Common.Perception.PerceptionVisible
instance Data.Binary.Class.Binary Game.LambdaHack.Common.Perception.Perception


-- | Generation of places from place kinds.
module Game.LambdaHack.Server.DungeonGen.Place

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

-- | The parameters of a place. Most are immutable and set 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)

-- | 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

-- | Construct a fence around an area, with the given tile group.
buildFenceRnd :: COps -> GroupName TileKind -> Area -> Rnd TileMapEM

-- | 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 -> Area -> Rnd (TileMapEM, Place)
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) -> !TileMapEM -> ![Place] -> !Bool -> Cave

-- | the kind of the cave
[dkind] :: Cave -> !(Id CaveKind)

-- | tile kinds in the cave
[dmap] :: Cave -> !TileMapEM

-- | places generated in the cave
[dplaces] :: Cave -> ![Place]

-- | whether the cave is dark
[dnight] :: Cave -> !Bool

-- | Cave generation by an algorithm inspired by the original Rogue,
buildCave :: COps -> AbsDepth -> AbsDepth -> Id CaveKind -> Rnd Cave
instance GHC.Show.Show Game.LambdaHack.Server.DungeonGen.Cave.Cave


-- | Server types and operations for items that don't involve server state
--   nor our custom monads.
module Game.LambdaHack.Server.ItemRev

-- | Reverse item map, for item creation, to keep items and item
--   identifiers in bijection.
type ItemRev = HashMap ItemKnown ItemId

-- | Build an item with the given stats.
buildItem :: FlavourMap -> DiscoveryKindRev -> Id ItemKind -> ItemKind -> LevelId -> Item

-- | Generate an item based on level.
newItem :: COps -> FlavourMap -> DiscoveryKindRev -> UniqueSet -> Freqs ItemKind -> Int -> LevelId -> AbsDepth -> AbsDepth -> Rnd (Maybe (ItemKnown, ItemFull, ItemDisco, ItemSeed, GroupName ItemKind))
type UniqueSet = EnumSet (Id ItemKind)

-- | The reverse map to <tt>DiscoveryKind</tt>, needed for item creation.
type DiscoveryKindRev = EnumMap (Id ItemKind) ItemKindIx
serverDiscos :: COps -> Rnd (DiscoveryKind, DiscoveryKindRev)

-- | The map of item ids to item seeds, needed for item creation.
type ItemSeedDict = EnumMap ItemId ItemSeed

-- | 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


-- | Server and client game state types and operations.
module Game.LambdaHack.Common.State

-- | View on game state. <a>Remembered</a> fields carry a subset of the
--   info in the client copies of the state. Clients never directly change
--   their <tt>State</tt>, but apply atomic actions sent by the server to
--   do so.
data State
sdungeon :: State -> Dungeon
stotalDepth :: State -> AbsDepth
sactorD :: State -> ActorDict
sitemD :: State -> ItemDict
sfactionD :: State -> FactionDict
stime :: State -> Time
scops :: State -> COps
shigh :: State -> ScoreDict
sgameModeId :: State -> Id ModeKind

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

-- | Initial empty state.
emptyState :: 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 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
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


-- | Operations on the <a>Actor</a> type that need the <a>State</a> type,
--   but not the <tt>Action</tt> type. TODO: Document an export list after
--   it's rewritten according to #17.
module Game.LambdaHack.Common.ActorState
fidActorNotProjAssocs :: FactionId -> State -> [(ActorId, Actor)]
fidActorNotProjList :: FactionId -> State -> [Actor]
actorAssocsLvl :: (FactionId -> Bool) -> Level -> ActorDict -> [(ActorId, Actor)]
actorAssocs :: (FactionId -> Bool) -> LevelId -> State -> [(ActorId, Actor)]
actorList :: (FactionId -> Bool) -> LevelId -> State -> [Actor]
actorRegularAssocsLvl :: (FactionId -> Bool) -> Level -> ActorDict -> [(ActorId, Actor)]
actorRegularAssocs :: (FactionId -> Bool) -> LevelId -> State -> [(ActorId, Actor)]
actorRegularList :: (FactionId -> Bool) -> LevelId -> State -> [Actor]
bagAssocs :: State -> ItemBag -> [(ItemId, Item)]
bagAssocsK :: State -> ItemBag -> [(ItemId, (Item, ItemQuant))]

-- | Calculate loot's worth for a faction of a given actor.
calculateTotal :: Actor -> State -> (ItemBag, Int)
mergeItemQuant :: ItemQuant -> ItemQuant -> ItemQuant
sharedAllOwnedFid :: Bool -> FactionId -> State -> ItemBag
findIid :: ActorId -> FactionId -> ItemId -> State -> [(Actor, CStore)]
getCBag :: Container -> State -> ItemBag
getActorBag :: ActorId -> CStore -> State -> ItemBag
getBodyActorBag :: Actor -> CStore -> State -> ItemBag
mapActorItems_ :: Monad m => (CStore -> ItemId -> ItemQuant -> m a) -> Actor -> State -> m ()
getActorAssocs :: ActorId -> CStore -> State -> [(ItemId, Item)]
nearbyFreePoints :: (Id TileKind -> Bool) -> Point -> LevelId -> State -> [Point]

-- | Compute the level identifier and starting position on the level, after
--   a level change.
whereTo :: LevelId -> Point -> Int -> Dungeon -> (LevelId, Point)
getCarriedAssocs :: Actor -> State -> [(ItemId, Item)]
getCarriedIidCStore :: Actor -> [(ItemId, CStore)]

-- | Finds all actors at a position on the current level.
posToActors :: Point -> LevelId -> State -> [(ActorId, Actor)]
getItemBody :: ItemId -> State -> Item

-- | 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

-- | Gets actor body from the current level. Error if not found.
getActorBody :: ActorId -> State -> Actor
tryFindHeroK :: FactionId -> Int -> State -> Maybe (ActorId, Actor)

-- | Get current time from the dungeon data.
getLocalTime :: LevelId -> State -> Time

-- | Price an item, taking count into consideration.
itemPrice :: (Item, Int) -> Int
regenCalmDelta :: Actor -> [ItemFull] -> State -> Int64
actorInAmbient :: Actor -> State -> Bool
actorSkills :: Maybe ActorId -> ActorId -> [ItemFull] -> State -> Skills
dispEnemy :: ActorId -> ActorId -> [ItemFull] -> State -> Bool
fullAssocs :: COps -> DiscoveryKind -> DiscoveryEffect -> ActorId -> [CStore] -> State -> [(ItemId, ItemFull)]
itemToFull :: COps -> DiscoveryKind -> DiscoveryEffect -> ItemId -> Item -> ItemQuant -> ItemFull
goesIntoEqp :: ItemFull -> Bool
goesIntoInv :: ItemFull -> Bool
goesIntoSha :: ItemFull -> Bool
eqpOverfull :: Actor -> Int -> Bool
eqpFreeN :: Actor -> Int
storeFromC :: Container -> CStore

-- | 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
aidFromC :: Container -> Maybe ActorId
hasCharge :: Time -> ItemFull -> Bool
strongestMelee :: Bool -> Time -> [(ItemId, ItemFull)] -> [(Int, (ItemId, ItemFull))]
isMelee :: ItemFull -> Bool
isMeleeEqp :: ItemFull -> Bool


-- | Game action monads and basic building blocks for human and computer
--   player actions. Has no access to the the main action type.
module Game.LambdaHack.Common.MonadStateRead
class (Monad m, Functor m) => MonadStateRead m
getState :: MonadStateRead m => m State
getsState :: MonadStateRead m => (State -> a) -> m a
getLevel :: MonadStateRead m => LevelId -> m Level
nUI :: MonadStateRead m => m Int
posOfAid :: MonadStateRead m => ActorId -> m (LevelId, Point)
factionCanEscape :: MonadStateRead m => FactionId -> m Bool
getGameMode :: MonadStateRead m => m ModeKind
getEntryArena :: MonadStateRead m => Faction -> m LevelId


-- | The unpopulated dungeon generation routine.
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 -> Rnd (Id TileKind) -> Maybe (Rnd (Id TileKind)) -> Int -> Int -> TileMapEM -> Rnd TileMap
placeStairs :: COps -> TileMap -> CaveKind -> [Point] -> Rnd Point

-- | Create a level from a cave.
buildLevel :: COps -> Cave -> AbsDepth -> LevelId -> LevelId -> LevelId -> AbsDepth -> Int -> Maybe Bool -> Rnd Level

-- | Build rudimentary level from a cave kind.
levelFromCaveKind :: COps -> CaveKind -> AbsDepth -> TileMap -> ([Point], [Point]) -> Int -> Freqs ItemKind -> Int -> Freqs ItemKind -> Int -> [Point] -> Level
findGenerator :: COps -> LevelId -> LevelId -> LevelId -> AbsDepth -> Int -> (GroupName CaveKind, Maybe Bool) -> Rnd Level


-- | Abstract syntax human player commands.
module Game.LambdaHack.Client.UI.HumanCmd
data CmdCategory
CmdMenu :: CmdCategory
CmdMove :: CmdCategory
CmdItem :: CmdCategory
CmdTgt :: CmdCategory
CmdAuto :: CmdCategory
CmdMeta :: CmdCategory
CmdMouse :: CmdCategory
CmdInternal :: CmdCategory
CmdDebug :: CmdCategory
CmdMinimal :: CmdCategory

-- | Abstract syntax of player commands.
data HumanCmd
Move :: !Vector -> HumanCmd
Run :: !Vector -> HumanCmd
Wait :: HumanCmd
MoveItem :: ![CStore] -> !CStore -> !(Maybe Part) -> !Part -> !Bool -> HumanCmd
DescribeItem :: !ItemDialogMode -> HumanCmd
Project :: ![Trigger] -> HumanCmd
Apply :: ![Trigger] -> HumanCmd
AlterDir :: ![Trigger] -> HumanCmd
TriggerTile :: ![Trigger] -> HumanCmd
RunOnceAhead :: HumanCmd
MoveOnceToCursor :: HumanCmd
RunOnceToCursor :: HumanCmd
ContinueToCursor :: HumanCmd
GameRestart :: !(GroupName ModeKind) -> HumanCmd
GameExit :: HumanCmd
GameSave :: HumanCmd
Tactic :: HumanCmd
Automate :: HumanCmd
GameDifficultyCycle :: HumanCmd
PickLeader :: !Int -> HumanCmd
MemberCycle :: HumanCmd
MemberBack :: HumanCmd
SelectActor :: HumanCmd
SelectNone :: HumanCmd
Clear :: HumanCmd
StopIfTgtMode :: HumanCmd
SelectWithPointer :: HumanCmd
Repeat :: !Int -> HumanCmd
Record :: HumanCmd
History :: HumanCmd
MarkVision :: HumanCmd
MarkSmell :: HumanCmd
MarkSuspect :: HumanCmd
Help :: HumanCmd
MainMenu :: HumanCmd
Macro :: !Text -> ![String] -> HumanCmd
MoveCursor :: !Vector -> !Int -> HumanCmd
TgtFloor :: HumanCmd
TgtEnemy :: HumanCmd
TgtAscend :: !Int -> HumanCmd
EpsIncr :: !Bool -> HumanCmd
TgtClear :: HumanCmd
CursorUnknown :: HumanCmd
CursorItem :: HumanCmd
CursorStair :: !Bool -> HumanCmd
Cancel :: HumanCmd
Accept :: HumanCmd
CursorPointerFloor :: HumanCmd
CursorPointerEnemy :: HumanCmd
TgtPointerFloor :: HumanCmd
TgtPointerEnemy :: HumanCmd
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
TriggerFeature :: !Part -> !Part -> !Feature -> Trigger
[verb] :: Trigger -> !Part
[object] :: Trigger -> !Part
[feature] :: Trigger -> !Feature

-- | Commands that are forbidden on a remote level, because they would
--   usually take time when invoked on one. Note that some commands that
--   take time are not included, because they don't take time in targeting
--   mode.
noRemoteHumanCmd :: HumanCmd -> Bool
categoryDescription :: CmdCategory -> Text

-- | Description of player commands.
cmdDescription :: HumanCmd -> Text
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.Read.Read 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.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.CmdCategory
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.HumanCmd.HumanCmd
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.HumanCmd.Trigger


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

-- | The data sufficent to draw a single game screen frame.
data SingleFrame
SingleFrame :: ![ScreenLine] -> !Overlay -> ![ScreenLine] -> !Bool -> SingleFrame

-- | screen, from top to bottom, line by line
[sfLevel] :: SingleFrame -> ![ScreenLine]

-- | some extra lines to show over the top
[sfTop] :: SingleFrame -> !Overlay

-- | some extra lines to show at the bottom
[sfBottom] :: SingleFrame -> ![ScreenLine]

-- | display only <tt>sfTop</tt>, on blank screen
[sfBlank] :: SingleFrame -> !Bool
decodeLine :: ScreenLine -> [AttrChar]
encodeLine :: [AttrChar] -> ScreenLine

-- | Overlays the <tt>sfTop</tt> and <tt>sfBottom</tt> fields onto the
--   <tt>sfLevel</tt> field. The resulting frame has empty <tt>sfTop</tt>
--   and <tt>sfBottom</tt>. To be used by simple frontends that don't
--   display overlays in separate windows<i>panes</i>scrolled views.
overlayOverlay :: SingleFrame -> SingleFrame

-- | 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

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

-- | Render animations on top of a screen frame.
renderAnim :: X -> Y -> SingleFrame -> Animation -> Frames
restrictAnim :: EnumSet Point -> Animation -> 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

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

-- | Swap-places animation, both hostile and friendly.
swapPlaces :: (Point, Point) -> Animation
moveProj :: (Point, Point, Point) -> Char -> Color -> Animation
fadeout :: Bool -> Bool -> Int -> X -> Y -> Rnd Animation
instance GHC.Base.Monoid Game.LambdaHack.Client.UI.Animation.Animation
instance GHC.Show.Show Game.LambdaHack.Client.UI.Animation.Animation
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Animation.Animation
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.Animation.SingleFrame
instance GHC.Show.Show Game.LambdaHack.Client.UI.Animation.SingleFrame
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.Animation.SingleFrame
instance Data.Binary.Class.Binary Game.LambdaHack.Client.UI.Animation.SingleFrame


-- | Frontend-independent keyboard input operations.
module Game.LambdaHack.Client.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

-- | left mouse button pressed
LeftButtonPress :: Key

-- | middle mouse button pressed
MiddleButtonPress :: Key

-- | right mouse button pressed
RightButtonPress :: Key

-- | an unknown key, registered to warn the user
Unknown :: !Text -> Key
showKey :: Key -> Text

-- | Configurable event handler for the direction keys. Used for directed
--   commands such as close door.
handleDir :: Bool -> Bool -> KM -> (Vector -> a) -> a -> a
dirAllKey :: Bool -> Bool -> [Key]

-- | Binding of both sets of movement keys.
moveBinding :: Bool -> Bool -> (Vector -> a) -> (Vector -> a) -> [(KM, a)]
mkKM :: String -> 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.
keyTranslate :: String -> Key

-- | Our own encoding of modifiers. Incomplete.
data Modifier
NoModifier :: Modifier
Shift :: Modifier
Control :: Modifier
Alt :: Modifier
data KM
KM :: !Key -> !Modifier -> !(Maybe Point) -> KM
[key] :: KM -> !Key
[modifier] :: KM -> !Modifier
[pointer] :: KM -> !(Maybe Point)
toKM :: Modifier -> Key -> KM

-- | Show a key with a modifier, if any.
showKM :: KM -> Text
escKM :: KM
spaceKM :: KM
returnKM :: KM
pgupKM :: KM
pgdnKM :: KM
leftButtonKM :: KM
rightButtonKM :: KM
instance GHC.Generics.Generic Game.LambdaHack.Client.Key.KM
instance GHC.Classes.Eq Game.LambdaHack.Client.Key.KM
instance GHC.Classes.Ord Game.LambdaHack.Client.Key.KM
instance GHC.Read.Read Game.LambdaHack.Client.Key.KM
instance GHC.Generics.Generic Game.LambdaHack.Client.Key.Modifier
instance GHC.Classes.Eq Game.LambdaHack.Client.Key.Modifier
instance GHC.Classes.Ord Game.LambdaHack.Client.Key.Modifier
instance GHC.Read.Read Game.LambdaHack.Client.Key.Modifier
instance GHC.Generics.Generic Game.LambdaHack.Client.Key.Key
instance GHC.Classes.Eq Game.LambdaHack.Client.Key.Key
instance GHC.Classes.Ord Game.LambdaHack.Client.Key.Key
instance GHC.Read.Read Game.LambdaHack.Client.Key.Key
instance Data.Binary.Class.Binary Game.LambdaHack.Client.Key.Key
instance Control.DeepSeq.NFData Game.LambdaHack.Client.Key.Key
instance Data.Binary.Class.Binary Game.LambdaHack.Client.Key.Modifier
instance Control.DeepSeq.NFData Game.LambdaHack.Client.Key.Modifier
instance Control.DeepSeq.NFData Game.LambdaHack.Client.Key.KM
instance GHC.Show.Show Game.LambdaHack.Client.Key.KM
instance Data.Binary.Class.Binary Game.LambdaHack.Client.Key.KM


-- | Personal game configuration file type definitions.
module Game.LambdaHack.Client.UI.Config

-- | Fully typed contents of the UI config file. This config is a part of a
--   game client.
data Config
Config :: ![(KM, ([CmdCategory], HumanCmd))] -> ![(Int, (Text, Text))] -> !Bool -> !Bool -> !String -> !Bool -> !Int -> !Int -> !Bool -> !Bool -> Config
[configCommands] :: Config -> ![(KM, ([CmdCategory], HumanCmd))]
[configHeroNames] :: Config -> ![(Int, (Text, Text))]

-- | the option for Vi keys takes precendence
[configVi] :: Config -> !Bool

-- | because the laptop keys are the default
[configLaptop] :: Config -> !Bool
[configFont] :: Config -> !String
[configColorIsBold] :: Config -> !Bool
[configHistoryMax] :: Config -> !Int
[configMaxFps] :: Config -> !Int
[configNoAnim] :: Config -> !Bool
[configRunStopMsgs] :: Config -> !Bool

-- | Read and parse UI config file.
mkConfig :: COps -> IO Config
applyConfigToDebug :: Config -> DebugModeCli -> COps -> DebugModeCli
instance GHC.Generics.Generic Game.LambdaHack.Client.UI.Config.Config
instance GHC.Show.Show Game.LambdaHack.Client.UI.Config.Config
instance Control.DeepSeq.NFData Game.LambdaHack.Client.UI.Config.Config


-- | The type of key-command mappings to be used for the UI.
module Game.LambdaHack.Client.UI.Content.KeyKind

-- | Key-command mappings to be used for the UI.
data KeyKind
KeyKind :: ![(KM, ([CmdCategory], HumanCmd))] -> KeyKind

-- | default client UI commands
[rhumanCommands] :: KeyKind -> ![(KM, ([CmdCategory], HumanCmd))]
macroLeftButtonPress :: HumanCmd
macroShiftLeftButtonPress :: HumanCmd


-- | Text frontend based on stdin/stdout, intended for bots.
module Game.LambdaHack.Client.UI.Frontend.Std

-- | No session data needs to be maintained by this frontend.
data FrontendSession

-- | Output to the screen via the frontend.
fdisplay :: FrontendSession -> Maybe SingleFrame -> IO ()

-- | Display a prompt, wait for any key.
fpromptGetKey :: FrontendSession -> SingleFrame -> IO KM
fsyncFrames :: FrontendSession -> IO ()

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

-- | Starts the main program loop using the frontend input and output.
startup :: DebugModeCli -> (FrontendSession -> IO ()) -> IO ()


-- | Re-export the operations of the chosen raw frontend (determined at
--   compile time with cabal flags).
module Game.LambdaHack.Client.UI.Frontend.Chosen
data RawFrontend
RawFrontend :: (Maybe SingleFrame -> IO ()) -> (SingleFrame -> IO KM) -> IO () -> !(Maybe (MVar ())) -> !DebugModeCli -> RawFrontend
[fdisplay] :: RawFrontend -> Maybe SingleFrame -> IO ()
[fpromptGetKey] :: RawFrontend -> SingleFrame -> IO KM
[fsyncFrames] :: RawFrontend -> IO ()
[fescMVar] :: RawFrontend -> !(Maybe (MVar ()))
[fdebugCli] :: RawFrontend -> !DebugModeCli
chosenStartup :: DebugModeCli -> (RawFrontend -> IO ()) -> IO ()
stdStartup :: DebugModeCli -> (RawFrontend -> IO ()) -> IO ()
nullStartup :: DebugModeCli -> (RawFrontend -> IO ()) -> IO ()

-- | The name of the chosen 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 over a channel.
data FrontReq

-- | show a frame
FrontNormalFrame :: !SingleFrame -> FrontReq
[frontFrame] :: FrontReq -> !SingleFrame

-- | perform a single explicit delay
FrontDelay :: FrontReq

-- | flush frames, possibly show fadeout/fadein and ask for a keypress
FrontKey :: ![KM] -> !SingleFrame -> FrontReq
[frontKM] :: FrontReq -> ![KM]
[frontFr] :: FrontReq -> !SingleFrame

-- | show a whole slideshow without interleaving with other clients
FrontSlides :: ![KM] -> ![SingleFrame] -> !(Maybe Bool) -> FrontReq
[frontClear] :: FrontReq -> ![KM]
[frontSlides] :: FrontReq -> ![SingleFrame]
[frontFromTop] :: FrontReq -> !(Maybe Bool)

-- | set the frontend option for auto-answering prompts
FrontAutoYes :: !Bool -> FrontReq

-- | exit frontend loop
FrontFinish :: FrontReq

-- | Connection channel between a frontend and a client. Frontend acts as a
--   server, serving keys, when given frames to display.
data ChanFrontend
ChanFrontend :: !(TQueue KM) -> !(TQueue FrontReq) -> ChanFrontend
[responseF] :: ChanFrontend -> !(TQueue KM)
[requestF] :: ChanFrontend -> !(TQueue FrontReq)

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

-- | Initialize the frontend and apply the given continuation to the
--   results of the initialization.
startupF :: DebugModeCli -> (Maybe (MVar ()) -> (ChanFrontend -> IO ()) -> IO ()) -> IO ()


-- | Binding of keys to commands. No operation in this module involves the
--   <tt>State</tt> or <tt>Action</tt> type.
module Game.LambdaHack.Client.UI.KeyBindings

-- | Bindings and other information about human player commands.
data Binding
Binding :: !(Map KM (Text, [CmdCategory], HumanCmd)) -> ![(KM, (Text, [CmdCategory], HumanCmd))] -> !(Map HumanCmd KM) -> Binding

-- | binding of keys to commands
[bcmdMap] :: Binding -> !(Map KM (Text, [CmdCategory], HumanCmd))

-- | the properly ordered list of commands for the help menu
[bcmdList] :: Binding -> ![(KM, (Text, [CmdCategory], HumanCmd))]

-- | and from commands to their keys
[brevMap] :: Binding -> !(Map HumanCmd KM)

-- | Binding of keys to movement and other standard commands, as well as
--   commands defined in the config file.
stdBinding :: KeyKind -> Config -> Binding

-- | Produce a set of help screens from the key bindings.
keyHelp :: Binding -> Slideshow


-- | Item slots for UI and AI item collections. TODO: document
module Game.LambdaHack.Client.ItemSlot
type ItemSlots = (EnumMap SlotChar ItemId, EnumMap SlotChar ItemId)
data SlotChar
SlotChar :: Int -> Char -> SlotChar
[slotPrefix] :: SlotChar -> Int
[slotChar] :: SlotChar -> Char
allSlots :: Int -> [SlotChar]
slotLabel :: SlotChar -> Part
slotRange :: [SlotChar] -> Text

-- | Assigns a slot to an item, for inclusion in the inventory or equipment
--   of a hero. Tries to to use the requested slot, if any.
assignSlot :: CStore -> Item -> FactionId -> Maybe Actor -> ItemSlots -> SlotChar -> State -> SlotChar
instance GHC.Classes.Eq Game.LambdaHack.Client.ItemSlot.SlotChar
instance GHC.Show.Show Game.LambdaHack.Client.ItemSlot.SlotChar
instance GHC.Classes.Ord Game.LambdaHack.Client.ItemSlot.SlotChar
instance Data.Binary.Class.Binary Game.LambdaHack.Client.ItemSlot.SlotChar
instance GHC.Enum.Enum Game.LambdaHack.Client.ItemSlot.SlotChar


-- | Breadth first search algorithms.
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
MoveToUnknown :: MoveLegal

-- | The distance value that denote no legal path between points. The next
--   value is the minimal distance value assigned to paths that don't enter
--   any 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.
fillBfs :: (Point -> Point -> MoveLegal) -> (Point -> Point -> Bool) -> Point -> Array BfsDistance -> Array BfsDistance

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

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

-- | The minimal distance value assigned to paths that don't enter any
--   unknown tiles.
minKnownBfs :: BfsDistance
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


-- | AI strategies to direct actors not controlled directly by human
--   players. No operation in this module involves the <tt>State</tt> or
--   <tt>Action</tt> type.
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


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

-- | Determine the total benefit from having an item in eqp or inv,
--   according to item type, and also the benefit confered by equipping the
--   item and from meleeing with it or applying it or throwing it.
totalUsefulness :: COps -> Actor -> [ItemFull] -> Faction -> ItemFull -> Maybe (Int, Int)

-- | How much AI benefits from applying the effect. Multipllied by item p.
--   Negative means harm to the enemy when thrown at him. Effects with zero
--   benefit won't ever be used, neither actively nor passively.
effectToBenefit :: COps -> Actor -> [ItemFull] -> Faction -> Effect -> Int


-- | The monad for writing to the game state and related operations.
module Game.LambdaHack.Atomic.MonadStateWrite
class MonadStateRead m => MonadStateWrite m
modifyState :: MonadStateWrite m => (State -> State) -> m ()
putState :: MonadStateWrite m => State -> m ()

-- | Update a given level data within state.
updateLevel :: MonadStateWrite m => LevelId -> (Level -> Level) -> m ()
updateActor :: MonadStateWrite m => ActorId -> (Actor -> Actor) -> m ()
updateFaction :: MonadStateWrite m => FactionId -> (Faction -> Faction) -> m ()
insertItemContainer :: MonadStateWrite m => ItemId -> ItemQuant -> Container -> m ()
insertItemActor :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> CStore -> m ()
deleteItemContainer :: MonadStateWrite m => ItemId -> ItemQuant -> Container -> m ()
deleteItemActor :: MonadStateWrite m => ItemId -> ItemQuant -> ActorId -> CStore -> m ()

-- | Update the actor time priority queue.
updatePrio :: (ActorPrio -> ActorPrio) -> Level -> Level

-- | Update the items on the ground map.
updateFloor :: (ItemFloor -> ItemFloor) -> Level -> Level

-- | Update the tile map.
updateTile :: (TileMap -> TileMap) -> Level -> Level

-- | Update the smell map.
updateSmell :: (SmellMap -> SmellMap) -> Level -> Level


-- | 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 (<tt>State</tt>).
--   
--   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 state. 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 them 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 :: !ItemId -> !Item -> !ItemQuant -> !Container -> UpdAtomic
UpdLoseItem :: !ItemId -> !Item -> !ItemQuant -> !Container -> UpdAtomic
UpdMoveActor :: !ActorId -> !Point -> !Point -> UpdAtomic
UpdWaitActor :: !ActorId -> !Bool -> UpdAtomic
UpdDisplaceActor :: !ActorId -> !ActorId -> UpdAtomic
UpdMoveItem :: !ItemId -> !Int -> !ActorId -> !CStore -> !CStore -> UpdAtomic
UpdAgeActor :: !ActorId -> !(Delta Time) -> UpdAtomic
UpdRefillHP :: !ActorId -> !Int64 -> UpdAtomic
UpdRefillCalm :: !ActorId -> !Int64 -> UpdAtomic
UpdFidImpressedActor :: !ActorId -> !FactionId -> !FactionId -> UpdAtomic
UpdTrajectory :: !ActorId -> !(Maybe ([Vector], Speed)) -> !(Maybe ([Vector], Speed)) -> UpdAtomic
UpdColorActor :: !ActorId -> !Color -> !Color -> UpdAtomic
UpdQuitFaction :: !FactionId -> !(Maybe Actor) -> !(Maybe Status) -> !(Maybe Status) -> UpdAtomic
UpdLeadFaction :: !FactionId -> !(Maybe (ActorId, Maybe Target)) -> !(Maybe (ActorId, Maybe Target)) -> 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
UpdAlterClear :: !LevelId -> !Int -> UpdAtomic
UpdSearchTile :: !ActorId -> !Point -> !(Id TileKind) -> !(Id TileKind) -> UpdAtomic
UpdLearnSecrets :: !ActorId -> !Int -> !Int -> UpdAtomic
UpdSpotTile :: !LevelId -> ![(Point, Id TileKind)] -> UpdAtomic
UpdLoseTile :: !LevelId -> ![(Point, Id TileKind)] -> UpdAtomic
UpdAlterSmell :: !LevelId -> !Point -> !(Maybe Time) -> !(Maybe Time) -> UpdAtomic
UpdSpotSmell :: !LevelId -> ![(Point, Time)] -> UpdAtomic
UpdLoseSmell :: !LevelId -> ![(Point, Time)] -> UpdAtomic
UpdTimeItem :: !ItemId -> !Container -> !ItemTimer -> !ItemTimer -> UpdAtomic
UpdAgeGame :: !(Delta Time) -> ![LevelId] -> UpdAtomic
UpdDiscover :: !Container -> !ItemId -> !(Id ItemKind) -> !ItemSeed -> !AbsDepth -> UpdAtomic
UpdCover :: !Container -> !ItemId -> !(Id ItemKind) -> !ItemSeed -> !AbsDepth -> UpdAtomic
UpdDiscoverKind :: !Container -> !ItemId -> !(Id ItemKind) -> UpdAtomic
UpdCoverKind :: !Container -> !ItemId -> !(Id ItemKind) -> UpdAtomic
UpdDiscoverSeed :: !Container -> !ItemId -> !ItemSeed -> !AbsDepth -> UpdAtomic
UpdCoverSeed :: !Container -> !ItemId -> !ItemSeed -> !AbsDepth -> UpdAtomic
UpdPerception :: !LevelId -> !Perception -> !Perception -> UpdAtomic
UpdRestart :: !FactionId -> !DiscoveryKind -> !FactionPers -> !State -> !Int -> !DebugModeCli -> UpdAtomic
UpdRestartServer :: !State -> UpdAtomic
UpdResume :: !FactionId -> !FactionPers -> UpdAtomic
UpdResumeServer :: !State -> UpdAtomic
UpdKillExit :: !FactionId -> UpdAtomic
UpdWriteSave :: UpdAtomic
UpdMsgAll :: !Msg -> UpdAtomic
UpdRecordHistory :: !FactionId -> UpdAtomic

-- | Abstract syntax of atomic special effects, that is, atomic commands
--   that only display special effects and don't change the state.
data SfxAtomic
SfxStrike :: !ActorId -> !ActorId -> !ItemId -> !CStore -> !HitAtomic -> SfxAtomic
SfxRecoil :: !ActorId -> !ActorId -> !ItemId -> !CStore -> !HitAtomic -> SfxAtomic
SfxProject :: !ActorId -> !ItemId -> !CStore -> SfxAtomic
SfxCatch :: !ActorId -> !ItemId -> !CStore -> SfxAtomic
SfxApply :: !ActorId -> !ItemId -> !CStore -> SfxAtomic
SfxCheck :: !ActorId -> !ItemId -> !CStore -> SfxAtomic
SfxTrigger :: !ActorId -> !Point -> !Feature -> SfxAtomic
SfxShun :: !ActorId -> !Point -> !Feature -> SfxAtomic
SfxEffect :: !FactionId -> !ActorId -> !Effect -> SfxAtomic
SfxMsgFid :: !FactionId -> !Msg -> SfxAtomic
SfxMsgAll :: !Msg -> SfxAtomic
SfxActorStart :: !ActorId -> SfxAtomic

-- | Determine if a strike special effect should depict a block of an
--   attack.
data HitAtomic
HitClear :: HitAtomic
HitBlock :: !Int -> HitAtomic
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.HitAtomic
instance GHC.Classes.Eq Game.LambdaHack.Atomic.CmdAtomic.HitAtomic
instance GHC.Show.Show Game.LambdaHack.Atomic.CmdAtomic.HitAtomic
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.UpdAtomic
instance Data.Binary.Class.Binary Game.LambdaHack.Atomic.CmdAtomic.SfxAtomic
instance Data.Binary.Class.Binary Game.LambdaHack.Atomic.CmdAtomic.HitAtomic


-- | 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. Special effects
--   (<tt>SfxAtomic</tt>) don't modify state.
handleCmdAtomic :: MonadStateWrite m => CmdAtomic -> m ()


-- | Atomic monads for handling atomic game state transformations.
module Game.LambdaHack.Atomic.MonadAtomic

-- | The monad for executing atomic game state transformations.
class MonadStateRead m => MonadAtomic m where execUpdAtomic = execAtomic . UpdAtomic execSfxAtomic = execAtomic . SfxAtomic

-- | Execute an arbitrary atomic game state transformation.
execAtomic :: MonadAtomic m => CmdAtomic -> m ()

-- | Execute an atomic command that really changes the state.
execUpdAtomic :: MonadAtomic m => UpdAtomic -> m ()

-- | Execute an atomic command that only displays special effects.
execSfxAtomic :: MonadAtomic m => SfxAtomic -> m ()

-- | Create and broadcast a set of atomic updates, one for each client.
broadcastUpdAtomic :: MonadAtomic m => (FactionId -> UpdAtomic) -> m ()

-- | Create and broadcast a set of atomic special effects, one for each
--   client.
broadcastSfxAtomic :: MonadAtomic m => (FactionId -> SfxAtomic) -> m ()


-- | 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.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
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.
--   
--   The goal of the mechanics is to ensure the commands don't carry
--   significantly more information than their corresponding state diffs
--   would. In other words, the atomic commands involving the positions
--   seen by a client should convey similar information as the client would
--   get by directly observing the changes the commands enact on the
--   visible portion of server game state. The client is then free to
--   change its copy of game state accordingly or not --- it only partially
--   reflects reality anyway.
--   
--   E.g., <tt>UpdDisplaceActor</tt> in a black room, with 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> should be (or the former should
--   be perceived as the latter). However, to simplify, we assing 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

-- | Determines if a command resets FOV.
--   
--   Invariant: if <tt>resetsFovCmdAtomic</tt> determines we do not need to
--   reset Fov, perception (<tt>ptotal</tt> to be precise, <tt>psmell</tt>
--   is irrelevant) of any faction does not change upon recomputation.
--   Otherwise, save/restore would change game state.
resetsFovCmdAtomic :: UpdAtomic -> Bool

-- | Decompose an atomic action. The original action is visible if it's
--   positions are visible both before and after the action (in between the
--   FOV might have changed). The decomposed actions are only tested vs the
--   FOV after the action and they give reduced information that still
--   modifies client's state to match the server state wrt the current FOV
--   and the subset of <tt>posUpdAtomic</tt> that is visible. The original
--   actions give more information not only due to spanning potentially
--   more positions than those visible. E.g., <tt>UpdMoveActor</tt> informs
--   about the continued existence of the actor between moves, v.s.,
--   popping out of existence and then back in.
breakUpdAtomic :: MonadStateRead m => UpdAtomic -> m [UpdAtomic]

-- | Decompose an atomic special effect.
breakSfxAtomic :: MonadStateRead m => SfxAtomic -> m [SfxAtomic]

-- | Messages for some unseen game object
--   creation<i>destruction</i>alteration.
loudUpdAtomic :: MonadStateRead m => Bool -> FactionId -> UpdAtomic -> m (Maybe Msg)

-- | Given the client, it's perception and an atomic command, determine if
--   the client notices the command.
seenAtomicCli :: Bool -> FactionId -> Perception -> PosAtomic -> Bool
seenAtomicSer :: PosAtomic -> Bool

-- | Generate the atomic updates that jointly perform a given item move.
generalMoveItem :: MonadStateRead m => ItemId -> Int -> Container -> Container -> m [UpdAtomic]
posProjBody :: Actor -> PosAtomic
instance GHC.Classes.Eq Game.LambdaHack.Atomic.PosAtomicRead.PosAtomic
instance GHC.Show.Show Game.LambdaHack.Atomic.PosAtomicRead.PosAtomic


-- | Atomic game state transformations.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Atomic

-- | The monad for executing atomic game state transformations.
class MonadStateRead m => MonadAtomic m where execUpdAtomic = execAtomic . UpdAtomic execSfxAtomic = execAtomic . SfxAtomic

-- | Execute an arbitrary atomic game state transformation.
execAtomic :: MonadAtomic m => CmdAtomic -> m ()

-- | Execute an atomic command that really changes the state.
execUpdAtomic :: MonadAtomic m => UpdAtomic -> m ()

-- | Execute an atomic command that only displays special effects.
execSfxAtomic :: MonadAtomic m => SfxAtomic -> m ()

-- | Create and broadcast a set of atomic updates, one for each client.
broadcastUpdAtomic :: MonadAtomic m => (FactionId -> UpdAtomic) -> m ()

-- | Create and broadcast a set of atomic special effects, one for each
--   client.
broadcastSfxAtomic :: MonadAtomic m => (FactionId -> SfxAtomic) -> m ()

-- | 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 state. 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 them 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 :: !ItemId -> !Item -> !ItemQuant -> !Container -> UpdAtomic
UpdLoseItem :: !ItemId -> !Item -> !ItemQuant -> !Container -> UpdAtomic
UpdMoveActor :: !ActorId -> !Point -> !Point -> UpdAtomic
UpdWaitActor :: !ActorId -> !Bool -> UpdAtomic
UpdDisplaceActor :: !ActorId -> !ActorId -> UpdAtomic
UpdMoveItem :: !ItemId -> !Int -> !ActorId -> !CStore -> !CStore -> UpdAtomic
UpdAgeActor :: !ActorId -> !(Delta Time) -> UpdAtomic
UpdRefillHP :: !ActorId -> !Int64 -> UpdAtomic
UpdRefillCalm :: !ActorId -> !Int64 -> UpdAtomic
UpdFidImpressedActor :: !ActorId -> !FactionId -> !FactionId -> UpdAtomic
UpdTrajectory :: !ActorId -> !(Maybe ([Vector], Speed)) -> !(Maybe ([Vector], Speed)) -> UpdAtomic
UpdColorActor :: !ActorId -> !Color -> !Color -> UpdAtomic
UpdQuitFaction :: !FactionId -> !(Maybe Actor) -> !(Maybe Status) -> !(Maybe Status) -> UpdAtomic
UpdLeadFaction :: !FactionId -> !(Maybe (ActorId, Maybe Target)) -> !(Maybe (ActorId, Maybe Target)) -> 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
UpdAlterClear :: !LevelId -> !Int -> UpdAtomic
UpdSearchTile :: !ActorId -> !Point -> !(Id TileKind) -> !(Id TileKind) -> UpdAtomic
UpdLearnSecrets :: !ActorId -> !Int -> !Int -> UpdAtomic
UpdSpotTile :: !LevelId -> ![(Point, Id TileKind)] -> UpdAtomic
UpdLoseTile :: !LevelId -> ![(Point, Id TileKind)] -> UpdAtomic
UpdAlterSmell :: !LevelId -> !Point -> !(Maybe Time) -> !(Maybe Time) -> UpdAtomic
UpdSpotSmell :: !LevelId -> ![(Point, Time)] -> UpdAtomic
UpdLoseSmell :: !LevelId -> ![(Point, Time)] -> UpdAtomic
UpdTimeItem :: !ItemId -> !Container -> !ItemTimer -> !ItemTimer -> UpdAtomic
UpdAgeGame :: !(Delta Time) -> ![LevelId] -> UpdAtomic
UpdDiscover :: !Container -> !ItemId -> !(Id ItemKind) -> !ItemSeed -> !AbsDepth -> UpdAtomic
UpdCover :: !Container -> !ItemId -> !(Id ItemKind) -> !ItemSeed -> !AbsDepth -> UpdAtomic
UpdDiscoverKind :: !Container -> !ItemId -> !(Id ItemKind) -> UpdAtomic
UpdCoverKind :: !Container -> !ItemId -> !(Id ItemKind) -> UpdAtomic
UpdDiscoverSeed :: !Container -> !ItemId -> !ItemSeed -> !AbsDepth -> UpdAtomic
UpdCoverSeed :: !Container -> !ItemId -> !ItemSeed -> !AbsDepth -> UpdAtomic
UpdPerception :: !LevelId -> !Perception -> !Perception -> UpdAtomic
UpdRestart :: !FactionId -> !DiscoveryKind -> !FactionPers -> !State -> !Int -> !DebugModeCli -> UpdAtomic
UpdRestartServer :: !State -> UpdAtomic
UpdResume :: !FactionId -> !FactionPers -> UpdAtomic
UpdResumeServer :: !State -> UpdAtomic
UpdKillExit :: !FactionId -> UpdAtomic
UpdWriteSave :: UpdAtomic
UpdMsgAll :: !Msg -> UpdAtomic
UpdRecordHistory :: !FactionId -> UpdAtomic

-- | Abstract syntax of atomic special effects, that is, atomic commands
--   that only display special effects and don't change the state.
data SfxAtomic
SfxStrike :: !ActorId -> !ActorId -> !ItemId -> !CStore -> !HitAtomic -> SfxAtomic
SfxRecoil :: !ActorId -> !ActorId -> !ItemId -> !CStore -> !HitAtomic -> SfxAtomic
SfxProject :: !ActorId -> !ItemId -> !CStore -> SfxAtomic
SfxCatch :: !ActorId -> !ItemId -> !CStore -> SfxAtomic
SfxApply :: !ActorId -> !ItemId -> !CStore -> SfxAtomic
SfxCheck :: !ActorId -> !ItemId -> !CStore -> SfxAtomic
SfxTrigger :: !ActorId -> !Point -> !Feature -> SfxAtomic
SfxShun :: !ActorId -> !Point -> !Feature -> SfxAtomic
SfxEffect :: !FactionId -> !ActorId -> !Effect -> SfxAtomic
SfxMsgFid :: !FactionId -> !Msg -> SfxAtomic
SfxMsgAll :: !Msg -> SfxAtomic
SfxActorStart :: !ActorId -> SfxAtomic

-- | Determine if a strike special effect should depict a block of an
--   attack.
data HitAtomic
HitClear :: HitAtomic
HitBlock :: !Int -> HitAtomic

-- | 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
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.
--   
--   The goal of the mechanics is to ensure the commands don't carry
--   significantly more information than their corresponding state diffs
--   would. In other words, the atomic commands involving the positions
--   seen by a client should convey similar information as the client would
--   get by directly observing the changes the commands enact on the
--   visible portion of server game state. The client is then free to
--   change its copy of game state accordingly or not --- it only partially
--   reflects reality anyway.
--   
--   E.g., <tt>UpdDisplaceActor</tt> in a black room, with 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> should be (or the former should
--   be perceived as the latter). However, to simplify, we assing 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

-- | Given the client, it's perception and an atomic command, determine if
--   the client notices the command.
seenAtomicCli :: Bool -> FactionId -> Perception -> PosAtomic -> Bool

-- | Generate the atomic updates that jointly perform a given item move.
generalMoveItem :: MonadStateRead m => ItemId -> Int -> Container -> Container -> m [UpdAtomic]
posProjBody :: Actor -> PosAtomic


-- | Server and client game state types and operations.
module Game.LambdaHack.Client.State

-- | Client state, belonging to a single faction. Some of the data, e.g,
--   the history, carries over from game to game, even across playing
--   sessions. Data invariant: if <tt>_sleader</tt> is <tt>Nothing</tt>
--   then so is <tt>srunning</tt>.
data StateClient
StateClient :: !(Maybe TgtMode) -> !Target -> !Int -> !(EnumMap ActorId (Target, Maybe PathEtc)) -> !(EnumSet LevelId) -> !(EnumMap ActorId (Bool, Array BfsDistance, Point, Int, Maybe [Point])) -> !(EnumSet ActorId) -> !(Maybe RunParams) -> !Report -> !History -> !(EnumMap LevelId Time) -> ![CmdAtomic] -> !DiscoveryKind -> !DiscoveryEffect -> !FactionPers -> !StdGen -> !KM -> !LastRecord -> ![KM] -> !(EnumSet ActorId) -> !Int -> !(Maybe ActorId) -> !FactionId -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Int -> !Int -> !ItemSlots -> !SlotChar -> !CStore -> !EscAI -> !DebugModeCli -> StateClient

-- | targeting mode
[stgtMode] :: StateClient -> !(Maybe TgtMode)

-- | the common, cursor target
[scursor] :: StateClient -> !Target

-- | a parameter of the tgt digital line
[seps] :: StateClient -> !Int

-- | targets of our actors in the dungeon
[stargetD] :: StateClient -> !(EnumMap ActorId (Target, Maybe PathEtc))

-- | the set of fully explored levels
[sexplored] :: StateClient -> !(EnumSet LevelId)

-- | pathfinding distances for our actors and paths to their targets, if
--   any
[sbfsD] :: StateClient -> !(EnumMap ActorId (Bool, Array BfsDistance, Point, Int, Maybe [Point]))

-- | the set of currently selected actors
[sselected] :: StateClient -> !(EnumSet ActorId)

-- | parameters of the current run, if any
[srunning] :: StateClient -> !(Maybe RunParams)

-- | current messages
[sreport] :: StateClient -> !Report

-- | history of messages
[shistory] :: StateClient -> !History

-- | moves are displayed up to this time
[sdisplayed] :: StateClient -> !(EnumMap LevelId Time)

-- | atomic commands performed to date
[sundo] :: StateClient -> ![CmdAtomic]

-- | remembered item discoveries
[sdiscoKind] :: StateClient -> !DiscoveryKind

-- | remembered effects&amp;Co of items
[sdiscoEffect] :: StateClient -> !DiscoveryEffect

-- | faction perception indexed by levels
[sfper] :: StateClient -> !FactionPers

-- | current random generator
[srandom] :: StateClient -> !StdGen

-- | last issued key command
[slastKM] :: StateClient -> !KM

-- | state of key sequence recording
[slastRecord] :: StateClient -> !LastRecord

-- | state of key sequence playback
[slastPlay] :: StateClient -> ![KM]

-- | actors that just got out of sight
[slastLost] :: StateClient -> !(EnumSet ActorId)

-- | player just waited this many times
[swaitTimes] :: StateClient -> !Int

-- | current picked party leader
[_sleader] :: StateClient -> !(Maybe ActorId)

-- | faction controlled by the client
[_sside] :: StateClient -> !FactionId

-- | exit the game loop
[squit] :: StateClient -> !Bool

-- | whether it's an AI client
[sisAI] :: StateClient -> !Bool

-- | mark leader and party FOV
[smarkVision] :: StateClient -> !Bool

-- | mark smell, if the leader can smell
[smarkSmell] :: StateClient -> !Bool

-- | mark suspect features
[smarkSuspect] :: StateClient -> !Bool

-- | current game difficulty level
[scurDiff] :: StateClient -> !Int

-- | next game difficulty level
[snxtDiff] :: StateClient -> !Int

-- | map from slots to items
[sslots] :: StateClient -> !ItemSlots

-- | last used slot
[slastSlot] :: StateClient -> !SlotChar

-- | last used store
[slastStore] :: StateClient -> !CStore

-- | just canceled AI control with ESC
[sescAI] :: StateClient -> !EscAI

-- | client debugging mode
[sdebugCli] :: StateClient -> !DebugModeCli

-- | Initial game client state.
defStateClient :: History -> Report -> FactionId -> Bool -> StateClient
defaultHistory :: Int -> IO History

-- | 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
type PathEtc = ([Point], (Point, Int))

-- | Current targeting mode of a client.
newtype TgtMode
TgtMode :: LevelId -> TgtMode
[tgtLevelId] :: TgtMode -> 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
type LastRecord = ([KM], [KM], Int)
data EscAI
EscAINothing :: EscAI
EscAIStarted :: EscAI
EscAIMenu :: EscAI
EscAIExited :: EscAI
toggleMarkVision :: StateClient -> StateClient
toggleMarkSmell :: StateClient -> StateClient
toggleMarkSuspect :: StateClient -> StateClient
instance GHC.Show.Show Game.LambdaHack.Client.State.StateClient
instance GHC.Classes.Eq Game.LambdaHack.Client.State.EscAI
instance GHC.Show.Show Game.LambdaHack.Client.State.EscAI
instance GHC.Show.Show Game.LambdaHack.Client.State.RunParams
instance Data.Binary.Class.Binary Game.LambdaHack.Client.State.TgtMode
instance GHC.Classes.Eq Game.LambdaHack.Client.State.TgtMode
instance GHC.Show.Show Game.LambdaHack.Client.State.TgtMode
instance Data.Binary.Class.Binary Game.LambdaHack.Client.State.StateClient
instance Data.Binary.Class.Binary Game.LambdaHack.Client.State.RunParams


-- | Basic client monad and related operations.
module Game.LambdaHack.Client.MonadClient
class MonadStateRead m => MonadClient m
getClient :: MonadClient m => m StateClient
getsClient :: MonadClient m => (StateClient -> a) -> m a
modifyClient :: MonadClient m => (StateClient -> StateClient) -> m ()
putClient :: MonadClient m => StateClient -> m ()
liftIO :: MonadClient m => IO a -> m a
saveChanClient :: MonadClient m => m (ChanSave (State, StateClient))
debugPrint :: MonadClient m => Text -> m ()
saveClient :: MonadClient m => m ()
saveName :: FactionId -> Bool -> String
restoreGame :: MonadClient m => m (Maybe (State, StateClient))

-- | Assuming the client runs on the same machine and for the same user as
--   the server, move the server savegame out of the way.
removeServerSave :: MonadClient m => m ()

-- | Invoke pseudo-random computation with the generator kept in the state.
rndToAction :: MonadClient m => Rnd a -> m a


-- | The client-server communication monads.
module Game.LambdaHack.Client.ProtocolClient
class MonadClient m => MonadClientReadResponse resp m | m -> resp
receiveResponse :: MonadClientReadResponse resp m => m resp
class MonadClient m => MonadClientWriteRequest req m | m -> req
sendRequest :: MonadClientWriteRequest req m => req -> m ()


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

-- | Cclient-server requests sent by AI clients.
data RequestAI
ReqAITimed :: !(RequestTimed a) -> RequestAI
ReqAILeader :: !ActorId -> !(Maybe Target) -> !RequestAI -> RequestAI
ReqAIPong :: RequestAI

-- | Client-server requests sent by UI clients.
data RequestUI
ReqUITimed :: !(RequestTimed a) -> RequestUI
ReqUILeader :: !ActorId -> !(Maybe Target) -> !RequestUI -> RequestUI
ReqUIGameRestart :: !ActorId -> !(GroupName ModeKind) -> !Int -> ![(Int, (Text, Text))] -> RequestUI
ReqUIGameExit :: !ActorId -> RequestUI
ReqUIGameSave :: RequestUI
ReqUITactic :: !Tactic -> RequestUI
ReqUIAutomate :: RequestUI
ReqUIPong :: [CmdAtomic] -> RequestUI

-- | Client-server requests that take game time. Sent by both AI and UI
--   clients.
data RequestTimed :: Ability -> *
[ReqMove] :: !Vector -> RequestTimed AbMove
[ReqMelee] :: !ActorId -> !ItemId -> !CStore -> RequestTimed AbMelee
[ReqDisplace] :: !ActorId -> RequestTimed AbDisplace
[ReqAlter] :: !Point -> !(Maybe Feature) -> RequestTimed AbAlter
[ReqWait] :: RequestTimed AbWait
[ReqMoveItems] :: ![(ItemId, Int, CStore, CStore)] -> RequestTimed AbMoveItem
[ReqProject] :: !Point -> !Int -> !ItemId -> !CStore -> RequestTimed AbProject
[ReqApply] :: !ItemId -> !CStore -> RequestTimed AbApply
[ReqTrigger] :: !(Maybe Feature) -> RequestTimed AbTrigger
data RequestAnyAbility
RequestAnyAbility :: !(RequestTimed a) -> RequestAnyAbility
data ReqFailure
MoveNothing :: ReqFailure
MeleeSelf :: ReqFailure
MeleeDistant :: ReqFailure
DisplaceDistant :: ReqFailure
DisplaceAccess :: ReqFailure
DisplaceProjectiles :: ReqFailure
DisplaceDying :: ReqFailure
DisplaceBraced :: ReqFailure
DisplaceImmobile :: ReqFailure
DisplaceSupported :: ReqFailure
AlterUnskilled :: ReqFailure
AlterDistant :: ReqFailure
AlterBlockActor :: ReqFailure
AlterBlockItem :: ReqFailure
AlterNothing :: ReqFailure
EqpOverfull :: ReqFailure
EqpStackFull :: ReqFailure
ApplyUnskilled :: ReqFailure
ApplyRead :: ReqFailure
ApplyOutOfReach :: ReqFailure
ApplyCharging :: ReqFailure
ItemNothing :: ReqFailure
ItemNotCalm :: ReqFailure
NotCalmPrecious :: ReqFailure
ProjectUnskilled :: ReqFailure
ProjectAimOnself :: ReqFailure
ProjectBlockTerrain :: ReqFailure
ProjectBlockActor :: ReqFailure
ProjectNotRanged :: ReqFailure
ProjectFragile :: ReqFailure
ProjectOutOfReach :: ReqFailure
TriggerNothing :: ReqFailure
NoChangeDunLeader :: ReqFailure
NoChangeLvlLeader :: ReqFailure
impossibleReqFailure :: ReqFailure -> Bool
showReqFailure :: ReqFailure -> Msg
anyToUI :: RequestAnyAbility -> RequestUI
permittedPrecious :: Bool -> Bool -> ItemFull -> Either ReqFailure Bool
permittedProject :: [Char] -> Bool -> Int -> ItemFull -> Actor -> [ItemFull] -> Either ReqFailure Bool
permittedApply :: [Char] -> Time -> Int -> ItemFull -> Actor -> [ItemFull] -> Either ReqFailure Bool
instance GHC.Show.Show Game.LambdaHack.Common.Request.RequestAI
instance GHC.Show.Show Game.LambdaHack.Common.Request.RequestUI
instance GHC.Show.Show Game.LambdaHack.Common.Request.RequestAnyAbility
instance GHC.Show.Show (Game.LambdaHack.Common.Request.RequestTimed a)


-- | Common client monad operations.
module Game.LambdaHack.Client.CommonClient

-- | Get the current perception of a client.
getPerFid :: MonadClient m => LevelId -> m Perception

-- | Calculate the position of an actor's target.
aidTgtToPos :: MonadClient m => ActorId -> LevelId -> Maybe Target -> m (Maybe Point)

-- | Check whether one is permitted to aim at a target (this is only
--   checked for actors; positions let player shoot at obstacles, e.g., to
--   destroy them). This assumes <tt>aidTgtToPos</tt> does not return
--   <tt>Nothing</tt>. 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.
aidTgtAims :: MonadClient m => ActorId -> LevelId -> Maybe Target -> m (Either Msg Int)

-- | 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 :: MonadClient m => Bool -> Actor -> Point -> Int -> m (Maybe Int)

-- | 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 :: MonadClient m => ActorId -> m Part

-- | 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 :: MonadClient m => ActorId -> Actor -> m 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 -> Actor -> m Part
actorSkillsClient :: MonadClient m => ActorId -> m Skills
updateItemSlot :: MonadClient m => CStore -> Maybe ActorId -> ItemId -> m SlotChar
fullAssocsClient :: MonadClient m => ActorId -> [CStore] -> m [(ItemId, ItemFull)]
activeItemsClient :: MonadClient m => ActorId -> m [ItemFull]
itemToFullClient :: MonadClient m => m (ItemId -> ItemQuant -> ItemFull)
pickWeaponClient :: MonadClient m => ActorId -> ActorId -> m (Maybe (RequestTimed AbMelee))
sumOrganEqpClient :: MonadClient m => EqpSlot -> ActorId -> m Int


-- | Semantics of abilities in terms of actions and the AI procedure for
--   picking the best action for an actor.
module Game.LambdaHack.Client.AI.ConditionClient

-- | Require that the target enemy is visible by the party.
condTgtEnemyPresentM :: MonadClient m => ActorId -> m Bool

-- | Require that the target enemy is remembered on the actor's level.
condTgtEnemyRememberedM :: MonadClient m => ActorId -> m Bool

-- | Require that the target enemy is adjacent to at least one friend.
condTgtEnemyAdjFriendM :: 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.
condAnyFoeAdjM :: MonadStateRead m => ActorId -> m Bool

-- | Require the actor's HP is low enough.
condHpTooLowM :: MonadClient m => ActorId -> m Bool

-- | Require the actor stands over a triggerable tile.
condOnTriggerableM :: MonadStateRead m => ActorId -> m Bool

-- | 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 :: MonadClient m => ActorId -> m Bool

-- | Check whether the actor has no weapon in equipment.
condNoEqpWeaponM :: MonadClient m => ActorId -> m Bool

-- | Check whether the actor has enough gear to go look for enemies.
condEnoughGearM :: MonadClient m => ActorId -> m Bool

-- | Require that the actor can project any items.
condCanProjectM :: MonadClient m => Bool -> ActorId -> m Bool

-- | Require the actor is not calm enough.
condNotCalmEnoughM :: MonadClient m => ActorId -> m Bool

-- | Require that the actor stands over a desirable item.
condDesirableFloorItemM :: MonadClient m => ActorId -> m Bool

-- | Require the actor is in a bad position to melee or can't melee at all.
condMeleeBadM :: MonadClient m => ActorId -> m Bool

-- | Require that the actor stands in the dark, but is betrayed by his own
--   equipped light,
condLightBetraysM :: MonadClient m => ActorId -> m Bool

-- | Produce the list of items with a given property available to the actor
--   and the items' values.
benAvailableItems :: MonadClient m => ActorId -> (Maybe Int -> ItemFull -> Actor -> [ItemFull] -> Bool) -> [CStore] -> m [((Maybe (Int, Int), (Int, CStore)), (ItemId, ItemFull))]
hinders :: Bool -> Bool -> Bool -> Bool -> Actor -> [ItemFull] -> ItemFull -> Bool

-- | Produce the list of items on the ground beneath the actor that are
--   worth picking up.
benGroundItems :: MonadClient m => ActorId -> m [((Maybe (Int, Int), (Int, CStore)), (ItemId, ItemFull))]
desirableItem :: Bool -> Maybe Int -> ItemFull -> Bool

-- | Produce the chess-distance-sorted list of non-low-HP foes on the
--   level. We don't consider path-distance, because we are interested in
--   how soon the foe can hit us, which can diverge greately from path
--   distance for short distances.
threatDistList :: MonadClient m => ActorId -> m [(Int, (ActorId, Actor))]

-- | Produce a list of acceptable adjacent points to flee to.
fleeList :: MonadClient m => ActorId -> m ([(Int, Point)], [(Int, Point)])


-- | Breadth first search and realted algorithms using the client monad.
module Game.LambdaHack.Client.BfsClient
invalidateBfs :: ActorId -> EnumMap ActorId (Bool, Array BfsDistance, Point, Int, Maybe [Point]) -> EnumMap ActorId (Bool, Array BfsDistance, Point, Int, Maybe [Point])

-- | Get cached BFS data and path or, if not stored, generate, store and
--   return. Due to laziness, they are not calculated until needed.
getCacheBfsAndPath :: forall m. MonadClient m => ActorId -> Point -> m (Array BfsDistance, Maybe [Point])
getCacheBfs :: MonadClient m => ActorId -> m (Array BfsDistance)
accessCacheBfs :: MonadClient m => ActorId -> Point -> m (Maybe Int)
unexploredDepth :: MonadClient m => m (Int -> LevelId -> Bool)

-- | Closest reachable unknown tile position, if any.
closestUnknown :: MonadClient m => ActorId -> m (Maybe Point)

-- | Closest (wrt paths) suspect tile.
closestSuspect :: MonadClient m => ActorId -> m [Point]

-- | Finds smells closest to the actor, except under the actor.
closestSmell :: MonadClient m => ActorId -> m [(Int, (Point, SmellTime))]

-- | Furthest (wrt paths) known position.
furthestKnown :: MonadClient m => ActorId -> m Point

-- | Closest (wrt paths) triggerable open tiles. 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.
closestTriggers :: MonadClient m => Maybe Bool -> ActorId -> m (Frequency Point)

-- | Closest (wrt paths) items and changeable tiles (e.g., item caches).
closestItems :: MonadClient m => ActorId -> m [(Int, (Point, Maybe ItemBag))]

-- | Closest (wrt paths) enemy actors.
closestFoes :: MonadClient m => [(ActorId, Actor)] -> ActorId -> m [(Int, (ActorId, Actor))]


-- | Semantics of abilities in terms of actions and the AI procedure for
--   picking the best action for an actor.
module Game.LambdaHack.Client.AI.HandleAbilityClient

-- | AI strategy based on actor's sight, smell, etc. Never empty.
actionStrategy :: forall m. MonadClient m => ActorId -> m (Strategy RequestAnyAbility)
instance GHC.Classes.Eq Game.LambdaHack.Client.AI.HandleAbilityClient.ApplyItemGroup


-- | Let AI pick the best target for an actor.
module Game.LambdaHack.Client.AI.PickTargetClient

-- | AI proposes possible targets for the actor. Never empty.
targetStrategy :: forall m. MonadClient m => ActorId -> m (Strategy (Target, Maybe PathEtc))
createPath :: MonadClient m => ActorId -> Target -> m (Maybe (Target, PathEtc))


-- | Semantics of most <tt>ResponseAI</tt> client commands.
module Game.LambdaHack.Client.AI.PickActorClient
pickActorToMove :: MonadClient m => ((ActorId, Actor) -> m (Maybe (Target, PathEtc))) -> ActorId -> m (ActorId, Actor)


-- | 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 AI player.
queryAI :: MonadClient m => ActorId -> m RequestAI

-- | Client signals to the server that it's still online.
pongAI :: MonadClient m => m RequestAI

-- | 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 (Target, PathEtc))

-- | Pick an action the actor will perfrom this turn.
pickAction :: MonadClient m => (ActorId, Actor) -> m RequestAnyAbility


-- | Handle atomic commands received by the client.
module Game.LambdaHack.Client.HandleAtomicClient

-- | Effect of atomic actions on client state is calculated in the global
--   state before the command is executed.
cmdAtomicSemCli :: MonadClient m => UpdAtomic -> m ()

-- | Clients keep a subset of atomic commands sent by the server and add
--   some of their own. The result of this function is the list of commands
--   kept for each command received.
cmdAtomicFilterCli :: MonadClient m => UpdAtomic -> m [UpdAtomic]


-- | Display game data on the screen using one of the available frontends
--   (determined at compile time with cabal flags).
module Game.LambdaHack.Client.UI.DrawClient

-- | Color mode for the display.
data ColorMode

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

-- | black+white only
ColorBW :: ColorMode

-- | Draw the whole screen: level map and status area. Pass at most a
--   single page if overlay of text unchanged to the frontends to display
--   separately or overlay over map, depending on the frontend.
draw :: MonadClient m => ColorMode -> LevelId -> Maybe Point -> Maybe Point -> Maybe (Array BfsDistance, Maybe [Point]) -> (Text, Maybe Text) -> (Text, Maybe Text) -> Overlay -> m SingleFrame


-- | 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
liftIO :: MonadClientUI m => IO a -> m a

-- | The information that is constant across a client playing session,
--   including many consecutive games in a single session, but is
--   completely disregarded and reset when a new playing session starts.
--   This includes a frontend session and keybinding info.
data SessionUI
SessionUI :: !ChanFrontend -> !Binding -> !(Maybe (MVar ())) -> !Config -> SessionUI

-- | connection with the frontend
[schanF] :: SessionUI -> !ChanFrontend

-- | binding of keys to commands
[sbinding] :: SessionUI -> !Binding
[sescMVar] :: SessionUI -> !(Maybe (MVar ()))
[sconfig] :: SessionUI -> !Config

-- | Color mode for the display.
data ColorMode

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

-- | black+white only
ColorBW :: ColorMode
promptGetKey :: MonadClientUI m => [KM] -> SingleFrame -> m KM

-- | Display an overlay and wait for a human player command.
getKeyOverlayCommand :: MonadClientUI m => Maybe Bool -> Overlay -> m KM

-- | Display a slideshow, awaiting confirmation for each slide except the
--   last.
getInitConfirms :: MonadClientUI m => ColorMode -> [KM] -> Slideshow -> m Bool
displayFrame :: MonadClientUI m => Maybe SingleFrame -> m ()
displayDelay :: MonadClientUI m => m ()

-- | Push frames or delays to the frame queue. Additionally set
--   <tt>sdisplayed</tt>. because animations not always happen after
--   <tt>SfxActorStart</tt> on the leader's level (e.g., death can lead to
--   leader change to another level mid-turn, and there could be melee and
--   animations on that level at the same moment). Insert delays, so that
--   the animations don't look rushed.
displayActorStart :: MonadClientUI m => Actor -> Frames -> m ()

-- | Draw the current level with the overlay on top.
drawOverlay :: MonadClientUI m => Bool -> ColorMode -> Overlay -> m SingleFrame
stopPlayBack :: MonadClientUI m => m ()
askConfig :: MonadClientUI m => m Config

-- | Get the key binding.
askBinding :: MonadClientUI m => m Binding

-- | Sync frames display with the frontend.
syncFrames :: MonadClientUI m => m ()
setFrontAutoYes :: MonadClientUI m => Bool -> m ()
tryTakeMVarSescMVar :: MonadClientUI m => m Bool
scoreToSlideshow :: MonadClientUI m => Int -> Status -> m Slideshow
getLeaderUI :: MonadClientUI m => m ActorId
getArenaUI :: MonadClientUI m => m LevelId
viewedLevel :: MonadClientUI m => m LevelId
targetDescLeader :: MonadClientUI m => ActorId -> m (Text, Maybe Text)
targetDescCursor :: MonadClientUI m => m (Text, Maybe Text)
leaderTgtToPos :: MonadClientUI m => m (Maybe Point)
leaderTgtAims :: MonadClientUI m => m (Either Text Int)
cursorToPos :: MonadClientUI m => m (Maybe Point)


-- | Startup up the frontend together with the server, which starts up
--   clients.
module Game.LambdaHack.Client.UI.StartupFrontendClient

-- | Wire together game content, the main loops of game clients, the main
--   game loop assigned to this frontend (possibly containing the server
--   loop, if the whole game runs in one process), UI config and the
--   definitions of game commands.
srtFrontend :: (DebugModeCli -> SessionUI -> State -> StateClient -> chanServerUI -> IO ()) -> (DebugModeCli -> SessionUI -> State -> StateClient -> chanServerAI -> IO ()) -> KeyKind -> COps -> DebugModeCli -> ((FactionId -> chanServerUI -> IO ()) -> (FactionId -> chanServerAI -> IO ()) -> IO ()) -> IO ()


-- | A set of widgets for UI clients.
module Game.LambdaHack.Client.UI.WidgetClient

-- | Display a message with a <tt>-more-</tt> prompt. Return value
--   indicates if the player tried to cancel/escape.
displayMore :: MonadClientUI m => ColorMode -> Msg -> m Bool

-- | 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 -> Msg -> m Bool

-- | Print a prompt and an overlay and wait for a player keypress. If many
--   overlays, scroll screenfuls with SPACE. Do not wrap screenfuls (in
--   some menus <tt>?</tt> cycles views, so the user can restart from the
--   top).
displayChoiceUI :: MonadClientUI m => Msg -> Overlay -> [KM] -> m (Either Slideshow KM)

-- | Push the frame depicting the current level to the frame queue. Only
--   one screenful of the report is shown, the rest is ignored.
displayPush :: MonadClientUI m => Msg -> m ()
describeMainKeys :: MonadClientUI m => m Msg

-- | The prompt is shown after the current message, but not added to
--   history. This is useful, e.g., in targeting mode, not to spam history.
promptToSlideshow :: MonadClientUI m => Msg -> m Slideshow

-- | The prompt is shown after the current message at the top of each
--   slide. Together they may take more than one line. The prompt is not
--   added to history. The portions of overlay that fit on the the rest of
--   the screen are displayed below. As many slides as needed are shown.
overlayToSlideshow :: MonadClientUI m => Msg -> Overlay -> m Slideshow
overlayToBlankSlideshow :: MonadClientUI m => Bool -> Msg -> Overlay -> m Slideshow

-- | Render animations on top of the current screen frame.
animate :: MonadClientUI m => LevelId -> Animation -> m Frames
fadeOutOrIn :: MonadClientUI m => Bool -> m ()


-- | Client monad for interacting with a human through UI.
module Game.LambdaHack.Client.UI.MsgClient

-- | Add a message to the current report.
msgAdd :: MonadClientUI m => Msg -> m ()

-- | Wipe out and set a new value for the current report.
msgReset :: MonadClientUI m => Msg -> m ()

-- | Store current report in the history and reset report.
recordHistory :: MonadClientUI m => m ()
type SlideOrCmd a = Either Slideshow a
failWith :: MonadClientUI m => Msg -> m (SlideOrCmd a)
failSlides :: MonadClientUI m => Slideshow -> m (SlideOrCmd a)
failSer :: MonadClientUI m => ReqFailure -> m (SlideOrCmd a)
failMsg :: MonadClientUI m => Msg -> m Slideshow

-- | 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 targeting mode.
lookAt :: MonadClientUI m => Bool -> Text -> Bool -> Point -> ActorId -> Text -> m Text

-- | Create a list of item names.
itemOverlay :: MonadClient m => CStore -> LevelId -> ItemBag -> m Overlay


-- | Display atomic commands received by the client.
module Game.LambdaHack.Client.UI.DisplayAtomicClient

-- | Visualize atomic actions 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 -> State -> StateClient -> UpdAtomic -> m ()

-- | Display special effects (text, animation) sent to the client.
displayRespSfxAtomicUI :: MonadClientUI m => Bool -> SfxAtomic -> m ()


-- | Inventory management and party cycling. TODO: document
module Game.LambdaHack.Client.UI.InventoryClient
data Suitability
SuitsEverything :: Suitability
SuitsNothing :: Msg -> Suitability
SuitsSomething :: (ItemFull -> Bool) -> Suitability

-- | 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 -> Bool -> [CStore] -> [CStore] -> m (SlideOrCmd ((ItemId, ItemFull), ItemDialogMode))

-- | Let the human player choose any item from a list of items and let him
--   specify the number of items. Used, e.g., for picking up and inventory
--   manipulation.
getAnyItems :: MonadClientUI m => m Suitability -> Text -> Text -> [CStore] -> [CStore] -> Bool -> Bool -> m (SlideOrCmd ([(ItemId, ItemFull)], ItemDialogMode))

-- | 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 -> [ItemFull] -> ItemDialogMode -> Text) -> ItemDialogMode -> m (SlideOrCmd ((ItemId, ItemFull), ItemDialogMode))

-- | Switches current member to the next on the level, if any, wrapping.
memberCycle :: MonadClientUI m => Bool -> m Slideshow

-- | Switches current member to the previous in the whole dungeon,
--   wrapping.
memberBack :: MonadClientUI m => Bool -> m Slideshow

-- | Select a faction leader. False, if nothing to do.
pickLeader :: MonadClientUI m => Bool -> ActorId -> m Bool
cursorPointerFloor :: MonadClientUI m => Bool -> Bool -> m Slideshow
cursorPointerEnemy :: MonadClientUI m => Bool -> Bool -> m Slideshow

-- | Move the cursor. Assumes targeting mode.
moveCursorHuman :: MonadClientUI m => Vector -> Int -> m Slideshow

-- | Cycle targeting mode. Do not change position of the cursor, switch
--   among things at that position.
tgtFloorHuman :: MonadClientUI m => m Slideshow
tgtEnemyHuman :: MonadClientUI m => m Slideshow

-- | Tweak the <tt>eps</tt> parameter of the targeting digital line.
epsIncrHuman :: MonadClientUI m => Bool -> m Slideshow
tgtClearHuman :: MonadClientUI m => m Slideshow

-- | Perform look around in the current position of the cursor. Normally
--   expects targeting mode and so that a leader is picked.
doLook :: MonadClientUI m => Bool -> m Slideshow
describeItemC :: MonadClientUI m => ItemDialogMode -> m (SlideOrCmd (RequestTimed AbMoveItem))
instance GHC.Classes.Eq Game.LambdaHack.Client.UI.InventoryClient.ItemDialogState
instance GHC.Show.Show Game.LambdaHack.Client.UI.InventoryClient.ItemDialogState


-- | Semantics of <tt>HumanCmd</tt> client commands that do not return
--   server commands. None of such commands takes game time. TODO: document
module Game.LambdaHack.Client.UI.HandleHumanLocalClient
gameDifficultyCycle :: MonadClientUI m => m ()
pickLeaderHuman :: MonadClientUI m => Int -> m Slideshow

-- | Switches current member to the next on the level, if any, wrapping.
memberCycleHuman :: MonadClientUI m => m Slideshow

-- | Switches current member to the previous in the whole dungeon,
--   wrapping.
memberBackHuman :: MonadClientUI m => m Slideshow
selectActorHuman :: MonadClientUI m => m ()
selectNoneHuman :: (MonadClientUI m, MonadClient m) => m ()

-- | Clear current messages, show the next screen if any.
clearHuman :: Monad m => m ()
stopIfTgtModeHuman :: MonadClientUI m => m ()
selectWithPointer :: MonadClientUI m => m ()
repeatHuman :: MonadClient m => Int -> m ()
recordHuman :: MonadClientUI m => m Slideshow
historyHuman :: MonadClientUI m => m Slideshow
markVisionHuman :: MonadClientUI m => m ()
markSmellHuman :: MonadClientUI m => m ()
markSuspectHuman :: MonadClientUI m => m ()

-- | Display command help.
helpHuman :: MonadClientUI m => m Slideshow

-- | Display the main menu.
mainMenuHuman :: MonadClientUI m => m Slideshow
macroHuman :: MonadClient m => [String] -> m ()

-- | Move the cursor. Assumes targeting mode.
moveCursorHuman :: MonadClientUI m => Vector -> Int -> m Slideshow

-- | Cycle targeting mode. Do not change position of the cursor, switch
--   among things at that position.
tgtFloorHuman :: MonadClientUI m => m Slideshow
tgtEnemyHuman :: MonadClientUI m => m Slideshow

-- | Change the displayed level in targeting mode to (at most) k levels
--   shallower. Enters targeting mode, if not already in one.
tgtAscendHuman :: MonadClientUI m => Int -> m Slideshow

-- | Tweak the <tt>eps</tt> parameter of the targeting digital line.
epsIncrHuman :: MonadClientUI m => Bool -> m Slideshow
tgtClearHuman :: MonadClientUI m => m Slideshow
cursorUnknownHuman :: MonadClientUI m => m Slideshow
cursorItemHuman :: MonadClientUI m => m Slideshow
cursorStairHuman :: MonadClientUI m => Bool -> m Slideshow

-- | Cancel something, e.g., targeting mode, resetting the cursor to the
--   position of the leader. Chosen target is not invalidated.
cancelHuman :: MonadClientUI m => m Slideshow -> m Slideshow

-- | Accept something, e.g., targeting mode, keeping cursor where it was.
--   Or perform the default action, if nothing needs accepting.
acceptHuman :: MonadClientUI m => m Slideshow -> m Slideshow
cursorPointerFloorHuman :: MonadClientUI m => m ()
cursorPointerEnemyHuman :: MonadClientUI m => m ()
tgtPointerFloorHuman :: MonadClientUI m => m Slideshow
tgtPointerEnemyHuman :: MonadClientUI m => m Slideshow


-- | 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.RunClient

-- | Continue running in the given direction.
continueRun :: MonadClient m => LevelId -> RunParams -> m (Either Msg RequestAnyAbility)


-- | Semantics of <a>Cmd</a> client commands that return server commands. A
--   couple of them do not take time, the rest does. Here prompts and menus
--   and displayed, but any feedback resulting from the commands (e.g.,
--   from inventory manipulation) is generated later on, for all clients
--   that witness the results of the commands. TODO: document
module Game.LambdaHack.Client.UI.HandleHumanGlobalClient
moveRunHuman :: MonadClientUI m => Bool -> Bool -> Bool -> Bool -> Vector -> m (SlideOrCmd RequestAnyAbility)

-- | Leader waits a turn (and blocks, etc.).
waitHuman :: MonadClientUI m => m (RequestTimed AbWait)
moveItemHuman :: forall m. MonadClientUI m => [CStore] -> CStore -> Maybe Part -> Bool -> m (SlideOrCmd (RequestTimed AbMoveItem))

-- | Display items from a given container store and describe the chosen
--   one.
describeItemHuman :: MonadClientUI m => ItemDialogMode -> m (SlideOrCmd (RequestTimed AbMoveItem))
projectHuman :: forall m. MonadClientUI m => [Trigger] -> m (SlideOrCmd (RequestTimed AbProject))
applyHuman :: MonadClientUI m => [Trigger] -> m (SlideOrCmd (RequestTimed AbApply))

-- | Ask for a direction and alter a tile, if possible.
alterDirHuman :: MonadClientUI m => [Trigger] -> m (SlideOrCmd (RequestTimed AbAlter))

-- | Leader tries to trigger the tile he's standing on.
triggerTileHuman :: MonadClientUI m => [Trigger] -> m (SlideOrCmd (RequestTimed AbTrigger))
runOnceAheadHuman :: MonadClientUI m => m (SlideOrCmd RequestAnyAbility)
moveOnceToCursorHuman :: MonadClientUI m => m (SlideOrCmd RequestAnyAbility)
runOnceToCursorHuman :: MonadClientUI m => m (SlideOrCmd RequestAnyAbility)
continueToCursorHuman :: MonadClientUI m => m (SlideOrCmd RequestAnyAbility)
gameRestartHuman :: MonadClientUI m => GroupName ModeKind -> m (SlideOrCmd RequestUI)
gameExitHuman :: MonadClientUI m => m (SlideOrCmd RequestUI)
gameSaveHuman :: MonadClientUI m => m RequestUI
tacticHuman :: MonadClientUI m => m (SlideOrCmd RequestUI)
automateHuman :: MonadClientUI m => m (SlideOrCmd RequestUI)


-- | Semantics of human player commands.
module Game.LambdaHack.Client.UI.HandleHumanClient

-- | The semantics of human player commands in terms of the <tt>Action</tt>
--   monad. Decides if the action takes time and what action to perform.
--   Some time cosuming commands are enabled in targeting mode, but cannot
--   be invoked in targeting mode on a remote level (level different than
--   the level of the leader).
cmdHumanSem :: MonadClientUI m => HumanCmd -> m (SlideOrCmd RequestUI)


-- | 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

-- | The monad that gives the client access to UI operations.
class MonadClient m => MonadClientUI m

-- | Handle the move of a UI player.
queryUI :: MonadClientUI m => m RequestUI

-- | Client signals to the server that it's still online, flushes frames
--   (if needed) and sends some extra info.
pongUI :: MonadClientUI m => m RequestUI

-- | Visualize atomic actions 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 -> State -> StateClient -> UpdAtomic -> m ()

-- | Display special effects (text, animation) sent to the client.
displayRespSfxAtomicUI :: MonadClientUI m => Bool -> SfxAtomic -> m ()

-- | Wire together game content, the main loops of game clients, the main
--   game loop assigned to this frontend (possibly containing the server
--   loop, if the whole game runs in one process), UI config and the
--   definitions of game commands.
srtFrontend :: (DebugModeCli -> SessionUI -> State -> StateClient -> chanServerUI -> IO ()) -> (DebugModeCli -> SessionUI -> State -> StateClient -> chanServerAI -> IO ()) -> KeyKind -> COps -> DebugModeCli -> ((FactionId -> chanServerUI -> IO ()) -> (FactionId -> chanServerAI -> IO ()) -> IO ()) -> IO ()

-- | Key-command mappings to be used for the UI.
data KeyKind

-- | The information that is constant across a client playing session,
--   including many consecutive games in a single session, but is
--   completely disregarded and reset when a new playing session starts.
--   This includes a frontend session and keybinding info.
data SessionUI

-- | Color mode for the display.
data ColorMode

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

-- | black+white only
ColorBW :: ColorMode

-- | Display a message with a <tt>-more-</tt> prompt. Return value
--   indicates if the player tried to cancel/escape.
displayMore :: MonadClientUI m => ColorMode -> Msg -> m Bool

-- | Add a message to the current report.
msgAdd :: MonadClientUI m => Msg -> m ()

-- | Let the human player issue commands until any command takes time.
humanCommand :: forall m. MonadClientUI m => m RequestUI


-- | Abstract syntax of client commands. See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Common.Response

-- | Abstract syntax of client commands that don't use the UI.
data ResponseAI
RespUpdAtomicAI :: !UpdAtomic -> ResponseAI
RespQueryAI :: !ActorId -> ResponseAI
RespPingAI :: ResponseAI

-- | Abstract syntax of client commands that use the UI.
data ResponseUI
RespUpdAtomicUI :: !UpdAtomic -> ResponseUI
RespSfxAtomicUI :: !SfxAtomic -> ResponseUI
RespQueryUI :: ResponseUI
RespPingUI :: ResponseUI
instance GHC.Show.Show Game.LambdaHack.Common.Response.ResponseUI
instance GHC.Show.Show Game.LambdaHack.Common.Response.ResponseAI


-- | 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.Atomic.BroadcastAtomicWrite

-- | Send an atomic action to all clients that can see it.
handleAndBroadcast :: forall m a. MonadStateWrite m => Bool -> Pers -> (a -> FactionId -> LevelId -> m Perception) -> m a -> (FactionId -> ResponseAI -> m ()) -> (FactionId -> ResponseUI -> m ()) -> CmdAtomic -> m ()


-- | Semantics of client commands.
module Game.LambdaHack.Client.HandleResponseClient
handleResponseAI :: (MonadAtomic m, MonadClientWriteRequest RequestAI m) => ResponseAI -> m ()
handleResponseUI :: (MonadClientUI m, MonadAtomic m, MonadClientWriteRequest RequestUI m) => ResponseUI -> m ()


-- | The main loop of the client, processing human and computer player
--   moves turn by turn.
module Game.LambdaHack.Client.LoopClient

-- | The main game loop for an AI client.
loopAI :: (MonadAtomic m, MonadClientReadResponse ResponseAI m, MonadClientWriteRequest RequestAI m) => DebugModeCli -> m ()

-- | The main game loop for a UI client.
loopUI :: (MonadClientUI m, MonadAtomic m, MonadClientReadResponse ResponseUI m, MonadClientWriteRequest RequestUI m) => DebugModeCli -> m ()


-- | Semantics of responses that are sent to clients.
--   
--   See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Client-server-architecture</a>.
module Game.LambdaHack.Client

-- | The main game loop for an AI client.
loopAI :: (MonadAtomic m, MonadClientReadResponse ResponseAI m, MonadClientWriteRequest RequestAI m) => DebugModeCli -> m ()

-- | The main game loop for a UI client.
loopUI :: (MonadClientUI m, MonadAtomic m, MonadClientReadResponse ResponseUI m, MonadClientWriteRequest RequestUI m) => DebugModeCli -> m ()

-- | Wire together game content, the main loops of game clients, the main
--   game loop assigned to this frontend (possibly containing the server
--   loop, if the whole game runs in one process), UI config and the
--   definitions of game commands.
srtFrontend :: (DebugModeCli -> SessionUI -> State -> StateClient -> chanServerUI -> IO ()) -> (DebugModeCli -> SessionUI -> State -> StateClient -> chanServerAI -> IO ()) -> KeyKind -> COps -> DebugModeCli -> ((FactionId -> chanServerUI -> IO ()) -> (FactionId -> chanServerAI -> IO ()) -> IO ()) -> IO ()


-- | Server and client game state types and operations.
module Game.LambdaHack.Server.State

-- | Global, server state.
data StateServer
StateServer :: !DiscoveryKind -> !DiscoveryKindRev -> !UniqueSet -> !DiscoveryEffect -> !ItemSeedDict -> !ItemRev -> !(EnumMap ItemId FovCache3) -> !FlavourMap -> !ActorId -> !ItemId -> !(EnumMap LevelId Int) -> !(EnumMap LevelId Time) -> ![CmdAtomic] -> !Pers -> !StdGen -> !RNGs -> !Bool -> !Bool -> !ClockTime -> !ClockTime -> !Time -> !(EnumMap FactionId [(Int, (Text, Text))]) -> !DebugModeSer -> !DebugModeSer -> StateServer

-- | full item kind discoveries data
[sdiscoKind] :: StateServer -> !DiscoveryKind

-- | reverse map, used for item creation
[sdiscoKindRev] :: StateServer -> !DiscoveryKindRev

-- | already generated unique items
[suniqueSet] :: StateServer -> !UniqueSet

-- | full item effect&amp;Co data
[sdiscoEffect] :: StateServer -> !DiscoveryEffect

-- | map from item ids to item seeds
[sitemSeedD] :: StateServer -> !ItemSeedDict

-- | reverse id map, used for item creation
[sitemRev] :: StateServer -> !ItemRev

-- | (sight, smell, light) aspect bonus of the item; zeroes if not in the
--   map
[sItemFovCache] :: StateServer -> !(EnumMap ItemId FovCache3)

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

-- | actors are processed up to this time
[sprocessed] :: StateServer -> !(EnumMap LevelId Time)

-- | atomic commands performed to date
[sundo] :: StateServer -> ![CmdAtomic]

-- | perception of all factions
[sper] :: StateServer -> !Pers

-- | 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

-- | this session start time
[sstart] :: StateServer -> !ClockTime

-- | this game start time
[sgstart] :: StateServer -> !ClockTime

-- | clips since the start of the session
[sallTime] :: StateServer -> !Time

-- | hero names sent by clients
[sheroNames] :: StateServer -> !(EnumMap FactionId [(Int, (Text, Text))])

-- | current debugging mode
[sdebugSer] :: StateServer -> !DebugModeSer

-- | debugging mode for the next game
[sdebugNxt] :: StateServer -> !DebugModeSer

-- | Initial, empty game server state.
emptyStateServer :: StateServer

-- | Debug commands. See <a>debugArgs</a> for the descriptions.
data DebugModeSer
DebugModeSer :: !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !(Maybe (GroupName ModeKind)) -> !Bool -> !Bool -> !(Maybe Int) -> !(Maybe StdGen) -> !(Maybe StdGen) -> !(Maybe FovMode) -> !Bool -> !Int -> !Bool -> !(Maybe String) -> !Bool -> !DebugModeCli -> DebugModeSer
[sknowMap] :: DebugModeSer -> !Bool
[sknowEvents] :: DebugModeSer -> !Bool
[sniffIn] :: DebugModeSer -> !Bool
[sniffOut] :: DebugModeSer -> !Bool
[sallClear] :: DebugModeSer -> !Bool
[sgameMode] :: DebugModeSer -> !(Maybe (GroupName ModeKind))
[sautomateAll] :: DebugModeSer -> !Bool
[skeepAutomated] :: DebugModeSer -> !Bool
[sstopAfter] :: DebugModeSer -> !(Maybe Int)
[sdungeonRng] :: DebugModeSer -> !(Maybe StdGen)
[smainRng] :: DebugModeSer -> !(Maybe StdGen)
[sfovMode] :: DebugModeSer -> !(Maybe FovMode)
[snewGameSer] :: DebugModeSer -> !Bool
[scurDiffSer] :: DebugModeSer -> !Int
[sdumpInitRngs] :: DebugModeSer -> !Bool
[ssavePrefixSer] :: DebugModeSer -> !(Maybe String)
[sdbgMsgSer] :: DebugModeSer -> !Bool

-- | client debug parameters
[sdebugCli] :: DebugModeSer -> !DebugModeCli
defDebugModeSer :: DebugModeSer
data RNGs
RNGs :: !(Maybe StdGen) -> !(Maybe StdGen) -> RNGs
[dungeonRandomGenerator] :: RNGs -> !(Maybe StdGen)
[startingRandomGenerator] :: RNGs -> !(Maybe StdGen)
data FovCache3
FovCache3 :: !Int -> !Int -> !Int -> FovCache3
[fovSight] :: FovCache3 -> !Int
[fovSmell] :: FovCache3 -> !Int
[fovLight] :: FovCache3 -> !Int
emptyFovCache3 :: FovCache3
instance GHC.Show.Show Game.LambdaHack.Server.State.StateServer
instance GHC.Show.Show Game.LambdaHack.Server.State.DebugModeSer
instance GHC.Classes.Eq Game.LambdaHack.Server.State.FovCache3
instance GHC.Show.Show Game.LambdaHack.Server.State.FovCache3
instance GHC.Show.Show Game.LambdaHack.Server.State.RNGs
instance Data.Binary.Class.Binary Game.LambdaHack.Server.State.StateServer
instance Data.Binary.Class.Binary Game.LambdaHack.Server.State.FovCache3
instance Data.Binary.Class.Binary Game.LambdaHack.Server.State.DebugModeSer
instance Data.Binary.Class.Binary Game.LambdaHack.Server.State.RNGs


-- | Parsing of commandline arguments.
module Game.LambdaHack.Server.Commandline

-- | Parse server debug parameters from commandline arguments.
debugArgs :: [String] -> IO DebugModeSer


-- | Field Of View scanning with a variety of algorithms. See
--   <a>https://github.com/LambdaHack/LambdaHack/wiki/Fov-and-los</a> for
--   discussion.
module Game.LambdaHack.Server.Fov

-- | Calculate the perception of the whole dungeon.
dungeonPerception :: FovMode -> State -> StateServer -> Pers

-- | Calculate faction's perception of a level based on the lit tiles
--   cache.
fidLidPerception :: FovMode -> PersLit -> FactionId -> LevelId -> Level -> Perception

-- | The cache of FOV information for a level, such as sight, smell and
--   light radiuses for each actor and bitmaps of clear and lit positions.
type PersLit = EnumMap LevelId (EnumMap FactionId [(Actor, FovCache3)], Array Bool, Array Bool)

-- | Compute all lit positions in the dungeon.
litInDungeon :: FovMode -> State -> StateServer -> PersLit

-- | Visually reachable positions (light passes through them to the actor).
--   The list may contain (many) repetitions.
newtype PerceptionReachable
PerceptionReachable :: [Point] -> PerceptionReachable
[preachable] :: PerceptionReachable -> [Point]

-- | All positions lit by dynamic lights on a level. Shared by all
--   factions. The list may contain (many) repetitions.
newtype PerceptionDynamicLit
PerceptionDynamicLit :: [Point] -> PerceptionDynamicLit
[pdynamicLit] :: PerceptionDynamicLit -> [Point]
instance GHC.Show.Show Game.LambdaHack.Server.Fov.PerceptionDynamicLit
instance GHC.Show.Show Game.LambdaHack.Server.Fov.PerceptionReachable


-- | Game action monads and basic building blocks for human and computer
--   player actions. Has no access to the the main action type. Does not
--   export the <tt>liftIO</tt> operation nor a few other implementation
--   details.
module Game.LambdaHack.Server.MonadServer
class MonadStateRead m => MonadServer m
getServer :: MonadServer m => m StateServer
getsServer :: MonadServer m => (StateServer -> a) -> m a
modifyServer :: MonadServer m => (StateServer -> StateServer) -> m ()
putServer :: MonadServer m => StateServer -> m ()
liftIO :: MonadServer m => IO a -> m a
saveChanServer :: MonadServer m => m (ChanSave (State, StateServer))
debugPossiblyPrint :: MonadServer m => Text -> m ()
debugPossiblyPrintAndExit :: MonadServer m => Text -> m ()
serverPrint :: MonadServer m => Text -> m ()
saveServer :: MonadServer m => m ()
saveName :: String

-- | Dumps RNG states from the start of the game to stderr.
dumpRngs :: MonadServer m => m ()

-- | Read the high scores dictionary. Return the empty table if no file.
restoreScore :: MonadServer m => COps -> m ScoreDict

-- | Generate a new score, register it and save.
registerScore :: MonadServer m => Status -> Maybe Actor -> FactionId -> m ()
resetSessionStart :: MonadServer m => m ()
resetGameStart :: MonadServer m => m ()
elapsedSessionTimeGT :: MonadServer m => Int -> m Bool
tellAllClipPS :: MonadServer m => m ()
tellGameClipPS :: MonadServer m => m ()
tryRestore :: MonadServer m => COps -> DebugModeSer -> m (Maybe (State, StateServer))

-- | Compute and insert auxiliary optimized components into game content,
--   to be used in time-critical sections of the code.
speedupCOps :: Bool -> COps -> COps

-- | Invoke pseudo-random computation with the generator kept in the state.
rndToAction :: MonadServer m => Rnd a -> m a

-- | Gets a random generator from the arguments or, if not present,
--   generates one.
getSetGen :: MonadServer m => Maybe StdGen -> m StdGen


-- | Debug output for requests and responseQs.
module Game.LambdaHack.Server.DebugServer
debugResponseAI :: MonadServer m => ResponseAI -> m ()
debugResponseUI :: MonadServer m => ResponseUI -> m ()
debugRequestAI :: MonadServer m => ActorId -> RequestAI -> m ()
debugRequestUI :: MonadServer m => ActorId -> RequestUI -> m ()
instance GHC.Show.Show a => GHC.Show.Show (Game.LambdaHack.Server.DebugServer.DebugAid a)


-- | Server operations for items.
module Game.LambdaHack.Server.ItemServer
rollItem :: (MonadAtomic m, MonadServer m) => Int -> LevelId -> Freqs ItemKind -> m (Maybe (ItemKnown, ItemFull, ItemDisco, ItemSeed, GroupName ItemKind))
rollAndRegisterItem :: (MonadAtomic m, MonadServer m) => LevelId -> Freqs ItemKind -> Container -> Bool -> Maybe Int -> m (Maybe (ItemId, (ItemFull, GroupName ItemKind)))
registerItem :: (MonadAtomic m, MonadServer m) => ItemFull -> ItemKnown -> ItemSeed -> Int -> Container -> Bool -> m ItemId
placeItemsInDungeon :: forall m. (MonadAtomic m, MonadServer m) => m ()
embedItemsInDungeon :: (MonadAtomic m, MonadServer m) => m ()
fullAssocsServer :: MonadServer m => ActorId -> [CStore] -> m [(ItemId, ItemFull)]
activeItemsServer :: MonadServer m => ActorId -> m [ItemFull]
itemToFullServer :: MonadServer m => m (ItemId -> ItemQuant -> ItemFull)

-- | Mapping over actor's items from a give store.
mapActorCStore_ :: MonadServer m => CStore -> (ItemId -> ItemQuant -> m a) -> Actor -> m ()


-- | Server operations common to many modules.
module Game.LambdaHack.Server.CommonServer
execFailure :: (MonadAtomic m, MonadServer m) => ActorId -> RequestTimed a -> ReqFailure -> m ()

-- | Update the cached perception for the selected level, for a faction.
--   The assumption is the level, and only the level, has changed since the
--   previous perception calculation.
resetFidPerception :: MonadServer m => PersLit -> FactionId -> LevelId -> m Perception
resetLitInDungeon :: MonadServer m => m PersLit
getPerFid :: MonadServer m => FactionId -> LevelId -> m Perception
revealItems :: (MonadAtomic m, MonadServer m) => Maybe FactionId -> Maybe (ActorId, Actor) -> m ()
moveStores :: (MonadAtomic m, MonadServer m) => ActorId -> CStore -> CStore -> m ()
deduceQuits :: (MonadAtomic m, MonadServer m) => FactionId -> Maybe (ActorId, Actor) -> Status -> m ()
deduceKilled :: (MonadAtomic m, MonadServer m) => ActorId -> Actor -> m ()
electLeader :: MonadAtomic m => FactionId -> LevelId -> ActorId -> m ()
addActor :: (MonadAtomic m, MonadServer m) => GroupName ItemKind -> FactionId -> Point -> LevelId -> (Actor -> Actor) -> Text -> Time -> m (Maybe ActorId)
addActorIid :: (MonadAtomic m, MonadServer m) => ItemId -> ItemFull -> Bool -> FactionId -> Point -> LevelId -> (Actor -> Actor) -> Text -> Time -> m (Maybe ActorId)
projectFail :: (MonadAtomic m, MonadServer m) => ActorId -> Point -> Int -> ItemId -> CStore -> Bool -> m (Maybe ReqFailure)
pickWeaponServer :: MonadServer m => ActorId -> m (Maybe (ItemId, CStore))
sumOrganEqpServer :: MonadServer m => EqpSlot -> ActorId -> m Int
actorSkillsServer :: MonadServer m => ActorId -> m Skills


-- | Server operations performed periodically in the game loop and related
--   operations.
module Game.LambdaHack.Server.PeriodicServer

-- | Sapwn, possibly, a monster according to the level's actor groups. We
--   assume heroes are never spawned.
spawnMonster :: (MonadAtomic m, MonadServer m) => LevelId -> m ()
addAnyActor :: (MonadAtomic m, MonadServer m) => Freqs ItemKind -> LevelId -> Time -> Maybe Point -> m (Maybe ActorId)
dominateFidSfx :: (MonadAtomic m, MonadServer m) => FactionId -> ActorId -> m Bool

-- | Advance the move time for the given actor
advanceTime :: (MonadAtomic m, MonadServer m) => ActorId -> m ()

-- | Swap the relative move times of two actors (e.g., when switching a UI
--   leader).
swapTime :: (MonadAtomic m, MonadServer m) => ActorId -> ActorId -> m ()

-- | Check if the given actor is dominated and update his calm. We don't
--   update calm once per game turn (even though it would make fast actors
--   less overpowered), beucase the effects of close enemies would
--   sometimes manifest only after a couple of player turns (or perhaps
--   never at all, if the player and enemy move away before that moment). A
--   side effect is that under peaceful circumstances, non-max calm causes
--   a consistent Calm regeneration UI indicator to be displayed each turn
--   (not every few turns).
managePerTurn :: (MonadAtomic m, MonadServer m) => ActorId -> m ()
leadLevelSwitch :: (MonadAtomic m, MonadServer m) => m ()
udpateCalm :: (MonadAtomic m, MonadServer m) => ActorId -> Int64 -> m ()


-- | The server definitions for the server-client communication protocol.
module Game.LambdaHack.Server.ProtocolServer

-- | Connection channel between the server and a single client.
data ChanServer resp req
ChanServer :: !(TQueue resp) -> !(TQueue req) -> ChanServer resp req
[responseS] :: ChanServer resp req -> !(TQueue resp)
[requestS] :: ChanServer resp req -> !(TQueue req)

-- | Connection information for all factions, indexed by faction
--   identifier.
type ConnServerDict = EnumMap FactionId ConnServerFaction

-- | The server monad with the ability to communicate with clients.
class MonadServer m => MonadServerReadRequest m
getDict :: MonadServerReadRequest m => m ConnServerDict
getsDict :: MonadServerReadRequest m => (ConnServerDict -> a) -> m a
modifyDict :: MonadServerReadRequest m => (ConnServerDict -> ConnServerDict) -> m ()
putDict :: MonadServerReadRequest m => ConnServerDict -> m ()
liftIO :: MonadServerReadRequest m => IO a -> m a
sendUpdateAI :: MonadServerReadRequest m => FactionId -> ResponseAI -> m ()
sendQueryAI :: MonadServerReadRequest m => FactionId -> ActorId -> m RequestAI
sendPingAI :: (MonadAtomic m, MonadServerReadRequest m) => FactionId -> m ()
sendUpdateUI :: MonadServerReadRequest m => FactionId -> ResponseUI -> m ()
sendQueryUI :: (MonadAtomic m, MonadServerReadRequest m) => FactionId -> ActorId -> m RequestUI
sendPingUI :: (MonadAtomic m, MonadServerReadRequest m) => FactionId -> m ()
killAllClients :: (MonadAtomic 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 :: (MonadAtomic m, MonadServerReadRequest m) => (FactionId -> ChanServer ResponseUI RequestUI -> IO ()) -> (FactionId -> ChanServer ResponseAI RequestAI -> IO ()) -> m ()

-- | Connections to the human-controlled client of a faction and to the AI
--   client for the same faction.
type ConnServerFaction = (Maybe (ChanServer ResponseUI RequestUI), ChanServer ResponseAI RequestAI)


-- | The main game action monad type implementation. Just as any other
--   component of the library, this implementation can be substituted. This
--   module should not be imported anywhere except in <tt>Action</tt> to
--   expose the executor to any code using the library.
module Game.LambdaHack.SampleImplementation.SampleMonadClient

-- | Init the client, then run an action, with a given session, state and
--   history, in the <tt>IO</tt> monad.
executorCli :: CliImplementation resp req () -> SessionUI -> State -> StateClient -> ChanServer resp req -> IO ()

-- | Client state transformation monad.
data CliImplementation resp req a
instance GHC.Base.Applicative (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance GHC.Base.Functor (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance GHC.Base.Monad (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance Game.LambdaHack.Common.MonadStateRead.MonadStateRead (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance Game.LambdaHack.Atomic.MonadStateWrite.MonadStateWrite (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance Game.LambdaHack.Client.MonadClient.MonadClient (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance Game.LambdaHack.Client.UI.MonadClientUI.MonadClientUI (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance Game.LambdaHack.Client.ProtocolClient.MonadClientReadResponse resp (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance Game.LambdaHack.Client.ProtocolClient.MonadClientWriteRequest req (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)
instance Game.LambdaHack.Atomic.MonadAtomic.MonadAtomic (Game.LambdaHack.SampleImplementation.SampleMonadClient.CliImplementation resp req)


-- | The main game action monad type implementation. Just as any other
--   component of the library, this implementation can be substituted. This
--   module should not be imported anywhere except in <tt>Action</tt> to
--   expose the executor to any code using the library.
module Game.LambdaHack.SampleImplementation.SampleMonadServer

-- | Run an action in the <tt>IO</tt> monad, with undefined state.
executorSer :: SerImplementation () -> IO ()

-- | Server state transformation monad.
data SerImplementation 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.ProtocolServer.MonadServerReadRequest Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation
instance Game.LambdaHack.Atomic.MonadAtomic.MonadAtomic Game.LambdaHack.SampleImplementation.SampleMonadServer.SerImplementation


-- | Operations for starting and restarting the game.
module Game.LambdaHack.Server.StartServer
gameReset :: MonadServer m => COps -> DebugModeSer -> Maybe (GroupName ModeKind) -> Maybe StdGen -> m State
reinitGame :: (MonadAtomic m, MonadServer m) => m ()
initPer :: MonadServer m => m ()

-- | Spawn actors of any specified faction, friendly or not. To be used for
--   initial dungeon population and for the summon effect.
recruitActors :: (MonadAtomic m, MonadServer m) => [Point] -> LevelId -> Time -> FactionId -> m Bool

-- | Apply debug options that don't need a new game.
applyDebug :: MonadServer m => m ()
initDebug :: MonadStateRead m => COps -> DebugModeSer -> m DebugModeSer


-- | Handle effects (most often caused by requests sent by clients).
module Game.LambdaHack.Server.HandleEffectServer
applyItem :: (MonadAtomic m, MonadServer m) => ActorId -> ItemId -> CStore -> m ()
itemEffectAndDestroy :: (MonadAtomic m, MonadServer m) => ActorId -> ActorId -> ItemId -> Container -> m ()
effectAndDestroy :: (MonadAtomic m, MonadServer m) => ActorId -> ActorId -> ItemId -> Container -> Bool -> [Effect] -> [Aspect Int] -> ItemQuant -> m ()
itemEffectCause :: (MonadAtomic m, MonadServer m) => ActorId -> Point -> Effect -> m Bool

-- | 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 :: (MonadAtomic m, MonadServer m) => CStore -> ActorId -> Actor -> Bool -> ItemId -> ItemQuant -> m ()
armorHurtBonus :: (MonadAtomic m, MonadServer m) => ActorId -> ActorId -> m Int


-- | The main loop of the server, processing human and computer player
--   moves turn by turn.
module Game.LambdaHack.Server.EndServer

-- | Continue or exit or restart the game.
endOrLoop :: (MonadAtomic m, MonadServer m) => m () -> (Maybe (GroupName ModeKind) -> m ()) -> m () -> m () -> m ()
dieSer :: (MonadAtomic m, MonadServer m) => ActorId -> Actor -> Bool -> m ()


-- | Semantics of request. 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. TODO: document
module Game.LambdaHack.Server.HandleRequestServer

-- | The semantics of server commands. The resulting actor id is of the
--   actor that carried out the request.
handleRequestAI :: (MonadAtomic m, MonadServer m) => FactionId -> ActorId -> RequestAI -> m (ActorId, m ())

-- | The semantics of server commands. The resulting actor id is of the
--   actor that carried out the request. <tt>Nothing</tt> means the command
--   took no time.
handleRequestUI :: (MonadAtomic m, MonadServer m) => FactionId -> RequestUI -> m (Maybe 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 :: (MonadAtomic m, MonadServer m) => ActorId -> Vector -> m ()

-- | Actor tries to swap positions with another.
reqDisplace :: (MonadAtomic m, MonadServer m) => ActorId -> ActorId -> m ()


-- | The main loop of the server, processing human and computer player
--   moves turn by turn.
module Game.LambdaHack.Server.LoopServer

-- | Start a game session, including the clients, and then loop,
--   communicating with the clients.
loopSer :: (MonadAtomic m, MonadServerReadRequest m) => COps -> DebugModeSer -> (FactionId -> ChanServer ResponseUI RequestUI -> IO ()) -> (FactionId -> ChanServer ResponseAI RequestAI -> IO ()) -> m ()


-- | Semantics of requests that are sent to the server.
--   
--   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.
loopSer :: (MonadAtomic m, MonadServerReadRequest m) => COps -> DebugModeSer -> (FactionId -> ChanServer ResponseUI RequestUI -> IO ()) -> (FactionId -> ChanServer ResponseAI RequestAI -> IO ()) -> m ()

-- | Compute and insert auxiliary optimized components into game content,
--   to be used in time-critical sections of the code.
speedupCOps :: Bool -> COps -> COps

-- | Parse server debug parameters from commandline arguments.
debugArgs :: [String] -> IO DebugModeSer

-- | client debug parameters
sdebugCli :: DebugModeSer -> DebugModeCli
