Allow tweaking z buffer when rendering polygon, improve explosion render

This commit is contained in:
jgk
2021-07-03 23:56:01 +02:00
parent 532f491327
commit 9df19a9e85
33 changed files with 339 additions and 82 deletions
+1 -1
View File
@@ -171,7 +171,7 @@ startInventory = IM.fromList (zip [0..20]
,boosterGun
,remoteLauncher
,grenade
,spawnGun lamp
,spawnGun (lamp 20)
,lasGun
,flamer
,poisonSprayer
+14 -14
View File
@@ -26,29 +26,29 @@ import Control.Lens
defaultInanimate :: Creature
defaultInanimate = defaultCreature & crActionPlan .~ Inanimate
lamp :: Creature
lamp = defaultInanimate
{ _crUpdate = initialiseLamp
lamp :: Float -> Creature
lamp h = defaultInanimate
{ _crUpdate = initialiseLamp h
, _crHP = 100
, _crPict = picAtCrPos lampPic
, _crPict = picAtCrPos (lampPic h)
, _crRad = 3
, _crMass = 3
}
lampPic :: Picture
lampPic = pictures
[ pictures . map (Poly3D 0 . map ((, blue) . (-.-.- (2.5,2.5,0)))) $ boxXYZ 5 5 99
, setDepth (100) $ color white $ circleSolid 3
lampPic :: Float -> Picture
lampPic h = pictures
[ pictures . map (Poly3D 0 . map ((, blue) . (-.-.- (2.5,2.5,0)))) $ boxXYZ 5 5 (h-1)
, setDepth h $ color white $ circleSolid 3
]
initialiseLamp :: CRUpdate
initialiseLamp w (f,g) cr = ( (addLS . f , g), Just $ cr & crUpdate .~ updateLamp i)
initialiseLamp :: Float -> CRUpdate
initialiseLamp h w (f,g) cr = ( (addLS . f , g), Just $ cr & crUpdate .~ updateLamp h i)
where
i = IM.newKey $ _lightSources $ f w -- to give different lights different keys
addLS = over lightSources (IM.insert i (lightAt (x,y,20) i))
addLS = over lightSources (IM.insert i (lightAt (x,y,h) i))
(x,y) = _crPos cr
updateLamp :: Int -> CRUpdate
updateLamp i = unrandUpdate handleLS internalUpdate
updateLamp :: Float -> Int -> CRUpdate
updateLamp h i = unrandUpdate handleLS internalUpdate
where
handleLS cr w
| _crHP cr < 0 = explosionFlashAt cPos
@@ -56,7 +56,7 @@ updateLamp i = unrandUpdate handleLS internalUpdate
| otherwise = w & lightSources . ix i . lsPos .~ f cPos
where
cPos = _crPos cr
f (x,y) = (x,y,120)
f (x,y) = (x,y,h)
internalUpdate cr
| _crHP cr < 0 = Nothing
| otherwise = Just $ doDamage cr
+13 -6
View File
@@ -16,6 +16,7 @@ import Dodge.Creature.Test
import Dodge.Item.Data
import Picture
import Geometry
import Geometry.Vector3D
import Control.Lens
import Data.List
@@ -29,12 +30,13 @@ basicCrPict col cr w = pictures $
targetingPic ++
[ tr . setDepth 0 $ color yellow $ circleSolid 10
, tr . piercingMod $ bluntScale $ naked col cr
, tr $ waist col
, tr $ torso (light4 col) (0,-crad) (0,crad)
, trFeet $ feet cr
, tr $ arms col cr
, tr $ drawEquipment cr
]
where
crad = _crRad cr
targetingPic = IM.elems $ IM.mapMaybeWithKey f $ _crInv cr
f invid it = fmap ((\g -> g invid it cr w) . snd) (it ^? itTargeting . _Just)
tr = uncurry translate (_crPos cr) . rotate (_crDir cr)
@@ -55,9 +57,6 @@ basicCrPict col cr w = pictures $
_ -> id
pastDams = _crPastDamage $ _crState cr
waist :: Color -> Picture
waist col = setDepth 10 . color (light4 col) . scale 0.5 1 $ circleSolid 8
feet :: Creature -> Picture
feet cr = case cr ^? crStance . carriage of
Just (Walking sa LeftForward) -> setL
@@ -99,7 +98,15 @@ arms col cr
f i = negate 2 + negate 6 * fromIntegral (sLen - i) / fromIntegral sLen
aimingTwist = crIsAiming' cr -- && crIt ^? itAimStance == Just TwoHandTwist
--crIt = _crInv cr IM.! _crInvSel cr
torso :: Color -> Point2 -> Point2 -> Picture
torso col x y = color col $ pictures
[ poly3 [addZ 20 x, addZ 12 v, addZ 12 ((0,0) -.- v), addZ 20 y]
, setDepth 12 . rotate a . scale 1 1 $ circleSolid $ magV v
]
where
v = 0.25 *.* (x -.- y)
a = argV v
naked :: Color -> Creature -> Picture
naked col cr
@@ -125,7 +132,7 @@ naked col cr
, shoulderH . translate 0 (negate 3) . rotate 0.2 . scale 0.5 1 $ color col' $ circleSolid $ _crRad cr
]
where
fhead = setDepth 30 $ circleSolid $ crad * 0.5
fhead = setDepth 22 $ circleSolid $ crad * 0.5
shoulderH = setDepth 20
twistA = negate 1
aimingOneHand = crIsAiming' cr && crIt ^? itAimStance == Just OneHand
+1
View File
@@ -93,6 +93,7 @@ movementSideEff cr w
Just (Boosting v)
-> makeFlameletTimed
(oldPos +.+ (_crRad cr + 3) *.* unitVectorAtAngle (_crDir cr + pi))
20
(momentum +.+ 1 *.* rotateV randDir (vInverse v))
Nothing
1
+12
View File
@@ -355,6 +355,18 @@ data Particle
, _btTimer' :: Int
, _btHitEffect' :: HitEffect
}
| PtZ
{ _ptDraw :: Particle -> Picture
, _ptUpdate' :: World -> Particle -> (World, Maybe Particle)
, _btVel' :: Point2
, _btColor' :: Color
, _btPos' :: Point2
, _btPassThrough' :: Maybe Int
, _btWidth' :: Float
, _btTimer' :: Int
, _btHitEffect' :: HitEffect
, _ptZ :: Float
}
| Pt'
{ _ptDraw :: Particle -> Picture
, _ptUpdate' :: World -> Particle -> (World, Maybe Particle)
+1 -1
View File
@@ -105,6 +105,6 @@ dropLight w = placeLS ls dec pos 0 w
dec = onLayer PtLayer $ color white $ circleSolid 8
dropLight' :: World -> World
dropLight' w = placeCr lamp pos 0 w
dropLight' w = placeCr (lamp 30) pos 0 w
where
pos = _crPos(you w)
+2 -2
View File
@@ -27,8 +27,8 @@ pictureWeaponOnAim p cr posInInv
= handD holsteredWep
| otherwise = blank
where
shoulderD = setDepth $ negate 0.005
handD = setDepth 0.01
shoulderD = setDepth 20.5
handD = setDepth 15
isSelected = _crInvSel cr == posInInv
drawnWep = uncurry translate (_crRad cr,0) p
twistWep = uncurry translate (0.5 * _crRad cr,0) p
+4 -4
View File
@@ -546,10 +546,10 @@ remoteShellPic
:: Int -- ^ Timer
-> Picture
remoteShellPic t
| rem (t+200) 20 < 9 = polygon [(-6,4),(-6,-4),(6,-4),(8,0),(6,4)]
| rem (t+200) 20 < 9 = setDepth 20 $ polygon [(-6,4),(-6,-4),(6,-4),(8,0),(6,4)]
| otherwise = pictures
[ onLayer UPtLayer $ polygon [(-6,4),(-6,-4),(6,-4),(8,0),(6,4)]
, setLayer 1 $ onLayer HPtLayer $ color col $ circleSolid 3
[ setDepth 20 $ polygon [(-6,4),(-6,-4),(6,-4),(8,0),(6,4)]
, setLayer 1 . setDepth 20.5 . color col $ circleSolid 3
]
where
col | t > (-99) = green
@@ -797,7 +797,7 @@ moveRemoteShell cid itid pj w
)
& soundFromPos (ShellSound i) newPos (fromIntegral smokeTrailSound) 1 250
& smokeGen
& makeFlameletTimed oldPos (0.5 *.* rotateV (pi+sparkD) accel) Nothing 3 10
& makeFlameletTimed oldPos 20 (0.5 *.* rotateV (pi+sparkD) accel) Nothing 3 10
| time > -200 = case thingHit of
Just _ -> doExplosion $ stopSoundFrom (ShellSound i) w
Nothing -> w
+3 -3
View File
@@ -3,7 +3,7 @@ module Dodge.Item.Weapon.Laser
where
import Dodge.Data
import Dodge.Picture
import Dodge.Picture.Layer
--import Dodge.Picture.Layer
import Dodge.Item.Attachment.Data
--import Dodge.Base
import Dodge.SoundLogic
@@ -56,7 +56,7 @@ moveLaser
-> (World, Maybe Particle)
moveLaser phaseV pos dir w pt
= ( set randGen g $ hitEffect w
, Just pt {_ptDraw = const $ onLayer PtLayer pic ,_ptUpdate' = ptTimer' 0 }
, Just pt {_ptDraw = const pic ,_ptUpdate' = ptTimer' 0 }
)
where
xp = pos +.+ 800 *.* unitVectorAtAngle dir
@@ -106,7 +106,7 @@ moveLaser phaseV pos dir w pt
Just (p,E3x2 wl) -> createSpark 8 colID (p +.+ safeNormalizeV (pos -.- p))
(reflectDir wl) Nothing
_ -> id
pic = pictures
pic = setDepth 20 $ pictures
[ fadeLine pos (head ps) 0.2 40 yellow
, setLayer 1 $ color (withAlpha 0.9 white) $ vThickLine (pos:ps)
, setLayer 1 $ color (withAlpha 0.5 yellow) $ vvThickLine (pos:ps)
+2 -7
View File
@@ -98,7 +98,7 @@ doThrust pj w = w
& randGen .~ g
& projectiles . ix i . pjVel %~ (\v -> accel +.+ frict *.* v)
& soundFromPos (ShellSound i) newPos (fromIntegral smokeTrailSound) 1 250
& makeFlameletTimed (oldPos -.- vel) (vel +.+ rotateV (pi+sparkD) accel) Nothing 3 10
& makeFlameletTimed (oldPos -.- vel) 0 (vel +.+ rotateV (pi+sparkD) accel) Nothing 3 10
& smokeGen
where
accel = _pjAcc pj
@@ -172,16 +172,11 @@ reduceSpinBy :: Float -> Projectile -> World -> World
reduceSpinBy x pj = projectiles . ix (_pjID pj) . pjSpin *~ x
shellPic :: Projectile -> Picture
shellPic pj
| t > 40 = onLayerL [levLayer CrLayer - 2]
$ uncurry translate pos $ rotate (argV accel) basePic
| otherwise = onLayer PtLayer $ uncurry translate pos $ rotate (argV accel) basePic
shellPic pj = setDepth 20 . uncurry translate pos $ rotate (argV accel) basePic
where
basePic = color black $ polygon [(-6,4),(-6,-4),(6,-4),(8,0),(6,4)]
accel = _pjAcc pj
pos = _pjPos pj
t = _pjTimer pj
pjEffTimeRange
:: (Int,Int)
+1 -1
View File
@@ -14,7 +14,7 @@ lightAt (x,y,z) i =
LS {_lsID = i
,_lsPos = (x,y,z)
,_lsDir = 0
,_lsRad = 500
,_lsRad = 700
,_lsIntensity = 0.75
}
basicLS :: PSType
+1 -1
View File
@@ -5,6 +5,6 @@ import Dodge.Data
import Picture
drawBul :: Particle -> Picture
drawBul pt = setLayer 1 . color thecolor $ thickLine (take 2 $ _btTrail' pt) (_btWidth' pt)
drawBul pt = setLayer 1 . setDepth 20 . color thecolor $ thickLine (take 2 $ _btTrail' pt) (_btWidth' pt)
where
thecolor = _btColor' pt
+2 -2
View File
@@ -118,7 +118,7 @@ bulIncCr' bt p cr w
sp = head $ _btTrail' bt
ep = sp +.+ _btVel' bt
v = evalState (randInCirc 1) $ _randGen w
incFlamelets = over worldEvents $ (.) (makeFlameletTimed p v Nothing 3 20)
incFlamelets = over worldEvents $ (.) (makeFlameletTimed p 20 v Nothing 3 20)
{- | Creates a shockwave when hitting a creature. -}
bulConCr' :: Particle -> Point2 -> Creature -> World -> World
bulConCr' bt p cr w
@@ -172,7 +172,7 @@ bulIncWall' bt p wl w = damageBlocksBy 5 wl $ incFlamelets w
pOut = p +.+ safeNormalizeV (sp -.- p)
wallV = uncurry (-.-) (_wlLine wl)
reflectVel = safeNormalizeV $ reflectIn wallV (_btVel' bt)
incFlamelets = over worldEvents $ (.) (makeFlameletTimed pOut reflectVel Nothing 3 20)
incFlamelets = over worldEvents $ (.) (makeFlameletTimed pOut 20 reflectVel Nothing 3 20)
{- | Create a shockwave on wall-}
bulConWall'
:: Particle
+1 -1
View File
@@ -11,7 +11,7 @@ import Control.Lens
aGenBulAt
:: Maybe Int -- ^ Pass-through creature id
-> Point2 -- ^ Start position
-> Point2 -- ^ Velocity
-> Point2 -- ^ Velocity
-> HitEffect
-> Float -- ^ Bullet width
-> Particle
+1 -1
View File
@@ -43,7 +43,7 @@ wedgeOfThickness t x y
n a b = (t*0.5) *.* errorNormalizeV 4200 (vNormal (a -.- b))
verticalPipe :: Float -> Color -> Point2 -> Float -> Float -> Picture
verticalPipe w col (xx,xy) za zb = pictures $ map (poly3D . f) ps
verticalPipe w col (xx,xy) za zb = pictures $ map (poly3Col . f) ps
where
x = (xx,xy,0)
xs = map (\(a,b) -> x +.+.+ (a,b,za)) [(w,0),(0,w),(-w,0),(0,-w)]
+21
View File
@@ -3,6 +3,7 @@ Helpers for random generation.
-}
module Dodge.RandomHelp where
import Geometry
import Geometry.Vector3D
import Geometry.Data
import System.Random
@@ -68,6 +69,26 @@ randInCirc maxRad = do rad <- state $ randomR (0,maxRad)
ang <- state $ randomR (0,2*pi)
return $ rad *.* unitVectorAtAngle ang
randOnUnitSphere :: RandomGen g => State g Point3
randOnUnitSphere = do
z <- state $ randomR (negate 1,1)
longitude <- state $ randomR (0, 2*pi)
let (x,y) = sqrt (1 - z^(2::Int)) *.* unitVectorAtAngle longitude
return (x,y,z)
randOnHemisphere :: RandomGen g => State g Point3
randOnHemisphere = do
z <- state $ randomR (0,1)
longitude <- state $ randomR (0, 2*pi)
let (x,y) = sqrt (1 - z^(2::Int)) *.* unitVectorAtAngle longitude
return (x,y,z)
randInHemisphere :: RandomGen g => State g Point3
randInHemisphere = do
p <- randOnHemisphere
r <- state $ randomR (0,1)
return $ r *.*.* p
randInRect :: RandomGen g => Float -> Float -> State g Point2
randInRect w h = do x <- state $ randomR (0,w)
y <- state $ randomR (0,h)
+6 -1
View File
@@ -64,7 +64,7 @@ doDrawing pdata w = do
depthFunc $= Just Less
let scPol = screenPolygon w
-- draw the lightmap. Probably changes the bound framebufferObject
createLightMap pdata (w ^. config . shadow_resolution) wallPoints lightPoints viewFroms
createLightMap pdata (w ^. config . shadow_resolution) wallPoints lightPoints
(foregroundPics w) scPol
clear [DepthBuffer]
@@ -95,6 +95,11 @@ doDrawing pdata w = do
blendFuncSeparate $= ((SrcAlpha,OneMinusSrcAlpha) , (Zero,One))
depthFunc $= Just Lequal
_ <- renderFoldable pdata $ picToLTree (Just 1) pic
depthMask $= Disabled
_ <- renderFoldable pdata $ picToLTree (Just 3) pic
_ <- renderFoldable pdata $ picToLTree (Just 4) pic
_ <- renderFoldable pdata $ picToLTree (Just 5) pic
depthMask $= Enabled
-- reset blend so that light map applies again
-- allows us to be certain these elements are drawn on top of those before,
-- in case we want transparency effects
+1 -1
View File
@@ -13,7 +13,7 @@ import Data.List
import Control.Lens
putLamp :: PSType
putLamp = PutCrit lamp
putLamp = PutCrit (lamp 90)
singleBlock :: Point2 -> [Placement]
singleBlock a =
+1 -1
View File
@@ -26,7 +26,7 @@ makeCloudAt rad t drawFunc p w = w & clouds %~ IM.insert i theCloud
drawCloudWith :: Float -> Float -> Color -> Cloud -> Picture
drawCloudWith radMult fadet col cl
= setLayer 2
. setDepth (-0.02)
. setDepth 25
$ circleSolidCol (withAlpha 0 col) (withAlpha a col) (radMult * _clRad cl)
where
a = min 1 $ fromIntegral (_clTimer cl) / fadet
+6 -3
View File
@@ -12,6 +12,7 @@ import Dodge.SoundLogic
import Dodge.SoundLogic.Synonyms
import Dodge.WorldEvent.Shockwave
import Geometry
import Geometry.Vector3D
import Picture
import Control.Monad.State
@@ -71,14 +72,16 @@ makeExplosionAt p w
$ makeShockwaveAt [] p 50 10 1 white w
where
fVs = replicateM 75 (randInCirc 1) & evalState $ _randGen w
fPs' = replicateM 75 (randInCirc 15) & evalState $ _randGen w
fPs'' = replicateM 75 (fmap (15 *.*.*) randInHemisphere) & evalState $ _randGen w
(fPs',zs) = let (a,b,c) = unzip3 fPs''
in (zip a b, c)
fPs = map (pushAgainstWalls . (+.+) p . (*.*) 0.5) fPs'
inversePushOut v = (15 - magV v) * 0.01 *.* v
fVs' = zipWith (+.+) fVs $ map inversePushOut fPs'
sizes = randomRs (2,6) $ _randGen w
times = randomRs (20,25) $ _randGen w
mF q v size time = makeFlameletTimed q v Nothing size time
newFs = zipWith4 mF fPs (fmap (3 *.*) fVs') sizes times
mF q z v size time = makeFlameletTimed q z v Nothing size time
newFs = zipWith5 mF fPs zs (fmap (3 *.*) fVs') sizes times
addFlames w' = foldr ($) w' newFs
pushAgainstWalls q = maybe q (uncurry (+.+)) $ reflectPointWalls p q $ wallsNearPoint q w
+1 -1
View File
@@ -49,7 +49,7 @@ Shockwave picture.
drawShockwave :: Particle -> Picture
drawShockwave pt = pic
where
pic = onLayer PtLayer $ uncurry translate p
pic = setDepth 20 . uncurry translate p
$ color (_btColor' pt) $ thickCircle rad thickness
p = _btPos' pt
r = _btRad' pt
+65 -15
View File
@@ -20,6 +20,7 @@ import Dodge.RandomHelp
--import Dodge.Debug
import Picture
import Geometry
--import Geometry.Data
import qualified IntMapHelp as IM
import Control.Lens
@@ -56,9 +57,9 @@ drawFlame rotd pt = thePic
ep = _btPos' pt
thePic = pictures
[ glow
, aPic prot2 0.002998 (scaleChange + 1,2) red
, aPic prot 0.002996 (scaleChange + 0.5,1.5) orange
, aPic prot3 0.002994 (scaleChange,1) white
, aPic prot2 18 (scaleChange + 1,2) red
, aPic prot 19 (scaleChange + 0.5,1.5) orange
, aPic prot3 20 (scaleChange,1) white
]
aPic :: (Point2 -> Point2) -> Float -> Point2 -> Color -> Picture
aPic offset depth (scalex,scaley) col
@@ -121,31 +122,80 @@ moveFlame rotd w pt
+.+ (0.2 *.* vel)
smokeCol = fst $ randomR (0.2,0.5) (_randGen w)
smokeGen = makeFlamerSmokeAt smokeCol ep
makeFlameletTimed
:: Point2 -- ^ Position
-> Float -- ^ z position
-> Point2 -- ^ Velocity
-> Maybe Int -- ^ Creature id
-> Float -- ^ Size
-> Int -- ^ Timer
-> World
-> World
makeFlameletTimed pos vel maycid size time w = w
makeFlameletTimed (x,y) z vel maycid size time w = w
& randGen .~ g
& particles %~ (theFlamelet :)
where
theFlamelet = Pt'
{ _ptDraw = drawFlamelet rot
theFlamelet = PtZ
{ _ptDraw = drawFlameletZ rot
, _ptUpdate' = moveFlamelet
, _btVel' = vel
, _btColor' = red
, _btPos' = pos
, _btPos' = (x,y)
, _btPassThrough' = maycid
, _btWidth' = size
, _btTimer' = time
, _btHitEffect' = destroyOnImpact (doFlameDam 1) noEff noEff
, _ptZ = z
}
(rot ,g) = randomR (0,3) $ _randGen w
drawFlameletZ
:: Float -- ^ Rotation
-> Particle
-> Picture
drawFlameletZ rot pt = pictures
[ setLayer 5 pic
, setLayer 4 pi2
, setLayer 3 piu
, setLayer 1 glow
]
where
z = _ptZ pt
sp = _btPos' pt
vel = _btVel' pt
ep = sp +.+ vel
size = _btWidth' pt
siz2 = size + 0.2
time = _btTimer' pt
glow = setDepth 19 $ uncurry translate ep
$ circleSolidCol (withAlpha 0 red) (withAlpha 0.05 red) 30
piu = setDepth (z + 20)
. uncurry translate ep
. color (dark red)
. rotate (negate (rot - 0.1 * fromIntegral time))
. scale s1 s1
$ polygon (rectNSWE siz2 (-siz2) (-siz2) siz2)
pi2 = setDepth (z + 20)
. uncurry translate ep
. color (mixColors (fromIntegral (max 0 (time-2))) (10-fromIntegral time)
orange (dark red)
)
. rotate (negate (rot + 0.2 * fromIntegral time))
. scale s2 s2
$ polygon (rectNSWE siz2 (-siz2) (-siz2) siz2)
pic = setDepth (z + 20)
. uncurry translate ep
. color (mixColors (fromIntegral (max 0 (time-2))) (10-fromIntegral time)
white (dark red)
)
. rotate (negate ( 0.1 * fromIntegral time + rot))
. scale sc sc
$ polygon [(-size,-size),(size,-size),(size,size),(-size,size)]
sc = (*) 2 $ log $ 1 + fromIntegral time / 20
s1 = (*) 2 $ log $ 2 + fromIntegral time / 40
s2 = 0.5 * (sc + s1)
drawFlamelet
:: Float -- ^ Rotation
-> Particle
@@ -158,16 +208,16 @@ drawFlamelet rot pt = setLayer 1 $ pictures [pic , piu , pi2 , glow]
size = _btWidth' pt
siz2 = size + 0.2
time = _btTimer' pt
glow = setDepth 0.336 $ uncurry translate ep
glow = setDepth 19 $ uncurry translate ep
$ circleSolidCol (withAlpha 0 red) (withAlpha 0.05 red) 30
piu = setDepth 0.334
piu = setDepth 20
. uncurry translate ep
. color (dark red)
. rotate (negate (rot - 0.1 * fromIntegral time))
. scale s1 s1
. polygon
$ rectNSWE siz2 (-siz2) (-siz2) siz2
pi2 = setDepth 0.332
pi2 = setDepth 20.2
. uncurry translate ep
. color (mixColors (fromIntegral (max 0 (time-2))) (10-fromIntegral time)
orange (dark red)
@@ -176,7 +226,7 @@ drawFlamelet rot pt = setLayer 1 $ pictures [pic , piu , pi2 , glow]
. scale s2 s2
. polygon
$ rectNSWE siz2 (-siz2) (-siz2) siz2
pic = setDepth 0.33
pic = setDepth 20.4
. uncurry translate ep
. color (mixColors (fromIntegral (max 0 (time-2))) (10-fromIntegral time)
white (dark red)
@@ -251,10 +301,10 @@ drawTeslaArc pt = pic
where
ps' = _ptPoints pt
pic = setLayer 1 $ pictures
[ onLayer PtLayer $ color (_ptColor pt) $ line ps'
, onLayer UPtLayer $ color (withAlpha 0.02 cyan) $ lineOfThickness 20 ps'
, onLayer UPtLayer $ color (withAlpha 0.02 cyan) $ lineOfThickness 25 ps'
, onLayer UPtLayer $ color (withAlpha 0.02 cyan) $ lineOfThickness 30 ps'
[ setDepth 20.5 $ color (_ptColor pt) $ line ps'
, setDepth 20 $ color (withAlpha 0.02 cyan) $ lineOfThickness 20 ps'
, setDepth 20 $ color (withAlpha 0.02 cyan) $ lineOfThickness 25 ps'
, setDepth 20 $ color (withAlpha 0.02 cyan) $ lineOfThickness 30 ps'
]
-- todo: fix electrical damage location
moveTeslaArc