sheet-parser-hs/lib/DND/Sheet/Parser.hs

74 lines
2.6 KiB
Haskell
Raw Normal View History

module DND.Sheet.Parser
2023-11-13 23:49:04 +01:00
( parseSheet
, createExample
, getStat
2024-11-19 10:41:25 +01:00
, getSkill
2024-12-01 17:35:24 +01:00
, getSkillMod
, getStatMod
, getSaveMod
2024-11-19 10:41:25 +01:00
, getProficiency
2024-12-01 17:35:24 +01:00
, scoreMod
) where
2024-12-01 17:35:24 +01:00
--import Control.Monad
2024-11-18 17:24:26 +01:00
import Data.Aeson
import qualified Data.ByteString.Lazy as B
2024-12-01 17:35:24 +01:00
--import qualified Data.ByteString.Lazy.UTF8 as BSU
2024-11-18 17:24:26 +01:00
import Data.Maybe (fromJust)
import DND.Bob (bob)
import DND.Sheet.Content
2024-11-19 10:41:25 +01:00
import qualified Data.Map as Map
parseSheet :: FilePath -> IO Character
2023-11-13 23:49:04 +01:00
parseSheet x = unwrap . decode =<< B.readFile x
where unwrap (Just y) = return y
unwrap Nothing = error $ "Failed to parse character sheet: " ++ x
createExample :: FilePath -> IO ()
createExample = flip encodeFile bob
getStat :: Character -> String -> Stat
getStat char s = head . filter (\a -> statName a == s) . stats $ char
2024-11-19 10:41:25 +01:00
getSkill :: Character -> String -> Skill
getSkill char s = head . filter (\a -> skillName a == s) . skills $ char
getProficiency :: Character -> Int
getProficiency = fromJust . flip Map.lookup profTable . charLevel . preamble
-- https://www.nerdsandscoundrels.com/how-to-calculate-proficiency-bonus-5e/
2024-12-01 17:35:24 +01:00
-- for some fucking reason there appears to be no simple mathematical way to
-- get a character's proficiency bonus
2024-11-19 10:41:25 +01:00
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
2024-12-01 17:35:24 +01:00
-- (stat.Score - 10) / 2
scoreMod :: Int -> Int
scoreMod x = div (x - 10) 2
2024-11-19 10:41:25 +01:00
2024-12-01 17:35:24 +01:00
getSkillMod :: Character -> String -> Int
getSkillMod char skillString = let
2024-11-19 10:41:25 +01:00
skill = getSkill char skillString
2024-12-01 17:35:24 +01:00
stat = getStat char $ skillStat skill
prof = getProficiency char
2024-11-19 10:41:25 +01:00
modifier = case skillMod skill of
Proficient -> prof
Expertise -> prof * 2
Half -> div prof 2
None -> 0
2024-12-01 17:35:24 +01:00
in (modifier +) . scoreMod . statScore $ stat
getStatMod :: Character -> String -> Int
getStatMod char statString = scoreMod $ statScore (getStat char statString)
getSaveMod :: Character -> String -> Int
getSaveMod char statString = let stat = getStat char statString
modifier = if statProf stat then getProficiency char else 0
in (modifier +) . scoreMod . statScore $ stat