-- | The type of cave kinds.
module Game.LambdaHack.Content.CaveKind
  ( CaveKind(..), makeData
#ifdef EXPOSE_INTERNAL
    -- * Internal operations
  , validateSingle, validateAll
#endif
  ) where

import Prelude ()

import Game.LambdaHack.Core.Prelude

import qualified Data.Text as T

import           Game.LambdaHack.Content.ItemKind (ItemKind)
import           Game.LambdaHack.Content.PlaceKind (PlaceKind)
import           Game.LambdaHack.Content.TileKind (TileKind)
import qualified Game.LambdaHack.Core.Dice as Dice
import           Game.LambdaHack.Core.Random
import           Game.LambdaHack.Definition.ContentData
import           Game.LambdaHack.Definition.Defs

-- | Parameters for the generation of dungeon levels.
-- Warning: for efficiency, avoid embedded items in any of the common tiles.
data CaveKind = CaveKind
  { CaveKind -> Char
csymbol         :: Char             -- ^ a symbol
  , CaveKind -> Text
cname           :: Text             -- ^ short description
  , CaveKind -> Freqs CaveKind
cfreq           :: Freqs CaveKind   -- ^ frequency within groups
  , CaveKind -> X
cXminSize       :: X                -- ^ minimal X size of the whole cave
  , CaveKind -> X
cYminSize       :: Y                -- ^ minimal Y size of the whole cave
  , CaveKind -> DiceXY
ccellSize       :: Dice.DiceXY      -- ^ size of a map cell holding a place
  , CaveKind -> DiceXY
cminPlaceSize   :: Dice.DiceXY      -- ^ minimal size of places; for merging
  , CaveKind -> DiceXY
cmaxPlaceSize   :: Dice.DiceXY      -- ^ maximal size of places; for growing
  , CaveKind -> Dice
cdarkOdds       :: Dice.Dice        -- ^ the odds a place is dark
                                        --   (level-scaled dice roll > 50)
  , CaveKind -> Dice
cnightOdds      :: Dice.Dice        -- ^ the odds the cave is dark
                                        --   (level-scaled dice roll > 50)
  , CaveKind -> Rational
cauxConnects    :: Rational         -- ^ a proportion of extra connections
  , CaveKind -> Rational
cmaxVoid        :: Rational
      -- ^ at most this proportion of rooms may be void
  , CaveKind -> X
cminStairDist   :: Int              -- ^ minimal distance between stairs
  , CaveKind -> Dice
cextraStairs    :: Dice.Dice        -- ^ extra stairs on top of from above
  , CaveKind -> Rational
cdoorChance     :: Chance           -- ^ the chance of a door in an opening
  , CaveKind -> Rational
copenChance     :: Chance           -- ^ if there's a door, is it open?
  , CaveKind -> X
chidden         :: Int              -- ^ if not open, hidden one in n times
  , CaveKind -> X
cactorCoeff     :: Int              -- ^ the lower, the more monsters spawn
  , CaveKind -> Freqs ItemKind
cactorFreq      :: Freqs ItemKind   -- ^ actor groups to consider
  , CaveKind -> Dice
citemNum        :: Dice.Dice        -- ^ number of initial items in the cave
  , CaveKind -> Freqs ItemKind
citemFreq       :: Freqs ItemKind   -- ^ item groups to consider
  , CaveKind -> Freqs PlaceKind
cplaceFreq      :: Freqs PlaceKind  -- ^ place groups to consider
  , CaveKind -> Bool
cpassable       :: Bool
      -- ^ are passable default tiles permitted
  , CaveKind -> Bool
labyrinth       :: Bool                -- ^ waste of time for AI to explore
  , CaveKind -> GroupName TileKind
cdefTile        :: GroupName TileKind  -- ^ the default cave tile
  , CaveKind -> GroupName TileKind
cdarkCorTile    :: GroupName TileKind  -- ^ the dark cave corridor tile
  , CaveKind -> GroupName TileKind
clitCorTile     :: GroupName TileKind  -- ^ the lit cave corridor tile
  , CaveKind -> GroupName TileKind
cwallTile       :: GroupName TileKind  -- ^ the tile used for @FWall@ fence
  , CaveKind -> GroupName TileKind
ccornerTile     :: GroupName TileKind  -- ^ tile used for the fence corners
  , CaveKind -> GroupName TileKind
cfenceTileN     :: GroupName TileKind  -- ^ the outer fence N wall
  , CaveKind -> GroupName TileKind
cfenceTileE     :: GroupName TileKind  -- ^ the outer fence E wall
  , CaveKind -> GroupName TileKind
cfenceTileS     :: GroupName TileKind  -- ^ the outer fence S wall
  , CaveKind -> GroupName TileKind
cfenceTileW     :: GroupName TileKind  -- ^ the outer fence W wall
  , CaveKind -> Bool
cfenceApart     :: Bool                -- ^ are places touching fence banned
  , CaveKind -> GroupName TileKind
clegendDarkTile :: GroupName TileKind  -- ^ the dark place plan legend
  , CaveKind -> GroupName TileKind
clegendLitTile  :: GroupName TileKind  -- ^ the lit place plan legend
  , CaveKind -> Freqs PlaceKind
cescapeFreq     :: Freqs PlaceKind     -- ^ escape groups, if any
  , CaveKind -> Freqs PlaceKind
cstairFreq      :: Freqs PlaceKind     -- ^ place groups for created stairs
  , CaveKind -> Freqs PlaceKind
cstairAllowed   :: Freqs PlaceKind     -- ^ extra groups for inherited
  , CaveKind -> Text
cdesc           :: Text                -- ^ full cave description
  }
  deriving X -> CaveKind -> ShowS
