Files
loop/src/Dodge/Damage.hs
T
2025-06-08 21:15:05 +01:00

56 lines
1.7 KiB
Haskell

{-# LANGUAGE LambdaCase #-}
module Dodge.Damage (
damageCrWl,
damageDirection,
damageCrWlID,
maxDamageType,
) where
import Dodge.Data.Damage.Type
import Geometry.Vector
import ListHelp
import Dodge.Data.CrWlID
import Dodge.Data.World
import qualified IntMapHelp as IM
import LensHelp
import qualified Data.Map.Strict as M
import FoldableHelp
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]
-- could sort for damage amount as well
damageDirection :: [Damage] -> Maybe Float
damageDirection ds = safeArgV =<< safeHead (ds ^.. each . dmVector)
dmType :: Damage -> DamageType
dmType = \case
Piercing {} -> PhysicalDamage
Blunt {} -> PhysicalDamage
Sparking {} -> CookingDamage
Crushing {} -> PhysicalDamage
Shattering {} -> PhysicalDamage
Flaming {} -> CookingDamage
Lasering {} -> CookingDamage
Flashing {} -> CookingDamage
Electrical {} -> CookingDamage
Explosive {} -> PhysicalDamage
Poison {} -> PoisonDamage
Enterrement {} -> PhysicalDamage
collectDamageTypes :: [Damage] -> M.Map DamageType Int
collectDamageTypes = foldl' (flip f) M.empty
where
f dm = at (dmType dm) . non 0 +~ _dmAmount dm
maxDamageType :: [Damage] -> Maybe (DamageType, Int)
maxDamageType = safeMinimumOn (negate . snd) . M.assocs . collectDamageTypes