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