118 lines
3.0 KiB
Haskell
118 lines
3.0 KiB
Haskell
module Dodge.Spark (
|
|
updateSpark,
|
|
sparkRandDir,
|
|
randDirSpark,
|
|
randSpark,
|
|
randSparkExtraVel,
|
|
makeSpark,
|
|
) where
|
|
|
|
import Control.Monad.State
|
|
import Dodge.Damage
|
|
import Dodge.Data.World
|
|
import Dodge.WorldEvent.ThingsHit
|
|
import Geometry
|
|
import LensHelp
|
|
import System.Random
|
|
|
|
-- should probably reduce spark speed more if it is very fast
|
|
updateSpark :: World -> Spark -> (World, Maybe Spark)
|
|
updateSpark w sk
|
|
| magV (_skVel sk) < 1 = (w, Nothing)
|
|
| otherwise = case thingHit sp ep w of
|
|
Nothing -> (w & randGen .~ g, Just $ sk & skPos .~ ep & skVel *~ 0.9
|
|
& skVel %~ rotateV a
|
|
& skOldPos .~ sp)
|
|
Just (hp, hthing) ->
|
|
( sparkDam sk hthing w
|
|
, Just $ sk & skPos .~ hp & skOldPos .~ sp & skVel .~ 0
|
|
)
|
|
where
|
|
(a,g) = randomR (-x,x) (_randGen w)
|
|
x = 1
|
|
sp = _skPos sk
|
|
ep = sp + _skVel sk
|
|
|
|
sparkDam :: Spark -> Either Creature Wall -> World -> World
|
|
sparkDam = damageCrWl . sparkToDamage
|
|
|
|
sparkToDamage :: Spark -> [Damage]
|
|
sparkToDamage sp = case _skType sp of
|
|
ElectricSpark -> [Electrical 10]
|
|
FireSpark -> [Flaming 1]
|
|
NormalSpark -> [Sparking 10]
|
|
|
|
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) = randdir `runState` _randGen w
|
|
|
|
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)
|
|
|
|
randSparkExtraVel ::
|
|
Point2 ->
|
|
SparkType ->
|
|
State StdGen Float ->
|
|
State StdGen Float ->
|
|
Point2 ->
|
|
World ->
|
|
World
|
|
randSparkExtraVel v dt randspeed randdir pos w =
|
|
w
|
|
& randGen .~ g
|
|
& cWorld . lWorld . sparks
|
|
.:~ Spark
|
|
{ _skVel = v + 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
|