-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A roguelike game engine in early and active development -- -- This is an alpha release of LambdaHack, 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 and content. -- -- This is a minor release, primarily intended to fix broken haddock -- documentation on Hackage by disabling gtk2hs dependency under GHC -- 7.6.1 (if you use GHC 7.6.1 and gtk2hs compiles for you, please run -- 'cabal install -fgtk --reinstall'). Changes since 0.2.6 are mostly -- unrelated to gameplay: strictly typed config files split into UI and -- rules; a switch from Text to String throughout the codebase; use of -- the external library miniutter for English sentence generation. -- -- Upcoming new features: playable monsters faction, more than two -- factions inhabiting the dungeon, AIvAI, PvP, improved ranged combat -- AI, dynamic light sources, explosions player action undo/redo, -- completely redesigned UI. Long term goals are focused around -- procedural content generation and include in-game content creation, -- auto-balancing and persistent content modification based on player -- behaviour. -- -- A larger game that depends on the LambdaHack library is Allure of the -- Stars, available from -- http://hackage.haskell.org/package/Allure. -- -- Note: All modules in the library are kept visible, to let games -- override each, but reuse as many as possible. 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. @package LambdaHack @version 0.2.6.5 -- | Queues implemented with two stacks to ensure fast writes. module Game.LambdaHack.Utils.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 -- | Remove all but the last written non-Nothing element of the -- queue. trimLQueue :: LQueue (Maybe a) -> LQueue (Maybe a) -- | Try reading a queue. Return Nothing if empty. tryReadLQueue :: LQueue a -> Maybe (a, LQueue a) -- | Write to the queue. Faster than reading. writeLQueue :: LQueue a -> a -> LQueue a -- | Colours and text attributes. module Game.LambdaHack.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] -- | 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. defaultAttr :: Attr data AttrChar AttrChar :: !Attr -> !Char -> AttrChar acAttr :: AttrChar -> !Attr acChar :: AttrChar -> !Char instance Show Color instance Eq Color instance Ord Color instance Enum Color instance Bounded Color instance Show Attr instance Eq Attr instance Ord Attr instance Show AttrChar instance Eq AttrChar instance Binary AttrChar instance Binary Attr instance Binary Color -- | The appearance of in-game items, as communicated to the player. module Game.LambdaHack.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] -- | Colour sets. darkCol :: [Color] -- | Colour sets. brightCol :: [Color] -- | Colour sets. stdCol :: [Color] -- | The standard full set of flavours. stdFlav :: [Flavour] -- | Get the underlying base colour of a flavour. flavourToColor :: Flavour -> Color -- | Construct the full name of a flavour. flavourToName :: Flavour -> Text instance Show Flavour instance Eq Flavour instance Ord Flavour instance Binary Flavour -- | Game time and speed. module Game.LambdaHack.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 -- | Time addition. timeAdd :: Time -> Time -> Time -- | How many time intervals of the latter kind fits in an interval of the -- former kind. timeFit :: Time -> Time -> Int -- | Negate a time interval. Can be used to subtract from a time or to -- reverse the ordering on time. timeNegate :: Time -> Time -- | Scale time by an Int scalar value. timeScale :: Time -> Int -> Time -- | Represent the main 10 thresholds of a time range by digits, given the -- total length of the time range. timeToDigit :: Time -> Time -> Char -- | Speed in meters per 1 million seconds (m/Ms). Actors at normal speed -- (2 m/s) take one time turn (0.5 s) to move one tile (1 m by 1 m). data Speed -- | Constructor for content definitions. toSpeed :: Double -> Speed -- | Normal speed (2 m/s) that suffices to move one tile in one turn. speedNormal :: Speed -- | Scale speed by an Int scalar value. speedScale :: Speed -> Int -> Speed -- | The number of time ticks it takes to walk 1 meter at the given speed. ticksPerMeter :: Speed -> Time -- | Distance in meters (so also in tiles, given the chess metric) traveled -- in a given time by a body with a given speed. traveled :: Speed -> Time -> Int -- | Calculate projectile speed from item weight in grams and speed bonus -- in percents. See -- https://github.com/kosmikus/LambdaHack/wiki/Item-statistics. speedFromWeight :: Int -> Int -> Speed -- | Calculate maximum range in meters of a projectile from its speed. See -- https://github.com/kosmikus/LambdaHack/wiki/Item-statistics. -- With this formula, each projectile flies for exactly one second, that -- is 2 turns, and then drops to the ground. Dividing and multiplying by -- 2 ensures both turns of flight cover the same distance. rangeFromSpeed :: Speed -> Int instance Show Time instance Eq Time instance Ord Time instance Show Speed instance Eq Speed instance Ord Speed instance Binary Speed instance Binary Time -- | Hacks that haven't found their home yet. module Game.LambdaHack.Misc -- | Level bounds. TODO: query terminal size instead and scroll view. normalLevelBound :: (Int, Int) -- | Integer division, rounding up. divUp :: Int -> Int -> Int -- | For each group that the kind belongs to, denoted by a Text -- name in the first component of a pair, the second component of a pair -- shows how common the kind is within the group. type Freqs = [(Text, Int)] -- |
-- breturn b a = [a | b] --breturn :: MonadPlus m => Bool -> a -> m a -- | The type of kinds of game factions (heroes, enemies, NPCs, etc.). module Game.LambdaHack.Content.FactionKind -- | Faction properties that are fixed for a given kind of factions. data FactionKind FactionKind :: !Char -> !Text -> !Freqs -> !Text -> !Text -> ![Text] -> ![Text] -> FactionKind -- | a symbol fsymbol :: FactionKind -> !Char -- | short description fname :: FactionKind -> !Text -- | frequency within groups ffreq :: FactionKind -> !Freqs -- | Ai to use for the selected actor fAiSelected :: FactionKind -> !Text -- | Ai to use for idle actors fAiIdle :: FactionKind -> !Text -- | initially in war with these factions fenemy :: FactionKind -> ![Text] -- | initially allied with these factions fally :: FactionKind -> ![Text] -- | No specific possible problems for the content of this kind, so far, so -- the validation function always returns the empty list of offending -- kinds. fvalidate :: [FactionKind] -> [FactionKind] instance Show FactionKind -- | 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 CDefs and -- it has instances for all content kinds, such as items kinds -- (Game.LambdaHack.Content.ItemKind). 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 CDefs -- instances, are defined in a directory of the game code proper, with -- names corresponding to their kinds. module Game.LambdaHack.CDefs -- | The general type of a particular game content, e.g., item kinds. data CDefs a CDefs :: (a -> Char) -> (a -> Text) -> (a -> Freqs) -> ([a] -> [a]) -> [a] -> CDefs a -- | symbol, e.g., to print on the map getSymbol :: CDefs a -> a -> Char -- | name, e.g., to show to the player getName :: CDefs a -> a -> Text -- | frequency within groups getFreq :: CDefs a -> a -> Freqs -- | validate and catch some offenders, if any validate :: CDefs a -> [a] -> [a] -- | all the defined content of this type content :: CDefs a -> [a] -- | 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 -> Cover -> Fence -> [Text] -> PlaceKind -- | a symbol psymbol :: PlaceKind -> Char -- | short description pname :: PlaceKind -> Text -- | frequency within groups pfreq :: PlaceKind -> Freqs -- | how to fill whole place based on the corner pcover :: PlaceKind -> Cover -- | whether to fence the place with solid border pfence :: PlaceKind -> Fence -- | plan of the top-left corner of the place ptopLeft :: PlaceKind -> [Text] -- | A method of filling the whole 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 -- | The choice of a fence type for the place. data Fence -- | put a solid wall fence around the place FWall :: Fence -- | leave an empty floor space around the place FFloor :: Fence -- | skip the fence and fill all with the place proper FNone :: Fence -- | Filter a list of kinds, passing through only the incorrect ones, if -- any. -- -- Verify that the top-left corner map is rectangular and not empty. pvalidate :: [PlaceKind] -> [PlaceKind] instance Show Cover instance Eq Cover instance Show Fence instance Eq Fence instance Show PlaceKind -- | Saving/loading with serialization and compression. module Game.LambdaHack.Utils.File -- | Serialize, compress and save data with an EOF marker. The OK -- 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 -- OK EOF marker ensures any easily detectable file corruption -- is discovered and reported before the function returns. strictDecodeEOF :: Binary a => FilePath -> IO a -- | Tools for specifying assertions. A step towards contracts. Actually, a -- bunch of hacks wrapping the original assert function, which -- is the only easy way of obtaining source locations. module Game.LambdaHack.Utils.Assert -- | If the first argument evaluates to True, then the result is the -- second argument. Otherwise an AssertionFailed exception is -- raised, containing a String with the source file and line -- number of the call to assert. -- -- Assertions can normally be turned on or off with a compiler flag (for -- GHC, assertions are normally on unless optimisation is turned on with -- -O or the -fignore-asserts option is given). When -- assertions are turned off, the first argument to assert is -- ignored, and the second argument is returned as the result. assert :: Bool -> a -> a -- | If the condition fails, display the value blamed for the failure. Used -- as in -- --
-- assert (c /= 0 `blame` c) $ 10 / c --blame :: Show a => Bool -> a -> Bool -- | Like error, but shows the source location and also the value to -- blame for the failure. To be used as in: -- --
-- assert `failure` ((x1, y1), (x2, y2), "designate a vertical line") --failure :: Show a => (Bool -> b -> b) -> a -> b -- | Like all, but if the predicate fails, blame all the list -- elements and especially those for which it fails. To be used as in: -- --
-- assert (allB (>= 0) [yf, xf, y1, x1, y2, x2]) --allB :: Show a => (a -> Bool) -> [a] -> Bool -- | Check that the value returned from a monad action satisfies a -- predicate. Reports source location and the suspects. Drops the value. checkM :: (Show a, Monad m) => (Bool -> m () -> m ()) -> (c -> Bool) -> a -> c -> m () -- | Verifies that the returned value is true (respectively, false). Used -- as in: -- --
-- open newValve >>= assert `trueM` (newValve, "is already opened, not new") --trueM :: (Show a, Monad m) => (Bool -> m () -> m ()) -> a -> Bool -> m () -- | Verifies that the returned value is true (respectively, false). Used -- as in: -- --
-- open newValve >>= assert `trueM` (newValve, "is already opened, not new") --falseM :: (Show a, Monad m) => (Bool -> m () -> m ()) -> a -> Bool -> m () -- | Basic cartesian geometry operations on 2D points. module Game.LambdaHack.PointXY -- | Spacial dimension for points and vectors. type X = Int -- | Spacial dimension for points and vectors. type Y = Int -- | 2D points in cartesian representation. newtype PointXY PointXY :: (X, Y) -> PointXY -- | A list of all points on a straight vertical or straight horizontal -- line between two points. Fails if no such line exists. fromTo :: PointXY -> PointXY -> [PointXY] -- | Sort the sequence of two points, in the derived lexicographic order. sortPointXY :: (PointXY, PointXY) -> (PointXY, PointXY) -- | Bresenham's line algorithm generalized to arbitrary starting -- eps (eps value of 0 gives the standard BLA). -- Includes the source point and goes through the target point to -- infinity. blaXY :: Int -> PointXY -> PointXY -> [PointXY] instance Eq PointXY instance Ord PointXY instance Show PointXY -- | Basic cartesian geometry operations on 2D vectors. module Game.LambdaHack.VectorXY -- | 2D vectors in cartesian representation. newtype VectorXY VectorXY :: (X, Y) -> VectorXY -- | Shift a point by a vector. shiftXY :: PointXY -> VectorXY -> PointXY -- | Vectors of all unit moves in the chessboard metric, clockwise, -- starting north-west. movesXY :: [VectorXY] -- | Vectors of all cardinal direction unit moves, clockwise, starting -- north. movesCardinalXY :: [VectorXY] -- | The lenght of a vector in the chessboard metric, where diagonal moves -- cost 1. chessDistXY :: VectorXY -> Int -- | Squared euclidean length of a vector. euclidDistSqXY :: VectorXY -> Int -- | Reverse an arbirary vector. negXY :: VectorXY -> VectorXY instance Show VectorXY instance Eq VectorXY -- | Rectangular areas of levels and their basic operations. module Game.LambdaHack.Area -- | The type of areas. The bottom left and the top right points. type Area = (X, Y, X, Y) -- | All (8 at most) closest neighbours of a point within an area. vicinityXY :: Area -> PointXY -> [PointXY] -- | All (4 at most) cardinal direction neighbours of a point within an -- area. vicinityCardinalXY :: Area -> PointXY -> [PointXY] -- | Checks that a point belongs to an area. insideXY :: PointXY -> Area -> Bool -- | Sort the corners of an area so that the bottom left is the first -- point. normalizeArea :: Area -> Area -- | Divide uniformly a larger area into the given number of smaller areas. grid :: (X, Y) -> Area -> [(PointXY, Area)] -- | Checks if it's an area with at least one field. validArea :: Area -> Bool -- | Checks if it's an area with exactly one field. trivialArea :: Area -> Bool -- | Enlarge (or shrink) the given area on all fours sides by the amount. expand :: Area -> Int -> Area -- | Common definitions for the Field of View algorithms. See -- https://github.com/kosmikus/LambdaHack/wiki/Fov-and-los for -- some more context and references. module Game.LambdaHack.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. newtype Bump B :: (X, Y) -> Bump -- | Straight line between points. type Line = (Bump, Bump) -- | 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 steeper, optionally negated, applied to the second -- argument. addHull :: (Bump -> Bump -> Bool) -> Bump -> ConvexHull -> ConvexHull instance Show Bump -- | DFOV (Digital Field of View) implemented according to specification at -- http://roguebasin.roguelikedevelopment.org/index.php?title=Digital_field_of_view_implementation. -- This fast version of the algorithm, based on PFOV, has AFAIK -- never been described nor implemented before. module Game.LambdaHack.FOV.Digital -- | Calculates the list of tiles, in Bump 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 (p1, f) and (p2, f). 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 -- d 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 is 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 -- http://roguebasin.roguelikedevelopment.org/index.php?title=Precise_Permissive_Field_of_View, -- 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.FOV.Permissive -- | Calculates the list of tiles, in Bump 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 (p1, f) and (p2, f). 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 d -- 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) -- | 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.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 (0, 1) means the whole 45 degrees arc of the -- processed octant is to be scanned. type Interval = (Rational, Rational) -- | Calculates the list of tiles, in SBump coordinates, visible -- from (0, 0). scan :: (SBump -> Bool) -> Distance -> Interval -> [SBump] -- | Game messages displayed on top of the screen for the player to read. module Game.LambdaHack.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 -- | Identical to append. (<>) :: Text -> Text -> Text -- | Separated by space unless one of them is empty (in which case just the -- non-empty one). (<+>) :: Text -> Text -> Text -- | Show a value in Text format. showT :: Show a => a -> Text -- | The "press something to see more" mark. moreMsg :: Msg -- | The confirmation request message. yesnoMsg :: Msg -- | Add spaces at the message end, for display overlayed over the level -- map. Also trims (does not wrap!) too long lines. padMsg :: 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 -- | 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 :: Report -> [Text] -- | Render a report as a (possibly very long) string. renderReport :: Report -> Text -- | The history of reports. data History -- | Empty history of reports. emptyHistory :: History -- | Construct a singleton history of reports. singletonHistory :: Report -> History -- | Add a report to history, handling repetitions. addReport :: Report -> History -> History -- | Render history as many lines of text, wrapping if necessary. renderHistory :: History -> Overlay -- | Take the given prefix of reports from a history. takeHistory :: Int -> History -> History -- | A screenful of text lines. When displayed, they are trimmed, not -- wrapped and any lines below the lower screen edge are not visible. type Overlay = [Text] -- | Split an overlay into overlays that fit on the screen. splitOverlay :: Y -> Overlay -> [Overlay] -- | Returns a function that looks up the characters in the string by -- location. Takes the width and height of the display plus the string. -- Returns also the message to print at the top and bottom. stringByLocation :: X -> Y -> Overlay -> (Text, PointXY -> Maybe Char, Maybe Text) instance Show Report instance Show History instance Binary History instance Binary Report instance Binary Text -- | Basic operations on 2D points represented as linear offsets. module Game.LambdaHack.Point -- | The type of locations on the 2D level map, heavily optimized. -- -- We represent the (level map on the) screen as a linear framebuffer, -- where Point is an Int offset counted from the first -- cell. We do bounds check for the X size whenever we convert between -- representations and each subsequent array access performs another -- check, effectively for Y size. After dungeon is generated (using -- PointXY, not Point), and converted to the -- Point representation, points are used mainly as keys and not -- constructed often, so the performance will improve due to smaller save -- files, the use of IntMap and cheaper array indexing, -- including cheaper bounds checks. We don't define Point as a -- newtype to avoid the trouble with using EnumMap in place of -- IntMap, etc. type Point = Int -- | Conversion from cartesian coordinates to Point. toPoint :: X -> PointXY -> Point -- | Print a point as a tuple of cartesian coordinates. showPoint :: X -> Point -> Text -- | The top-left corner location of the level. origin :: Point -- | The distance between two points in the chessboard metric. chessDist :: X -> Point -> Point -> Int -- | Checks whether two points are adjacent on the map (horizontally, -- vertically or diagonally). adjacent :: X -> Point -> Point -> Bool -- | Returns the 8, or less, surrounding locations of a given location. vicinity :: X -> Y -> Point -> [Point] -- | Returns the 4, or less, surrounding locations in cardinal directions -- from a given location. vicinityCardinal :: X -> Y -> Point -> [Point] -- | Checks that a point belongs to an area. inside :: X -> Point -> Area -> Bool -- | Calculate the displacement vector from a location to another. displacementXYZ :: X -> Point -> Point -> VectorXY -- | Bresenham's line algorithm generalized to arbitrary starting -- eps (eps value of 0 gives the standard BLA). Skips -- the source point and goes through the second point to the edge of the -- level. GIves Nothing if the points are equal. bla :: X -> Y -> Int -> Point -> Point -> Maybe [Point] -- | Screen frames and animations. module Game.LambdaHack.Animation -- | 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. defaultAttr :: Attr data AttrChar AttrChar :: !Attr -> !Char -> AttrChar acAttr :: AttrChar -> !Attr acChar :: AttrChar -> !Char -- | The data sufficent to draw a single game screen frame. data SingleFrame SingleFrame :: ![[AttrChar]] -> Text -> Text -> SingleFrame -- | content of the screen, line by line sfLevel :: SingleFrame -> ![[AttrChar]] -- | an extra line to show at the top sfTop :: SingleFrame -> Text -- | an extra line to show at the bottom sfBottom :: SingleFrame -> Text -- | Animation is a list of frame modifications to play one by one, where -- each modification if a map from locations to level map symbols. data Animation -- | Render animations on top of a screen frame. rederAnim :: X -> Y -> SingleFrame -> Animation -> [Maybe SingleFrame] -- | Attack animation. A part of it also reused for self-damage and -- healing. twirlSplash :: (Maybe Point, Maybe Point) -> Color -> Color -> Animation -- | Attack that hits through a block. blockHit :: (Maybe Point, Maybe Point) -> Color -> Color -> Animation -- | Attack that is blocked. blockMiss :: (Maybe Point, Maybe Point) -> Animation -- | Death animation for an organic body. deathBody :: Point -> Animation -- | Swap-places animation, both hostile and friendly. swapPlaces :: (Maybe Point, Maybe Point) -> Animation instance Eq SingleFrame instance Monoid Animation -- | Basic operations on 2D vectors represented in an efficient, but not -- unique, way. module Game.LambdaHack.Vector -- | 2D vectors represented as offsets in the linear framebuffer indexed by -- Point. -- -- A newtype is used to prevent mixing up the type with Point -- itself. Note that the offset representations of a vector is usually -- not unique. E.g., for vectors of length 1 in the chessboard metric, -- used to denote geographical directions, the representations are -- pairwise distinct if and only if the level width and height are at -- least 3. data Vector -- | Converts a vector in cartesian representation into Vector. toVector :: X -> VectorXY -> Vector -- | Translate a point by a vector. -- -- Particularly simple and fast implementation in the linear -- representation. shift :: Point -> Vector -> Point -- | Translate a point by a vector, but only if the result fits in an area. shiftBounded :: X -> Area -> Point -> Vector -> Point -- | Vectors of all unit moves, clockwise, starting north-west. moves :: X -> [Vector] -- | Vectors of all unit moves, clockwise, starting north-west, -- parameterized by level width. movesWidth :: [X -> Vector] -- | Tells if a vector has length 1 in the chessboard metric. isUnit :: X -> Vector -> Bool -- | Squared euclidean distance between two unit vectors. euclidDistSq :: X -> Vector -> Vector -> Int -- | Checks whether a unit vector is a diagonal direction, as opposed to -- cardinal. diagonal :: X -> Vector -> Bool -- | Reverse an arbirary vector. neg :: Vector -> Vector -- | Given two distinct locations, 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 :: X -> Point -> Point -> Vector -- | A vector from a point to another. We have -- --
-- shift loc1 (displacement loc1 loc2) == loc2 ---- -- Particularly simple and fast implementation in the linear -- representation. displacement :: Point -> Point -> Vector -- | A list of vectors between a list of points. displacePath :: [Point] -> [Vector] -- | A list of points that a list of vectors leads to. shiftPath :: Point -> [Vector] -> [Point] instance Show Vector instance Eq Vector instance Binary Vector -- | Frontend-independent keyboard input operations. module Game.LambdaHack.Key -- | Frontend-independent datatype to represent keys. data Key Esc :: Key Return :: Key Space :: Key Tab :: Key BackTab :: Key PgUp :: Key PgDn :: Key Left :: Key Right :: Key Up :: Key Down :: Key End :: Key Begin :: Key Home :: Key -- | a keypad key for a character (digits and operators) KP :: !Char -> Key -- | a single printable character Char :: !Char -> Key -- | an unknown key, registered to warn the user Unknown :: !String -> Key -- | Configurable event handler for the direction keys. Used for directed -- commands such as close door. handleDir :: X -> (Key, Modifier) -> (Vector -> a) -> a -> a dirAllMoveKey :: [Key] -- | Binding of both sets of movement keys. moveBinding :: ((X -> Vector) -> a) -> ((X -> Vector) -> a) -> [((Key, Modifier), (Text, Bool, a))] -- | 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 Control :: Modifier NoModifier :: Modifier -- | Show a key with a modifier, if any. showKM :: (Key, Modifier) -> Text instance Ord Key instance Eq Key instance Ord Modifier instance Eq Modifier instance Show Key instance Binary Key -- | Personal game configuration file type definitions. module Game.LambdaHack.Config -- | Fully typed contents of the rules config file. data Config Config :: !String -> ![(Text, Text)] -> !Int -> !FovMode -> !Int -> !Int -> !Int -> !Bool -> !Text -> Config configSelfString :: Config -> !String configCaves :: Config -> ![(Text, Text)] configDepth :: Config -> !Int configFovMode :: Config -> !FovMode configSmellTimeout :: Config -> !Int configBaseHP :: Config -> !Int configExtraHeroes :: Config -> !Int configFirstDeathEnds :: Config -> !Bool configFaction :: Config -> !Text -- | Fully typed contents of the UI config file. data ConfigUI ConfigUI :: ![(Key, String)] -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> ![(Int, Text)] -> ![(Key, Key)] -> !String -> !Int -> ConfigUI configCommands :: ConfigUI -> ![(Key, String)] configAppDataDir :: ConfigUI -> !FilePath configDiaryFile :: ConfigUI -> !FilePath configSaveFile :: ConfigUI -> !FilePath configBkpFile :: ConfigUI -> !FilePath configScoresFile :: ConfigUI -> !FilePath configRulesCfgFile :: ConfigUI -> !FilePath configUICfgFile :: ConfigUI -> !FilePath configHeroNames :: ConfigUI -> ![(Int, Text)] configMacros :: ConfigUI -> ![(Key, Key)] configFont :: ConfigUI -> !String configHistoryMax :: ConfigUI -> !Int -- | Field Of View scanning mode. data FovMode -- | restrictive shadow casting Shadow :: FovMode -- | permissive FOV Permissive :: FovMode -- | digital FOV with the given radius Digital :: Int -> FovMode -- | only feeling out adjacent tiles by touch Blind :: FovMode instance Show FovMode instance Read FovMode instance Show Config instance Show ConfigUI instance Binary ConfigUI instance Binary Config instance Binary FovMode -- | Re-export the operations of the chosen raw frontend (determined at -- compile time with cabal flags). module Game.LambdaHack.Action.Frontend.Chosen -- | No session data needs to be maintained by this frontend. type FrontendSession = () -- | Starts the main program loop using the frontend input and output. startup :: String -> (FrontendSession -> IO ()) -> IO () -- | The name of the frontend. frontendName :: String -- | Input key via the frontend. nextEvent :: FrontendSession -> Maybe Bool -> IO (Key, Modifier) -- | Display a prompt, wait for any key. promptGetAnyKey :: FrontendSession -> SingleFrame -> IO (Key, Modifier) -- | Output to the screen via the frontend. display :: FrontendSession -> Bool -> Bool -> Maybe SingleFrame -> IO () -- | A list of items with relative frequencies of appearance. module Game.LambdaHack.Utils.Frequency -- | The frequency distribution type. 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 frequecy 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 -- | Randomly choose an item according to the distribution. rollFreq :: Show a => Frequency a -> StdGen -> (a, StdGen) -- | Test if the frequency distribution is empty. nullFreq :: Frequency a -> Bool -- | give acces to raw frequency values runFrequency :: Frequency a -> [(Int, a)] -- | short description for debug, etc. nameFrequency :: Frequency a -> Text instance Show a => Show (Frequency a) instance Functor Frequency instance MonadPlus Frequency instance Monad Frequency -- | Representation of probabilities and random computations. module Game.LambdaHack.Random -- | The monad of computations with random generator state. type Rnd a = State StdGen a -- | Get a random object within a range with a uniform distribution. randomR :: Random a => (a, a) -> Rnd a -- | Get 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 -- | Roll a single die. roll :: Int -> Rnd Int -- | Dice: 1d7, 3d3, 1d0, etc. RollDice a b represents a -- rolls of b-sided die. data RollDice RollDice :: Word8 -> Word8 -> RollDice -- | Roll dice and sum the results. rollDice :: RollDice -> Rnd Int -- | Maximal value of dice. maxDice :: RollDice -> Int -- | Minimal value of dice. minDice :: RollDice -> Int -- | Mean value of dice. meanDice :: RollDice -> Rational -- | Dice for rolling a pair of integer parameters pertaining to, -- respectively, the X and Y cartesian 2D coordinates. data RollDiceXY RollDiceXY :: (RollDice, RollDice) -> RollDiceXY -- | Roll the two sets of dice. rollDiceXY :: RollDiceXY -> Rnd (Int, Int) -- | 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. type RollDeep = (RollDice, RollDice) -- | Roll dice scaled with current level depth. Note that at the first -- level, the scaled dice are always ignored. rollDeep :: Int -> Int -> RollDeep -> Rnd Int -- | Roll dice scaled with current level depth and return True if -- the results if greater than 50. chanceDeep :: Int -> Int -> RollDeep -> Rnd Bool -- | Generate a RollDeep that always gives a constant integer. intToDeep :: Int -> RollDeep -- | Maximal value of scaled dice. maxDeep :: RollDeep -> Int -- | Fractional chance. type Chance = Rational -- | Give True, with probability determined by the fraction. chance :: Chance -> Rnd Bool instance Eq RollDice instance Ord RollDice instance Show RollDiceXY instance Read RollDice instance Show RollDice -- | Effects of content on other content. No operation in this module -- involves the State or Action type. module Game.LambdaHack.Effect -- | All possible effects, some of them parameterized or dependent on -- outside coefficients, e.g., item power. data Effect NoEffect :: Effect Heal :: Effect Wound :: !RollDice -> Effect Dominate :: Effect SummonFriend :: Effect SummonEnemy :: Effect ApplyPerfume :: Effect Regeneration :: Effect Searching :: Effect Ascend :: Effect Descend :: Effect -- | Suffix to append to a basic content name, if the content causes the -- effect. effectToSuffix :: Effect -> Text -- | How much AI benefits from applying the effect. Multipllied by item -- power. Negative means harm to the enemy when thrown at him. Effects -- with zero benefit won't ever be used, neither actively nor passively. effectToBenefit :: Effect -> Int instance Show Effect instance Read Effect instance Eq Effect instance Ord Effect -- | Terrain tile features. module Game.LambdaHack.Feature -- | All possible terrain tile features, some of them parameterized or -- dependent on outside coefficients, e.g., on the tile secrecy value. data Feature -- | triggered by ascending Ascendable :: Feature -- | triggered by descending Descendable :: Feature -- | triggered by opening Openable :: Feature -- | triggered by closing Closable :: Feature -- | triggered when the tile's secrecy becomes zero Hidden :: Feature -- | causes the effect when triggered Cause :: !Effect -> Feature -- | transitions to any tile of the group when triggered ChangeTo :: !Text -> Feature -- | actors can walk through Walkable :: Feature -- | actors can see through Clear :: Feature -- | is lit with an ambient shine Lit :: Feature -- | sustains the effect continuously, TODO Aura :: !Effect -> Feature -- | items and stairs can be generated there Boring :: Feature -- | is a (not hidden) door, stair, etc. Exit :: Feature -- | used for visible paths throughout the level Path :: Feature -- | discovering the secret will require this many turns Secret :: !RollDice -> Feature instance Show Feature instance Read Feature instance Eq Feature instance Ord Feature -- | The type of kinds of terrain tiles. module Game.LambdaHack.Content.TileKind -- | The type of kinds of terrain tiles. See Tile.hs for -- explanation of the absence of a corresponding type Tile that -- would hold particular concrete tiles in the dungeon. data TileKind TileKind :: !Char -> !Text -> !Freqs -> !Color -> !Color -> ![Feature] -> TileKind -- | map symbol tsymbol :: TileKind -> !Char -- | short description tname :: TileKind -> !Text -- | frequency within groups tfreq :: TileKind -> !Freqs -- | map color tcolor :: TileKind -> !Color -- | map color when not in FOV tcolor2 :: TileKind -> !Color -- | properties tfeature :: TileKind -> ![Feature] -- | Filter a list of kinds, passing through only the incorrect ones, if -- any. -- -- If tiles look the same on the map, the description should be the same, -- too. Otherwise, the player has to inspect manually all the tiles of -- that kind to see if any is special. This is a part of a stronger but -- less precise property that tiles that look the same can't be -- distinguished by player actions (but may behave differently wrt -- dungeon generation, AI preferences, etc.). tvalidate :: [TileKind] -> [TileKind] instance Show TileKind -- | 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 Rule to hold any changing parameters, just -- RuleKind 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 RuleKind will -- become just a starting template, analogously as for the other content. -- -- The raccessible field holds a predicate that tells whether -- one location is accessible from another. Precondition: the two -- locations are next to each other. data RuleKind RuleKind :: Char -> Text -> Freqs -> (X -> Point -> TileKind -> Point -> TileKind -> Bool) -> Text -> (FilePath -> IO FilePath) -> Version -> [Char] -> [Char] -> String -> String -> Text -> RuleKind -- | a symbol rsymbol :: RuleKind -> Char -- | short description rname :: RuleKind -> Text -- | frequency within groups rfreq :: RuleKind -> Freqs raccessible :: RuleKind -> X -> Point -> TileKind -> Point -> TileKind -> 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 -- | symbols of melee weapons ritemMelee :: RuleKind -> [Char] -- | symbols of items AI can project ritemProject :: RuleKind -> [Char] -- | the default game rules config file rcfgRulesDefault :: RuleKind -> String -- | the default UI settings config file rcfgUIDefault :: RuleKind -> String -- | the ASCII art for the Main Menu rmainMenuArt :: RuleKind -> Text -- | Validates the ASCII art format (TODO). ruvalidate :: [RuleKind] -> [RuleKind] instance Show RuleKind -- | Abstract syntax of player commands. module Game.LambdaHack.Command -- | Abstract syntax of player commands. The type is abstract, but the -- values are created outside this module via the Read class (from config -- file) . data Cmd Apply :: Part -> Part -> [Char] -> Cmd verb :: Cmd -> Part object :: Cmd -> Part syms :: Cmd -> [Char] Project :: Part -> Part -> [Char] -> Cmd verb :: Cmd -> Part object :: Cmd -> Part syms :: Cmd -> [Char] TriggerDir :: Part -> Part -> Feature -> Cmd verb :: Cmd -> Part object :: Cmd -> Part feature :: Cmd -> Feature TriggerTile :: Part -> Part -> Feature -> Cmd verb :: Cmd -> Part object :: Cmd -> Part feature :: Cmd -> Feature Pickup :: Cmd Drop :: Cmd Wait :: Cmd GameExit :: Cmd GameRestart :: Cmd GameSave :: Cmd Inventory :: Cmd TgtFloor :: Cmd TgtEnemy :: Cmd TgtAscend :: Int -> Cmd EpsIncr :: Bool -> Cmd Cancel :: Cmd Accept :: Cmd Clear :: Cmd History :: Cmd CfgDump :: Cmd HeroCycle :: Cmd HeroBack :: Cmd Help :: Cmd -- | Major commands land on the first page of command help. majorCmd :: Cmd -> Bool -- | Time cosuming commands are marked as such in help and cannot be -- invoked in targeting mode on a remote level (level different than the -- level of the selected hero). timedCmd :: Cmd -> Bool -- | Description of player commands. cmdDescription :: Cmd -> Text instance Show Cmd instance Read Cmd instance Eq Cmd instance Ord Cmd -- | Generic binding of keys to commands, procesing macros, printing -- command help. No operation in this module involves the State -- or Action type. module Game.LambdaHack.Binding -- | Bindings and other information about player commands. data Binding a Binding :: Map (Key, Modifier) (Text, Bool, a) -> Map Key Key -> [Key] -> [(Key, Modifier)] -> Map Cmd Key -> Binding a -- | binding keys to commands kcmd :: Binding a -> Map (Key, Modifier) (Text, Bool, a) -- | macro map kmacro :: Binding a -> Map Key Key -- | major, most often used, commands kmajor :: Binding a -> [Key] -- | direction keys for moving and running kdir :: Binding a -> [(Key, Modifier)] -- | map from cmds to their main keys krevMap :: Binding a -> Map Cmd Key -- | Produce a set of help screens from the key bindings. keyHelp :: Binding a -> [Overlay] -- | The type of kinds of weapons and treasure. module Game.LambdaHack.Content.ItemKind -- | Item properties that are fixed for a given kind of items. data ItemKind ItemKind :: !Char -> !Text -> !Freqs -> ![Flavour] -> !Effect -> !RollDeep -> !RollDeep -> !Part -> !Part -> !Int -> !Int -> ItemKind -- | map symbol isymbol :: ItemKind -> !Char -- | generic name iname :: ItemKind -> !Text -- | frequency within groups ifreq :: ItemKind -> !Freqs -- | possible flavours iflavour :: ItemKind -> ![Flavour] -- | the effect when activated ieffect :: ItemKind -> !Effect -- | created in that quantify icount :: ItemKind -> !RollDeep -- | created with that power ipower :: ItemKind -> !RollDeep -- | the verb for applying and possibly combat iverbApply :: ItemKind -> !Part -- | the verb for projecting iverbProject :: ItemKind -> !Part -- | weight in grams iweight :: ItemKind -> !Int -- | percentage bonus or malus to throw speed itoThrow :: ItemKind -> !Int -- | No specific possible problems for the content of this kind, so far, so -- the validation function always returns the empty list of offending -- kinds. ivalidate :: [ItemKind] -> [ItemKind] instance Show ItemKind -- | Operations on the Area type that involve random numbers. module Game.LambdaHack.AreaRnd -- | Pick a random point within an area. xyInArea :: Area -> Rnd PointXY -- | Create a random room according to given parameters. mkRoom :: (X, Y) -> Area -> Rnd Area -- | Create a void room, i.e., a single point 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 [(PointXY, PointXY)] -- | Pick a single random connection between adjacent areas within a grid. randomConnection :: (X, Y) -> Rnd (PointXY, PointXY) -- | The coordinates of consecutive fields of a corridor. type Corridor = [PointXY] -- | Try to connect two places with a corridor. Choose entrances at least 4 -- tiles distant from the edges, if possible. connectPlaces :: Area -> Area -> Rnd Corridor -- | The type of cave layout kinds. module Game.LambdaHack.Content.CaveKind -- | Parameters for the generation of dungeon levels. data CaveKind CaveKind :: Char -> Text -> Freqs -> X -> Y -> RollDiceXY -> RollDiceXY -> RollDeep -> Rational -> Chance -> Int -> Int -> Chance -> Chance -> Chance -> RollDice -> Text -> Text -> Text -> Text -> Text -> Text -> CaveKind -- | a symbol csymbol :: CaveKind -> Char -- | short description cname :: CaveKind -> Text -- | frequency within groups cfreq :: CaveKind -> Freqs -- | 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 -> RollDiceXY -- | minimal size of places cminPlaceSize :: CaveKind -> RollDiceXY -- | the chance a place is dark cdarkChance :: CaveKind -> RollDeep -- | a proportion of extra connections cauxConnects :: CaveKind -> Rational -- | the chance of not creating a place cvoidChance :: CaveKind -> Chance -- | extra places, may overlap except two cnonVoidMin :: CaveKind -> Int -- | 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, is it hidden? chiddenChance :: CaveKind -> Chance -- | the number of items in the cave citemNum :: CaveKind -> RollDice -- | the default cave tile group name cdefaultTile :: CaveKind -> Text -- | the cave corridor tile group name ccorridorTile :: CaveKind -> Text -- | the filler wall group name cfillerTile :: CaveKind -> Text -- | the dark place plan legend ground name cdarkLegendTile :: CaveKind -> Text -- | the lit place plan legend ground name clitLegendTile :: CaveKind -> Text -- | the hidden tiles ground name chiddenTile :: CaveKind -> Text -- | Filter a list of kinds, passing through only the incorrect ones, if -- any. -- -- Catch caves with not enough space for all the places. Check the size -- of the cave descriptions to make sure they fit on screen. cvalidate :: [CaveKind] -> [CaveKind] instance Show CaveKind -- | AI strategies to direct actors not controlled by the player. No -- operation in this module involves the State or -- Action type. module Game.LambdaHack.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 -- | Strategy with no actions at all. reject :: Strategy a -- | Conditionally accepted strategy. (.=>) :: Bool -> Strategy a -> Strategy a -- | 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 return, but pick a name of the single frequency. returN :: Text -> a -> Strategy a instance Show a => Show (Strategy a) instance MonadPlus Strategy instance Monad Strategy -- | Display game data on the screen and receive user input using one of -- the available raw frontends and derived operations. module Game.LambdaHack.Action.Frontend -- | No session data needs to be maintained by this frontend. type FrontendSession = () -- | Starts the main program loop using the frontend input and output. startup :: String -> (FrontendSession -> IO ()) -> IO () -- | The name of the frontend. frontendName :: String -- | Input key via the frontend. nextEvent :: FrontendSession -> Maybe Bool -> IO (Key, Modifier) -- | Push a frame or a single frame's worth of delay to the frame queue. displayFrame :: FrontendSession -> Bool -> Maybe SingleFrame -> IO () -- | Display a prompt, wait for any of the specified keys (for any key, if -- the list is empty). Repeat if an unexpected key received. promptGetKey :: FrontendSession -> [(Key, Modifier)] -> SingleFrame -> IO (Key, Modifier) -- | AI strategy abilities. module Game.LambdaHack.Ability -- | All possible AI actor abilities. AI chooses among these when -- considering the next action to perform. The ability descriptions refer -- to the target that any actor picks each turn, depending on the actor's -- characteristics and his environment. data Ability -- | move along a set path, if any, meleeing any opponents Track :: Ability -- | heal if almost dead Heal :: Ability -- | flee if almost dead Flee :: Ability -- | melee target Melee :: Ability -- | gather items, if no foes visible Pickup :: Ability -- | attack the visible target opponent at range, some of the time Ranged :: Ability -- | use items, if target opponent visible, some of the time Tools :: Ability -- | chase the target, ignoring any actors on the way Chase :: Ability -- | wander around, meleeing any opponents on the way Wander :: Ability instance Show Ability instance Eq Ability instance Ord Ability instance Enum Ability instance Bounded Ability -- | The type of kinds of monsters and heroes. module Game.LambdaHack.Content.ActorKind -- | Actor properties that are fixed for a given kind of actors. data ActorKind ActorKind :: !Char -> !Text -> !Freqs -> !Color -> !Speed -> !RollDice -> !Bool -> !Bool -> !Int -> !Int -> ![Ability] -> ActorKind -- | map symbol asymbol :: ActorKind -> !Char -- | short description aname :: ActorKind -> !Text -- | frequency within groups afreq :: ActorKind -> !Freqs -- | map color acolor :: ActorKind -> !Color -- | natural speed in m/s aspeed :: ActorKind -> !Speed -- | encodes initial and maximal hp ahp :: ActorKind -> !RollDice -- | can it see? asight :: ActorKind -> !Bool -- | can it smell? asmell :: ActorKind -> !Bool -- | intelligence aiq :: ActorKind -> !Int -- | number of turns to regenerate 1 HP aregen :: ActorKind -> !Int -- | the set of supported abilities acanDo :: ActorKind -> ![Ability] -- | Filter a list of kinds, passing through only the incorrect ones, if -- any. -- -- Make sure actor kinds can be told apart on the level map. avalidate :: [ActorKind] -> [ActorKind] instance Show ActorKind -- | The type of kinds of AI strategies. module Game.LambdaHack.Content.StrategyKind -- | Strategy properties that are fixed for a given kind of strategies. data StrategyKind StrategyKind :: !Char -> !Text -> !Freqs -> ![Ability] -> StrategyKind -- | a symbol ssymbol :: StrategyKind -> !Char -- | short description sname :: StrategyKind -> !Text -- | frequency within groups sfreq :: StrategyKind -> !Freqs -- | abilities to pick from in roughly that order sabilities :: StrategyKind -> ![Ability] -- | No specific possible problems for the content of this kind, so far, so -- the validation function always returns the empty list of offending -- kinds. svalidate :: [StrategyKind] -> [StrategyKind] instance Show StrategyKind -- | General content types and operations. module Game.LambdaHack.Kind -- | Content identifiers for the content type c. data Id c -- | Type family for auxiliary data structures for speeding up content -- operations. -- | Content operations for the content of type a. data Ops a Ops :: (Id a -> Char) -> (Id a -> Text) -> (Id a -> a) -> (Text -> Id a) -> (Text -> (a -> Bool) -> Rnd (Id a)) -> (forall b. (Id a -> a -> b -> b) -> b -> b) -> (Id a, Id a) -> Speedup a -> Ops a -- | the symbol of a content element at id osymbol :: Ops a -> Id a -> Char -- | the name of a content element at id oname :: Ops a -> Id a -> Text -- | 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 -> Text -> Id a -- | pick a random id belonging to a group and satisfying a predicate opick :: Ops a -> Text -> (a -> Bool) -> Rnd (Id a) -- | fold over all content elements of a ofoldrWithKey :: Ops a -> forall b. (Id a -> a -> b -> b) -> b -> b -- | bounds of identifiers of content a obounds :: Ops a -> (Id a, Id a) -- | auxiliary speedup components ospeedup :: Ops a -> Speedup a -- | Operations for all content types, gathered together. data COps COps :: !(Ops ActorKind) -> !(Ops CaveKind) -> !(Ops FactionKind) -> !(Ops ItemKind) -> !(Ops PlaceKind) -> !(Ops RuleKind) -> !(Ops StrategyKind) -> !(Ops TileKind) -> COps coactor :: COps -> !(Ops ActorKind) cocave :: COps -> !(Ops CaveKind) cofact :: COps -> !(Ops FactionKind) coitem :: COps -> !(Ops ItemKind) coplace :: COps -> !(Ops PlaceKind) corule :: COps -> !(Ops RuleKind) costrat :: COps -> !(Ops StrategyKind) cotile :: COps -> !(Ops TileKind) -- | Create content operations for type a from definition of -- content of type a. createOps :: Show a => CDefs a -> Ops a -- | The standard ruleset used for level operations. stdRuleset :: Ops RuleKind -> RuleKind -- | Arrays of content identifiers pointing to the content type c, -- where the identifiers are represented as Word8 (and so -- content of type c can have at most 256 elements). The arrays -- are indexed by type i, e.g., a dungeon tile location. data Array i c -- | Content identifiers array lookup. (!) :: Ix i => Array i c -> i -> Id c -- | Construct a content identifiers array updated with the association -- list. (//) :: Ix i => Array i c -> [(i, Id c)] -> Array i c -- | Create a content identifiers array from a list of elements. listArray :: Ix i => (i, i) -> [Id c] -> Array i c -- | Create a content identifiers array from an association list. array :: Ix i => (i, i) -> [(i, Id c)] -> Array i c -- | Content identifiers array bounds. bounds :: Ix i => Array i c -> (i, i) -- | Fold left strictly over an array. foldlArray :: Ix i => (a -> Id c -> a) -> a -> Array i c -> a instance Show (Id c) instance Eq (Id c) instance Ord (Id c) instance Ix (Id c) instance (Show i, Ix i) => Show (Array i c) instance (Ix i, Binary i) => Binary (Array i c) instance Show COps instance Binary (Id c) -- | Actors in the game: monsters and heroes. No operation in this module -- involves the State or Action type. module Game.LambdaHack.Actor -- | A unique identifier of an actor in a dungeon. type ActorId = Int -- | Find a hero name in the config file, or create a stock name. findHeroName :: ConfigUI -> Int -> Text -- | 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 :: Int -> Int -> Rnd Bool -- | The part of speech describing the actor. partActor :: Ops ActorKind -> Actor -> Part -- | Actor properties that are changing throughout the game. If they are -- dublets of properties from ActorKind, they are usually -- modified temporarily, but tend to return to the original value from -- ActorKind over time. E.g., HP. data Actor Actor :: !(Id ActorKind) -> !(Maybe Char) -> !(Maybe Text) -> !(Maybe Color) -> !(Maybe Speed) -> !Int -> !(Maybe (Vector, Int)) -> Target -> !Point -> !Char -> !Time -> !Time -> !(Id FactionKind) -> !Bool -> Actor -- | the kind of the actor bkind :: Actor -> !(Id ActorKind) -- | individual map symbol bsymbol :: Actor -> !(Maybe Char) -- | individual name bname :: Actor -> !(Maybe Text) -- | individual map color bcolor :: Actor -> !(Maybe Color) -- | individual speed bspeed :: Actor -> !(Maybe Speed) -- | current hit points bhp :: Actor -> !Int -- | direction and distance of running bdir :: Actor -> !(Maybe (Vector, Int)) -- | target for ranged attacks and AI btarget :: Actor -> Target -- | current location bloc :: Actor -> !Point -- | next inventory letter bletter :: Actor -> !Char -- | absolute time of next action btime :: Actor -> !Time -- | last bracing expires at this time bwait :: Actor -> !Time -- | to which faction the actor belongs bfaction :: Actor -> !(Id FactionKind) -- | is a projectile? (shorthand only, ^ this can be deduced from bkind) bproj :: Actor -> !Bool -- | A template for a new non-projectile actor. The initial target is -- invalid to force a reset ASAP. template :: Id ActorKind -> Maybe Char -> Maybe Text -> Int -> Point -> Time -> Id FactionKind -> Bool -> Actor -- | Increment current hit points of an actor. addHp :: Ops ActorKind -> Int -> Actor -> Actor -- | Add time taken by a single step at the actor's current speed. timeAddFromSpeed :: Ops ActorKind -> Actor -> Time -> Time -- | Whether an actor is braced for combat this turn. braced :: Actor -> Time -> Bool -- | Checks for the presence of actors in a location. Does not check if the -- tile is walkable. unoccupied :: [Actor] -> Point -> Bool -- | The unique kind of heroes. heroKindId :: Ops ActorKind -> Id ActorKind -- | The unique kind of projectiles. projectileKindId :: Ops ActorKind -> Id ActorKind -- | Access actor speed, individual or, otherwise, stock. actorSpeed :: Ops ActorKind -> Actor -> Speed -- | The type of na actor target. data Target -- | target an actor with its last seen location TEnemy :: ActorId -> Point -> Target -- | target a given location TLoc :: Point -> Target -- | target the list of locations one after another TPath :: [Vector] -> Target -- | target current position of the cursor; default TCursor :: Target instance Show Target instance Eq Target instance Show Actor instance Binary Target instance Binary Actor -- | Personal game configuration file support. module Game.LambdaHack.Action.ConfigIO -- | Read and parse rules config file and supplement it with random seeds. mkConfigRules :: Ops RuleKind -> IO (Config, StdGen, StdGen) -- | Read and parse UI config file. mkConfigUI :: Ops RuleKind -> IO ConfigUI -- | Dumps the current configuration to a file. dump :: Config -> FilePath -> IO () instance Show CP -- | Weapons, treasure and all the other items in the game. No operation in -- this module involves the State or Action type. TODO: -- Document after it's rethought and rewritten wrt separating inventory -- manangement and items proper. module Game.LambdaHack.Item -- | Game items in inventories or strewn around the dungeon. data Item Item :: !(Id ItemKind) -> !Int -> Maybe Char -> !Int -> Item -- | kind of the item jkind :: Item -> !(Id ItemKind) -- | power of the item jpower :: Item -> !Int -- | inventory symbol jletter :: Item -> Maybe Char -- | inventory count jcount :: Item -> !Int -- | Generate an item. newItem :: Ops ItemKind -> Int -> Int -> Rnd Item -- | Represent an item on the map. viewItem :: Ops ItemKind -> Id ItemKind -> FlavourMap -> (Char, Color) -- | Price an item, taking count into consideration. itemPrice :: Ops ItemKind -> Item -> Int strongestSearch :: Ops ItemKind -> [Item] -> Maybe Item strongestSword :: COps -> [Item] -> Maybe Item strongestRegen :: Ops ItemKind -> [Item] -> Maybe Item -- | Adds an item to a list of items, joining equal items. Also returns the -- joined item. joinItem :: Item -> [Item] -> (Item, [Item]) removeItemByLetter :: Item -> [Item] -> [Item] equalItemIdentity :: Item -> Item -> Bool removeItemByIdentity :: Item -> [Item] -> [Item] -- | Assigns a letter to an item, for inclusion in the inventory of a hero. -- Takes a remembered letter and a starting letter. assignLetter :: Maybe Char -> Char -> [Item] -> Maybe Char letterLabel :: Maybe Char -> Part cmpLetterMaybe :: Maybe Char -> Maybe Char -> Ordering maxLetter :: Char -> Char -> Char letterRange :: [Char] -> Text -- | Flavours assigned to items in this game. type FlavourMap = Map (Id ItemKind) Flavour getFlavour :: Ops ItemKind -> FlavourMap -> Id ItemKind -> Flavour -- | Randomly chooses flavour for all item kinds for this game. dungeonFlavourMap :: Ops ItemKind -> Rnd FlavourMap -- | The type of already discovered items. type Discoveries = Set (Id ItemKind) instance Show Item instance Binary Item -- | Operations concerning dungeon level tiles. -- -- Unlike for many other content types, there is no type Tile, -- of particular concrete tiles in the dungeon, corresponding to -- TileKind (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 Tile 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 Tile type, we express various properties of -- concrete tiles by arrays or sparse IntMaps, as appropriate. -- -- Actors at normal speed (2 m/s) take one turn to move one tile (1 m by -- 1 m). module Game.LambdaHack.Tile -- | The time interval needed to discover a given secret, e.g., a hidden -- terrain tile, e.g., a hidden door. type SecretTime = Time -- | 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 has all features of the first set and no features -- of the second. kindHas :: [Feature] -> [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 -- FOV, hence tabulated. isClear :: Ops TileKind -> Id TileKind -> Bool -- | Whether a tile is lit on its own. Essential for efficiency of -- Perception, hence tabulated. isLit :: Ops TileKind -> Id TileKind -> Bool -- | Whether a tile can be explored, possibly yielding a treasure or a -- hidden message. We exclude doors and hidden features (TODO: and -- features created by actors, e.g., dug out). isExplorable :: Ops TileKind -> Id TileKind -> Bool -- | The player can't tell one tile from the other. similar :: TileKind -> TileKind -> Bool -- | The player can't tell if the tile is hidden or not. canBeHidden :: Ops TileKind -> TileKind -> Bool speedup :: Ops TileKind -> Speedup TileKind -- | Inhabited dungeon levels and the operations to query and change them -- as the game progresses. module Game.LambdaHack.Level -- | All actors on the level, indexed by actor identifier. type ActorDict = IntMap Actor -- | Items carried by actors, indexed by actor identifier. type InvDict = IntMap [Item] -- | Current smell on map tiles. type SmellMap = IntMap SmellTime -- | Current secrecy value on map tiles. type SecretMap = IntMap SecretTime -- | Actual and remembered item lists on map tiles. type ItemMap = IntMap ([Item], [Item]) -- | Tile kinds on the map. type TileMap = Array Point TileKind -- | A single, inhabited dungeon level. data Level Level :: ActorDict -> InvDict -> X -> Y -> SmellMap -> SecretMap -> ItemMap -> TileMap -> TileMap -> Text -> Text -> (Point, Point) -> Time -> Int -> Int -> Level -- | all actors on the level lactor :: Level -> ActorDict -- | items belonging to actors linv :: Level -> InvDict -- | width of the level lxsize :: Level -> X -- | height of the level lysize :: Level -> Y -- | smells lsmell :: Level -> SmellMap -- | secrecy values lsecret :: Level -> SecretMap -- | items on the ground litem :: Level -> ItemMap -- | map tiles lmap :: Level -> TileMap -- | remembered map tiles lrmap :: Level -> TileMap -- | level description for the player ldesc :: Level -> Text -- | debug information from cave generation lmeta :: Level -> Text -- | destination of the (up, down) stairs lstairs :: Level -> (Point, Point) -- | date of the last activity on the level ltime :: Level -> Time -- | total number of clear tiles lclear :: Level -> Int -- | number of clear tiles already seen lseen :: Level -> Int -- | Update the hero and monster maps. updateActorDict :: (ActorDict -> ActorDict) -> Level -> Level -- | Update the hero items and monster items maps. updateInv :: (InvDict -> InvDict) -> Level -> Level -- | Update the smell map. updateSmell :: (SmellMap -> SmellMap) -> Level -> Level -- | Update the items on the ground map. updateIMap :: (ItemMap -> ItemMap) -> Level -> Level -- | Update the tile and remembered tile maps. updateLMap :: (TileMap -> TileMap) -> Level -> Level -- | Update the tile and remembered tile maps. updateLRMap :: (TileMap -> TileMap) -> Level -> Level -- | Place all items on the list at a location on the level. dropItemsAt :: [Item] -> Point -> Level -> Level -- | Query for actual and remembered tile kinds on the map. at :: Level -> Point -> Id TileKind -- | Query for actual and remembered tile kinds on the map. rememberAt :: Level -> Point -> Id TileKind -- | Query for actual and remembered items on the ground. atI :: Level -> Point -> [Item] -- | Query for actual and remembered items on the ground. rememberAtI :: Level -> Point -> [Item] -- | Check whether one location is accessible from another, using the -- formula from the standard ruleset. accessible :: COps -> Level -> Point -> Point -> Bool -- | Check whether the location contains a door of secrecy lower than -- k and that can be opened according to the standard ruleset. openable :: Ops TileKind -> Level -> SecretTime -> Point -> Bool -- | Find a random location on the map satisfying a predicate. findLoc :: TileMap -> (Point -> Id TileKind -> Bool) -> Rnd Point -- | Try to find a random location on the map satisfying the conjunction of -- the list of predicates. If the premitted 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. findLocTry :: Int -> TileMap -> [Point -> Id TileKind -> Bool] -> Rnd Point instance Show Level instance Binary Level -- | The game arena comprised of levels. No operation in this module -- involves the State, COps, Config or -- Action type. module Game.LambdaHack.Dungeon -- | Level ids are, for now, ordered linearly by depth. data LevelId -- | Depth of a level. levelNumber :: LevelId -> Int -- | Default level for a given depth. levelDefault :: Int -> LevelId -- | The complete dungeon is a map from level names to levels. data Dungeon -- | Create a dungeon from a list of levels and maximum depth. The depth is -- only a danger indicator; there may potentially be multiple levels with -- the same depth. fromList :: [(LevelId, Level)] -> Int -> Dungeon -- | Association list corresponding to the dungeon. Starts at the supplied -- level id (usually the current level) to try to speed up the searches -- and keep the dungeon lazy. currentFirst :: LevelId -> Dungeon -> [(LevelId, Level)] -- | Adjust the level at a given id. adjust :: (Level -> Level) -> LevelId -> Dungeon -> Dungeon -- | Adjust the level at a given id. mapDungeon :: (Level -> Level) -> Dungeon -> Dungeon -- | Find a level with the given id. (!) :: Dungeon -> LevelId -> Level -- | Try to look up a level with the given id. lookup :: LevelId -> Dungeon -> Maybe Level -- | Maximum depth of the dungeon. depth :: Dungeon -> Int instance Show LevelId instance Eq LevelId instance Ord LevelId instance Show Dungeon instance Binary Dungeon instance Binary LevelId -- | Game state and persistent player diary types and operations. module Game.LambdaHack.State -- | The state of a single game that can be saved and restored. It's -- completely disregarded and reset when a new game is started. In -- practice, we maintain some extra state (DungeonPerception), but it's -- only temporary, existing for a single turn and then invalidated. data State State :: ActorId -> Cursor -> FlavourMap -> Discoveries -> Dungeon -> LevelId -> Int -> StdGen -> Config -> Maybe Bool -> Maybe (Bool, Status) -> Id FactionKind -> DebugMode -> State -- | represents the player-controlled actor splayer :: State -> ActorId -- | cursor location and level to return to scursor :: State -> Cursor -- | association of flavour to items sflavour :: State -> FlavourMap -- | items (kinds) that have been discovered sdisco :: State -> Discoveries -- | all dungeon levels sdungeon :: State -> Dungeon -- | identifier of the current level slid :: State -> LevelId -- | stores next actor index scounter :: State -> Int -- | current random generator srandom :: State -> StdGen -- | this game's config (including initial RNG) sconfig :: State -> Config -- | last command unexpectedly took some time stakeTime :: State -> Maybe Bool -- | cause of game end/exit squit :: State -> Maybe (Bool, Status) -- | our faction sfaction :: State -> Id FactionKind -- | debugging mode sdebug :: State -> DebugMode -- | Current targeting mode of the player. data TgtMode -- | not in targeting mode TgtOff :: TgtMode -- | the player requested targeting mode explicitly TgtExplicit :: TgtMode -- | the mode was entered (and will be exited) automatically TgtAuto :: TgtMode -- | Current targeting cursor parameters. data Cursor Cursor :: TgtMode -> LevelId -> Point -> LevelId -> Int -> Cursor -- | targeting mode ctargeting :: Cursor -> TgtMode -- | cursor level clocLn :: Cursor -> LevelId -- | cursor coordinates clocation :: Cursor -> Point -- | the level current player resides on creturnLn :: Cursor -> LevelId -- | a parameter of the tgt digital line ceps :: Cursor -> Int -- | Current result of the game. data Status -- | the player lost the game on the given level Killed :: !LevelId -> Status -- | game is supended Camping :: Status -- | the player won Victor :: Status -- | the player quits and starts a new game Restart :: Status -- | Get current level from the dungeon data. slevel :: State -> Level -- | Get current time from the dungeon data. stime :: State -> Time -- | Initial game state. defaultState :: Config -> Id FactionKind -> FlavourMap -> Dungeon -> LevelId -> Point -> StdGen -> State -- | Update cursor parameters within state. updateCursor :: (Cursor -> Cursor) -> State -> State -- | Update time within state. updateTime :: (Time -> Time) -> State -> State -- | Update item discoveries within state. updateDiscoveries :: (Discoveries -> Discoveries) -> State -> State -- | Update level data within state. updateLevel :: (Level -> Level) -> State -> State -- | Update dungeon data within state. updateDungeon :: (Dungeon -> Dungeon) -> State -> State -- | The diary contains all the player data that carries over from game to -- game, even across playing sessions. That includes the last message, -- previous messages and otherwise recorded history of past games. This -- can be extended with other data and used for calculating player -- achievements, unlocking advanced game features and for general data -- mining, e.g., augmenting AI or procedural content generation. data Diary Diary :: Report -> History -> Diary sreport :: Diary -> Report shistory :: Diary -> History -- | Initial player diary. defaultDiary :: IO Diary -- | Produces a textual description of the terrain and items at an already -- explored location. Mute for unknown locations. The detailed variant is -- for use in the targeting mode. lookAt :: COps -> Bool -> Bool -> State -> Level -> Point -> Text -> Text -- | The part of speech describing the item. If cheating is allowed, full -- identity of the item is revealed together with its flavour (e.g. at -- the game over screen). partItemCheat :: Bool -> Ops ItemKind -> State -> Item -> Part -- | The part of speech describing the item. partItem :: Ops ItemKind -> State -> Item -> Part partItemNWs :: Ops ItemKind -> State -> Item -> Part data DebugMode DebugMode :: Maybe FovMode -> Bool -> DebugMode smarkVision :: DebugMode -> Maybe FovMode somniscient :: DebugMode -> Bool cycleMarkVision :: State -> State toggleOmniscient :: State -> State instance Show TgtMode instance Eq TgtMode instance Show Cursor instance Show Status instance Eq Status instance Ord Status instance Show DebugMode instance Show State instance Binary Status instance Binary Cursor instance Binary TgtMode instance Binary State instance Binary Diary -- | Saving and restoring games and player diaries. module Game.LambdaHack.Action.Save -- | Save a simple serialized version of the current state. Protected by a -- lock to avoid corrupting the file. saveGameFile :: ConfigUI -> State -> IO () -- | Restore a saved game, if it exists. Initialize directory structure, if -- needed. restoreGame :: ConfigUI -> (FilePath -> IO FilePath) -> Text -> IO (Either (State, Diary, Msg) (Diary, Msg)) -- | Remove the backup of the savegame and save the player diary. Should be -- called before any non-error exit from the game. Sometimes the backup -- file does not exist and it's OK. We don't bother reporting any other -- removal exceptions, either, because the backup file is relatively -- unimportant. We wait on the mvar, because saving the diary at game -- shutdown is important. rmBkpSaveDiary :: ConfigUI -> Diary -> IO () -- | Save the diary and a backup of the save game file, in case of crashes. -- This is only a backup, so no problem is the game is shut down before -- saving finishes, so we don't wait on the mvar. However, if a previous -- save is already in progress, we skip this save. saveGameBkp :: ConfigUI -> State -> Diary -> IO () -- | High score table operations. module Game.LambdaHack.Action.HighScore -- | Take care of saving a new score to the table and return a list of -- messages to display. register :: ConfigUI -> Bool -> Int -> Time -> ClockTime -> Status -> IO (Msg, [Overlay]) instance Eq ScoreRecord instance Ord ScoreRecord instance Binary ScoreRecord -- | Operations on the Actor type that need the State type, -- but not the Action type. TODO: Document an export list after -- it's rewritten according to #17. module Game.LambdaHack.ActorState -- | Checks whether an actor identifier represents a hero. isProjectile :: State -> ActorId -> Bool -- | Checks whether an actor identifier represents a hero. isAHero :: State -> ActorId -> Bool getPlayerBody :: State -> Actor -- | Finds an actor body on any level. Fails if not found. findActorAnyLevel :: ActorId -> State -> (LevelId, Actor, [Item]) -- | Calculate loot's worth for heroes on the current level. calculateTotal :: Ops ItemKind -> State -> ([Item], Int) -- | How long until an actor's smell vanishes from a tile. smellTimeout :: State -> Time -- | Create a set of initial heroes on the current level, at location ploc. initialHeroes :: COps -> Point -> ConfigUI -> State -> State -- | Removes a player from the current level. deletePlayer :: State -> State -- | The list of actors and their levels for all heroes in the dungeon. allHeroesAnyLevel :: State -> [ActorId] -- | Finds an actor at a location on the current level. Perception -- irrelevant. locToActor :: Point -> State -> Maybe ActorId -- | Removes the actor, if present, from the current level. deleteActor :: ActorId -> State -> State -- | Create a new hero on the current level, close to the given location. addHero :: COps -> Point -> ConfigUI -> State -> State -- | Create a new monster in the level, at a given position and with a -- given actor kind and HP. addMonster :: Ops TileKind -> Id ActorKind -> Int -> Point -> Id FactionKind -> Bool -> State -> State updateAnyActorItem :: ActorId -> ([Item] -> [Item]) -> State -> State -- | Add actor to the current level. insertActor :: ActorId -> Actor -> State -> State heroList :: State -> [Actor] -- | Checks if the actor is present on the current level. The order of -- argument here and in other functions is set to allow -- --
-- b <- gets (memActor a) --memActor :: ActorId -> State -> Bool -- | Gets actor body from the current level. Error if not found. getActor :: ActorId -> State -> Actor updateAnyActorBody :: ActorId -> (Actor -> Actor) -> State -> State hostileList :: State -> [Actor] -- | Gets actor's items from the current level. Empty list, if not found. getActorItem :: ActorId -> State -> [Item] getPlayerItem :: State -> [Item] tryFindHeroK :: State -> Int -> Maybe ActorId dangerousList :: State -> [Actor] factionList :: [Id FactionKind] -> State -> [Actor] -- | Create a projectile actor containing the given missile. addProjectile :: COps -> Item -> Point -> Id FactionKind -> [Point] -> Time -> State -> State foesAdjacent :: X -> Y -> Point -> [Actor] -> Bool -- | Calculate the location of player's target. targetToLoc :: IntSet -> State -> Point -> Maybe Point hostileAssocs :: Id FactionKind -> Level -> [(ActorId, Actor)] -- | Generation of places from place kinds. module Game.LambdaHack.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 -- cdefaultTile. type TileMapXY = Map PointXY (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 -> !Text -> !(Id TileKind) -> !(Id TileKind) -> Place qkind :: Place -> !(Id PlaceKind) qarea :: Place -> !Area qseen :: Place -> !Bool qlegend :: Place -> !Text qsolidFence :: Place -> !(Id TileKind) qhollowFence :: Place -> !(Id TileKind) -- | For CAlternate 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. placeValid :: Area -> PlaceKind -> Bool -- | Construct a fence around an area, with the given tile kind. buildFence :: Id TileKind -> Area -> TileMapXY -- | Given a few parameters, roll and construct a Place -- datastructure and fill a cave section acccording to it. buildPlace :: COps -> CaveKind -> Id TileKind -> Int -> Int -> Area -> Rnd (TileMapXY, Place) instance Show Place instance Binary Place -- | Generation of caves (not yet inhabited dungeon levels) from cave -- kinds. module Game.LambdaHack.Cave -- | The map of tile kinds in a cave. The map is sparse. The default tile -- that eventually fills the empty spaces is specified in the cave kind -- specification with cdefaultTile. type TileMapXY = TileMapXY -- | The map of starting secrecy strength of tiles in a cave. The map is -- sparse. Unspecified tiles have secrecy strength of 0. type SecretMapXY = Map PointXY SecretTime -- | The map of starting items in tiles of a cave. The map is sparse. -- Unspecified tiles have no starting items. type ItemMapXY = Map PointXY Item -- | The type of caves (not yet inhabited dungeon levels). data Cave Cave :: !(Id CaveKind) -> TileMapXY -> SecretMapXY -> ItemMapXY -> Text -> [Place] -> Cave -- | the kind of the cave dkind :: Cave -> !(Id CaveKind) -- | tile kinds in the cave dmap :: Cave -> TileMapXY -- | secrecy strength of cave tiles dsecret :: Cave -> SecretMapXY -- | starting items in the cave ditem :: Cave -> ItemMapXY -- | debug information about the cave dmeta :: Cave -> Text -- | places generated in the cave dplaces :: Cave -> [Place] -- | Cave generation by an algorithm inspired by the original Rogue, buildCave :: COps -> Int -> Int -> Id CaveKind -> Rnd Cave instance Show Cave -- | Dungeon operations that require State, COps or -- Config type. module Game.LambdaHack.DungeonState -- | Freshly generated and not yet populated dungeon. data FreshDungeon FreshDungeon :: LevelId -> Point -> Dungeon -> FreshDungeon -- | starting level for the party entryLevel :: FreshDungeon -> LevelId -- | starting location for the party entryLoc :: FreshDungeon -> Point -- | level maps freshDungeon :: FreshDungeon -> Dungeon -- | Generate the dungeon for a new game. generate :: COps -> Config -> Rnd FreshDungeon -- | Compute the level identifier and starting location on the level, after -- a level change. whereTo :: State -> Int -> Maybe (LevelId, Point) -- | Field Of View scanning with a variety of algorithms. See -- https://github.com/kosmikus/LambdaHack/wiki/Fov-and-los for -- discussion. module Game.LambdaHack.FOV -- | Perform a full scan for a given location. Returns the locations that -- are currently in the field of view. The Field of View algorithm to -- use, passed in the second argument, is set in the config file. fullscan :: Ops TileKind -> FovMode -> Point -> Level -> [Point] -- | Actors perceiving other actors and the dungeon level. module Game.LambdaHack.Perception -- | The type representing the perception for all levels in the dungeon. type DungeonPerception = [(LevelId, Perception)] -- | The type representing the perception of all actors on the level. -- -- Note: Heroes share visibility and only have separate reachability. The -- pplayer field must be void on all levels except where he resides. -- Right now, the field is used only for player-controlled monsters. data Perception -- | The set of tiles visible by at least one hero. totalVisible :: Perception -> IntSet -- | For debug only: the set of tiles reachable (would be visible if lit) -- by at least one hero. debugTotalReachable :: Perception -> IntSet -- | Calculate the perception of all actors on the level. dungeonPerception :: COps -> State -> DungeonPerception -- | Check whether a location is within the visually reachable area of the -- given actor (disregarding lighting). Defaults to false if the actor is -- not player-controlled (monster or hero). actorReachesLoc :: ActorId -> Point -> Perception -> Maybe ActorId -> Bool -- | Check whether an actor is within the visually reachable area of the -- given actor (disregarding lighting). Not quite correct if FOV not -- symmetric (e.g., Shadow). Defaults to false if neither actor -- is player-controlled. actorReachesActor :: ActorId -> ActorId -> Point -> Point -> Perception -> Maybe ActorId -> Bool -- | Whether an actor can see another. An approximation. actorSeesActor :: Ops TileKind -> Perception -> Level -> ActorId -> ActorId -> Point -> Point -> ActorId -> Bool -- | Game action monad and basic building blocks for player and monster -- actions. Exports liftIO for injecting IO into the -- Action monad, but does not export the implementation of the -- Action monad. The liftIO and handlerToIO operations are -- used only in Action.hs. module Game.LambdaHack.Action.ActionLift -- | The type of the function inside any action. (Separated from the -- Action type to document each argument with haddock.) type ActionFun r a = Session -> DungeonPerception -> (State -> Diary -> a -> IO r) -> (Msg -> IO r) -> State -> Diary -> IO r -- | Actions of player-controlled characters and of any other actors. data Action a liftIO :: IO a -> Action a -- | Run an action, with a given session, state and diary, in the -- IO monad. handlerToIO :: Session -> State -> Diary -> Action () -> IO () -- | Update the cached perception for the given computation. withPerception :: Action () -> Action () -- | Get the current perception. getPerception :: Action Perception -- | Actions and screen frames, including delays, resulting from performing -- the actions. type ActionFrame a = Action (a, [Maybe SingleFrame]) -- | Return the value with an empty set of screen frames. returnNoFrame :: a -> ActionFrame a -- | Return the trivial value with a single frame to show. returnFrame :: SingleFrame -> ActionFrame () -- | As the when monad operation, but on type ActionFrame -- (). whenFrame :: Bool -> ActionFrame () -> ActionFrame () -- | Inject action into actions with screen frames. inFrame :: Action () -> ActionFrame () -- | The information that is constant across a playing session, including -- many consecutive games in a single session, but is completely -- disregarded and reset when a new playing session starts. data Session Session :: FrontendSession -> COps -> Binding (ActionFrame ()) -> ConfigUI -> Session -- | frontend session information sfs :: Session -> FrontendSession -- | game content scops :: Session -> COps -- | binding of keys to commands sbinding :: Session -> Binding (ActionFrame ()) -- | the UI config for this session sconfigUI :: Session -> ConfigUI -- | Get the frontend session. getFrontendSession :: Action FrontendSession -- | Get the content operations. getCOps :: Action COps -- | Get the key binding. getBinding :: Action (Binding (ActionFrame ())) -- | Get the config from the config file. getConfigUI :: Action ConfigUI -- | Reset the state and resume from the last backup point, i.e., invoke -- the failure continuation. abort :: Action a -- | Abort with the given message. abortWith :: Msg -> Action a -- | Abort and print the given msg if the condition is true. abortIfWith :: Bool -> Msg -> Action a -- | Abort and conditionally print the fixed message. neverMind :: Bool -> Action a -- | Set the current exception handler. First argument is the handler, -- second is the computation the handler scopes over. tryWith :: (Msg -> Action a) -> Action a -> Action a -- | Take a handler and a computation. If the computation fails, the -- handler is invoked and then the computation is retried. tryRepeatedlyWith :: (Msg -> Action ()) -> Action () -> Action () -- | Try the given computation and silently catch failure. tryIgnore :: Action () -> Action () -- | Get the current diary. getDiary :: Action Diary -- | Add a message to the current report. msgAdd :: Msg -> Action () -- | Wipe out and set a new value for the history. historyReset :: History -> Action () -- | Wipe out and set a new value for the current report. msgReset :: Msg -> Action () instance MonadState State Action instance Functor Action instance Monad Action instance Show (Action a) -- | Display game data on the screen using one of the available frontends -- (determined at compile time with cabal flags). module Game.LambdaHack.Draw -- | Color mode for the display. data ColorMode -- | normal, with full colours ColorFull :: ColorMode -- | black+white only ColorBW :: ColorMode -- | Draw the whole screen: level map, status area and, at most, a single -- page overlay of text divided into lines. draw :: ColorMode -> COps -> Perception -> State -> Overlay -> SingleFrame -- | Render animations on top of the current screen frame. animate :: State -> Diary -> COps -> Perception -> Animation -> [Maybe SingleFrame] -- | Game action monad and basic building blocks for player and monster -- actions. Uses liftIO of the Action monad, but does -- not export it. Has no direct access to the Action monad -- implementation. module Game.LambdaHack.Action -- | Actions of player-controlled characters and of any other actors. data Action a -- | Get the current perception. getPerception :: Action Perception -- | Get the content operations. getCOps :: Action COps -- | Get the key binding. getBinding :: Action (Binding (ActionFrame ())) -- | Get the config from the config file. getConfigUI :: Action ConfigUI -- | Actions and screen frames, including delays, resulting from performing -- the actions. type ActionFrame a = Action (a, [Maybe SingleFrame]) -- | Return the value with an empty set of screen frames. returnNoFrame :: a -> ActionFrame a -- | Return the trivial value with a single frame to show. returnFrame :: SingleFrame -> ActionFrame () -- | As the when monad operation, but on type ActionFrame -- (). whenFrame :: Bool -> ActionFrame () -> ActionFrame () -- | Inject action into actions with screen frames. inFrame :: Action () -> ActionFrame () -- | Set the current exception handler. Apart of executing it, draw and -- pass along a frame with the abort message, if any. tryWithFrame :: Action a -> ActionFrame a -> ActionFrame a -- | Reset the state and resume from the last backup point, i.e., invoke -- the failure continuation. abort :: Action a -- | Abort with the given message. abortWith :: Msg -> Action a -- | Abort and print the given msg if the condition is true. abortIfWith :: Bool -> Msg -> Action a -- | Abort and conditionally print the fixed message. neverMind :: Bool -> Action a -- | Set the current exception handler. First argument is the handler, -- second is the computation the handler scopes over. tryWith :: (Msg -> Action a) -> Action a -> Action a -- | Take a handler and a computation. If the computation fails, the -- handler is invoked and then the computation is retried. tryRepeatedlyWith :: (Msg -> Action ()) -> Action () -> Action () -- | Try the given computation and silently catch failure. tryIgnore :: Action () -> Action () -- | Get the current diary. getDiary :: Action Diary -- | Add a message to the current report. msgAdd :: Msg -> Action () -- | Store current report in the history and reset report. recordHistory :: Action () -- | Wait for a player command. getKeyCommand :: Maybe Bool -> Action (Key, Modifier) -- | Display frame and wait for a player command. getKeyFrameCommand :: SingleFrame -> Action (Key, Modifier) -- | A series of confirmations for all overlays. getOverConfirm :: [SingleFrame] -> Action Bool -- | Display a msg with a more prompt. Return value indicates if -- the player tried to cancel/escape. displayMore :: ColorMode -> Msg -> Action 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 :: Msg -> Action Bool -- | Print a msg and several overlays, one per page. All frames require -- confirmations. Raise abort if the player presses ESC. displayOverAbort :: Msg -> [Overlay] -> Action () -- | Print a msg and several overlays, one per page. The last frame does -- not expect a confirmation and so does not show the invitation to press -- some keys. displayOverlays :: Msg -> Msg -> [Overlay] -> ActionFrame () -- | 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 ? cycles views, so the user can restart from the -- top). displayChoiceUI :: Msg -> [Overlay] -> [(Key, Modifier)] -> Action (Key, Modifier) -- | Push a frame or a single frame's worth of delay to the frame queue. displayFramePush :: Maybe SingleFrame -> Action () -- | Draw the current level. The prompt is displayed, but not added to -- history. The prompt is appended to the current message and only the -- first screenful of the resulting overlay is displayed. drawPrompt :: ColorMode -> Msg -> Action SingleFrame -- | Initialize perception, etc., display level and run the action. startClip :: Action () -> Action () -- | Update heroes memory. remember :: Action () -- | Update heroes memory at the given list of locations. rememberList :: [Point] -> Action () -- | Save the diary and a backup of the save game file, in case of crashes. -- -- See saveGameBkp. saveGameBkp :: Action () -- | Dumps the current game rules configuration to a file. dumpCfg :: FilePath -> Action () -- | Continue or restart or exit the game. endOrLoop :: Action () -> Action () -- | The name of the frontend. frontendName :: String -- | Wire together content, the definitions of game commands, config and a -- high-level startup function to form the starting game session. -- Evaluate to check for errors, in particular verify content -- consistency. Then create the starting game config from the default -- config file and initialize the engine with the starting session. startFrontend :: COps -> (ConfigUI -> Binding (ActionFrame ())) -> Action () -> IO () -- | Debugging. debug :: Text -> Action () -- | The effectToAction function and all it depends on. This file should -- not depend on Actions.hs nor ItemAction.hs. TODO: Add an export list -- and document after it's rewritten according to #17. module Game.LambdaHack.EffectAction -- | Sentences such as "Dog barks loudly." actorVerb :: Ops ActorKind -> Actor -> Text -> Text -- | Invoke pseudo-random computation with the generator kept in the state. rndToAction :: Rnd a -> Action a -- | Update actor stats. Works for actors on other levels, too. updateAnyActor :: ActorId -> (Actor -> Actor) -> Action () -- | Update player-controlled actor stats. updatePlayerBody :: (Actor -> Actor) -> Action () -- | The source actor affects the target actor, with a given effect and -- power. The second argument is verbosity of the resulting message. Both -- actors are on the current level and can be the same actor. The first -- bool result indicates if the effect was spectacular enough for the -- actors to identify it (and the item that caused it, if any). The -- second bool tells if the effect was seen by or affected the party. effectToAction :: Effect -> Int -> ActorId -> ActorId -> Int -> Bool -> Action (Bool, Bool) -- | The boolean part of the result says if the ation was interesting and -- the string part describes how the target reacted (not what the source -- did). eff :: Effect -> Int -> ActorId -> ActorId -> Int -> Action (Bool, Text) nullEffect :: Action (Bool, Text) squashActor :: ActorId -> ActorId -> Action () effLvlGoUp :: Int -> Action () -- | Change level and reset it's time and update the times of all actors. -- The player may be added to lactor of the new level only after -- this operation is executed. switchLevel :: LevelId -> Action () -- | The player leaves the dungeon. fleeDungeon :: Action () -- | The source actor affects the target actor, with a given item. If the -- event is seen, the item may get identified. itemEffectAction :: Int -> ActorId -> ActorId -> Item -> Bool -> Action () -- | Make the item known to the player. discover :: Item -> Action () -- | Make the actor controlled by the player. Switch level, if needed. -- False, if nothing to do. Should only be invoked as a direct result of -- a player action or the selected player actor death. selectPlayer :: ActorId -> Action Bool -- | Focus on the hero being woundeddisplacedetc. focusIfOurs :: ActorId -> Action Bool summonHeroes :: Int -> Point -> Action () summonMonsters :: Int -> Point -> Action () -- | Remove dead heroes (or dead dominated monsters). Check if game is -- over. For now we only check the selected hero and at current level, -- but if poison, etc. is implemented, we'd need to check all heroes on -- any level. checkPartyDeath :: Action () -- | End game, showing the ending screens, if requested. gameOver :: Bool -> Action () -- | Create a list of item names, split into many overlays. itemOverlay :: Bool -> Bool -> [Item] -> Action [Overlay] stopRunning :: Action () -- | Perform look around in the current location of the cursor. doLook :: ActionFrame () -- | The game action stuff that is independent from ItemAction.hs (both -- depend on EffectAction.hs). TODO: Add an export list and document -- after it's rewritten according to #17. module Game.LambdaHack.Actions gameSave :: Action () gameExit :: Action () gameRestart :: Action () moveCursor :: Vector -> Int -> ActionFrame () move :: Vector -> ActionFrame () ifRunning :: ((Vector, Int) -> Action a) -> Action a -> Action a -- | Guess and report why the bump command failed. guessBump :: Ops TileKind -> Feature -> Id TileKind -> Action () -- | Player tries to trigger a tile using a feature. bumpTile :: Point -> Feature -> Action () -- | Perform the action specified for the tile in case it's triggered. triggerTile :: Point -> Action () -- | Ask for a direction and trigger a tile, if possible. playerTriggerDir :: Feature -> Part -> Action () -- | Player tries to trigger a tile in a given direction. playerBumpDir :: Feature -> Vector -> Action () -- | Player tries to trigger the tile he's standing on. playerTriggerTile :: Feature -> Action () -- | An actor opens a door: player (hero or controlled monster) or enemy. actorOpenDoor :: ActorId -> Vector -> Action () -- | Change the displayed level in targeting mode to (at most) k levels -- shallower. Enters targeting mode, if not already in one. tgtAscend :: Int -> ActionFrame () heroesAfterPl :: Action [ActorId] -- | Switches current hero to the next hero on the level, if any, wrapping. -- We cycle through at most 10 heroes (@, 1--9). cycleHero :: Action () -- | Switches current hero to the previous hero in the whole dungeon, if -- any, wrapping. We cycle through at most 10 heroes (@, 1--9). backCycleHero :: Action () -- | Search for hidden doors. search :: Action () -- | This function performs a move (or attack) by any actor, i.e., it can -- handle monsters, heroes and both. moveOrAttack :: Bool -> ActorId -> Vector -> Action () -- | Resolves the result of an actor moving into another. Usually this -- involves melee attack, but with two heroes it just changes focus. -- Actors on blocked locations can be attacked without any restrictions. -- For instance, an actor embedded in a wall can be attacked from an -- adjacent position. This function is analogous to projectGroupItem, but -- for melee and not using up the weapon. actorAttackActor :: ActorId -> ActorId -> Action () -- | Resolves the result of an actor running (not walking) into another. -- This involves switching positions of the two actors. actorRunActor :: ActorId -> ActorId -> Action () -- | Create a new monster in the level, at a random position. rollMonster :: COps -> Perception -> State -> Rnd State -- | Generate a monster, possibly. generateMonster :: Action () -- | Possibly regenerate HP for all actors on the current level. regenerateLevelHP :: Action () -- | Display command help. displayHelp :: ActionFrame () -- | Display the main menu. displayMainMenu :: ActionFrame () displayHistory :: ActionFrame () dumpConfig :: Action () -- | Add new smell traces to the level. Only humans leave a strong scent. addSmell :: Action () -- | Update the wait/block count. setWaitBlock :: ActorId -> Action () -- | Player waits a turn (and blocks, etc.). waitBlock :: Action () -- | Running and disturbance. module Game.LambdaHack.Running -- | Start running in the given direction and with the given number of -- tiles already traversed (usually 0). The first turn of running -- succeeds much more often than subsequent turns, because most of the -- disturbances are ignored, since the player is aware of them and still -- explicitly requests a run. run :: (Vector, Int) -> ActionFrame () -- | This function implements the actual logic of running. It checks if we -- have to stop running because something interesting cropped up, it -- ajusts the direction given by the vector if we reached a corridor's -- corner (we never change direction except in corridors) and it -- increments the counter of traversed tiles. continueRun :: (Vector, Int) -> Action () -- | Item UI code with the Action type and everything it depends on -- that is not already in Action.hs and EffectAction.hs. This file should -- not depend on Actions.hs. TODO: Add an export list and document after -- it's rewritten according to #17. module Game.LambdaHack.ItemAction -- | Display inventory inventory :: ActionFrame () -- | Let the player choose any item with a given group name. Note that this -- does not guarantee the chosen item belongs to the group, as the player -- can override the choice. getGroupItem :: [Item] -> Part -> [Char] -> Text -> Text -> Action Item applyGroupItem :: ActorId -> Part -> Item -> Action () playerApplyGroupItem :: Part -> Part -> [Char] -> Action () projectGroupItem :: ActorId -> Point -> Part -> Item -> Action () playerProjectGroupItem :: Part -> Part -> [Char] -> ActionFrame () playerProjectGI :: Part -> Part -> [Char] -> ActionFrame () -- | Start the monster targeting mode. Cycle between monster targets. targetMonster :: TgtMode -> ActionFrame () -- | Start the floor targeting mode or reset the cursor location to the -- player. targetFloor :: TgtMode -> ActionFrame () -- | Set, activate and display cursor information. setCursor :: TgtMode -> ActionFrame () -- | Tweak the eps parameter of the targeting digital line. epsIncr :: Bool -> Action () -- | End targeting mode, accepting the current location or not. endTargeting :: Bool -> Action () endTargetingMsg :: Action () -- | Cancel something, e.g., targeting mode, resetting the cursor to the -- position of the player. Chosen target is not invalidated. cancelCurrent :: ActionFrame () -> ActionFrame () -- | Accept something, e.g., targeting mode, keeping cursor where it was. -- Or perform the default action, if nothing needs accepting. acceptCurrent :: ActionFrame () -> ActionFrame () -- | Clear current messages, show the next screen if any. clearCurrent :: Action () -- | Drop a single item. dropItem :: Action () removeOnlyFromInventory :: ActorId -> Item -> Point -> Action () -- | Remove given item from an actor's inventory or floor. TODO: this is -- subtly wrong: if identical items are on the floor and in inventory, -- the floor one will be chosen, regardless of player intention. TODO: -- right now it ugly hacks (with the ploc) around removing items of dead -- heros/monsters. The subtle incorrectness helps here a lot, because -- items of dead heroes land on the floor, so we use them up in -- inventory, but remove them after use from the floor. removeFromInventory :: ActorId -> Item -> Point -> Action () -- | Remove given item from the given location. Tell if successful. removeFromLoc :: Item -> Point -> Action Bool actorPickupItem :: ActorId -> Action () pickupItem :: Action () allObjectsName :: Text -- | Let the player choose any item from a list of items. getAnyItem :: Text -> [Item] -> Text -> Action Item data ItemDialogState INone :: ItemDialogState ISuitable :: ItemDialogState IAll :: ItemDialogState -- | Let the player choose a single, preferably suitable, item from a list -- of items. getItem :: Text -> (Item -> Bool) -> Text -> [Item] -> Text -> Action Item instance Eq ItemDialogState -- | Semantics of player commands. module Game.LambdaHack.CommandAction -- | The associaction of commands to keys defined in config. configCmds :: ConfigUI -> [(Key, Cmd)] -- | The list of semantics and other info for all commands from config. semanticsCmds :: [(Key, Cmd)] -> [((Key, Modifier), (Text, Bool, ActionFrame ()))] -- | Binding of keys to commands implemented with the Action monad. module Game.LambdaHack.BindingAction -- | Binding of keys to movement and other standard commands, as well as -- commands defined in the config file. stdBinding :: ConfigUI -> Binding (ActionFrame ()) -- | AI strategy operations implemented with the Action monad. module Game.LambdaHack.StrategyAction -- | AI proposes possible targets for the actor. Never empty. targetStrategy :: COps -> ActorId -> State -> Perception -> [Ability] -> Strategy Target -- | AI strategy based on actor's sight, smell, intelligence, etc. Never -- empty. strategy :: COps -> ActorId -> State -> [Ability] -> Strategy (Action ()) -- | The main loop of the game, processing player and AI moves turn by -- turn. module Game.LambdaHack.Turn -- | Start a clip (a part of a turn for which one or more frames will be -- generated). Do whatever has to be done every fixed number of time -- units, e.g., monster generation. Run the player and other actors -- moves. Eventually advance the time and repeat. handleTurn :: Action ()