Allow sticky grenades to move after killing creature stuck to

This commit is contained in:
2025-01-06 13:22:46 +00:00
parent 04ba9fcce2
commit beaf65f3f7
+27 -17
View File
@@ -1,10 +1,12 @@
{-# LANGUAGE LambdaCase #-}
--{-# OPTIONS_GHC -Wno-unused-imports #-} --{-# OPTIONS_GHC -Wno-unused-imports #-}
module Dodge.Projectile.Update ( module Dodge.Projectile.Update (
updateProjectile, updateProjectile,
) where ) where
import Data.Foldable import Data.Foldable
import Data.List (delete) import Data.List (delete, deleteBy)
import Data.Maybe import Data.Maybe
import Dodge.Base import Dodge.Base
import Dodge.Data.World import Dodge.Data.World
@@ -31,7 +33,7 @@ updateProjectile pj w =
$ foldl' (flip $ upProjectile pj) w (_pjUpdates pj) $ foldl' (flip $ upProjectile pj) w (_pjUpdates pj)
upProjectile :: Projectile -> ProjectileUpdate -> World -> World upProjectile :: Projectile -> ProjectileUpdate -> World -> World
upProjectile pj pu = case pu of upProjectile pj = \case
ThrustPU st et ThrustPU st et
| act st et -> doThrust pj (pj ^? pjType . rkSmoke . _Just) | act st et -> doThrust pj (pj ^? pjType . rkSmoke . _Just)
| otherwise -> id | otherwise -> id
@@ -79,7 +81,7 @@ applyGravityPU pj w
| otherwise = x * 0.9 | otherwise = x * 0.9
newz = pj ^. pjZ + pj ^. pjZVel newz = pj ^. pjZ + pj ^. pjZVel
-- consider using thingHit, pushing any hit creature back -- consider pushing any hit creature back
shellCollisionCheck :: shellCollisionCheck ::
Projectile -> Projectile ->
World -> World ->
@@ -112,7 +114,7 @@ tryShellBounce (p, Right wl) pj w
w w
& cWorld . lWorld . projectiles . ix (_pjID pj) . pjVel & cWorld . lWorld . projectiles . ix (_pjID pj) . pjVel
%~ reflectIn hitline %~ reflectIn hitline
& cWorld . lWorld . projectiles . ix (_pjID pj) . pjPos & cWorld . lWorld . projectiles . ix (_pjID pj) . pjPos
.~ p - normalizeV (pj ^. pjVel) .~ p - normalizeV (pj ^. pjVel)
& soundStart (ShellSound (pj ^. pjID)) (pj ^. pjPos) click1S Nothing & soundStart (ShellSound (pj ^. pjID)) (pj ^. pjPos) click1S Nothing
| isJust $ pj ^? pjType . gnHitEffect . bounceTolerance = | isJust $ pj ^? pjType . gnHitEffect . bounceTolerance =
@@ -131,7 +133,6 @@ tryShellBounce (p, Left cr) pj w
(rotateV (- cr ^. crDir) (p - cr ^. crPos)) (rotateV (- cr ^. crDir) (p - cr ^. crPos))
(pj ^. pjDir - cr ^. crDir) (pj ^. pjDir - cr ^. crDir)
) )
-- & cWorld . lWorld . projectiles . ix (_pjID pj) . pjUpdates %~ delete ApplyGravityPU
& soundOriginIDsAt (ShellSound (pj ^. pjID)) [slapS, slap1S] (pj ^. pjPos) & soundOriginIDsAt (ShellSound (pj ^. pjID)) [slapS, slap1S] (pj ^. pjPos)
tryShellBounce _ pj w = explodeShell pj w tryShellBounce _ pj w = explodeShell pj w
@@ -172,6 +173,8 @@ doThrust pj smoke w =
(sparkD, _) = randomR (-0.2, 0.2) $ _randGen w (sparkD, _) = randomR (-0.2, 0.2) $ _randGen w
r1 = randInCirc 10 & evalState $ _randGen w r1 = randInCirc 10 & evalState $ _randGen w
-- there doesn't seem to be a more sensible way to filter the first occurence of
-- a list than deleteBy
trySpinByCID :: trySpinByCID ::
-- | creature id -- | creature id
Int -> Int ->
@@ -180,8 +183,12 @@ trySpinByCID ::
Projectile -> Projectile ->
World -> World ->
World World
trySpinByCID cid i pj w = w & cWorld . lWorld . projectiles . ix pjid . pjSpin .~ newSpin trySpinByCID cid i pj w =
w & cWorld . lWorld . projectiles . ix pjid . pjSpin .~ newSpin
& cWorld . lWorld . projectiles . ix pjid . pjUpdates %~ deleteBy f (StartSpinPU 0 0 0)
where where
f _ StartSpinPU{} = True
f _ _ = False
pjid = _pjID pj pjid = _pjID pj
dir = argV $ _pjVel pj dir = argV $ _pjVel pj
newSpin = case w ^? cWorld . lWorld . creatures . ix cid of newSpin = case w ^? cWorld . lWorld . creatures . ix cid of
@@ -208,17 +215,20 @@ pjRemoteSetDirection ph pj w = case ph of
pjMovement :: Projectile -> World -> World pjMovement :: Projectile -> World -> World
pjMovement pj w pjMovement pj w
| Just GStuckWall{} <- pj ^? pjType . gnHitEffect = w | Just GStuckWall{} <- pj ^? pjType . gnHitEffect = w
| Just (GStuckCreature crid p d) <- pj ^? pjType . gnHitEffect = fromMaybe | Just (GStuckCreature crid p d) <- pj ^? pjType . gnHitEffect
(w & cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjType .~ Grenade GStick) , Just cr <- w ^? cWorld . lWorld . creatures . ix crid =
$ do let cpos = cr ^. crPos
cpos <- w ^? cWorld . lWorld . creatures . ix crid . crPos cdir = cr ^. crDir
cdir <- w ^? cWorld . lWorld . creatures . ix crid . crDir vel = cpos - cr ^. crOldPos
return $ in w
w & cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjPos
& cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjPos .~ cpos + rotateV cdir p
.~ cpos + rotateV cdir p & cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjDir
& cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjDir .~ d + cdir
.~ d + cdir & cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjVel
.~ vel
| Just GStuckCreature{} <- pj ^? pjType . gnHitEffect =
w & cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjType .~ Grenade GStick
| otherwise = | otherwise =
w w
& cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjSpin *~ 0.99 & cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjSpin *~ 0.99