Rethink damage data type, work on damage sensors

This commit is contained in:
2022-03-13 09:27:35 +00:00
parent d340fd73c3
commit 06a501ff88
30 changed files with 356 additions and 240 deletions
+3 -4
View File
@@ -4,17 +4,16 @@ module Dodge.WorldEvent.Damage
import Dodge.Data
import Geometry
import Dodge.Wall.Damage
import Control.Lens
import LensHelp
damThingHitWith
:: (Point2 -> Point2 -> Point2 -> DamageType)
:: (Point2 -> Point2 -> Point2 -> Damage)
-> Point2
-> Point2
-> Maybe (Point2, Either Creature Wall)
-> World
-> World
damThingHitWith partDT sp ep mayEiCrWl = case mayEiCrWl of
Just (hitp,Left cr ) -> creatures . ix (_crID cr) . crState . crDamage %~ (partDT sp hitp ep :)
Just (hitp,Left cr) -> creatures . ix (_crID cr) . crState . crDamage .:~ partDT sp hitp ep
Just (hitp,Right wl) -> damageWall (partDT sp hitp ep) wl
Nothing -> id
+1 -1
View File
@@ -63,7 +63,7 @@ penWalls crEff wlEff pt hitThings w = case hitThings of
doFlameDam :: Int -> Particle -> Point2 -> Creature -> World -> World
doFlameDam amount pt p cr = creatures . ix (_crID cr) . crState . crDamage .:~
Flaming amount sp p ep
Damage Flaming amount sp p ep NoDamageEffect
where
sp = _ptPos pt
ep = sp +.+ _ptVel pt
+9 -3
View File
@@ -60,13 +60,17 @@ mvShockwave is w pt
t = _ptTimer pt
tFraction = fromIntegral t / fromIntegral (_ptMaxTime pt)
rad = r - (3/4) * r * tFraction
doDams = over creatures (IM.map damCr) . flip (IM.foldl' (flip $ damageWall (Explosive 10000 p)))
doDams = over creatures (IM.map damCr)
. flip (IM.foldl' (flip $ damageWall (Damage Explosive 10000 p p p NoDamageEffect)))
hitBlocks
hitBlocks = wallsOnCirc p rad $ wallsNearPoint p w
damCr cr
| _crID cr `elem` is || dist (_crPos cr) p >= rad + _crRad cr = cr
| otherwise = cr & crState . crDamage .:~
PushDam dam (25 * push *.* squashNormalizeV (_crPos cr -.- p))
Damage PushDam dam cpos cpos cpos
(PushBackDamage (25 * push *.* squashNormalizeV (_crPos cr -.- p)))
where
cpos = _crPos cr
{- Create a shockwave going from an outside circle into a center point. -}
inverseShockwaveAt
:: Point2 -- Center position
@@ -103,7 +107,9 @@ moveInverseShockwave w pt
damCr cr
| dist (_crPos cr) p >= rad + _crRad cr = cr
| otherwise = cr & crState . crDamage .:~
PushDam 1 (25 *.* squashNormalizeV (p -.- _crPos cr))
Damage PushDam 1 cpos cpos cpos (PushBackDamage $ 25 *.* squashNormalizeV (p -.- cpos))
where
cpos = _crPos cr
drawInverseShockwave :: Particle -> Picture
drawInverseShockwave pt
+26 -24
View File
@@ -12,6 +12,7 @@ import Dodge.WorldEvent.Cloud
import Dodge.WorldEvent.Flash
import Dodge.SoundLogic
import Dodge.RandomHelp
import Dodge.Wall.Damage
import Picture
import Geometry
import qualified IntMapHelp as IM
@@ -27,26 +28,27 @@ aFlameParticle
-> Maybe Int -- ^ Creature id
-> Particle
aFlameParticle t pos vel maycid = PtZ
{ _ptDraw = drawFlame vel
, _ptUpdate = moveFlame vel
, _ptVel = vel
, _ptColor = red
, _ptPos = pos
, _ptCrIgnore = maycid
, _ptWidth = 4
, _ptTimer = t
, _ptHitEff = destroyOnImpact (doFlameDam 1) noEff
, _ptZ = 20
{ _ptDraw = drawFlame vel
, _ptUpdate = moveFlame vel
, _ptVel = vel
, _ptColor = red
, _ptPos = pos
, _ptCrIgnore = maycid
, _ptWidth = 4
, _ptTimer = t
, _ptHitEff = destroyOnImpact (doFlameDam 1)
(\_ p -> damageWall (Damage Flaming 19 p p p NoDamageEffect))
, _ptZ = 20
}
drawFlame
drawFlame
:: Point2 -- ^ Rotate direction
-> Particle
-> Picture
drawFlame rotd pt = pictures
drawFlame rotd pt = pictures
[ glow
, aPic 3 prot2 25 (V2 (scaleChange + 1) 2 ) $ V4 2 (-1) (-1) 0.5
, aPic 3 prot 22 (V2 (scaleChange + 0.5) 1) $ V4 1 0.5 0 2
, aPic 1 prot3 20 (V2 scaleChange 0.5 ) $ V4 1 1 1 1
, aPic 3 prot2 25 (V2 (scaleChange + 1) 2 ) $ V4 2 (-1) (-1) 0.5
, aPic 3 prot 22 (V2 (scaleChange + 0.5) 1 ) $ V4 1 0.5 0 2
, aPic 1 prot3 20 (V2 scaleChange 0.5) $ V4 1 1 1 1
]
where
ep = _ptPos pt
@@ -69,17 +71,16 @@ drawFlame rotd pt = pictures
prot2 p' = p' +.+ rotateV (negate $ fromIntegral time) (V2 0 1)
prot3 p' = p' +.+ rotateV (2 + fromIntegral time * 0.1) (V2 0 2)
{- TODO: add generalised area damage particles/hiteffects. -}
moveFlame
:: Point2 -- ^ Rotation direction
moveFlame :: Point2 -- ^ Rotation direction
-> World
-> Particle
-> (World, Maybe Particle)
moveFlame rotd w pt
| time <= 0 = (makeFlamerSmokeAt (addZ 20 ep) w, Nothing)
| otherwise = case thingsHitExceptCr (_ptCrIgnore pt) sp ep w of
((_,Left _):_) -> (doSound damcrs , mvPt 0.7)
(thing@(p,Right wl):_) -> (doSound . fst $ hiteff [thing] damcrs , rfl wl p)
_ -> (flameFlicker pt $ doSound damcrs , mvPt 0.98)
((_,Left _):_) -> (doSound damcrs , mvPt 0.7)
(th@(p,Right wl):_) -> (doSound . fst $ hiteff [th] damcrs , rfl wl p)
_ -> (flameFlicker pt $ doSound damcrs , mvPt 0.98)
where
time = _ptTimer pt
doSound = soundContinue Flame (V2 x y) fireLoudS (Just 2)
@@ -98,7 +99,7 @@ moveFlame rotd w pt
angleCoeff x' = abs $ 1 - abs ( (x' * 2 - pi) / pi )
hiteff = _ptHitEff pt pt
rfl wl p = Just $ pt
{ _ptTimer = time -1
{ _ptTimer = time - 1
, _ptPos = pOut p
, _ptVel = reflV wl
}
@@ -195,7 +196,7 @@ moveFlamelet w pt
damcrs = w & creatures %~ IM.map damifclose
isClose cr = dist ep (_crPos cr) < _crRad cr + size
damifclose cr
| isClose cr = cr & crState . crDamage .:~ Flaming 3 sp ep ep
| isClose cr = cr & crState . crDamage .:~ Damage Flaming 3 sp ep ep NoDamageEffect
| otherwise = cr
-- | At writing the radius is half the size of the effect area
makeGasCloud
@@ -223,6 +224,7 @@ makeGasCloud pos vel w = w
cloudPoisonDamage :: Cloud -> World -> World
cloudPoisonDamage c w = w & creatures %~ flip (foldr (IM.adjust doDam)) damagedCrs
where
damagedCrs = IM.keys $ IM.filter f $ creaturesNearPoint (stripZ $ _clPos c) w
damagedCrs = IM.keys $ IM.filter f $ creaturesNearPoint clpos w
f cr = dist3 (addZ 20 $ _crPos cr) (_clPos c) < _crRad cr + _clRad c + 10
doDam cr = cr & crState . crDamage .:~ PoisonDam 1
doDam cr = cr & crState . crDamage .:~ Damage PoisonDam 1 clpos clpos clpos NoDamageEffect
clpos = stripZ $ _clPos c