Refactor weapon usages

This commit is contained in:
2021-08-27 16:31:43 +01:00
parent cb8613036f
commit dd44a93476
11 changed files with 308 additions and 60 deletions
+9 -3
View File
@@ -7,6 +7,7 @@ import Dodge.Item.Attachment
import Dodge.Item.Attachment.Data
import Dodge.Item.Weapon.ExtraEffect
import Dodge.Item.Weapon.InventoryDisplay
import Dodge.Item.Weapon.AmmoParams
import Dodge.Item.Data
import Dodge.Picture.Layer
import Dodge.Item.Draw
@@ -30,9 +31,14 @@ autoGun = defaultAutoGun
, _wpReloadState = 0
, _itUseRate = 5
, _itUseTime = 0
, _itUse = \_ -> charFiringStrat
[('M',autoFireMode)
,('S',singleFireMode)
, _itUse = useAmmoParams
, _itUseModifiers =
[ charFiringStratI
[('M',shootWithSoundI autoGunSound . torqueBeforeForcedI 0.05)
,('S',hammerCheckI . shootWithSoundI autoGunSound)
]
, withRandomDirI (autogunSpread/2)
, withMuzFlareI
]
, _wpSpread = autogunSpread
, _wpRange = 20
+4 -1
View File
@@ -37,7 +37,10 @@ launcher = defaultGun
, _wpReloadState = 0
, _itUseRate = 20
, _itUseTime = 0
, _itUse = shootWithSound launcherSound . aRocketWithItemParams
, _itUse = aRocketWithItemParams
, _itUseModifiers =
[ shootWithSoundI launcherSound
]
, _wpSpread = 0.02
, _wpRange = 20
, _itFloorPict = onLayer FlItLayer launcherPic
+185 -3
View File
@@ -1,6 +1,32 @@
{- |
Weapon effects when pulling the trigger. -}
module Dodge.Item.Weapon.TriggerType
-- ( hammerCheckI
-- , shootWithSoundI
-- , shootWithSoundForI
-- , withMuzFlareI
-- , withVelWthHiteff
-- , ammoUseCheckI
-- , rateIncABI
-- , torqueBeforeForcedI
-- , torqueAfterI
-- , withSoundI
-- , withThickSmokeI
-- , withThinSmokeI
-- , withRandomOffsetI
-- , withRandomDirI
-- , withRecoilI
-- , withSidePushAfterI
-- , withSidePushI
-- , withWarmUpI
-- , spreadNumI
-- , numI
-- , randWalkAngle -- ^ should be made into a modifier, perhaps
-- , hammerCheckI
-- , hammerCheckL
-- , shootL
-- , useTimeCheckI
-- ) where
where
import Dodge.Data
import Dodge.SoundLogic
@@ -20,6 +46,18 @@ import Data.Maybe
import qualified Data.IntMap.Strict as IM
import Data.Foldable
withThinSmokeI
:: (Item -> Creature -> World -> World) -- ^ Underlying effect
-> Item
-> Creature
-> World
-> World
withThinSmokeI eff item cr w = eff item cr $ foldl' (flip $ makeThinSmokeAt . (+.+ pos)) w ps
where
dir = _crDir cr
pos = _crPos cr +.+ (_crRad cr +0.5) *.* unitVectorAtAngle dir
ps = (replicateM 5 . randInCirc) 8 & evalState $ _randGen w
withThinSmoke
:: (Creature -> World -> World) -- ^ Underlying effect
-> Creature
@@ -31,6 +69,17 @@ withThinSmoke eff cr w = eff cr $ foldl' (flip $ makeThinSmokeAt . (+.+ pos)) w
pos = _crPos cr +.+ (_crRad cr +0.5) *.* unitVectorAtAngle dir
ps = (replicateM 5 . randInCirc) 8 & evalState $ _randGen w
withThickSmokeI
:: (Item -> Creature -> World -> World) -- ^ Underlying effect
-> Item
-> Creature
-> World
-> World
withThickSmokeI eff item cr w = eff item cr $ foldl' (flip $ makeThickSmokeAt . (+.+ pos)) w ps
where
dir = _crDir cr
pos = _crPos cr +.+ (_crRad cr + 15) *.* unitVectorAtAngle dir
ps = (replicateM 20 . randInCirc) 8 & evalState $ _randGen w
withThickSmoke
:: (Creature -> World -> World) -- ^ Underlying effect
-> Creature
@@ -121,9 +170,32 @@ rateIncABI startRate fastRate exeffFirst exeffCont eff item cr w
&& _itUseTime item == 0
&& _wpLoadedAmmo item > 0
reloadCondition = _wpLoadedAmmo item == 0
{- |
Shoot a weapon rapidly after a warm up.
Applies ammo check as well. -}
{- | Apply effect after a warm up. -}
withWarmUpI
:: Int -- ^ warm up sound id
-> (Item -> Creature -> World -> World)
-- ^ underlying effect
-> Item
-> Creature
-> World
-> World
withWarmUpI soundID f item cr w
| reloadCondition = fromMaybe w $ startReloadingWeapon cr w
| _wpReloadState item /= 0 = w
| curWarmUp < maxWarmUp = w
& pointerToItem . wpCurWarmUp +~ 2
& soundFrom (CrWeaponSound cid) soundID 2 0
| otherwise = w
& pointerToItem . wpCurWarmUp .~ maxWarmUp
& f item cr
where
cid = _crID cr
itRef = _crInvSel cr
pointerToItem = creatures . ix cid . crInv . ix itRef
curWarmUp = _wpCurWarmUp item
maxWarmUp = _wpMaxWarmUp item
reloadCondition = _wpLoadedAmmo item == 0
{- | Apply effect after a warm up. -}
withWarmUp
:: Int -- ^ warm up sound id
-> (Creature -> World -> World)
@@ -156,7 +228,26 @@ withSound
-> Creature
-> World -> World
withSound soundid f cr = soundOncePos soundid (_crPos cr) . f cr
{- | Adds a sound to a creature based world effect.
The sound is emitted from the creature's position. -}
withSoundI
:: Int -- ^ Sound id
-> (Item -> Creature -> World -> World) -- ^ Underlying effect
-> Item
-> Creature
-> World -> World
withSoundI soundid f item cr = soundOncePos soundid (_crPos cr) . f item cr
withRecoilI
:: Float -- ^ Recoil amount
-> (Item -> Creature -> World -> World)
-> Item
-> Creature
-> World -> World
withRecoilI recoilAmount eff item cr = eff item cr . over (creatures . ix cid) pushback
where
cid = _crID cr
pushback = over crPos (+.+ rotateV (_crDir cr) (V2 ((-recoilAmount) / _crMass cr ) 0))
withRecoil
:: Float -- ^ Recoil amount
-> (Creature -> World -> World)
@@ -198,6 +289,19 @@ withSidePush maxSide eff cr w = eff cr . over (creatures . ix cid) push $ w
-- consider unifying the pushes using a direction vector
{- | Pushes a creature sideways by a random amount.
Applied after the underlying effect. -}
withSidePushAfterI
:: Float -- ^ Maximal possible side push amount
-> (Item -> Creature -> World -> World)
-> Item
-> Creature -- ^ Creature id
-> World -> World
withSidePushAfterI maxSide eff item cr w = over (creatures . ix cid) push . eff item cr $ w
where
cid = _crID cr
push = over crPos (+.+ rotateV (_crDir cr) (V2 0 (pushAmount / _crMass cr)))
(pushAmount, _) = randomR (-maxSide,maxSide) $ _randGen w
{- | Pushes a creature sideways by a random amount.
Applied after the underlying effect. -}
withSidePushAfter
:: Float -- ^ Maximal possible side push amount
-> (Creature -> World -> World)
@@ -327,6 +431,22 @@ useTimeCheck f cr w = case theItem ^? itUseTime of
setUseTime = creatures . ix cid . crInv . ix (_crInvSel cr) . itUseTime +~ useRate
theItem = _crInv cr IM.! _crInvSel cr
useRate = fromMaybe 0 $ theItem ^? itUseRate
{- |
Applies a world effect after an item use cooldown check. -}
useTimeCheckI
:: (Item -> Creature -> World -> World) -- ^ Underlying effect
-> Item
-> Creature
-> World
-> World
useTimeCheckI f item cr w = case item ^? itUseTime of
Just 0 -> f item cr $ setUseTime w
_ -> w
where
cid = _crID cr
setUseTime = creatures . ix cid . crInv . ix (_crInvSel cr) . itUseTime +~ useRate
useRate = fromMaybe 0 $ item ^? itUseRate
{- | Applies a world effect after a hammer position check. -}
hammerCheck
:: (Creature -> World -> World) -- ^ Underlying effect
@@ -353,6 +473,27 @@ hammerCheckI f it cr w = case it ^? itHammer of
cid = _crID cr
setHammerDown = creatures . ix cid . crInv . ix (_crInvSel cr) . itHammer .~ HammerDown
{- | Applies a world effect after an ammo check. -}
ammoUseCheckI
:: (Item -> Creature -> World -> World)
-- ^ Underlying effect
-> Item
-> Creature
-> World
-> World
ammoUseCheckI f item cr w
| fireCondition = f item cr w & pointerToItem %~
( (wpLoadedAmmo -~ 1) . (itUseTime .~ _itUseRate item) )
| reloadCondition = fromMaybe w $ startReloadingWeapon cr w
| otherwise = w
where
cid = _crID cr
itRef = _crInvSel cr
pointerToItem = creatures . ix cid . crInv . ix itRef
fireCondition = _wpReloadState item == 0
&& _itUseTime item == 0
&& _wpLoadedAmmo item > 0
reloadCondition = _wpLoadedAmmo item == 0
{- | Applies a world effect after an ammo check. -}
shoot
:: (Creature -> World -> World)
-- ^ Underlying effect
@@ -468,6 +609,19 @@ withVelWthHiteff vel width hiteff cr = over particles (newbul : )
dir = _crDir cr
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
{- | Apply the effect to a translated creature. -}
withRandomOffsetI
:: Float -- ^ Max possible translate
-> (Item -> Creature -> World -> World)
-- ^ Underlying effect
-> Item
-> Creature
-> World
-> World
withRandomOffsetI offsetAmount f item cr w = f item (cr & crPos %~ (+.+ offV)) $ set randGen g w
where
(offsetVal , g) = randomR (-offsetAmount,offsetAmount) $ _randGen w
offV = rotateV (_crDir cr) (V2 0 offsetVal)
{- | Apply the effect to a translated creature. -}
withRandomOffset
:: Float -- ^ Max possible translate
-> (Creature -> World -> World)
@@ -568,6 +722,20 @@ torqueAfter torque feff cr w
(rot, g) = randomR (-torque,torque) $ _randGen w
rotateScope = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
. itAttachment . _Just . scopePos %~ rotateV rot
spreadNumI
:: (Item -> Creature -> World -> World)
-> Item
-> Creature
-> World
-> World
spreadNumI eff item cr w = foldr f w dirs
where
dirs = zipWith (+)
[-spread,-spread+(2*spread/fromIntegral numBul)..spread]
(randomRs (0,spread/fromIntegral numBul) (_randGen w))
f dir = eff item (cr & crDir +~ dir)
spread = _wpSpread item
numBul = _wpNumBarrels item
{- | Create multiple bullets with a given spread, a given amount, given velocity,
given width and given 'HitEffect'. -}
spreadNumVelWthHiteff
@@ -590,6 +758,20 @@ spreadNumVelWthHiteff spread num vel wth eff cr w = over particles (newbuls ++)
dirs = map (_crDir cr +) $ zipWith (+)
[-spread,-spread+(2*spread/fromIntegral num)..]
(randomRs (0,spread/5) (_randGen w))
numI
:: (Item -> Creature -> World -> World)
-> Item
-> Creature
-> World
-> World
numI eff item cr w = foldr f w poss
where
cp :: Float
cp = -0.5 * fromIntegral numBul
poss :: [V2 Float]
poss = map (rotateV (_crDir cr) . V2 0 . (*5) . (+ cp) . fromIntegral) [0 .. numBul - 1]
f pos = eff item (cr & crPos %~ (+.+ pos))
numBul = _wpNumBarrels item
{- | Create a number of bullets side by side with a given velocity,
given width and given 'HitEffect'. -}
numVelWthHitEff
+2 -2
View File
@@ -9,7 +9,7 @@ import Dodge.Base.Zone
import Dodge.Base.Collide
import Dodge.Picture.Layer
--import Dodge.Item.Weapon.Decoration
import Dodge.Item.Weapon.TriggerType
--import Dodge.Item.Weapon.TriggerType
--import Dodge.WorldEvent.Flash
--import Dodge.WorldEvent.ThingsHit
import Picture
@@ -114,7 +114,7 @@ aTractorBeam
-> World
aTractorBeam col cr w
= set (creatures . ix cid . crInv . ix itRef . itUse)
(\_ -> shoot $ aTractorBeam ((col + 1) `mod` 10))
(\_ -> aTractorBeam ((col + 1) `mod` 10))
$ over projectiles (IM.insert i (tractorBeamAt col i pos dir)) w
where
i = newProjectileKey w