Reify shockwaves

This commit is contained in:
2022-07-24 00:20:28 +01:00
parent 97174535d8
commit 5b9e9968f3
17 changed files with 197 additions and 166 deletions
+20 -82
View File
@@ -1,8 +1,6 @@
module Dodge.WorldEvent.Shockwave
( makeShockwaveAt
, inverseShockwaveAt
, drawShockwave
, mvShockwave
) where
import Dodge.Zoning.Wall
import Dodge.Data
@@ -24,58 +22,18 @@ makeShockwaveAt
-> Color -- ^ Color of shockwave.
-> World -- ^ Start world.
-> World
makeShockwaveAt is p rad dam push col = instantParticles .:~ Shockwave
{ _ptUpdate = mvShockwave is
, _ptColor = col
, _ptPos = p
, _ptRad = rad
, _ptDam = dam
, _ptPush = push
, _ptMaxTime = 10
, _ptTimer = 10
makeShockwaveAt is p rad dam push col = shockwaves .:~ Shockwave
{ _swInvulnerableCrs = is
, _swDirection = OutwardShockwave
, _swColor = col
, _swPos = p
, _swRad = rad
, _swDam = dam
, _swPush = push
, _swMaxTime = 10
, _swTimer = 10
}
{- Shockwave picture. -}
drawShockwave :: Particle -> Picture
drawShockwave pt = setDepth 20
. setLayer BloomLayer
. uncurryV translate (_ptPos pt)
. color (_ptColor pt)
$ thickCircle rad thickness
where
r = _ptRad pt
thickness = tFraction**2 * r
rad = r - (3/4) * r * tFraction
tFraction = fromIntegral (_ptTimer pt) / fromIntegral (_ptMaxTime pt)
mvShockwave
:: [Int] -- ^ IDs of invulnerable creatures.
-> World -> Particle -> (World, Maybe Particle)
mvShockwave is w pt
| _ptTimer pt <= 0 = ( w , Nothing)
| otherwise = (doDams w , Just $ pt & ptTimer -~ 1)
where
r = _ptRad pt
p = _ptPos pt
push = _ptPush pt
dam = _ptDam pt
t = _ptTimer pt
tFraction = fromIntegral t / fromIntegral (_ptMaxTime pt)
rad = r - (3/4) * r * tFraction
doDams w' = over creatures (IM.map damCr)
$ foldl'
(flip $ damageWall (Damage EXPLOSIVE 10000 p p p NoDamageEffect))
w'
hitBlocks
hitBlocks = map snd . overlapCircWalls p rad $ wlsNearCirc p rad w
-- this is not expansive enough
damCr cr
| _crID cr `elem` is || dist (_crPos cr) p >= rad + _crRad cr = cr
| otherwise = cr & crState . csDamage .:~
Damage PUSHDAM dam (cpos -.- v) cpos (cpos +.+ v)
(PushBackDamage (25 * push))
where
cpos = _crPos cr
v = normalizeV (cpos -.- p)
{- Create a shockwave going from an outside circle into a center point. -}
inverseShockwaveAt
:: Point2 -- Center position
@@ -84,34 +42,14 @@ inverseShockwaveAt
-> Float -- Push amount
-> World
-> World
inverseShockwaveAt p rad dam push = instantParticles .:~ Shockwave
{ _ptUpdate = moveInverseShockwave
, _ptColor = cyan
, _ptPos = p
, _ptRad = rad
, _ptDam = dam
, _ptPush = push
, _ptMaxTime = 10
, _ptTimer = 10
inverseShockwaveAt p rad dam push = shockwaves .:~ Shockwave
{ _swDirection = InwardShockwave
, _swInvulnerableCrs = []
, _swColor = cyan
, _swPos = p
, _swRad = rad
, _swDam = dam
, _swPush = push
, _swMaxTime = 10
, _swTimer = 10
}
moveInverseShockwave
:: World
-> Particle
-> (World, Maybe Particle)
moveInverseShockwave w pt
| t <= 0 = ( w, Nothing)
| otherwise = (dams w, Just $ ptTimer -~ 1 $ pt )
where
p = _ptPos pt
r = _ptRad pt
t = _ptTimer pt
rad = r - 0.1 * r * fromIntegral (10 - t)
dams = over creatures (IM.map damCr) -- . flip (foldr (damageBlocksBy 1)) hitBlocks
-- hitBlocks = wallsOnCirc' p rad $ wallsNearPoint' p w
damCr cr
| dist (_crPos cr) p >= rad + _crRad cr = cr
| otherwise = cr & crState . csDamage .:~
Damage PUSHDAM 1 (cpos +.+ v) cpos (cpos -.- v) (PushBackDamage 25)
where
cpos = _crPos cr
v = normalizeV (cpos -.- p)
+11 -10
View File
@@ -30,16 +30,17 @@ makeStaticBall p = randEnergyBallAt aStaticBall p . (posEvents .:~ thesparker)
where
thesparker = PosEvent SparkSpawner 10 p
concBall :: Point2 -> State g Particle
concBall p = return Shockwave
{ _ptUpdate = mvShockwave []
, _ptColor = white
, _ptPos = p
, _ptRad = 15
, _ptDam = 4
, _ptPush = 1
, _ptMaxTime = 10
, _ptTimer = 10
concBall :: Point2 -> Shockwave
concBall p = Shockwave
{ _swDirection = OutwardShockwave
, _swInvulnerableCrs = []
, _swColor = white
, _swPos = p
, _swRad = 15
, _swDam = 4
, _swPush = 1
, _swMaxTime = 10
, _swTimer = 10
}
aStaticBall :: Point2 -> State g EnergyBall