{-# LANGUAGE LambdaCase #-} module Dodge.Damage ( damageCrWl , damageDirection , damageCrWlID , maxDamageType ) where import qualified Data.Map.Strict as M import Dodge.Data.CrWlID import Dodge.Data.World import FoldableHelp import Geometry.Vector import LensHelp import qualified IntMapHelp as IM damageCrWlID :: Damage -> CrWlID -> World -> World damageCrWlID dam = \case NothingID -> id CrID cid -> cWorld . lWorld . creatures . ix cid . crState . csDamage .:~ dam WlID wlid -> cWorld . lWorld . wallDamages %~ IM.insertWith (++) wlid [dam] damageCrWl :: Damage -> Either Creature Wall -> World -> World damageCrWl dt (Left cr) = cWorld . lWorld . creatures . ix (_crID cr) . crState . csDamage .:~ dt damageCrWl dt (Right wl) = cWorld . lWorld . wallDamages %~ IM.insertWith (++) (_wlID wl) [dt] damageDirection :: [Damage] -> Maybe Float damageDirection ds = do dm <- safeMinimumOn (negate . _dmAmount) ds safeArgV (_dmTo dm -.- _dmFrom dm) collectDamageTypes :: [Damage] -> M.Map DamageType Int collectDamageTypes = foldl' (flip f) M.empty where f dm = M.insertWith (+) (_dmType dm) (_dmAmount dm) maxDamageType :: [Damage] -> Maybe (DamageType, Int) maxDamageType = safeMinimumOn (negate . snd) . M.assocs . collectDamageTypes