module Dodge.Spark ( updateSpark, sparkRandDir, createBarrelSpark, randDirSpark, randSpark, makeSpark, ) where import Dodge.Damage import Control.Monad.State import Dodge.Data.World import Dodge.WorldEvent.ThingsHit import Geometry import LensHelp import System.Random updateSpark :: World -> Spark -> (World, Maybe Spark) updateSpark w sk | magV (_skVel sk) < 1 = (w, Nothing) | otherwise = case thingHit sp ep w of Nothing -> (w, Just $ sk & skPos .~ ep & skVel *~ 0.9 & skOldPos .~ sp) Just (hp, hthing) -> ( sparkDam' sk sp ep (hp, hthing) w , Just $ sk & skPos .~ hp & skOldPos .~ sp & skVel .~ 0 ) where sp = _skPos sk ep = sp + _skVel sk sparkDam' :: Spark -> Point2 -> Point2 -> (Point2, Either Creature Wall) -> World -> World sparkDam' sk sp ep mayEiCrWl = case mayEiCrWl of (hitp, eicrwl) -> damageCrWl (thedam hitp) eicrwl where thedam hitp = Damage (sparkToDamage sk) 10 sp hitp ep -- NoDamageEffect sparkToDamage :: Spark -> DamageType sparkToDamage sp = case _skType sp of ElectricSpark ->ELECTRICAL FireSpark -> FLAMING NormalSpark -> SPARKING createBarrelSpark :: Point2 -> Float -> World -> World createBarrelSpark pos dir = sparkRandDir 0.1 pos dir makeSpark :: SparkType -> Point2 -> Float -> World -> World makeSpark st p d = cWorld . lWorld . sparks .:~ Spark { _skVel = rotateV d (V2 5 0) , _skPos = p , _skOldPos = p , _skType = st } randDirSpark :: State StdGen Float -> Point2 -> World -> World randDirSpark randdir pos w = w & randGen .~ g & cWorld . lWorld . sparks .:~ Spark { _skVel = rotateV dir (V2 5 0) , _skPos = pos , _skOldPos = pos , _skType = NormalSpark } where (dir, g) = (`runState` _randGen w) $ do d <- randdir return d randSpark :: SparkType -> State StdGen Float -> State StdGen Float -> Point2 -> World -> World randSpark dt randspeed randdir pos w = w & randGen .~ g & cWorld . lWorld . sparks .:~ Spark { _skVel = rotateV dir (V2 speed 0) , _skPos = pos , _skOldPos = pos , _skType = dt } where ((dir, speed), g) = (`runState` _randGen w) $ do d <- randdir x <- randspeed return (d, x) sparkRandDir :: Float -> Point2 -> Float -> World -> World sparkRandDir a pos dir = randDirSpark (state $ randomR (dir - a, dir + a)) pos