{- 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