[CaveKind] -> ShowS
CaveKind -> String
(X -> CaveKind -> ShowS)
-> (CaveKind -> String) -> ([CaveKind] -> ShowS) -> Show CaveKind
forall a.
(X -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CaveKind] -> ShowS
$cshowList :: [CaveKind] -> ShowS
show :: CaveKind -> String
$cshow :: CaveKind -> String
showsPrec :: X -> CaveKind -> ShowS
$cshowsPrec :: X -> CaveKind -> ShowS
Show  -- No Eq and Ord to make extending logically sound

-- | Catch caves with not enough space for all the places. Check the size
-- of the cave descriptions to make sure they fit on screen. Etc.
validateSingle :: CaveKind -> [Text]
validateSingle :: CaveKind -> [Text]
validateSingle CaveKind{..} =
  let (minCellSizeX :: X
minCellSizeX, minCellSizeY :: X
minCellSizeY) = DiceXY -> (X, X)
Dice.infDiceXY DiceXY
ccellSize
      (minMinSizeX :: X
minMinSizeX, minMinSizeY :: X
minMinSizeY) = DiceXY -> (X, X)
Dice.infDiceXY DiceXY
cminPlaceSize
      (maxMinSizeX :: X
maxMinSizeX, maxMinSizeY :: X
maxMinSizeY) = DiceXY -> (X, X)
Dice.supDiceXY DiceXY
cminPlaceSize
      (minMaxSizeX :: X
minMaxSizeX, minMaxSizeY :: X
minMaxSizeY) = DiceXY -> (X, X)
Dice.infDiceXY DiceXY
cmaxPlaceSize
  in [ "cname longer than 25" | Text -> X
T.length Text
cname X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 25 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "cXminSize < 20" | X
cXminSize X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 20 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "cYminSize < 20" | X
cYminSize X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 20 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minCellSizeX < 1" | X
minCellSizeX X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 1 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minCellSizeY < 1" | X
minCellSizeY X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 1 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minCellSizeX < 6 && stairs"
        | X
minCellSizeX X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 6 Bool -> Bool -> Bool
&& Bool -> Bool
not (Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cstairFreq Bool -> Bool -> Bool
&& Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cescapeFreq) ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minCellSizeY < 4 && stairs"
        | X
minCellSizeY X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 4 Bool -> Bool -> Bool
&& Bool -> Bool
not (Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cstairFreq Bool -> Bool -> Bool
&& Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cescapeFreq) ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minMinSizeX < 5 && stairs"
        | X
minMinSizeX X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 5 Bool -> Bool -> Bool
&& Bool -> Bool
not (Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cstairFreq Bool -> Bool -> Bool
&& Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cescapeFreq) ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minMinSizeY < 3 && stairs"
        | X
minMinSizeY X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 3 Bool -> Bool -> Bool
&& Bool -> Bool
not (Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cstairFreq Bool -> Bool -> Bool
&& Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cescapeFreq) ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minMinSizeX < 1" | X
minMinSizeX X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 1 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minMinSizeY < 1" | X
minMinSizeY X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 1 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minMaxSizeX < maxMinSizeX" | X
minMaxSizeX X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< X
maxMinSizeX ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "minMaxSizeY < maxMinSizeY" | X
minMaxSizeY X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< X
maxMinSizeY ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "cextraStairs < 0" | Dice -> X
Dice.infDice Dice
cextraStairs X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 0 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "chidden < 0" | X
chidden X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 0 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "cactorCoeff < 0" | X
cactorCoeff X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 0 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "citemNum < 0" | Dice -> X
Dice.infDice Dice
citemNum X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< 0 ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "stairs suggested, but not defined"
        | Dice -> X
Dice.supDice Dice
cextraStairs X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0 Bool -> Bool -> Bool
&& Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
cstairFreq ]

