{-# LANGUAGE DeriveGeneric #-} -- | The type of game rule sets and assorted game data. module Game.LambdaHack.Content.RuleKind ( RuleKind(..), makeData #ifdef EXPOSE_INTERNAL -- * Internal operations , validateSingle, validateAll #endif ) where import Prelude () import Game.LambdaHack.Common.Prelude import Control.DeepSeq import qualified Data.Text as T import Data.Version import GHC.Generics (Generic) import Game.LambdaHack.Common.ContentData -- | The type of game rule sets and assorted game data. -- -- In principle, it'se possible to have many rule sets -- and switch between them during a game session or even a single game. data RuleKind = RuleKind { rsymbol :: Char -- ^ a symbol , rname :: Text -- ^ short description , rfreq :: Freqs RuleKind -- ^ frequency within groups , rtitle :: Text -- ^ title of the game (not lib) , rfontDir :: FilePath -- ^ font directory for the game (not lib) , rexeVersion :: Version -- ^ version of the game , rcfgUIName :: FilePath -- ^ name of the UI config file , rcfgUIDefault :: String -- ^ the default UI settings config file , rmainMenuArt :: Text -- ^ the ASCII art for the main menu , rintroScreen :: [String] -- ^ the intro screen (first help screen) text , rfirstDeathEnds :: Bool -- ^ whether first non-spawner actor death -- ends the game , rwriteSaveClips :: Int -- ^ game is saved that often (not on browser) , rleadLevelClips :: Int -- ^ server switches leader level that often , rscoresFile :: FilePath -- ^ name of the scores file , rnearby :: Int -- ^ what distance between actors is 'nearby' } deriving Generic -- | A dummy instance of the 'Show' class, to satisfy general requirments -- about content. We won't don't expect to ever print out whole rule sets. instance Show RuleKind where show _ = "The game ruleset specification." instance NFData RuleKind -- | Catch invalid rule kind definitions. validateSingle :: RuleKind -> [Text] validateSingle RuleKind{rmainMenuArt} = let ts = T.lines rmainMenuArt tsNot110 = filter ((/= 110) . T.length) ts in case tsNot110 of [] -> [ "rmainMenuArt doesn't have 60 lines, but " <> tshow (length ts) | length ts /= 60] tNot110 : _ -> ["rmainMenuArt has a line with length other than 110:" <> tNot110] -- | Since we have only one rule kind, the set of rule kinds is always valid. validateAll :: [RuleKind] -> ContentData RuleKind -> [Text] validateAll _ _ = [] makeData :: [RuleKind] -> ContentData RuleKind makeData = makeContentData "RuleKind" rname rfreq validateSingle validateAll