83 lines
2.6 KiB
Haskell
83 lines
2.6 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 Linear
|
|
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 ::
|
|
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
|
|
|
|
makeExplosionAt :: Point3 -> Point3 -> World -> World
|
|
makeExplosionAt p vel w =
|
|
w
|
|
& soundStart (Explosion (w ^. cWorld . lWorld . lClock)) (p ^. _xy) bangS Nothing
|
|
& addFlames
|
|
& cWorld . lWorld . worldEvents .:~ MakeTempLight (LSParam p 150 (V3 1 0.5 0)) 20
|
|
& makeShockwaveAt [] p 50 100 1 white
|
|
where
|
|
fVs = fmap (`v2z` 0) $ replicateM 100 (randInCirc 8) & evalState $ _randGen w
|
|
fdamps = replicateM 100 (state $ randomR (0, 1)) & evalState $ _randGen w
|
|
sizes = randomRs (2, 9) $ _randGen w
|
|
times = randomRs (15, 20) $ _randGen w
|
|
mF v damp size time = makeFlamelet p (v + damp *^ vel) size time
|
|
newFs = zipWith4 mF fVs fdamps sizes times
|
|
addFlames w' = foldl' (&) w' newFs
|