-- | Validate all cave kinds.
-- Note that names don't have to be unique: we can have several variants
-- of a cave with a given name.
validateAll :: ContentData ItemKind
            -> ContentData PlaceKind
            -> ContentData TileKind
            -> [CaveKind]
            -> ContentData CaveKind
            -> [Text]
validateAll :: ContentData ItemKind
-> ContentData PlaceKind
-> ContentData TileKind
-> [CaveKind]
-> ContentData CaveKind
-> [Text]
validateAll coitem :: ContentData ItemKind
coitem coplace :: ContentData PlaceKind
coplace cotile :: ContentData TileKind
cotile content :: [CaveKind]
content cocave :: ContentData CaveKind
cocave =
  let missingActorFreq :: [GroupName ItemKind]
missingActorFreq = (GroupName ItemKind -> Bool)
-> [GroupName ItemKind] -> [GroupName ItemKind]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (GroupName ItemKind -> Bool) -> GroupName ItemKind -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContentData ItemKind -> GroupName ItemKind -> Bool
forall a. ContentData a -> GroupName a -> Bool
omemberGroup ContentData ItemKind
coitem)
                         ([GroupName ItemKind] -> [GroupName ItemKind])
-> [GroupName ItemKind] -> [GroupName ItemKind]
forall a b. (a -> b) -> a -> b
$ (CaveKind -> [GroupName ItemKind])
-> [CaveKind] -> [GroupName ItemKind]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((GroupName ItemKind, X) -> GroupName ItemKind)
-> Freqs ItemKind -> [GroupName ItemKind]
forall a b. (a -> b) -> [a] -> [b]
map (GroupName ItemKind, X) -> GroupName ItemKind
forall a b. (a, b) -> a
fst (Freqs ItemKind -> [GroupName ItemKind])
-> (CaveKind -> Freqs ItemKind) -> CaveKind -> [GroupName ItemKind]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CaveKind -> Freqs ItemKind
cactorFreq) [CaveKind]
content
      missingItemFreq :: [GroupName ItemKind]
missingItemFreq = (GroupName ItemKind -> Bool)
-> [GroupName ItemKind] -> [GroupName ItemKind]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (GroupName ItemKind -> Bool) -> GroupName ItemKind -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContentData ItemKind -> GroupName ItemKind -> Bool
forall a. ContentData a -> GroupName a -> Bool
omemberGroup ContentData ItemKind
coitem)
                        ([GroupName ItemKind] -> [GroupName ItemKind])
-> [GroupName ItemKind] -> [GroupName ItemKind]
forall a b. (a -> b) -> a -> b
$ (CaveKind -> [GroupName ItemKind])
-> [CaveKind] -> [GroupName ItemKind]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((GroupName ItemKind, X) -> GroupName ItemKind)
-> Freqs ItemKind -> [GroupName ItemKind]
forall a b. (a -> b) -> [a] -> [b]
map (GroupName ItemKind, X) -> GroupName ItemKind
forall a b. (a, b) -> a
fst (Freqs ItemKind -> [GroupName ItemKind])
-> (CaveKind -> Freqs ItemKind) -> CaveKind -> [GroupName ItemKind]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CaveKind -> Freqs ItemKind
citemFreq) [CaveKind]
content
      missingPlaceFreq :: [GroupName PlaceKind]
missingPlaceFreq = (GroupName PlaceKind -> Bool)
-> [GroupName PlaceKind] -> [GroupName PlaceKind]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (GroupName PlaceKind -> Bool) -> GroupName PlaceKind -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContentData PlaceKind -> GroupName PlaceKind -> Bool
forall a. ContentData a -> GroupName a -> Bool
omemberGroup ContentData PlaceKind
coplace)
                         ([GroupName PlaceKind] -> [GroupName PlaceKind])
