Refactor muzzle location when item used, remove saveSlot/seed

This commit is contained in:
2025-10-12 14:54:03 +01:00
parent bbda28cbc1
commit f312cc41ff
5 changed files with 198 additions and 254 deletions
+1
View File
@@ -18,6 +18,7 @@ data SoundOrigin
| CrMouth Int
| CrChasm Int
| CrWeaponSound Int Int
| ItemSound Int Int
| CrWeaponFailSound Int
| MachineSound Int
| MachineAltSound Int
+101 -158
View File
@@ -8,7 +8,6 @@ module Dodge.HeldUse (
heldEffectMuzzles,
) where
import Linear (_xy)
import Color
import Control.Applicative
import Control.Monad
@@ -36,6 +35,7 @@ import Dodge.Tesla
import Geometry
import qualified IntMapHelp as IM
import LensHelp
import Linear (_xy, _xyz)
import ListHelp
import NewInt
import Picture.Base
@@ -205,9 +205,17 @@ heldItemMuzzles itm = \case
AUTORIFLE -> dbwMuzzles & ix 0 . mzPos .~ V2 25 0
BURSTRIFLE -> dbwMuzzles & ix 0 . mzPos .~ V2 25 0 & ix 0 . mzInaccuracy .~ 0.05
MINIGUNX i ->
replicate
i
(Muzzle (V2 30 0) 0 0.05 maguse1 NoFlare MuzzleShootBullet 10)
[ ( Muzzle
(V2 (30 + 40 * fromIntegral j / fromIntegral i) 0)
0
0.05
maguse1
NoFlare
MuzzleShootBullet
10
)
| j <- [0 .. i -1]
]
& ix 0 . mzFlareType .~ MiniGunFlare
BANGROD ->
dbwMuzzles
@@ -646,27 +654,23 @@ loadMuzzle loc cr (b, w) mz = maybe (b, w) (True,) $ case mz ^. mzAmmoSlot of
useLoadedAmmo loc cr mz (Just (usedammo, mag)) $
removeAmmoFromMag usedammo mid w
makeMuzzleFlare :: Muzzle -> LocationDT OItem -> Creature -> World -> World
makeMuzzleFlare mz loc cr = case mz ^. mzFlareType of
makeMuzzleFlare :: Point3Q -> LocationDT OItem -> FlareType -> World -> World
makeMuzzleFlare (p, q) loc = \case
NoFlare -> id
BasicFlare -> basicMuzFlare pos dir
NoLightFlare -> muzFlareAt (V4 10 10 1 3) (pos `v2z` 20) dir
BasicFlare -> basicMuzFlare (p ^. _xy) dir
NoLightFlare -> muzFlareAt (V4 10 10 1 3) p dir
MiniGunFlare ->
oddcheck (cWorld . lWorld . lights .:~ LSParam (pos `v2z` 20) 100 (V3 1 1 0.5))
. muzFlareAt (V4 10 10 1 3) (pos `v2z` 20) dir
HeavySmokeFlare -> basicMuzFlare pos dir
oddcheck (cWorld . lWorld . lights .:~ LSParam p 100 (V3 1 1 0.5))
. muzFlareAt (V4 10 10 1 3) p dir
HeavySmokeFlare -> basicMuzFlare (p ^. _xy) dir
LasGunFlare ->
flareCircleAt (getLaserColor loc) 0.8 (pos `v2z` 20)
flareCircleAt (getLaserColor loc) 0.8 p
. ( cWorld . lWorld . lights
.:~ LSParam (pos `v2z` 10) 100 (xyzV4 $ getLaserColor loc)
.:~ LSParam p 100 (getLaserColor loc ^. _xyz) -- p had z=10
)
TeslaGunFlare -> cWorld . lWorld . lights .:~ LSParam (pos `v2z` 10) 100 (V3 0 0 1)
TeslaGunFlare -> cWorld . lWorld . lights .:~ LSParam p 100 (V3 0 0 1) -- p had z=10
where
(V3 x y _, q) =
locOrient loc cr
`Q.comp` (_mzPos mz `v2z` 0, Q.axisAngle (V3 0 0 1) (_mzRot mz))
pos = (cr ^. crPos . _xy) + rotateV (_crDir cr) (V2 x y)
dir = _crDir cr + Q.qToAng q
dir = Q.qToAng q
oddcheck f w
| odd (w ^. cWorld . lWorld . lClock) = f w
| otherwise = w
@@ -722,12 +726,12 @@ useLoadedAmmo ::
World ->
World
useLoadedAmmo loc cr mz m w =
makeMuzzleFlare mz loc cr $ case _mzEffect mz of
makeMuzzleFlare pq loc (mz ^. mzFlareType) $ case _mzEffect mz of
MuzzleShootBullet -> shootBullets loc cr (mz, x, magtree) w
MuzzleLaser -> creatureShootLaser loc cr mz w
MuzzlePulseLaser -> creatureShootPulseLaser loc cr mz w
MuzzlePulseBall -> creatureShootPulseBall loc cr mz w
MuzzleTesla -> shootTeslaArc loc cr mz w
MuzzleLaser -> creatureShootLaser pq' loc (w & randGen .~ g)
MuzzlePulseLaser -> creatureShootPulseLaser pq' cr (w & randGen .~ g)
MuzzlePulseBall -> shootPulseBall pq' (w & randGen .~ g)
MuzzleTesla -> shootTeslaArc pq' loc (w & randGen .~ g)
MuzzleTractor -> shootTractorBeam cr w
MuzzleRLauncher -> createProjectileR pq loc magtree cr w
MuzzleGLauncher ->
@@ -738,7 +742,8 @@ useLoadedAmmo loc cr mz m w =
(getPJStabiliser itmtree)
cr
w
MuzzleNozzle{} -> useGasParams mitid mz loc cr $ walkNozzle mz itm w
MuzzleNozzle{} -> useGasParams pq' mitid mz loc cr $ walkNozzle mz itm
$ w & randGen .~ g
MuzzleShatter -> shootShatter itm cr w
MuzzleDetector ->
itemDetectorEffect
@@ -754,13 +759,14 @@ useLoadedAmmo loc cr mz m w =
MuzzleScroller -> useTimeScrollGun itm cr w
where
pq = muzzlePos loc cr mz
(pq', g) = muzzleRandPos loc cr mz `runState` (w ^. randGen)
itmtree = loc ^. locDT
mitid = magtree ^. dtValue . _1 . itID
itm = itmtree ^. dtValue . _1
(x, magtree) = fromJust m
muzzlePos :: LocationDT OItem -> Creature -> Muzzle -> Point3Q
muzzlePos m cr muz = (p1,q1) `Q.comp` pq `Q.comp` (p3,q3)
muzzlePos m cr muz = (p1, q1) `Q.comp` pq `Q.comp` (p3, q3)
where
pq = locOrient m cr
p1 = cr ^. crPos
@@ -768,6 +774,16 @@ muzzlePos m cr muz = (p1,q1) `Q.comp` pq `Q.comp` (p3,q3)
p3 = addZ 0 $ muz ^. mzPos
q3 = Q.qz $ muz ^. mzRot
muzzleRandPos :: LocationDT OItem -> Creature -> Muzzle -> State StdGen Point3Q
muzzleRandPos m cr muz = do
a <- state $ randomR (- inacc, inacc)
y <- case muz ^. mzRandomOffset of
0 -> return 0
i -> state $ randomR (- i, i)
return $ muzzlePos m cr muz `Q.comp` (V3 0 y 0, Q.qz a)
where
inacc = _mzInaccuracy muz
getAttachedSFLink :: ItemSF -> DTree OItem -> Maybe (NewInt ItmInt)
getAttachedSFLink sf = (^? dtRight . folding (find f) . dtValue . _1 . itID)
where
@@ -822,28 +838,15 @@ tractorBeamAt pos outpos dir power =
, _tbTime = 10
}
creatureShootLaser :: LocationDT OItem -> Creature -> Muzzle -> World -> World
creatureShootLaser loc cr mz w =
w
& randGen .~ g
& shootLaser
(CrWeaponSound (_crID cr) 0)
(getLaserDamage loc)
(getLaserPhaseV loc)
pos
dir
(getLaserColor loc)
where
(V3 x y _, q) =
locOrient loc cr
`Q.comp` ((_mzPos mz + V2 0 offset) `v2z` 0, Q.axisAngle (V3 0 0 1) (_mzRot mz))
pos = cr ^. crPos . _xy + rotateV (_crDir cr) (V2 x y)
dir = _crDir cr + Q.qToAng q + a
(a, g) = randomR (- inacc, inacc) $ _randGen w
inacc = _mzInaccuracy mz
offset = case mz ^. mzRandomOffset of
0 -> 0
i -> fst . randomR (- i, i) $ _randGen w
creatureShootLaser :: Point3Q -> LocationDT OItem -> World -> World
creatureShootLaser (p, q) loc =
shootLaser
(ItemSound (loc ^. locDT . dtValue . _1 . itID . unNInt) 0)
(getLaserDamage loc)
(getLaserPhaseV loc)
(p ^. _xy)
(Q.qToAng q)
(getLaserColor loc)
shootLaser ::
SoundOrigin ->
@@ -854,37 +857,24 @@ shootLaser ::
Color ->
World ->
World
shootLaser so lt pv p dir col w =
w
& cWorld . lWorld . lasers
.:~ Laser
{ _lpType = lt
, _lpPhaseV = pv
, _lpPos = p
, _lpDir = dir
, _lpColor = col
}
& soundContinue so p tone440sawtoothquietS (Just 2)
shootLaser so lt pv p dir col =
( cWorld . lWorld . lasers
.:~ Laser
{ _lpType = lt
, _lpPhaseV = pv
, _lpPos = p
, _lpDir = dir
, _lpColor = col
}
)
. soundContinue so p tone440sawtoothquietS (Just 2)
creatureShootPulseLaser :: LocationDT OItem -> Creature -> Muzzle -> World -> World
creatureShootPulseLaser loc cr mz w =
w
& randGen .~ g
& shootPulseLaser
creatureShootPulseLaser :: Point3Q -> Creature -> World -> World
creatureShootPulseLaser (p,q) cr =
shootPulseLaser
(CrWeaponSound (_crID cr) 0)
pos
dir
where
(V3 x y _, q) =
locOrient loc cr
`Q.comp` ((_mzPos mz + V2 0 offset) `v2z` 0, Q.axisAngle (V3 0 0 1) (_mzRot mz))
pos = cr ^. crPos . _xy + rotateV (_crDir cr) (V2 x y)
dir = _crDir cr + Q.qToAng q + a
(a, g) = randomR (- inacc, inacc) $ _randGen w
inacc = _mzInaccuracy mz
offset = case mz ^. mzRandomOffset of
0 -> 0
i -> fst . randomR (- i, i) $ _randGen w
(p ^. _xy)
(Q.qToAng q)
shootPulseLaser :: SoundOrigin -> Point2 -> Float -> World -> World
shootPulseLaser so p dir w =
@@ -899,37 +889,22 @@ shootPulseLaser so p dir w =
}
& soundStart so p lasPulseS Nothing
creatureShootPulseBall :: LocationDT OItem -> Creature -> Muzzle -> World -> World
creatureShootPulseBall loc cr mz w = w & randGen .~ g & shootPulseBall pos dir
where
(V3 x y _, q) =
locOrient loc cr
`Q.comp` ((_mzPos mz + V2 0 offset) `v2z` 0, Q.axisAngle (V3 0 0 1) (_mzRot mz))
pos = cr ^. crPos . _xy + rotateV (_crDir cr) (V2 x y)
dir = _crDir cr + Q.qToAng q + a
(a, g) = randomR (- inacc, inacc) $ _randGen w
inacc = _mzInaccuracy mz
offset = case mz ^. mzRandomOffset of
0 -> 0
i -> fst . randomR (- i, i) $ _randGen w
shootPulseBall :: Point2 -> Float -> World -> World
shootPulseBall p dir w =
shootPulseBall :: Point3Q -> World -> World
shootPulseBall (p, q) w =
w
& cWorld . lWorld . pulseBalls . at i
?~ PulseBall
{ _pbPos = p
, _pbVel = 3.5 * unitVectorAtAngle dir
{ _pbPos = p ^. _xy
, _pbVel = 3.5 * unitVectorAtAngle (Q.qToAng q)
, _pbTimer = 200
, _pbID = i
}
& soundStart (PBSound i) p energyReleaseS Nothing
& soundStart (PBSound i) (p ^. _xy) energyReleaseS Nothing
where
i = IM.newKey $ w ^. cWorld . lWorld . pulseBalls
removeAmmoFromMag :: Int -> Int -> World -> World
removeAmmoFromMag x magid =
cWorld . lWorld . items . ix magid . itConsumables . _Just -~ x
removeAmmoFromMag x magid = cWorld . lWorld . items . ix magid . itConsumables . _Just -~ x
getBulletType :: DTree OItem -> Maybe Bullet
getBulletType magtree =
@@ -995,22 +970,13 @@ shootBullets loc cr (mz, x, magtree) w = fromMaybe w $ do
return $ foldl' (&) w (replicate x (shootBullet thebullet loc cr mz))
shootBullet :: Bullet -> LocationDT OItem -> Creature -> Muzzle -> World -> World
shootBullet bu loc cr mz w = makeBullet bu itm bulpos dir . (randGen .~ g) $ w
shootBullet bu loc cr mz w = makeBullet bu itm pq . (randGen .~ g) $ w
where
(V3 x y _, q) =
locOrient loc cr
`Q.comp` ((_mzPos mz + V2 0 offset) `v2z` 0, Q.axisAngle (V3 0 0 1) (_mzRot mz))
(pq, g) = muzzleRandPos loc cr mz `runState` (w ^. randGen)
itm = loc ^. locDT . dtValue . _1
bulpos = cr ^. crPos . _xy + rotateV (_crDir cr) (V2 x y)
(a, g) = randomR (- inacc, inacc) $ _randGen w
dir = _crDir cr + Q.qToAng q + a
inacc = _mzInaccuracy mz
offset = case mz ^. mzRandomOffset of
0 -> 0
i -> fst . randomR (- i, i) $ _randGen w
makeBullet :: Bullet -> Item -> Point2 -> Float -> World -> World
makeBullet thebullet itm bulpos dir w =
makeBullet :: Bullet -> Item -> Point3Q -> World -> World
makeBullet thebullet itm (p, q) w =
w & randGen .~ g''
& cWorld . lWorld . bullets
.:~ ( thebullet
@@ -1020,6 +986,8 @@ makeBullet thebullet itm bulpos dir w =
& buDrag *~ drag
)
where
bulpos = p ^. _xy
dir = Q.qToAng q
g = _randGen w
(drag, g') = case heldItemRifling (_ibtHeld $ _itType itm) of --unsafe
ConstFloat x -> (x, g)
@@ -1120,33 +1088,26 @@ mcUseHeld hit = case hit of
_ -> mcShootAuto
useGasParams ::
Point3Q ->
NewInt ItmInt ->
Muzzle ->
LocationDT OItem ->
Creature ->
World ->
World
useGasParams (NInt magitid) mz loc cr w =
useGasParams pq (NInt magitid) mz loc cr w =
w
& createGas gastype pressure pos dir cr
& randGen .~ g'
& createGas gastype pressure (pq ^. _1 . _xy) dir cr
& randGen .~ g
where
itm = loc ^. locDT . dtValue . _1
(pressure, g) = doGenFloat (_nzPressure $ _mzEffect mz) (_randGen w)
gastype = fromMaybe (error "cannot find gas ammo") $ do
hit <- itm ^? itType . ibtHeld
fueltype <- w ^? cWorld . lWorld . items . ix magitid >>= magAmmoParams >>= (^? ampCreateGas)
fueltype <- w ^? cWorld . lWorld . items . ix magitid
>>= magAmmoParams >>= (^? ampCreateGas)
gasType hit fueltype
(V3 x y _, q) =
locOrient loc cr
`Q.comp` ((_mzPos mz + V2 0 offset) `v2z` 0, Q.axisAngle (V3 0 0 1) (_mzRot mz))
pos = cr ^. crPos . _xy + rotateV (_crDir cr) (V2 x y)
(a, g') = randomR (- inacc, inacc) g
inacc = _mzInaccuracy mz
offset = case mz ^. mzRandomOffset of
0 -> 0
i -> fst . randomR (- i, i) $ _randGen w
dir = _crDir cr + Q.qToAng q + a + _nzAngle (_itParams itm)
dir = Q.qToAng (pq ^. _2) + _nzAngle (_itParams itm)
gasType :: HeldItemType -> GasFuel -> Maybe GasCreate
gasType hit _ = case hit of
@@ -1210,30 +1171,24 @@ mcShootAuto itm mc w
w
& cWorld . lWorld . items . ix i . itTimeLastUsed
.~ w ^. cWorld . lWorld . lClock
& makeBullet defaultBullet itm pos dir
-- & makeBullet defaultBullet itm pos dir
| otherwise = w
where
lastused = itm ^. itTimeLastUsed
pos = _mcPos mc +.+ 20 *.* unitVectorAtAngle dir
dir = mc ^?! mcType . _McTurret . tuDir
-- pos = _mcPos mc +.+ 20 *.* unitVectorAtAngle dir
-- dir = mc ^?! mcType . _McTurret . tuDir
-- | assumes that the item is held
shootTeslaArc :: LocationDT OItem -> Creature -> Muzzle -> World -> World
shootTeslaArc loc cr mz w =
shootTeslaArc :: Point3Q -> LocationDT OItem -> World -> World
shootTeslaArc (p, q) loc w =
w' & cWorld . lWorld . items . ix itid . itParams .~ ip
& soundContinue (CrWeaponSound (_crID cr) 0) pos elecCrackleS (Just 2)
& soundContinue (ItemSound itid 0) pos elecCrackleS (Just 2)
where
itm = loc ^. locDT . dtValue . _1
itid = itm ^. itID . unNInt
(w', ip) = makeTeslaArc (itm ^. itParams) pos dir w
(V3 x y _, q) =
locOrient loc cr
`Q.comp` ((_mzPos mz + V2 0 offset) `v2z` 0, Q.axisAngle (V3 0 0 1) (_mzRot mz))
pos = cr ^. crPos . _xy + rotateV (_crDir cr) (V2 x y)
dir = _crDir cr + Q.qToAng q
offset = case mz ^. mzRandomOffset of
0 -> 0
i -> fst . randomR (- i, i) $ _randGen w
(w', ip) = makeTeslaArc (itm ^. itParams) pos (Q.qToAng q) w
pos = p ^. _xy
determineProjectileTracking :: DTree OItem -> DTree OItem -> RocketHoming
determineProjectileTracking magtree itmtree =
@@ -1265,7 +1220,7 @@ determineProjectileTracking magtree itmtree =
_ -> False
createProjectileR ::
Point3Q ->
Point3Q ->
LocationDT OItem ->
DTree OItem ->
Creature ->
@@ -1323,18 +1278,17 @@ createProjectile ::
Creature ->
World ->
World
createProjectile x pjtype mtree stab cr w = fromMaybe (failsound w) $ do
createProjectile x pjtype mtree stab cr w = fromMaybe w $ do
magitid <- mtree ^? dtValue . _1 . itID . unNInt
ammoitem <- w ^? cWorld . lWorld . items . ix magitid
let rdetonate =
(^. dtValue . _1 . itID) <$> find isrdet (mtree ^. dtLeft)
rscreen =
(^. dtValue . _1 . itID) <$> find isrscreen (mtree ^. dtLeft)
let rdetonate = getmid isrdet
rscreen = getmid isrscreen
aparams <-
((mtree ^? dtLeft) >>= find isampay >>= (^? dtValue . _1 . itType . ibtAttach . shellPayload))
<|> magAmmoParams ammoitem ^? _Just . ampPayload
return . makesound $ createShell x rdetonate rscreen stab pjtype aparams cr w
return $ createShell x rdetonate rscreen stab pjtype aparams cr w
where
getmid t = find t (mtree ^. dtLeft) <&> (^. dtValue . _1 . itID)
isrdet :: DTree OItem -> Bool
isrdet y = case y ^. dtValue . _2 of
RemoteDetonatorSF{} -> True
@@ -1348,17 +1302,6 @@ createProjectile x pjtype mtree stab cr w = fromMaybe (failsound w) $ do
AmmoPayloadSF{} -> True
_ -> False
-- the sound should be moved to the projectile firing
makesound =
soundMultiFrom
[CrWeaponSound (_crID cr) j | j <- [0 .. 3]]
(cr ^. crPos . _xy)
tap4S
Nothing
failsound w' = case w' ^? input . mouseButtons . ix SDL.ButtonLeft of
Just 0 -> soundStart (CrWeaponSound (_crID cr) 0) (cr ^. crPos . _xy) click1S Nothing w'
_ -> soundContinue (CrWeaponSound (_crID cr) 0) (cr ^. crPos . _xy) click1S Nothing w'
---- need to add these to muzzle flare?
--makeMuzzleSmoke :: Muzzle -> Item -> Creature -> World -> World
--makeMuzzleSmoke mz itm cr w = case mz ^. mzFlareType of
+2 -2
View File
@@ -27,8 +27,8 @@ startSeedGame _ i u =
startSeedGameConc :: Int -> PreloadData -> IO (Universe -> Maybe Universe)
startSeedGameConc seed pdata = do
w <- generateWorldFromSeed (pdata ^?! renderData) seed
createDirectoryIfMissing True "saveSlot"
writeFile "saveSlot/seed" $ show seed
createDirectoryIfMissing True "generated/saveSlot"
writeFile "generated/saveSlot/seed" $ show seed
return $
Just
. saveWorldInSlot (LevelStartSlot 0)