Simplify bullet movement code

This commit is contained in:
2025-01-08 20:27:04 +00:00
parent bd42f44278
commit 97317a621b
2 changed files with 82 additions and 87 deletions
+69 -74
View File
@@ -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
+13 -13
View File
@@ -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