-> [GroupName PlaceKind] -> [GroupName PlaceKind]
forall a b. (a -> b) -> a -> b
$ (CaveKind -> [GroupName PlaceKind])
-> [CaveKind] -> [GroupName PlaceKind]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((GroupName PlaceKind, X) -> GroupName PlaceKind)
-> Freqs PlaceKind -> [GroupName PlaceKind]
forall a b. (a -> b) -> [a] -> [b]
map (GroupName PlaceKind, X) -> GroupName PlaceKind
forall a b. (a, b) -> a
fst (Freqs PlaceKind -> [GroupName PlaceKind])
-> (CaveKind -> Freqs PlaceKind)
-> CaveKind
-> [GroupName PlaceKind]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CaveKind -> Freqs PlaceKind
cplaceFreq) [CaveKind]
content
      missingEscapeGroup :: Freqs PlaceKind
missingEscapeGroup = ((GroupName PlaceKind, X) -> Bool)
-> Freqs PlaceKind -> Freqs PlaceKind
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((GroupName PlaceKind, X) -> Bool)
-> (GroupName PlaceKind, X)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContentData PlaceKind -> GroupName PlaceKind -> Bool
forall a. ContentData a -> GroupName a -> Bool
omemberGroup ContentData PlaceKind
coplace (GroupName PlaceKind -> Bool)
-> ((GroupName PlaceKind, X) -> GroupName PlaceKind)
-> (GroupName PlaceKind, X)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GroupName PlaceKind, X) -> GroupName PlaceKind
forall a b. (a, b) -> a
fst)
                           (Freqs PlaceKind -> Freqs PlaceKind)
-> Freqs PlaceKind -> Freqs PlaceKind
forall a b. (a -> b) -> a -> b
$ (CaveKind -> Freqs PlaceKind) -> [CaveKind] -> Freqs PlaceKind
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CaveKind -> Freqs PlaceKind
cescapeFreq [CaveKind]
content
      missingStairFreq :: [GroupName PlaceKind]
missingStairFreq = (GroupName PlaceKind -> Bool)
-> [GroupName PlaceKind] -> [GroupName PlaceKind]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (GroupName PlaceKind -> Bool) -> GroupName PlaceKind -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContentData PlaceKind -> GroupName PlaceKind -> Bool
forall a. ContentData a -> GroupName a -> Bool
omemberGroup ContentData PlaceKind
coplace)
                         ([GroupName PlaceKind] -> [GroupName PlaceKind])
-> [GroupName PlaceKind] -> [GroupName PlaceKind]
forall a b. (a -> b) -> a -> b
$ (CaveKind -> [GroupName PlaceKind])
-> [CaveKind] -> [GroupName PlaceKind]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((GroupName PlaceKind, X) -> GroupName PlaceKind)
-> Freqs PlaceKind -> [GroupName PlaceKind]
forall a b. (a -> b) -> [a] -> [b]
map (GroupName PlaceKind, X) -> GroupName PlaceKind
forall a b. (a, b) -> a
fst (Freqs PlaceKind -> [GroupName PlaceKind])
-> (CaveKind -> Freqs PlaceKind)
-> CaveKind
-> [GroupName PlaceKind]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CaveKind -> Freqs PlaceKind
cstairFreq) [CaveKind]
content
      tileGroupFuns :: [CaveKind -> GroupName TileKind]
tileGroupFuns = [ CaveKind -> GroupName TileKind
cdefTile, CaveKind -> GroupName TileKind
cdarkCorTile, CaveKind -> GroupName TileKind
clitCorTile, CaveKind -> GroupName TileKind
cwallTile
                      , CaveKind -> GroupName TileKind
cfenceTileN, CaveKind -> GroupName TileKind
cfenceTileE, CaveKind -> GroupName TileKind
cfenceTileS, CaveKind -> GroupName TileKind
cfenceTileW
                      , CaveKind -> GroupName TileKind
clegendDarkTile, CaveKind -> GroupName TileKind
clegendLitTile ]
      g :: CaveKind -> [GroupName TileKind]
g kind :: CaveKind
kind = ((CaveKind -> GroupName TileKind) -> GroupName TileKind)
-> [CaveKind -> GroupName TileKind] -> [GroupName TileKind]
forall a b. (a -> b) -> [a] -> [b]
map ((CaveKind -> GroupName TileKind) -> CaveKind -> GroupName TileKind
forall a b. (a -> b) -> a -> b
$ CaveKind
kind) [CaveKind -> GroupName TileKind]
tileGroupFuns
      missingTileFreq :: [GroupName TileKind]
