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 #-}
module Dodge.Projectile.Update (
updateProjectile,
) where
import Data.Foldable
import Data.List (delete)
import Data.List (delete, deleteBy)
import Data.Maybe
import Dodge.Base
import Dodge.Data.World
@@ -31,7 +33,7 @@ updateProjectile pj w =
$ foldl' (flip $ upProjectile pj) w (_pjUpdates pj)
upProjectile :: Projectile -> ProjectileUpdate -> World -> World
upProjectile pj pu = case pu of
upProjectile pj = \case
ThrustPU st et
| act st et -> doThrust pj (pj ^? pjType . rkSmoke . _Just)
| otherwise -> id
@@ -79,7 +81,7 @@ applyGravityPU pj w
| otherwise = x * 0.9
newz = pj ^. pjZ + pj ^. pjZVel
-- consider using thingHit, pushing any hit creature back
-- consider pushing any hit creature back
shellCollisionCheck ::
Projectile ->
World ->
@@ -112,7 +114,7 @@ tryShellBounce (p, Right wl) pj w
w
& cWorld . lWorld . projectiles . ix (_pjID pj) . pjVel
%~ reflectIn hitline
& cWorld . lWorld . projectiles . ix (_pjID pj) . pjPos
& cWorld . lWorld . projectiles . ix (_pjID pj) . pjPos
.~ p - normalizeV (pj ^. pjVel)
& soundStart (ShellSound (pj ^. pjID)) (pj ^. pjPos) click1S Nothing
| isJust $ pj ^? pjType . gnHitEffect . bounceTolerance =
@@ -131,7 +133,6 @@ tryShellBounce (p, Left cr) pj w
(rotateV (- cr ^. crDir) (p - cr ^. crPos))
(pj ^. pjDir - cr ^. crDir)
)
-- & cWorld . lWorld . projectiles . ix (_pjID pj) . pjUpdates %~ delete ApplyGravityPU
& soundOriginIDsAt (ShellSound (pj ^. pjID)) [slapS, slap1S] (pj ^. pjPos)
tryShellBounce _ pj w = explodeShell pj w
@@ -172,6 +173,8 @@ doThrust pj smoke w =
(sparkD, _) = randomR (-0.2, 0.2) $ _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 ::
-- | creature id
Int ->
@@ -180,8 +183,12 @@ trySpinByCID ::
Projectile ->
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
f _ StartSpinPU{} = True
f _ _ = False
pjid = _pjID pj
dir = argV $ _pjVel pj
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 pj w
| Just GStuckWall{} <- pj ^? pjType . gnHitEffect = w
| Just (GStuckCreature crid p d) <- pj ^? pjType . gnHitEffect = fromMaybe
(w & cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjType .~ Grenade GStick)
$ do
cpos <- w ^? cWorld . lWorld . creatures . ix crid . crPos
cdir <- w ^? cWorld . lWorld . creatures . ix crid . crDir
return $
w
& cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjPos
.~ cpos + rotateV cdir p
& cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjDir
.~ d + cdir
| Just (GStuckCreature crid p d) <- pj ^? pjType . gnHitEffect
, Just cr <- w ^? cWorld . lWorld . creatures . ix crid =
let cpos = cr ^. crPos
cdir = cr ^. crDir
vel = cpos - cr ^. crOldPos
in w
& cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjPos
.~ cpos + rotateV cdir p
& cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjDir
.~ 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 =
w
& cWorld . lWorld . projectiles . ix (pj ^. pjID) . pjSpin *~ 0.99