Files
loop/src/Dodge/WorldEvent/Flash.hs
T

115 lines
4.2 KiB
Haskell

module Dodge.WorldEvent.Flash
where
import Dodge.Data
import Dodge.Base
import Dodge.LightSources
import Dodge.WorldEvent.ThingsHit
import Dodge.WorldEvent.HelperParticle
import Picture
import Geometry
import Data.Maybe (maybeToList)
import Control.Lens
-- projected naming: three base types of light:
-- glare : "low lighting", draws lines around creatures and walls
-- flare : coloured light drawn on top of picture in fixed shapes
-- light : removal of shadows
-- duration (subject to modification):
-- flash : short, abrupt changes in alpha
-- glow : continuous, potentially long, fading, slow changes in alpha
-- flicker : potentially long, moving, abrupt changes in alpha
glareAt :: Int -> Float -> Float -> Color -> Float -> Int -> Float -> Point2 -> World -> World
glareAt t len wdth col alphay nrays rad p w = foldr (glareLine t len wdth col alphay p) w ps
where ps = map ((+.+) p) $ nRaysRad nrays rad
sparkFlashAt :: Point2 -> World -> World
sparkFlashAt p =
-- over particles' ((:) (flashFlareAt white 0.2 p))
glareAt 2 10 5 white 0.05 20 30 p
bloodFlashAt :: Point2 -> World -> World
bloodFlashAt p =
over particles' ((:) (flashFlareAt red 0.4 p))
. glareAt 2 10 5 red 0.05 20 30 p
teslaGunFlashAt :: Point2 -> World -> World
teslaGunFlashAt p =
over particles' ((:) (flashFlareAt cyan 0.3 p))
. glareAt 2 10 5 cyan 0.1 20 30 p
laserGunFlashAt :: Point2 -> World -> World
laserGunFlashAt p =
over particles' ((:) (flashFlareAt yellow 0.2 p))
. glareAt 2 10 5 yellow 0.05 20 30 p
glareLine :: Int -> Float -> Float -> Color -> Float -> Point2 -> Point2 -> World -> World
glareLine t len wdth col alphay a b w = w & particles' %~ (maybeToList linePt ++)
where linePt :: Maybe Particle'
linePt = glareBetween t len wdth col alphay a b w
glareBetween :: Int -> Float -> Float -> Color -> Float -> Point2 -> Point2 -> World -> Maybe Particle'
glareBetween 0 _ _ _ _ _ _ _ = Nothing
glareBetween t len wdth col alphay a b w
= Just $ Particle' {_ptPict' = lowLightPic len wdth col alphay a b w
,_ptUpdate' = \ w' _ -> (w',glareBetween (t-1) len wdth col alphay a b w')
}
lowLightPic :: Float -> Float -> Color -> Float -> Point2 -> Point2 -> World -> Picture
lowLightPic len wdth col alphay a b w
= case thingsHitLongLine a b w of
((p, E3x2 wall):_)
-> setCol . lineOfThickness wdth $ [p +.+ x, p -.- x]
where x = len *.* (normalizeV $ wa -.- wb)
(wa:wb:_) = _wlLine wall
((p, E3x1 cr):_)
-> setCol . uncurry translate cp . rotate (-0.25 * pi + argV (p -.- cp))
$ thickArc 0 (pi/2) (_crRad cr) wdth
where cp = _crPos cr
_ -> blank
where setCol = color (withAlpha alphay col) . setDepth (-0.5) . setLayer 2
flashFlareAt :: Color -> Float -> Point2 -> Particle'
flashFlareAt col alphax (x,y) =
Particle'
{ _ptPict' = setLayer 2 . setDepth (-0.9) . translate x y
$ circleSolidCol (withAlpha 0 col) (withAlpha alphax col) 30
, _ptUpdate' = ptTimer' 1
}
explosionFlashAt :: Point2 -> World -> World
explosionFlashAt p = over tempLightSources ((:) $ tLightFade 20 150 intensityFunc p)
. glareAt 20 10 5 white 0.3 75 150 p
where intensityFunc x
| x < 10 = 1 / (10 - fromIntegral x)
| otherwise = 1
flameGlareAt = glareAt 2 10 5 orange 0.05 8 50
lowLightDirected :: Color -> Float -> Point2 -> Point2 -> [Float] -> World -> World
lowLightDirected col alpha a b angles w
= foldr (\angle w' -> glareLine 2 10 5 col alpha a (a +.+ rotateV angle b) w') w angles
muzzleFlashAt :: Point2 -> World -> World
muzzleFlashAt p = over particles' ((:) (muzzleFlashPt p))
. glareAt 2 10 5 white 0.5 20 30 p
muzzleFlashPt :: Point2 -> Particle'
muzzleFlashPt (x,y) =
Particle'
{ _ptPict' = setDepth 0
. setLayer 2
. translate x y
$ circleSolidCol (withAlpha 0 white) (withAlpha 0.2 white) 20
, _ptUpdate' = ptTimer' 1
}
laserScopeTargetGlow :: Color -> Point2 -> World -> World
laserScopeTargetGlow col p = glareAt 2 3 1 col 0.1 15 5 p