100 lines
2.8 KiB
Haskell
100 lines
2.8 KiB
Haskell
{-# LANGUAGE LambdaCase #-}
|
|
|
|
module Dodge.EnergyBall (
|
|
updateEnergyBall,
|
|
makeFlamelet,
|
|
makeMovingEB,
|
|
) where
|
|
|
|
import Data.Maybe
|
|
import Dodge.Base.Collide
|
|
import Dodge.Damage
|
|
import Dodge.Data.World
|
|
import Dodge.SoundLogic
|
|
import Dodge.Spark
|
|
import Geometry
|
|
import LensHelp
|
|
import Linear.V3
|
|
import Picture
|
|
import RandomHelp
|
|
|
|
makeFlamelet :: Point3 -> Point3 -> Float -> Int -> World -> World
|
|
makeFlamelet p v s t =
|
|
cWorld . lWorld . energyBalls
|
|
.:~ EnergyBall
|
|
{ _ebVel = v
|
|
, _ebPos = p
|
|
, _ebTimer = t
|
|
, _ebType = FlameletBall s
|
|
}
|
|
|
|
updateEnergyBall :: World -> EnergyBall -> (World, Maybe EnergyBall)
|
|
updateEnergyBall w eb
|
|
| _ebTimer eb <= 0 = (w, Nothing)
|
|
| otherwise =
|
|
( ebEffect eb . ebFlicker eb $ ebDamage (eb ^. ebPos) (_ebType eb) w
|
|
, Just $ eb & ebTimer -~ 1 & ebPos . _xy .~ bp & ebVel . _xy .~ drag * bv
|
|
)
|
|
where
|
|
drag = case eb ^. ebType of
|
|
ExplosiveBall -> 0.9
|
|
_ -> 0.85
|
|
p = (eb ^. ebPos + eb ^. ebVel) ^. _xy
|
|
(bp, bv) = fromMaybe (p, eb ^. ebVel . _xy) $ bouncePoint (const True) 0 (eb ^. ebPos . _xy) p w
|
|
|
|
ebEffect :: EnergyBall -> World -> World
|
|
ebEffect eb = case _ebType eb of
|
|
ElectricalBall i ->
|
|
soundContinue (EBSound i) (eb ^. ebPos . _xy) elecCrackleS (Just 2)
|
|
. randSparkExtraVel
|
|
(eb ^. ebVel . _xy)
|
|
ElectricSpark
|
|
(state (randomR (3, 6)))
|
|
(state (randomR (0, 2 * pi)))
|
|
(eb ^. ebPos . _xy)
|
|
IncendiaryBall{}
|
|
| _ebTimer eb == 20 ->
|
|
soundStart (EBSound (-1)) (eb ^. ebPos . _xy) fireFadeS Nothing
|
|
_ -> id
|
|
|
|
makeMovingEB :: Point2 -> EnergyBallType -> Point2 -> World -> World
|
|
makeMovingEB v ebt p =
|
|
cWorld . lWorld . energyBalls
|
|
.:~ EnergyBall
|
|
{ _ebVel = v `v2z` 0
|
|
, _ebPos = p `v2z` 20
|
|
, _ebTimer = 20
|
|
, _ebType = ebt
|
|
}
|
|
|
|
ebFlicker :: EnergyBall -> World -> World
|
|
ebFlicker pt
|
|
| _ebTimer pt `mod` 7 == 0 =
|
|
cWorld . lWorld . lights
|
|
.:~ LSParam (pt ^. ebPos) 70 (0.5 * xyzV4 (ebColor pt))
|
|
| otherwise = id
|
|
|
|
ebColor :: EnergyBall -> Color
|
|
ebColor eb = case eb ^. ebType of
|
|
IncendiaryBall{} -> red
|
|
FlameletBall{} -> red
|
|
ElectricalBall{} -> cyan
|
|
ExplosiveBall -> white
|
|
FlashBall -> white
|
|
|
|
ebDamage :: Point3 -> EnergyBallType -> World -> World
|
|
ebDamage sp dt
|
|
| z > 0 && z < 25 = damageInCircle (const $ ebtToDamage (sp ^. _xy) dt) (sp ^. _xy) r
|
|
| otherwise = id
|
|
where
|
|
z = sp ^. _z
|
|
r = fromMaybe 5 $ dt ^? fbSize
|
|
|
|
ebtToDamage :: Point2 -> EnergyBallType -> Damage
|
|
ebtToDamage p = \case
|
|
FlameletBall{} -> Flaming 1
|
|
IncendiaryBall{} -> Flaming 10
|
|
ElectricalBall{} -> Electrical 10
|
|
ExplosiveBall -> Explosive 10 p
|
|
FlashBall -> Flashing 10 p
|