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

90 lines
2.9 KiB
Haskell

{-
Explosions: creation of shockwave and particles at a given point.
-}
module Dodge.WorldEvent.Explosion (
makeExplosionAt,
makeFlameExplosionAt,
makePoisonExplosionAt,
makeTeslaExplosionAt,
) where
import Control.Monad
import Data.List
import Dodge.Data.World
import Dodge.EnergyBall
import Dodge.SoundLogic
import Dodge.WorldEvent.Shockwave
import Dodge.WorldEvent.SpawnParticle
import Geometry
import LensHelp
import Picture
import RandomHelp
makePoisonExplosionAt ::
-- | Position
Point2 ->
World ->
World
makePoisonExplosionAt p w =
soundMultiFrom [Explosion 0, Explosion 1] p bangS Nothing $
foldl' (flip $ makeGasCloud p) w $
replicateM 25 (randInCirc 2) & evalState $ _randGen w
-- just change the number after replicateM to get more or less clouds
-- suggested change: use random positions, offset from p, rather than velocities
-- so, p +.+ randomOffset
-- currently the clouds push away from each other rather hard if they are close
makeTeslaExplosionAt ::
-- | Position
Point2 ->
World ->
World
makeTeslaExplosionAt = undefined
-- soundOncePos grenadeBang pos $ foldr ($) w listOfFunctions -- a bit shorter
-- where
-- xs = randomRs (0, 2*pi) $ _randGen w
-- j = newProjectileKey w
-- pks = [j..]
-- listOfFunctions = map
-- (\i -> over projectiles (IM.insert (pks!!i) (makeTeslaArcAt (pks!!i) pos (xs!!i))))
-- [1 .. 29]
makeFlameExplosionAt ::
-- | Position
Point2 ->
World ->
World
makeFlameExplosionAt p w =
soundMultiFrom [Explosion 0, Explosion 1] p bangS Nothing w
& cWorld . lWorld . flames .++~ newFlames
where
newFlames = zipWith makeFlameWithVelAndTime velocities timers
makeFlameWithVelAndTime vel time = Flame time vel p
velocities = replicateM 15 (randInCirc 1) & evalState $ _randGen w
timers = randomRs (80, 100) $ _randGen w
-- the ( Nthing :: Maybe Int ) here is "maybe" a creature id that the
-- particle passes through for the first frame of its existence
makeExplosionAt :: Point2 -> Point2 -> World -> World
makeExplosionAt p vel w =
w
& soundMultiFrom [Explosion 0, Explosion 1] p bangS Nothing
& addFlames
& cWorld . lWorld . worldEvents
.:~ MakeTempLight (LSParam (addZ 20 p) 150 (V3 1 0.5 0)) 20
& makeShockwaveAt [] p 50 50 1 white
where
fVs = replicateM 100 (randInCirc 1) & evalState $ _randGen w
fPs' = replicateM 100 (randInCirc 5) & evalState $ _randGen w
fdamps = replicateM 100 (state $ randomR (0,1)) & evalState $ _randGen w
inversePushOut v = (15 - magV v) * 0.01 *.* v
fVs' = zipWith (+.+) fVs $ map inversePushOut fPs'
sizes = randomRs (2, 9) $ _randGen w
times = randomRs (15, 20) $ _randGen w
mF q v damp size time = makeFlamelet (q - (2*v + 2* vel)) (v + damp *.* vel) size time
newFs = zipWith4 (mF p) (zipWith (+) fPs' (fmap (3 *.*) fVs')) fdamps sizes times
addFlames w' = foldl' (flip ($)) w' newFs