Refactor, add bullet modules and weapon effect modifiers

This commit is contained in:
2021-05-27 02:50:33 +02:00
parent 0187ae6001
commit 346c426b43
13 changed files with 395 additions and 144 deletions
+80 -70
View File
@@ -18,6 +18,7 @@ import Dodge.Item.Weapon.TriggerType
import Dodge.Item.Weapon.ExtraEffect
import Dodge.Item.Weapon.UseEffect
import Dodge.Item.Weapon.Laser
import Dodge.Item.Weapon.Shell
import Dodge.Default.Weapon
import Dodge.Item.Weapon.Booster
import Dodge.Item.Weapon.Grenade
@@ -43,23 +44,22 @@ import qualified Data.Set as S
--import qualified Data.Map as M
pistol :: Item
pistol = Weapon
pistol = defaultGun
{ _itName = "PISTOL"
, _itIdentity = Pistol
, _wpMaxAmmo = 15
, _wpLoadedAmmo = 15
, _wpAmmo = GenericAmmo
, _wpReloadTime = 40
, _wpReloadState = 0
, _itUseRate = 8
, _itUseTime = 0
, _itUse = \_ ->
hammerCheck
. shootWithSound 0
. withRandomDir 0.1
. withMuzFlare
. withVelWthHiteff (30,0) 2
$ destroyOnImpact bulHitCr bulHitWall' bulHitFF'
, _itUse = useAmmoParams
, _itUseModifiers =
[ hammerCheckI
, shootWithSoundI 0
, withRandomDirI 0.1
, withMuzFlareI
]
, _itLeftClickUse = Nothing
, _wpSpread = 0.02
, _wpRange = 20
@@ -80,7 +80,20 @@ pistol = Weapon
, _itInvColor = white
, _itTargeting = Nothing
, _itWorldTrigger = Nothing
, _wpAmmo = basicBullet
}
basicBullet :: Ammo
basicBullet = BulletAmmo
{ _amString = "BULLET"
, _amBulEff = destroyOnImpact bulHitCr bulHitWall' bulHitFF'
, _amBulWth = 2
, _amBulVel = (30,0)
}
useAmmoParams :: Item -> Creature -> World -> World
useAmmoParams it = withVelWthHiteff (_amBulVel b) (_amBulWth b) (_amBulEff b)
where
b = _wpAmmo it
effectGun :: String -> (Creature -> World -> World) -> Item
effectGun name eff = defaultGun
{ _itName = name ++ "Gun"
@@ -118,6 +131,7 @@ autoGun = defaultGun
, _itScrollUp = incCharMode
, _itScrollDown = decCharMode
, _itInvDisplay = basicWeaponDisplay
, _wpAmmo = basicBullet
}
autoFireMode, singleFireMode, autoGunNonTwistEff :: Creature -> World -> World
autoFireMode = shootWithSound (fromIntegral autoGunSound)
@@ -289,19 +303,25 @@ hvAutoGun = defaultAutoGun
, _wpReloadState = 0
, _itUseRate = 25
, _itUseTime = 0
, _itUse = \_ -> rateIncAB 24 10 (torqueBeforeForced 0.1 mkHvBul) $ torqueAfter 0.2 mkHvBul
, _itUse = \it -> rateIncAB 24 10 (torqueBeforeForced 0.1 (mkHvBul it))
(torqueAfter 0.2 (mkHvBul it))
, _wpRange = 20
, _itFloorPict = onLayer FlItLayer $ color orange $ polygon $ rectNESW 5 5 (-5) (-5)
, _itAimingSpeed = 0.2
, _itAimingRange = 1
, _itEquipPict = pictureWeaponOnAim $ color orange $ polygon $ rectNESW 5 5 (-5) (-5)
, _wpAmmo = BulletAmmo
{_amString = "HVBULLET"
, _amBulEff = penWalls hvBulHitCr' hvBulHitWall' bulHitFF'
, _amBulWth = 6
, _amBulVel = (80,0)
}
}
where
mkHvBul = withSound (fromIntegral longGunSound)
mkHvBul it = withSound (fromIntegral longGunSound)
. withThinSmoke
. withMuzFlare
. withVelWthHiteff (80,0) 6
$ penWalls hvBulHitCr' hvBulHitWall' bulHitFF'
$ useAmmoParams it
ltAutoGun :: Item
ltAutoGun = defaultAutoGun
{ _itName = "AUTO-LT"
@@ -337,11 +357,11 @@ miniGun = defaultAutoGun
, _itUseRate = 2
, _itUseTime = 0
, _itUse = \_ -> withWarmUp 50 . torqueBefore 0.03 . withSidePush 50 . withRecoil 15
. withRandomDir 0.1
. withRandomOffset 9
. withMuzFlare
. withVelWthHiteff (30,0) 2
$ destroyOnImpact bulBounceArmCr' bulHitWall' bulHitFF'
. withRandomDir 0.1
. withRandomOffset 9
. withMuzFlare
. withVelWthHiteff (30,0) 2
$ destroyOnImpact bulBounceArmCr' bulHitWall' bulHitFF'
, _wpRange = 20
, _itFloorPict = onLayer FlItLayer $ color red $ polygon $ rectNESW 9 5 (-9) (-5)
, _itAimingSpeed = 0.4
@@ -529,6 +549,16 @@ aTeslaArc' cr w
(sideOffset,g) = randomR (-5,5) $ _randGen w
dir = _crDir cr
remoteShellPic' :: Projectile -> Picture
remoteShellPic' pj
| t > 40 = onLayerL [levLayer CrLayer - 2]
$ uncurry translate pos $ rotate dir $ remoteShellPic t
| otherwise = uncurry translate pos $ rotate dir $ remoteShellPic t
where
t = _pjTimer pj
pos = _pjPos pj
dir = _pjDir pj
remoteShellPic
:: Int -- ^ Timer
-> Picture
@@ -735,13 +765,18 @@ fireRemoteLauncher cr w = setLocation
cid = _crID cr
dir = _crDir cr
pos = _crPos cr +.+ rotateV dir (_crRad cr + 1,0)
remRocket = IM.insert i $ Projectile
remRocket = IM.insert i $ Shell
{ _pjPos = pos
, _pjStartPos = pos
, _pjVel = rotateV dir (1,0)
, _pjDraw = \_ -> blank
, _pjDraw = remoteShellPic'
, _pjID = i
, _pjUpdate = \_ -> moveRemoteShell 50 i cid itid dir
, _pjUpdate = \pj -> decTimMvVel pj . moveRemoteShell cid itid pj
, _pjAcc = (0,0)
, _pjDir = dir
, _pjSpin = 0
, _pjPayload = makeExplosionAt
, _pjTimer = 50
}
j = _crInvSel cr
newitid = IM.newKey $ _itemPositions w
@@ -756,69 +791,44 @@ fireRemoteLauncher cr w = setLocation
_ -> w'
itid = fromMaybe newitid maybeitid
moveRemoteShell :: Int -> Int -> Int -> Int -> Float -> World -> World
moveRemoteShell time i cid itid _ w
moveRemoteShell :: Int -> Int -> Projectile -> World -> World
moveRemoteShell cid itid pj w
| time > 40 = if circOnSomeWall oldPos 4 w
then doExplosion w
else over (projectiles . ix i . pjPos) (+.+ vel)
$ set (projectiles . ix i . pjDraw) (\_ -> piclow)
$ set (projectiles . ix i . pjUpdate)
(\_ -> moveRemoteShell (time-1) i cid itid newdir)
$ setScope
w
then doExplosion w
else w & setScope
| time >= 20 = case thingHit of
Just _ -> doExplosion w
Nothing -> over (projectiles . ix i . pjPos) (+.+ vel)
$ set (projectiles . ix i . pjDraw) (\_ -> pic)
$ set (projectiles . ix i . pjUpdate)
(\_ -> moveRemoteShell (time-1) i cid itid newdir)
$ setScope
w
Nothing -> setScope w & projectiles . ix i . pjDir .~ newdir
| time > -99 = case thingHit of
Just _ -> doExplosion
$ stopSoundFrom (ShellSound i)
w
Nothing -> over (projectiles . ix i . pjPos) (+.+ vel)
$ set randGen g
$ set (projectiles . ix i . pjDraw) (\_ -> pic)
$ set (projectiles . ix i . pjUpdate) (\_ -> moveRemoteShell (time-1) i cid itid newdir)
$ over (projectiles . ix i . pjVel) (\v -> accel +.+ frict *.* v)
$ soundFromPos (ShellSound i) newPos (fromIntegral smokeTrailSound) 1 250
$ smokeGen
$ makeFlameletTimed oldPos (0.5 *.* rotateV (pi+sparkD) accel) Nothing 3 10
$ setScope
w
Just _ -> doExplosion $ stopSoundFrom (ShellSound i) w
Nothing -> w & set randGen g
& projectiles . ix i %~
( ( pjVel %~ ( (accel +.+) . (frict *.*) ) )
. ( pjDir .~ newdir )
)
& soundFromPos (ShellSound i) newPos (fromIntegral smokeTrailSound) 1 250
& smokeGen
& makeFlameletTimed oldPos (0.5 *.* rotateV (pi+sparkD) accel) Nothing 3 10
& setScope
| time > -200 = case thingHit of
Just _ -> doExplosion
$ stopSoundFrom (ShellSound i)
w
Nothing -> over (projectiles . ix i . pjPos) (+.+ vel)
$ set (projectiles . ix i . pjDraw) (\_ -> pic)
$ set (projectiles . ix i . pjUpdate) (\_ -> moveRemoteShell (time-1) i cid itid newdir)
$ setScope
w
| otherwise = doExplosion
$ stopSoundFrom (ShellSound i)
w
Just _ -> doExplosion $ stopSoundFrom (ShellSound i) w
Nothing -> setScope w
| otherwise = doExplosion $ stopSoundFrom (ShellSound i) w
where
pj = _projectiles w IM.! i
oldPos = _pjPos pj
vel = _pjVel pj
newPos = oldPos +.+ vel
time = _pjTimer pj
i = _pjID pj
oldPos = _pjPos pj
vel = _pjVel pj
newPos = oldPos +.+ vel
newdir
| SDL.ButtonRight `S.member` _mouseButtons w
&& w ^? creatures . ix cid . crInvSel == w ^? itemPositions . ix itid . itInvId
= _cameraRot w + argV (_mousePos w)
| otherwise = dir
accel = rotateV newdir (2,0)
(frict,g) = randomR (0.6,0.9) $ _randGen w
(frict,g) = randomR (0.6,0.9) $ _randGen w
(sparkD,_) = randomR (-0.5,0.5) $ _randGen w
dir = argV vel
pic = uncurry translate newPos
$ rotate (argV accel) $ remoteShellPic time
piclow = onLayerL [levLayer CrLayer - 2]
$ uncurry translate newPos $ rotate (argV accel)
$ remoteShellPic time
hitCr = fst <$> collideCircCrsPoint oldPos newPos 4 w
hitWl = fst <$> collideCircWalls' oldPos newPos 2 (wallsNearPoint newPos w)
thingHit = hitCr <|> hitWl