diff --git a/src/Dodge/Bullet.hs b/src/Dodge/Bullet.hs index 789ee6313..61e86f879 100644 --- a/src/Dodge/Bullet.hs +++ b/src/Dodge/Bullet.hs @@ -2,49 +2,43 @@ module Dodge.Bullet ( updateBullet, ) where -import Linear -import Dodge.Item.Weapon.Bullet -import System.Random +import Data.Bifunctor import Data.Foldable import Data.Maybe import Dodge.Creature.Test import Dodge.Data.World import Dodge.EnergyBall +import Dodge.Item.Weapon.Bullet import Dodge.Movement.Turn import Dodge.WorldEvent.SpawnParticle import Dodge.WorldEvent.ThingsHit import Geometry -import qualified IntMapHelp as IM +--import qualified IntMapHelp as IM import LensHelp import qualified ListHelp as List -import Data.Bifunctor +import System.Random updateBullet :: World -> Bullet -> (World, Maybe Bullet) updateBullet w bu - | magV (_buVel bu) < 1 = (endspawn w, Nothing) --- have to be slightly carefull not to accelerate bullets using magnets + | magV (_buVel bu) < 1 = (useBulletPayload bu (_buPos bu) w, Nothing) + -- have to be slightly carefull not to accelerate bullets using magnets | otherwise = second (Just . updateBulVel) . hitEffFromBul w $ applyMagnetsToBul bu w - where - endspawn = fromMaybe id $ do - partspawn <- useBulletPayload bu - return $ partspawn p - p = _buPos bu -- do we want this to drain energy from the deflection source? applyMagnetsToBul :: Bullet -> World -> Bullet applyMagnetsToBul bu = foldl' doMagnetBuBu bu . _oldMagnets . _lWorld . _cWorld doMagnetBuBu :: Bullet -> Magnet -> Bullet -doMagnetBuBu bu mg +doMagnetBuBu bu mg | notclose = bu | otherwise = case _mgField mg of MagnetAlign -> doturntowards mgalignpos MagnetDeflect -> doturntowards mgdeflectpos MagnetAttract -> doturntowards mpos - MagnetRepulse -> doturntowards (2*bpos - mpos) + MagnetRepulse -> doturntowards (2 * bpos - mpos) where notclose = d > 100 - doturntowards p = bu & buVel %~ vecTurnTo (10 * pi / (d+40)) bpos p + doturntowards p = bu & buVel %~ vecTurnTo (10 * pi / (d + 40)) bpos p bvel = bu ^. buVel mpos = mg ^. mgPos bpos = bu ^. buPos @@ -58,9 +52,10 @@ doMagnetBuBu bu mg updateBulVel :: Bullet -> Bullet updateBulVel bt = bt & buVel .*.*~ _buDrag bt + --case _buTrajectory bt of -- BasicBulletTrajectory -> bt & buVel .*.*~ _buDrag bt --- MagnetTrajectory tpos -> bt +-- MagnetTrajectory tpos -> bt -- & buVel %~ (clipV 20 . (+.+ 5 *.* normalizeV (tpos -.- _buPos bt))) -- FlechetteTrajectory tpos -> bt & buVel %~ vecTurnTo 0.2 (_buPos bt) tpos -- BezierTrajectory spos tpos xpos -> @@ -76,8 +71,8 @@ updateBulVel bt = bt & buVel .*.*~ _buDrag bt -- leftitms <- itm ^? ldtLeft -- mag <- lookup (AmmoInLink 0 atype) leftitms -- thebullet <- mag ^? ldtValue . itUse . amagParams . ampBullet --- return $ w --- & randGen .~ g' +-- return $ w +-- & randGen .~ g' -- & cWorld . lWorld . instantBullets -- .:~ ( thebullet -- & buPos .~ _crPos cr @@ -113,16 +108,16 @@ bounceDir (_, Right wl) | _wlBouncy wl = Just $ uncurry (-.-) (_wlLine wl) bounceDir (p, Left cr) | crIsArmouredFrom p cr = Just $ vNormal $ p -.- _crPos cr bounceDir _ = Nothing -useBulletPayload :: Bullet -> Maybe (Point2 -> World -> World) +useBulletPayload :: Bullet -> Point2 -> World -> World useBulletPayload bu = case _buPayload bu of - BulSpark -> Nothing - BulFlak -> Just (makeFlak bu) - BulFrag -> Just makeFragBullets - BulGas -> Just (`makeGasCloud` V2 0 0) - BulBall IncBall -> Just incBallAt - BulBall ConcBall -> Just $ \p -> cWorld . lWorld . shockwaves .:~ concBall p - BulBall TeslaBall -> Just makeStaticBall - BulBall FlashBall -> Just makeFlashBall + BulSpark -> const id + BulFlak -> makeFlak bu + BulFrag -> makeFragBullets + BulGas -> (`makeGasCloud` V2 0 0) + BulBall IncBall -> incBallAt + BulBall ConcBall -> \p -> cWorld . lWorld . shockwaves .:~ concBall p + BulBall TeslaBall -> makeStaticBall + BulBall FlashBall -> makeFlashBall makeFragBullets :: Point2 -> World -> World makeFragBullets p w = w & cWorld . lWorld . bullets .++~ bus @@ -130,44 +125,50 @@ makeFragBullets p w = w & cWorld . lWorld . bullets .++~ bus bus = zipWith f (take 10 as) (take 10 ss) as = randomRs (0, 2 * pi) $ _randGen w ss = randomRs (5, 15) $ _randGen w - f a s = defaultBullet & buVel .~ s *.* unitVectorAtAngle a - & buDrag .~ 0.8 - & buPos .~ p - & buOldPos .~ p - & buWidth .~ 1 - & buDamages .~ - [ Damage PIERCING 5 0 0 0 $ PushBackDamage 2 - ] + f a s = + defaultBullet & buVel .~ s *.* unitVectorAtAngle a + & buDrag .~ 0.8 + & buPos .~ p + & buOldPos .~ p + & buWidth .~ 1 + & buDamages .~ [Damage PIERCING 5 0 0 0 $ PushBackDamage 2] makeFlak :: Bullet -> Point2 -> World -> World makeFlak bu _ w = w & cWorld . lWorld . bullets .++~ [f x | x <- xs] where s = min 10 (0.5 * magV (_buVel bu)) - xs = take 5 $ randomRs (-s,s) $ _randGen w - f x = bu & buVel %~ g x --- & buTimer .~ 97 - & buPayload .~ BulSpark - & buWidth .~ 0.5 - & buDamages .~ - [ Damage PIERCING 25 0 0 0 $ PushBackDamage 2 - ] + xs = take 5 $ randomRs (- s, s) $ _randGen w + f x = + bu & buVel %~ g x + -- & buTimer .~ 97 + & buPayload .~ BulSpark + & buWidth .~ 0.5 + & buDamages + .~ [Damage PIERCING 25 0 0 0 $ PushBackDamage 2] g x v = v +.+ x *.* normalizeV (vNormal v) hitEffFromBul :: World -> Bullet -> (World, Bullet) hitEffFromBul w bu = case _buEffect bu of PenetrateBullet -> movePenBullet bu hitstream w - BounceBullet -> case List.safeHead hitstream of - Nothing -> (w, moveBullet bu) - Just (hp, crwl) -> fromMaybe (expireAndDamage bu hitstream w) $ do - dir <- bounceDir (hp, crwl) - return - ( w - , bu - & buPos .~ hp +.+ normalizeV (_buPos bu -.- hp) - & buVel %~ reflectIn dir --- & buTrajectory .~ BasicBulletTrajectory --- & buTimer -~ 1 - ) + BounceBullet -> fromMaybe (expireAndDamage bu hitstream w) $ do + (hp, crwl) <- hitstream ^? _head + dir <- bounceDir (hp, crwl) + return + ( w + , bu + & buPos .~ hp +.+ normalizeV (_buPos bu -.- hp) + & buVel %~ reflectIn dir + ) + -- BounceBullet -> case List.safeHead hitstream of + -- Nothing -> (w, moveBullet bu) + -- Just (hp, crwl) -> fromMaybe (expireAndDamage bu hitstream w) $ do + -- dir <- bounceDir (hp, crwl) + -- return + -- ( w + -- , bu + -- & buPos .~ hp +.+ normalizeV (_buPos bu -.- hp) + -- & buVel %~ reflectIn dir + -- ) DestroyBullet -> expireAndDamage bu hitstream w where ep = sp +.+ _buVel bu @@ -182,7 +183,9 @@ setFromToDams bu p = map f (_buDamages bu) damageThingHit :: Bullet -> (Point2, Either Creature Wall) -> World -> World damageThingHit bu (p, crwl) = case crwl of Left cr -> cWorld . lWorld . creatures . ix (_crID cr) . crState . csDamage .++~ dams - Right wl -> cWorld . lWorld . wallDamages %~ IM.insertWith (++) (_wlID wl) dams + -- Right wl -> cWorld . lWorld . wallDamages %~ IM.insertWith (++) (_wlID wl) dams + -- hopefully the following doesn't introduce a space leak + Right wl -> cWorld . lWorld . wallDamages . at (_wlID wl) . non mempty <>~ dams where dams = setFromToDams bu p @@ -196,29 +199,21 @@ expireAndDamage bt things w = case List.safeHead things of Just x -> (damageThingHit bt x w, stopBulletAt (fst x) bt) moveBullet :: Bullet -> Bullet -moveBullet pt = pt - & buPos %~ (+.+ _buVel pt) - & buOldPos .~ _buPos pt +moveBullet pt = pt & buPos +~ _buVel pt & buOldPos .~ _buPos pt stopBulletAt :: Point2 -> Bullet -> Bullet -stopBulletAt hitp pt = pt - & buPos .~ hitp +.+ normalizeV (p -.- hitp) - & buOldPos .~ p - & buVel .~ 0 - where - p = _buPos pt +stopBulletAt hitp pt = + pt + & buPos .~ hitp + & buOldPos .~ _buPos pt + & buVel .~ 0 -movePenBullet :: - Bullet -> - [(Point2, Either Creature Wall)] -> - World -> - (World, Bullet) +movePenBullet :: Bullet -> [(Point2, Either Creature Wall)] -> World -> (World, Bullet) movePenBullet bu hitstream w = case hitstream of [] -> (w, moveBullet bu) - ((p, crwl) : strm) -> - if penThing crwl - then first (damageThingHit bu (p, crwl)) $ movePenBullet bu strm w - else expireAndDamage bu hitstream w + ((p, crwl) : strm) | penThing crwl -> + first (damageThingHit bu (p, crwl)) $ movePenBullet bu strm w + _ -> expireAndDamage bu hitstream w penThing :: Either Creature Wall -> Bool penThing (Left _) = True diff --git a/tags b/tags index 62d5e0b57..3d6af848b 100644 --- a/tags +++ b/tags @@ -3429,7 +3429,7 @@ applyGravityPU src/Dodge/Projectile/Update.hs 56;" f applyIndividualDamage src/Dodge/Creature/Damage.hs 49;" f applyIndividualDamage' src/Dodge/Creature/Damage.hs 52;" f applyInvLock src/Dodge/HeldUse.hs 177;" f -applyMagnetsToBul src/Dodge/Bullet.hs 33;" f +applyMagnetsToBul src/Dodge/Bullet.hs 32;" f applyNoDamage src/Dodge/Creature/Damage.hs 11;" f applyPastDamages src/Dodge/Creature/State.hs 142;" f applyPiercingDamage src/Dodge/Creature/Damage.hs 57;" f @@ -3864,7 +3864,7 @@ damageHP src/Dodge/Creature/Damage.hs 65;" f damageMaterial src/Dodge/Material/Damage.hs 7;" f damageSensor src/Dodge/Placement/Instance/Sensor.hs 15;" f damageStone src/Dodge/Material/Damage.hs 20;" f -damageThingHit src/Dodge/Bullet.hs 182;" f +damageThingHit src/Dodge/Bullet.hs 183;" f damageTypeThreshold src/Dodge/Placement/Instance/Sensor.hs 45;" f damageWall src/Dodge/Wall/Damage.hs 15;" f damageWallEffect src/Dodge/Wall/DamageEffect.hs 11;" f @@ -3985,7 +3985,6 @@ deleteWallFromZones src/Dodge/Wall/Zone.hs 23;" f deleteWallID src/Dodge/Wall/Delete.hs 13;" f deleteWallIDs src/Dodge/Wall/Delete.hs 28;" f denormalEdges src/Polyhedra.hs 136;" f -destroyAt src/Dodge/Bullet.hs 203;" f destroyBlock src/Dodge/Block.hs 56;" f destroyDoor src/Dodge/Block.hs 83;" f destroyInvItem src/Dodge/Inventory.hs 39;" f @@ -4081,7 +4080,7 @@ doItmCrWdWd src/Dodge/Euse.hs 27;" f doLoop src/Loop.hs 60;" f doMCrAc src/Dodge/CreatureEffect.hs 57;" f doMP2Ac src/Dodge/CreatureEffect.hs 73;" f -doMagnetBuBu src/Dodge/Bullet.hs 36;" f +doMagnetBuBu src/Dodge/Bullet.hs 35;" f doMagnetBuBu src/Dodge/MagnetBuBu.hs 7;" f doMagnetUpdate src/Dodge/Magnet/Update.hs 6;" f doModificationEffect src/Dodge/ModificationEffect.hs 7;" f @@ -4319,7 +4318,7 @@ expandPolyBy src/Dodge/LevelGen/StaticWalls.hs 91;" f expandPolyByFixed src/Dodge/LevelGen/StaticWalls.hs 97;" f expandPolyCorners src/Dodge/LevelGen/StaticWalls.hs 103;" f expandToSquare src/Dodge/LevelGen/StaticWalls/Deprecated.hs 83;" f -expireAndDamage src/Dodge/Bullet.hs 189;" f +expireAndDamage src/Dodge/Bullet.hs 190;" f expireAndDamageFL src/Dodge/Flame.hs 47;" f explodeShell src/Dodge/Projectile/Update.hs 238;" f explosionS src/Dodge/SoundLogic/ExternallyGeneratedSounds.hs 416;" f @@ -4576,7 +4575,7 @@ highBar src/Dodge/Room/Foreground.hs 89;" f highDiagonalMesh src/Dodge/Room/Foreground.hs 35;" f highMesh src/Dodge/Room/Foreground.hs 25;" f hit1S src/Dodge/SoundLogic/ExternallyGeneratedSounds.hs 432;" f -hitEffFromBul src/Dodge/Bullet.hs 155;" f +hitEffFromBul src/Dodge/Bullet.hs 157;" f hitS src/Dodge/SoundLogic/ExternallyGeneratedSounds.hs 400;" f holdForm src/Dodge/Creature/Boid.hs 136;" f holsterWeapon src/Dodge/Creature/Volition.hs 14;" f @@ -4905,7 +4904,7 @@ makeDefaultCorpse src/Dodge/Corpse/Make.hs 14;" f makeDoorDebris src/Dodge/Block/Debris.hs 18;" f makeEnumOption src/Dodge/Menu/OptionType.hs 13;" f makeExplosionAt src/Dodge/WorldEvent/Explosion.hs 72;" f -makeFlak src/Dodge/Bullet.hs 141;" f +makeFlak src/Dodge/Bullet.hs 142;" f makeFlame src/Dodge/Flame.hs 131;" f makeFlameExplosionAt src/Dodge/WorldEvent/Explosion.hs 55;" f makeFlamelet src/Dodge/EnergyBall.hs 17;" f @@ -5046,12 +5045,12 @@ modTo src/Geometry/Zone.hs 10;" f mouseClickOptionsList src/Dodge/Update/Input/ScreenLayer.hs 59;" f mouseCursorType src/Dodge/Render/Picture.hs 80;" f mouseWorldPos src/Dodge/Base/Coordinate.hs 48;" f -moveBullet src/Dodge/Bullet.hs 198;" f +moveBullet src/Dodge/Bullet.hs 199;" f moveCombineSel src/Dodge/Update/Scroll.hs 112;" f moveHammerUp src/Dodge/Hammer.hs 5;" f moveInverseShockwave src/Dodge/Shockwave/Update.hs 53;" f moveLSThen src/Dodge/Placement/Instance/LightSource.hs 30;" f -movePenBullet src/Dodge/Bullet.hs 213;" f +movePenBullet src/Dodge/Bullet.hs 214;" f moveRoomBy src/Dodge/Room/Link.hs 53;" f moveShockwave src/Dodge/Shockwave/Update.hs 17;" f moveToSideFirstOutLink src/Dodge/Room/Warning.hs 54;" f @@ -5186,7 +5185,7 @@ pauseSound src/Dodge/SoundLogic.hs 41;" f pauseTime src/Dodge/Update.hs 180;" f peZoneSize src/Dodge/Zoning/Pathing.hs 46;" f pedestalRoom src/Dodge/Room/Containing.hs 50;" f -penThing src/Dodge/Bullet.hs 225;" f +penThing src/Dodge/Bullet.hs 226;" f perMat src/MatrixHelper.hs 49;" f perceptionUpdate src/Dodge/Creature/Perception.hs 22;" f performAction src/Dodge/Creature/Action.hs 92;" f @@ -5673,7 +5672,7 @@ setCrPosture src/Dodge/Creature/YourControl.hs 172;" f setDepth src/Picture/Base.hs 128;" f setDirPS src/Dodge/PlacementSpot.hs 49;" f setFallback src/Dodge/PlacementSpot.hs 127;" f -setFromToDams src/Dodge/Bullet.hs 177;" f +setFromToDams src/Dodge/Bullet.hs 178;" f setInLinks src/Dodge/RoomLink.hs 51;" f setInLinksByType src/Dodge/RoomLink.hs 54;" f setInLinksPD src/Dodge/RoomLink.hs 74;" f @@ -5917,6 +5916,7 @@ stone5S src/Dodge/SoundLogic/ExternallyGeneratedSounds.hs 468;" f stoneDebris src/Dodge/Block/Debris.hs 137;" f stoneWallDamage src/Dodge/Wall/DamageEffect.hs 24;" f stopAllSounds src/Sound.hs 124;" f +stopBulletAt src/Dodge/Bullet.hs 205;" f stopPushing src/Dodge/Block.hs 107;" f stopSoundFrom src/Dodge/SoundLogic.hs 206;" f strFromEquipment src/Dodge/Creature/Statistics.hs 17;" f @@ -6176,8 +6176,8 @@ updateBarrel src/Dodge/Barreloid.hs 45;" f updateBarreloid src/Dodge/Barreloid.hs 13;" f updateBaseWheelEvent src/Dodge/Update/Scroll.hs 28;" f updateBounds src/Dodge/Update/Camera.hs 215;" f -updateBulVel src/Dodge/Bullet.hs 58;" f -updateBullet src/Dodge/Bullet.hs 22;" f +updateBulVel src/Dodge/Bullet.hs 57;" f +updateBullet src/Dodge/Bullet.hs 21;" f updateBullets src/Dodge/Update.hs 523;" f updateCamera src/Dodge/Update/Camera.hs 27;" f updateCloseObjects src/Dodge/Inventory.hs 110;" f