diff --git a/src/Dodge/Projectile/Update.hs b/src/Dodge/Projectile/Update.hs index f402a82a7..7f3fce263 100644 --- a/src/Dodge/Projectile/Update.hs +++ b/src/Dodge/Projectile/Update.hs @@ -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