{-# LANGUAGE DeriveGeneric #-}
module Game.LambdaHack.Common.Ability
( Ability(..), Skills
, zeroSkills, unitSkills, addSkills, scaleSkills, tacticSkills
, blockOnly, meleeAdjacent, meleeAndRanged, ignoreItems
) where
import Prelude ()
import Game.LambdaHack.Common.Prelude
import Control.DeepSeq
import Data.Binary
import qualified Data.EnumMap.Strict as EM
import Data.Hashable (Hashable)
import GHC.Generics (Generic)
import Game.LambdaHack.Common.Misc
data Ability =
AbMove
| AbMelee
| AbDisplace
| AbAlter
| AbWait
| AbMoveItem
| AbProject
| AbApply
deriving (Eq, Ord, Generic, Enum, Bounded)
type Skills = EM.EnumMap Ability Int
zeroSkills :: Skills
zeroSkills = EM.empty
unitSkills :: Skills
unitSkills = EM.fromDistinctAscList $ zip [minBound..maxBound] (repeat 1)
addSkills :: Skills -> Skills -> Skills
addSkills = EM.unionWith (+)
scaleSkills :: Int -> Skills -> Skills
scaleSkills n = EM.map (n *)
tacticSkills :: Tactic -> Skills
tacticSkills TExplore = zeroSkills
tacticSkills TFollow = zeroSkills
tacticSkills TFollowNoItems = ignoreItems
tacticSkills TMeleeAndRanged = meleeAndRanged
tacticSkills TMeleeAdjacent = meleeAdjacent
tacticSkills TBlock = blockOnly
tacticSkills TRoam = zeroSkills
tacticSkills TPatrol = zeroSkills
minusTen, blockOnly, meleeAdjacent, meleeAndRanged, ignoreItems :: Skills
minusTen = EM.fromDistinctAscList $ zip [minBound..maxBound] (repeat (-10))
blockOnly = EM.delete AbWait minusTen
meleeAdjacent = EM.delete AbMelee blockOnly
meleeAndRanged = EM.delete AbProject meleeAdjacent
ignoreItems = EM.fromList $ zip [AbMoveItem, AbProject, AbApply] (repeat (-10))
instance Show Ability where
show AbMove = "move"
show AbMelee = "melee"
show AbDisplace = "displace"
show AbAlter = "alter tile"
show AbWait = "wait"
show AbMoveItem = "manage items"
show AbProject = "fling"
show AbApply = "apply"
instance NFData Ability
instance Binary Ability where
put = putWord8 . toEnum . fromEnum
get = fmap (toEnum . fromEnum) getWord8
instance Hashable Ability