diff --git a/lib/DND/Sheet/Parser.hs b/lib/DND/Sheet/Parser.hs index 29a0620..877cbd3 100644 --- a/lib/DND/Sheet/Parser.hs +++ b/lib/DND/Sheet/Parser.hs @@ -1,11 +1,13 @@ module DND.Sheet.Parser ( parseSheet ---, getSheet -, listSkills , createExample , getName , getStat -, listSkillNames +, getSkill +, getSkillNames +, getStatNames +, getSkillScore +, getProficiency ) where import Control.Monad @@ -15,21 +17,13 @@ import qualified Data.ByteString.Lazy.UTF8 as BSU import Data.Maybe (fromJust) import DND.Bob (bob) import DND.Sheet.Content - ---getSheet :: FilePath -> IO B.ByteString ---getSheet = B.readFile +import qualified Data.Map as Map parseSheet :: FilePath -> IO Character parseSheet x = unwrap . decode =<< B.readFile x where unwrap (Just y) = return y unwrap Nothing = error $ "Failed to parse character sheet: " ++ x -listSkills :: Character -> [Skill] -listSkills = join . map skills . stats - -listSkillNames :: Character -> IO () -listSkillNames = mapM_ (putStrLn . skillName) . listSkills - createExample :: FilePath -> IO () createExample = flip encodeFile bob @@ -38,3 +32,40 @@ getName = charName . preamble getStat :: Character -> String -> Stat getStat char s = head . filter (\a -> statName a == s) . stats $ char + +getSkill :: Character -> String -> Skill +getSkill char s = head . filter (\a -> skillName a == s) . skills $ char + +getSkillNames :: Character -> [String] +getSkillNames = map skillStat . skills + +getStatNames :: Character -> [String] +getStatNames = map statName . stats + +getProficiency :: Character -> Int +getProficiency = fromJust . flip Map.lookup profTable . charLevel . preamble + -- https://www.nerdsandscoundrels.com/how-to-calculate-proficiency-bonus-5e/ + -- for some fucking reason there appears to be no simple mathematical way to get a character's proficiency bonus + where profTable = Map.fromList + [ (1,2), (2,2), (3,2), (4,2) + , (5,3), (6,3), (7,3), (8,3) + , (9,4), (10,4), (11,4), (12,4) + , (13,5), (14,5), (15,5), (16,5) + , (17,6), (18,6), (19,6), (20,6) + ] + +-- https://worldbuildersjunction.com/dungeon-and-dragons-ability-scores-explained-for-beginners/ +-- from the Go implementation +-- return (stat.Score - 10) / 2 + +getSkillScore :: Character -> String -> Int +getSkillScore char skillString = let + skill = getSkill char skillString + stat = getStat char $ skillStat skill + prof = getProficiency char + modifier = case skillMod skill of + Proficient -> prof + Expertise -> prof * 2 + Half -> div prof 2 + None -> 0 + in (modifier +) . (`div` 2) $ statScore stat - 10 diff --git a/sheet-parser-hs.cabal b/sheet-parser-hs.cabal index b03ea5f..3666132 100644 --- a/sheet-parser-hs.cabal +++ b/sheet-parser-hs.cabal @@ -68,6 +68,7 @@ library , bytestring , utf8-string , random + , containers hs-source-dirs: lib