56 lines
1.7 KiB
Haskell
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
|