-- | The type of kinds of monsters and heroes. module Game.LambdaHack.Content.ActorKind ( ActorKind(..), avalidate ) where import Control.Arrow ((&&&)) import qualified Data.List as L import qualified Data.Ord as Ord import Data.Text (Text) import Game.LambdaHack.Common.Ability import Game.LambdaHack.Common.Color import Game.LambdaHack.Common.Misc import qualified Game.LambdaHack.Common.Random as Random import Game.LambdaHack.Common.Time -- TODO: make all but a few fields optional in some way, so that, a.g., -- a game content with no regeneration does not ever need to mention aregen. -- | Actor properties that are fixed for a given kind of actors. data ActorKind = ActorKind { asymbol :: !Char -- ^ map symbol , aname :: !Text -- ^ short description , afreq :: !Freqs -- ^ frequency within groups , acolor :: !Color -- ^ map color , aspeed :: !Speed -- ^ natural speed in m/s , ahp :: !Random.RollDice -- ^ encodes initial and maximal hp , asight :: !Bool -- ^ can it see? , asmell :: !Bool -- ^ can it smell? , aiq :: !Int -- ^ intelligence , aregen :: !Int -- ^ number of turns to regenerate 1 HP , acanDo :: ![Ability] -- ^ the set of supported abilities } deriving Show -- No Eq and Ord to make extending it logically sound, see #53 -- | 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] avalidate l = let cmp = Ord.comparing $ asymbol &&& acolor eq ka1 ka2 = cmp ka1 ka2 == Ord.EQ sorted = L.sortBy cmp l nubbed = L.nubBy eq sorted in L.deleteFirstsBy eq sorted nubbed