{-# LANGUAGE DeriveGeneric #-}
module Game.LambdaHack.Content.TileKind
( TileKind(..), Feature(..)
, makeData
, isUknownSpace, unknownId
, isSuspectKind, isOpenableKind, isClosableKind
, talterForStairs, floorSymbol
#ifdef EXPOSE_INTERNAL
, validateSingle, validateAll
, validateDups, hardwiredTileGroups
#endif
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import Control.DeepSeq
import Data.Binary
import qualified Data.Char as Char
import Data.Hashable
import GHC.Generics (Generic)
import Game.LambdaHack.Content.ItemKind (ItemKind)
import Game.LambdaHack.Definition.Color
import Game.LambdaHack.Definition.ContentData
import Game.LambdaHack.Definition.Defs
data TileKind = TileKind
{ TileKind -> Char
tsymbol :: Char
, TileKind -> Text
tname :: Text
, TileKind -> Freqs TileKind
tfreq :: Freqs TileKind
, TileKind -> Color
tcolor :: Color
, TileKind -> Color
tcolor2 :: Color
, TileKind -> Word8
talter :: Word8
, TileKind -> [Feature]
tfeature :: [Feature]
}
deriving Int -> TileKind -> ShowS
[TileKind] -> ShowS
TileKind -> String
(Int -> TileKind -> ShowS)
-> (TileKind -> String) -> ([TileKind] -> ShowS) -> Show TileKind
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TileKind] -> ShowS
$cshowList :: [TileKind] -> ShowS
show :: TileKind -> String
$cshow :: TileKind -> String
showsPrec :: Int -> TileKind -> ShowS
$cshowsPrec :: Int -> TileKind -> ShowS
Show
data Feature =
Embed (GroupName ItemKind)
| OpenTo (GroupName TileKind)
| CloseTo (GroupName TileKind)
| ChangeTo (GroupName TileKind)
| HideAs (GroupName TileKind)
| BuildAs (GroupName TileKind)
| RevealAs (GroupName TileKind)
| ObscureAs (GroupName TileKind)
| Walkable
| Clear
| Dark
| OftenItem
| VeryOftenItem
| OftenActor
| NoItem
| NoActor
| ConsideredByAI
| Trail
| Spice
deriving (Int -> Feature -> ShowS
[Feature] -> ShowS
Feature -> String
(Int -> Feature -> ShowS)
-> (Feature -> String) -> ([Feature] -> ShowS) -> Show Feature
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Feature] -> ShowS
$cshowList :: [Feature] -> ShowS
show :: Feature -> String
$cshow :: Feature -> String
showsPrec :: Int -> Feature -> ShowS
$cshowsPrec :: Int -> Feature -> ShowS
Show, Feature -> Feature -> Bool
(Feature -> Feature -> Bool)
-> (Feature -> Feature -> Bool) -> Eq Feature
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Feature -> Feature -> Bool
$c/= :: Feature -> Feature -> Bool
== :: Feature -> Feature -> Bool
$c== :: Feature -> Feature -> Bool
Eq, Eq Feature
Eq Feature =>
(Feature -> Feature -> Ordering)
-> (Feature -> Feature -> Bool)
-> (Feature -> Feature -> Bool)
-> (Feature -> Feature -> Bool)
-> (Feature -> Feature -> Bool)
-> (Feature -> Feature -> Feature)
-> (Feature -> Feature -> Feature)
-> Ord Feature
Feature -> Feature -> Bool
Feature -> Feature -> Ordering
Feature -> Feature -> Feature
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Feature -> Feature -> Feature
$cmin :: Feature -> Feature -> Feature
max :: Feature -> Feature -> Feature
$cmax :: Feature -> Feature -> Feature
>= :: Feature -> Feature -> Bool
$c>= :: Feature -> Feature -> Bool
> :: Feature -> Feature -> Bool
$c> :: Feature -> Feature -> Bool
<= :: Feature -> Feature -> Bool
$c<= :: Feature -> Feature -> Bool
< :: Feature -> Feature -> Bool
$c< :: Feature -> Feature -> Bool
compare :: Feature -> Feature -> Ordering
$ccompare :: Feature -> Feature -> Ordering
$cp1Ord :: Eq Feature
Ord, (forall x. Feature -> Rep Feature x)
-> (forall x. Rep Feature x -> Feature) -> Generic Feature
forall x. Rep Feature x -> Feature
forall x. Feature -> Rep Feature x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Feature x -> Feature
$cfrom :: forall x. Feature -> Rep Feature x
Generic)
instance Binary Feature
instance Hashable Feature
instance NFData Feature
validateSingle :: TileKind -> [Text]
validateSingle :: TileKind -> [Text]
validateSingle t :: TileKind
t@TileKind{..} =
[ "suspect tile is walkable" | Feature
Walkable Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature
Bool -> Bool -> Bool
&& TileKind -> Bool
isSuspectKind TileKind
t ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "openable tile is open" | Feature
Walkable Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature
Bool -> Bool -> Bool
&& TileKind -> Bool
isOpenableKind TileKind
t ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "closable tile is closed" | Feature
Walkable Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Feature]
tfeature
Bool -> Bool -> Bool
&& TileKind -> Bool
isClosableKind TileKind
t ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "walkable tile is considered for triggering by AI"
| Feature
Walkable Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature
Bool -> Bool -> Bool
&& Feature
ConsideredByAI Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "trail tile not walkable" | Feature
Walkable Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Feature]
tfeature
Bool -> Bool -> Bool
&& Feature
Trail Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "OftenItem and NoItem on a tile" | Feature
OftenItem Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature
Bool -> Bool -> Bool
&& Feature
NoItem Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "OftenActor and NoActor on a tile" | Feature
OftenItem Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature
Bool -> Bool -> Bool
&& Feature
NoItem Feature -> [Feature] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Feature]
tfeature ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (let f :: Feature -> Bool
f :: Feature -> Bool
f OpenTo{} = Bool
True
f CloseTo{} = Bool
True
f ChangeTo{} = Bool
True
f _ = Bool
False
ts :: [Feature]
ts = (Feature -> Bool) -> [Feature] -> [Feature]
forall a. (a -> Bool) -> [a] -> [a]
filter Feature -> Bool
f [Feature]
tfeature
in [ "more than one OpenTo, CloseTo and ChangeTo specification"
| [Feature] -> Int
forall a. [a] -> Int
length [Feature]
ts Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 1 ])
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (let f :: Feature -> Bool
f :: Feature -> Bool
f HideAs{} = Bool
True
f _ = Bool
False
ts :: [Feature]
ts = (Feature -> Bool) -> [Feature] -> [Feature]
forall a. (a -> Bool) -> [a] -> [a]
filter Feature -> Bool
f [Feature]
tfeature
in ["more than one HideAs specification" | [Feature] -> Int
forall a. [a] -> Int
length [Feature]
ts Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 1])
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (let f :: Feature -> Bool
f :: Feature -> Bool
f BuildAs{} = Bool
True
f _ = Bool
False
ts :: [Feature]
ts = (Feature -> Bool) -> [Feature] -> [Feature]
forall a. (a -> Bool) -> [a] -> [a]
filter Feature -> Bool
f [Feature]
tfeature
in ["more than one BuildAs specification" | [Feature] -> Int
forall a. [a] -> Int
length [Feature]
ts Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 1])
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (Feature -> [Text]) -> [Feature] -> [Text]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (TileKind -> Feature -> [Text]
validateDups TileKind
t)
[ Feature
Walkable, Feature
Clear, Feature
Dark, Feature
OftenItem, Feature
OftenActor, Feature
NoItem, Feature
NoActor
, Feature
ConsideredByAI, Feature
Trail, Feature
Spice ]
validateDups :: TileKind -> Feature -> [Text]
validateDups :: TileKind -> Feature -> [Text]
validateDups TileKind{..} feat :: Feature
feat =
let ts :: [Feature]
ts = (Feature -> Bool) -> [Feature] -> [Feature]
forall a. (a -> Bool) -> [a] -> [a]
filter (Feature -> Feature -> Bool
forall a. Eq a => a -> a -> Bool
== Feature
feat) [Feature]
tfeature
in ["more than one" Text -> Text -> Text
<+> Feature -> Text
forall a. Show a => a -> Text
tshow Feature
feat Text -> Text -> Text
<+> "specification" | [Feature] -> Int
forall a. [a] -> Int
length [Feature]
ts Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 1]
validateAll :: ContentData ItemKind -> [TileKind] -> ContentData TileKind
-> [Text]
validateAll :: ContentData ItemKind
-> [TileKind] -> ContentData TileKind -> [Text]
validateAll coitem :: ContentData ItemKind
coitem content :: [TileKind]
content cotile :: ContentData TileKind
cotile =
let g :: Feature -> Maybe (GroupName TileKind)
g :: Feature -> Maybe (GroupName TileKind)
g (OpenTo grp :: GroupName TileKind
grp) = GroupName TileKind -> Maybe (GroupName TileKind)
forall a. a -> Maybe a
Just GroupName TileKind
grp
g (CloseTo grp :: GroupName TileKind
grp) = GroupName TileKind -> Maybe (GroupName TileKind)
forall a. a -> Maybe a
Just GroupName TileKind
grp
g (ChangeTo grp :: GroupName TileKind
grp) = GroupName TileKind -> Maybe (GroupName TileKind)
forall a. a -> Maybe a
Just GroupName TileKind
grp
g (HideAs grp :: GroupName TileKind
grp) = GroupName TileKind -> Maybe (GroupName TileKind)
forall a. a -> Maybe a
Just GroupName TileKind
grp
g (BuildAs grp :: GroupName TileKind
grp) = GroupName TileKind -> Maybe (GroupName TileKind)
forall a. a -> Maybe a
Just GroupName TileKind
grp
g (RevealAs grp :: GroupName TileKind
grp) = GroupName TileKind -> Maybe (GroupName TileKind)
forall a. a -> Maybe a
Just GroupName TileKind
grp
g (ObscureAs grp :: GroupName TileKind
grp) = GroupName TileKind -> Maybe (GroupName TileKind)
forall a. a -> Maybe a
Just GroupName TileKind
grp
g _ = Maybe (GroupName TileKind)
forall a. Maybe a
Nothing
missingTileGroups :: [(Text, [GroupName TileKind])]
missingTileGroups =
[ (TileKind -> Text
tname TileKind
k, [GroupName TileKind]
absGroups)
| TileKind
k <- [TileKind]
content
, let grps :: [GroupName TileKind]
grps = (Feature -> Maybe (GroupName TileKind))
-> [Feature] -> [GroupName TileKind]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Feature -> Maybe (GroupName TileKind)
g ([Feature] -> [GroupName TileKind])
-> [Feature] -> [GroupName TileKind]
forall a b. (a -> b) -> a -> b
$ TileKind -> [Feature]
tfeature TileKind
k
absGroups :: [GroupName TileKind]
absGroups = (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]
grps
, Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GroupName TileKind] -> Bool
forall a. [a] -> Bool
null [GroupName TileKind]
absGroups
]
h :: Feature -> Maybe (GroupName ItemKind)
h :: Feature -> Maybe (GroupName ItemKind)
h (Embed grp :: GroupName ItemKind
grp) = GroupName ItemKind -> Maybe (GroupName ItemKind)
forall a. a -> Maybe a
Just GroupName ItemKind
grp
h _ = Maybe (GroupName ItemKind)
forall a. Maybe a
Nothing
missingItemGroups :: [(Text, [GroupName ItemKind])]
missingItemGroups =
[ (TileKind -> Text
tname TileKind
k, [GroupName ItemKind]
absGroups)
| TileKind
k <- [TileKind]
content
, let grps :: [GroupName ItemKind]
grps = (Feature -> Maybe (GroupName ItemKind))
-> [Feature] -> [GroupName ItemKind]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Feature -> Maybe (GroupName ItemKind)
h ([Feature] -> [GroupName ItemKind])
-> [Feature] -> [GroupName ItemKind]
forall a b. (a -> b) -> a -> b
$ TileKind -> [Feature]
tfeature TileKind
k
absGroups :: [GroupName ItemKind]
absGroups = (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]
grps
, Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GroupName ItemKind] -> Bool
forall a. [a] -> Bool
null [GroupName ItemKind]
absGroups
]
missingHardwiredGroups :: [GroupName TileKind]
missingHardwiredGroups =
(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]
hardwiredTileGroups
in [ "unknown tile (the first) should be the unknown one"
| TileKind -> Word8
talter ([TileKind] -> TileKind
forall a. [a] -> a
head [TileKind]
content) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= 1 Bool -> Bool -> Bool
|| TileKind -> Text
tname ([TileKind] -> TileKind
forall a. [a] -> a
head [TileKind]
content) Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= "unknown space" ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "no tile other than the unknown (the first) should require skill 1"
| (TileKind -> Bool) -> [TileKind] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\tk :: TileKind
tk -> TileKind -> Word8
talter TileKind
tk Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 1) ([TileKind] -> [TileKind]
forall a. [a] -> [a]
tail [TileKind]
content) ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "only unknown tile may have talter 1"
| (TileKind -> Bool) -> [TileKind] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 1) (Word8 -> Bool) -> (TileKind -> Word8) -> TileKind -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TileKind -> Word8
talter) ([TileKind] -> Bool) -> [TileKind] -> Bool
forall a b. (a -> b) -> a -> b
$ [TileKind] -> [TileKind]
forall a. [a] -> [a]
tail [TileKind]
content ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "mentioned tile groups not in content:" Text -> Text -> Text
<+> [(Text, [GroupName TileKind])] -> Text
forall a. Show a => a -> Text
tshow [(Text, [GroupName TileKind])]
missingTileGroups
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [(Text, [GroupName TileKind])] -> Bool
forall a. [a] -> Bool
null [(Text, [GroupName TileKind])]
missingTileGroups ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "embedded item groups not in content:" Text -> Text -> Text
<+> [(Text, [GroupName ItemKind])] -> Text
forall a. Show a => a -> Text
tshow [(Text, [GroupName ItemKind])]
missingItemGroups
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [(Text, [GroupName ItemKind])] -> Bool
forall a. [a] -> Bool
null [(Text, [GroupName ItemKind])]
missingItemGroups ]
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [ "hardwired groups not in content:" Text -> Text -> Text
<+> [GroupName TileKind] -> Text
forall a. Show a => a -> Text
tshow [GroupName TileKind]
missingHardwiredGroups
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [GroupName TileKind] -> Bool
forall a. [a] -> Bool
null [GroupName TileKind]
missingHardwiredGroups ]
hardwiredTileGroups :: [GroupName TileKind]
hardwiredTileGroups :: [GroupName TileKind]
hardwiredTileGroups =
[ "unknown space", "legendLit", "legendDark", "unknown outer fence"
, "basic outer fence" ]
isUknownSpace :: ContentId TileKind -> Bool
{-# INLINE isUknownSpace #-}
isUknownSpace :: ContentId TileKind -> Bool
isUknownSpace tt :: ContentId TileKind
tt = Word16 -> ContentId TileKind
forall c. Word16 -> ContentId c
toContentId 0 ContentId TileKind -> ContentId TileKind -> Bool
forall a. Eq a => a -> a -> Bool
== ContentId TileKind
tt
unknownId :: ContentId TileKind
{-# INLINE unknownId #-}
unknownId :: ContentId TileKind
unknownId = Word16 -> ContentId TileKind
forall c. Word16 -> ContentId c
toContentId 0
isSuspectKind :: TileKind -> Bool
isSuspectKind :: TileKind -> Bool
isSuspectKind t :: TileKind
t =
let getTo :: Feature -> Bool
getTo RevealAs{} = Bool
True
getTo ObscureAs{} = Bool
True
getTo _ = Bool
False
in (Feature -> Bool) -> [Feature] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Feature -> Bool
getTo ([Feature] -> Bool) -> [Feature] -> Bool
forall a b. (a -> b) -> a -> b
$ TileKind -> [Feature]
tfeature TileKind
t
isOpenableKind :: TileKind -> Bool
isOpenableKind :: TileKind -> Bool
isOpenableKind t :: TileKind
t =
let getTo :: Feature -> Bool
getTo OpenTo{} = Bool
True
getTo _ = Bool
False
in (Feature -> Bool) -> [Feature] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Feature -> Bool
getTo ([Feature] -> Bool) -> [Feature] -> Bool
forall a b. (a -> b) -> a -> b
$ TileKind -> [Feature]
tfeature TileKind
t
isClosableKind :: TileKind -> Bool
isClosableKind :: TileKind -> Bool
isClosableKind t :: TileKind
t =
let getTo :: Feature -> Bool
getTo CloseTo{} = Bool
True
getTo _ = Bool
False
in (Feature -> Bool) -> [Feature] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Feature -> Bool
getTo ([Feature] -> Bool) -> [Feature] -> Bool
forall a b. (a -> b) -> a -> b
$ TileKind -> [Feature]
tfeature TileKind
t
talterForStairs :: Word8
talterForStairs :: Word8
talterForStairs = 3
floorSymbol :: Char.Char
floorSymbol :: Char
floorSymbol = Int -> Char
Char.chr 183
makeData :: ContentData ItemKind -> [TileKind] -> ContentData TileKind
makeData :: ContentData ItemKind -> [TileKind] -> ContentData TileKind
makeData coitem :: ContentData ItemKind
coitem =
String
-> (TileKind -> Text)
-> (TileKind -> Freqs TileKind)
-> (TileKind -> [Text])
-> ([TileKind] -> ContentData TileKind -> [Text])
-> [TileKind]
-> ContentData TileKind
forall c.
Show c =>
String
-> (c -> Text)
-> (c -> Freqs c)
-> (c -> [Text])
-> ([c] -> ContentData c -> [Text])
-> [c]
-> ContentData c
makeContentData "TileKind" TileKind -> Text
tname TileKind -> Freqs TileKind
tfreq TileKind -> [Text]
validateSingle (ContentData ItemKind
-> [TileKind] -> ContentData TileKind -> [Text]
validateAll ContentData ItemKind
coitem)