module Dodge.Particle.HitEffect.Penetrate where
import Dodge.Data
import Dodge.Particle.Update
import Dodge.Particle.HitEffect.ExpireAndDamage
import Geometry
--import LensHelp

import Data.Bifunctor
import Streaming
import qualified Streaming.Prelude as S

penetrate 
    :: ((Point2,Either Creature Wall) -> Particle -> Maybe Particle) 
        -- | penetration test, can update particle if it penetrates
    -> (Particle -> Point2 -> [Damage]) -- | damages when penetrating
    -> (Particle -> Point2 -> [Damage]) -- | damages when not penetrating
    -> Particle
    -> Stream (Of (Point2, Either Creature Wall)) Identity ()
    -> World
    -> (World, Maybe Particle)
penetrate t pendam stopdam pt hitThings w = case runIdentity $ S.uncons hitThings of
    Nothing -> (w, mvPt pt)
    Just (x,xs) -> case t x pt of
        Nothing -> expireAndDamage stopdam pt hitThings w
        Just pt' -> first (doDamages pendam x pt) $ penetrate t pendam stopdam pt' xs w
