{- Explosions: creation of shockwave and particles at a given point. -} module Dodge.WorldEvent.Explosion ( makeExplosionAt, makeFlameExplosionAt, makePoisonExplosionAt, makeTeslaExplosionAt, ) where --import Dodge.WorldEvent.Flash --import Geometry.Vector3D import Control.Monad import Data.List import Dodge.Base.Collide import Dodge.Data.World import Dodge.EnergyBall import Dodge.Flame import Dodge.LightSource import Dodge.SoundLogic import Dodge.WorldEvent.Shockwave import Dodge.WorldEvent.SpawnParticle import Geometry import LensHelp import Picture import RandomHelp --import Data.Maybe 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 = aFlameParticle time p vel 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 -> World -> World makeExplosionAt p w = w & soundMultiFrom [Explosion 0, Explosion 1] p bangS Nothing & addFlames & cWorld . lWorld . tempLightSources .:~ theTLS & makeShockwaveAt [] p 50 50 1 white where theTLS = tlsTimeRadColPos 20 150 (V3 1 0.5 0) (addZ 20 p) fVs = replicateM 100 (randInCirc 1) & evalState $ _randGen w --fPs'' = replicateM 100 (fmap (15 *.*.*) randInHemisphere) & evalState $ _randGen w fPs'' = replicateM 100 (fmap (15 *.*.*) randInHemisphere) & evalState $ _randGen w (fPs', zs) = let (a, b, c) = unzip3 $ map fromV3 fPs'' in (zipWith V2 a b, c) --fPs = map (pushAgainstWalls . (+.+) p . (*.*) 0.5) fPs' fPs = map (pushAgainstWalls . (+.+) p) fPs' inversePushOut v = (15 - magV v) * 0.01 *.* v fVs' = zipWith (+.+) fVs $ map inversePushOut fPs' sizes = randomRs (2, 9) $ _randGen w --times = randomRs (20,25) $ _randGen w times = randomRs (15, 20) $ _randGen w mF q z v size time = makeFlamelet q z v size time newFs = zipWith5 mF fPs zs (fmap (3 *.*) fVs') sizes times addFlames w' = foldl' (flip ($)) w' newFs --pushAgainstWalls q = maybe q (uncurry (+.+)) $ reflectPointWalls p q wls --pushAgainstWalls q = maybe q fst $ reflectPointWalls p q wls pushAgainstWalls q = maybe q fst $ bouncePoint (const True) 1 p q w -- wls = wallsNearPoint p w