module Dodge.Shockwave.Update where import Dodge.Creature.Radius import Data.Foldable import Dodge.Base.Collide import Dodge.Data.World import Dodge.Wall.Damage import Dodge.Zoning.Wall import Geometry.Vector import qualified IntMapHelp as IM import LensHelp updateShockwave :: World -> Shockwave -> (World, Maybe Shockwave) updateShockwave w sw = case _swDirection sw of OutwardShockwave -> moveShockwave w sw InwardShockwave -> moveInverseShockwave w sw moveShockwave :: World -> Shockwave -> (World, Maybe Shockwave) moveShockwave w sw | _swTimer sw <= 0 = (w, Nothing) | otherwise = (doDams w, Just $ sw & swTimer -~ 1) where is = _swInvulnerableCrs sw r = _swRad sw p = _swPos sw push = _swPush sw dam = _swDam sw t = _swTimer sw tFraction = fromIntegral t / fromIntegral (_swMaxTime sw) rad = r - (3 / 4) * r * tFraction doDams w' = over (cWorld . lWorld . creatures) (IM.map damCr) $ foldl' (flip $ damageWall (Damage EXPLOSIVE 1000 p p p NoDamageEffect)) w' hitBlocks hitBlocks = map snd . overlapCircWalls p rad $ wlsNearCirc p rad w -- this is not expansive enough damCr cr | _crID cr `elem` is || dist (_crPos cr) p >= rad + crRad (cr ^. crType) = cr | otherwise = cr & crState . csDamage .:~ Damage CONCUSSIVE dam (cpos -.- v) cpos (cpos +.+ v) (PushBackDamage (25 * push)) where cpos = _crPos cr v = normalizeV (cpos -.- p) moveInverseShockwave :: World -> Shockwave -> (World, Maybe Shockwave) moveInverseShockwave w sw | t <= 0 = (w, Nothing) | otherwise = (dams w, Just $ swTimer -~ 1 $ sw) where p = _swPos sw r = _swRad sw t = _swTimer sw rad = r - 0.1 * r * fromIntegral (10 - t) dams = over (cWorld . lWorld . creatures) (IM.map damCr) -- . flip (foldr (damageBlocksBy 1)) hitBlocks -- hitBlocks = wallsOnCirc' p rad $ wallsNearPoint' p w damCr cr | dist (_crPos cr) p >= rad + crRad (cr ^. crType) = cr | otherwise = cr & crState . csDamage .:~ Damage CONCUSSIVE 1 (cpos +.+ v) cpos (cpos -.- v) (PushBackDamage 25) where cpos = _crPos cr v = normalizeV (cpos -.- p)