module Dodge.Creature.Damage where import Color import Data.List import Dodge.Creature.Test import Dodge.Data.World import Dodge.Spark import Geometry import LensHelp applyNoDamage :: [Damage] -> Creature -> World -> World applyNoDamage _ _ = id applyCreatureDamage :: [Damage] -> Creature -> World -> World applyCreatureDamage dms cr = case _crMaterial cr of Flesh -> defaultApplyDamage dms cr Crystal -> id _ -> defaultApplyDamage dms cr defaultApplyDamage :: [Damage] -> Creature -> World -> World defaultApplyDamage ds cr w = foldl' (applyIndividualDamage cr) w ds' & cWorld . creatures . ix (_crID cr) %~ doPoisonDam where (ps, ds') = partition isPoison ds isPoison Damage{_dmType = POISONDAM} = True isPoison _ = False poisonDam = quot (max 0 (sum (map _dmAmount ps))) 10 doPoisonDam = crHP -~ poisonDam applyDamageEffect :: Damage -> DamageEffect -> Creature -> World -> World applyDamageEffect dm de cr w = case de of PushDamage push pushexp pushRad -> w & cWorld . creatures . ix (_crID cr) . crPos .+.+~ pushAmount *.* squashNormalizeV (_crPos cr -.- fromDir) where pushAmount | dist (_crPos cr) fromDir == 0 = 0 | otherwise = min 5 $ (push * 5 * pushRad / (dist (_crPos cr) fromDir * _crMass cr)) ** pushexp PushBackDamage pback -> w & cWorld . creatures . ix (_crID cr) . crPos .+.+~ (pback / _crMass cr) *.* (_dmTo dm -.- fromDir) TorqueDamage rot -> w & cWorld . creatures . ix (_crID cr) . crDir +~ rot NoDamageEffect -> w where fromDir = _dmFrom dm --p = _dmAt dm applyIndividualDamage :: Creature -> World -> Damage -> World applyIndividualDamage cr w dm = applyDamageEffect dm (_dmEffect dm) cr $ applyIndividualDamage' cr w dm applyIndividualDamage' :: Creature -> World -> Damage -> World applyIndividualDamage' cr w dm = case _dmType dm of PIERCING -> applyPiercingDamage cr dm w _ -> w & damageHP cr (_dmAmount dm) applyPiercingDamage :: Creature -> Damage -> World -> World applyPiercingDamage cr dm | crIsArmouredFrom p cr = colSpark (brightX 10 1.5 orange) p1 (argV (p1 -.- p)) | otherwise = damageHP cr $ _dmAmount dm where p = _dmAt dm p1 = p +.+ 2 *.* squashNormalizeV (p -.- _crPos cr) damageHP :: Creature -> Int -> World -> World damageHP cr x = cWorld . creatures . ix (_crID cr) %~ ( (crHP -~ x) . (crPastDamage +~ x) )