missingTileFreq = (GroupName TileKind -> Bool)
-> [GroupName TileKind] -> [GroupName TileKind]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (GroupName TileKind -> Bool) -> GroupName TileKind -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContentData TileKind -> GroupName TileKind -> Bool
forall a. ContentData a -> GroupName a -> Bool
omemberGroup ContentData TileKind
cotile)
                        ([GroupName TileKind] -> [GroupName TileKind])
-> [GroupName TileKind] -> [GroupName TileKind]
forall a b. (a -> b) -> a -> b
$ (CaveKind -> [GroupName TileKind])
-> [CaveKind] -> [GroupName TileKind]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CaveKind -> [GroupName TileKind]
g [CaveKind]
content
  in [ "cactorFreq item groups not in content:" Text -> Text -> Text
<+> [GroupName ItemKind] -> Text
forall a. Show a => a -> Text
tshow [GroupName ItemKind]
missingActorFreq
     | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GroupName ItemKind] -> Bool
forall a. [a] -> Bool
null [GroupName ItemKind]
missingActorFreq ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "citemFreq item groups not in content:" Text -> Text -> Text
<+> [GroupName ItemKind] -> Text
forall a. Show a => a -> Text
tshow [GroupName ItemKind]
missingItemFreq
        | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GroupName ItemKind] -> Bool
forall a. [a] -> Bool
null [GroupName ItemKind]
missingItemFreq ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "cplaceFreq place groups not in content:" Text -> Text -> Text
<+> [GroupName PlaceKind] -> Text
forall a. Show a => a -> Text
tshow [GroupName PlaceKind]
missingPlaceFreq
        | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GroupName PlaceKind] -> Bool
forall a. [a] -> Bool
null [GroupName PlaceKind]
missingPlaceFreq ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "cescapeFreq place groups not in content:"
          Text -> Text -> Text
<+> Freqs PlaceKind -> Text
forall a. Show a => a -> Text
tshow Freqs PlaceKind
missingEscapeGroup
        | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Freqs PlaceKind -> Bool
forall a. [a] -> Bool
null Freqs PlaceKind
missingEscapeGroup ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "cstairFreq place groups not in content:" Text -> Text -> Text
<+> [GroupName PlaceKind] -> Text
forall a. Show a => a -> Text
tshow [GroupName PlaceKind]
missingStairFreq
        | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GroupName PlaceKind] -> Bool
forall a. [a] -> Bool
null [GroupName PlaceKind]
missingStairFreq ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "tile groups not in content:" Text -> Text -> Text
<+> [GroupName TileKind] -> Text
forall a. Show a => a -> Text
tshow [GroupName TileKind]
missingTileFreq
        | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GroupName TileKind] -> Bool
forall a. [a] -> Bool
null [GroupName TileKind]
missingTileFreq ]
     [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "no cave defined for \"default random\""
        | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ ContentData CaveKind -> GroupName CaveKind -> Bool
forall a. ContentData a -> GroupName a -> Bool
omemberGroup ContentData CaveKind
cocave "default random" ]

makeData :: ContentData ItemKind
         -> ContentData PlaceKind
         -> ContentData TileKind
         -> [CaveKind]
         -> ContentData CaveKind
makeData :: ContentData ItemKind
-> ContentData PlaceKind
-> ContentData TileKind
-> [CaveKind]
-> ContentData CaveKind
makeData coitem :: ContentData ItemKind
coitem coplace :: ContentData PlaceKind
coplace cotile :: ContentData TileKind
cotile =
  String
-> (CaveKind -> Text)
-> (CaveKind -> Freqs CaveKind)
-> (CaveKind -> [Text])
-> ([CaveKind] -> ContentData CaveKind -> [Text])
-> [CaveKind]
-> ContentData CaveKind
forall c.
Show c =>
String
-> (c -> Text)
-> (c -> Freqs c)
-> (c -> [Text])
-> ([c] -> ContentData c -> [Text])
-> [c]
-> ContentData c
makeContentData "CaveKind" CaveKind -> Text
cname CaveKind -> Freqs CaveKind
cfreq CaveKind -> [Text]
validateSingle
                  (ContentData ItemKind
-> ContentData PlaceKind
-> ContentData TileKind
-> [CaveKind]
-> ContentData CaveKind
-> [Text]
validateAll ContentData ItemKind
coitem ContentData PlaceKind
coplace ContentData TileKind
cotile)