|
|
|
@@ -1,15 +1,17 @@
|
|
|
|
|
{- |
|
|
|
|
|
Weapon effects when pulling the trigger. -}
|
|
|
|
|
module Dodge.Item.Weapon.TriggerType
|
|
|
|
|
( shootWithSoundI
|
|
|
|
|
, shootWithSoundForI
|
|
|
|
|
( useAmmo
|
|
|
|
|
, withMuzFlareI
|
|
|
|
|
, withVelWthHiteff
|
|
|
|
|
, withOldDir
|
|
|
|
|
, trigDoAlso
|
|
|
|
|
--, withVelWthHiteff
|
|
|
|
|
, ammoUseCheckI
|
|
|
|
|
, rateIncABI
|
|
|
|
|
, torqueBeforeForcedI
|
|
|
|
|
, torqueAfterI
|
|
|
|
|
, withSoundI
|
|
|
|
|
, withSoundForI
|
|
|
|
|
, withThickSmokeI
|
|
|
|
|
, withThinSmokeI
|
|
|
|
|
, withRandomOffsetI
|
|
|
|
@@ -34,7 +36,6 @@ import Dodge.Creature.Action (startReloadingWeapon)
|
|
|
|
|
import Dodge.WorldEvent (muzzleFlashAt,tempLightForAt)
|
|
|
|
|
import Dodge.WorldEvent.Cloud
|
|
|
|
|
import Dodge.RandomHelp
|
|
|
|
|
import Dodge.Particle.Bullet.Spawn
|
|
|
|
|
import Dodge.Item.Attachment.Data
|
|
|
|
|
import Dodge.Item.Data
|
|
|
|
|
import Geometry
|
|
|
|
@@ -47,32 +48,26 @@ import qualified Data.IntMap.Strict as IM
|
|
|
|
|
import Data.Foldable
|
|
|
|
|
|
|
|
|
|
type ChainEffect =
|
|
|
|
|
(Item -> Creature -> World -> World)
|
|
|
|
|
(Item -> Creature -> World -> World)
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature -- ^ Creature id
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
|
|
|
|
|
-- Note that this uses the "base" creature and item values
|
|
|
|
|
trigDoAlso
|
|
|
|
|
:: (Item -> Creature -> World -> World)
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
trigDoAlso afterEff eff item cr = afterEff item cr . eff item cr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
withThinSmokeI
|
|
|
|
|
:: (Item -> Creature -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
withThinSmokeI :: ChainEffect
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
withThickSmokeI
|
|
|
|
|
:: (Item -> Creature -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
withThickSmokeI :: ChainEffect
|
|
|
|
|
withThickSmokeI eff item cr w = eff item cr $ foldl' (flip $ makeThickSmokeAt . (+.+ pos)) w ps
|
|
|
|
|
where
|
|
|
|
|
dir = _crDir cr
|
|
|
|
@@ -84,8 +79,9 @@ withThickSmokeI eff item cr w = eff item cr $ foldl' (flip $ makeThickSmokeAt .
|
|
|
|
|
|
|
|
|
|
ammoCheckI :: ChainEffect
|
|
|
|
|
ammoCheckI eff item cr w
|
|
|
|
|
| _wpLoadedAmmo item == 0
|
|
|
|
|
| _wpLoadedAmmo item <= 0
|
|
|
|
|
= fromMaybe w (startReloadingWeapon cr w)
|
|
|
|
|
| _wpReloadState item > 0 = w
|
|
|
|
|
| otherwise = eff item cr w
|
|
|
|
|
|
|
|
|
|
{- |
|
|
|
|
@@ -95,13 +91,9 @@ Applies ammo check and use cooldown check. -}
|
|
|
|
|
rateIncABI
|
|
|
|
|
:: Int -- ^ Start rate
|
|
|
|
|
-> Int -- ^ End rate
|
|
|
|
|
-> ((Item -> Creature -> World -> World) -> Item -> Creature -> World -> World) -- ^ Extra effect on first fire
|
|
|
|
|
-> ((Item -> Creature -> World -> World) -> Item -> Creature -> World -> World) -- ^ Extra effect on continued fire
|
|
|
|
|
-> (Item -> Creature -> World -> World) -- ^ Extra effect (always applied)
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
-> ChainEffect -- ^ Extra effect on first fire
|
|
|
|
|
-> ChainEffect -- ^ Extra effect on continued fire
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
rateIncABI startRate fastRate exeffFirst exeffCont eff item cr w
|
|
|
|
|
| repeatFire = w
|
|
|
|
|
& pointItem %~ ( (itUseRate .~ max fastRate (currentRate - 1))
|
|
|
|
@@ -126,12 +118,7 @@ rateIncABI startRate fastRate exeffFirst exeffCont eff item cr w
|
|
|
|
|
{- | Apply effect after a warm up. -}
|
|
|
|
|
withWarmUpI
|
|
|
|
|
:: Int -- ^ warm up sound id
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-- ^ underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
withWarmUpI soundID f item cr w
|
|
|
|
|
| _wpReloadState item /= 0 = w
|
|
|
|
|
| curWarmUp < maxWarmUp = w
|
|
|
|
@@ -150,18 +137,22 @@ withWarmUpI soundID f item cr w
|
|
|
|
|
The sound is emitted from the creature's position. -}
|
|
|
|
|
withSoundI
|
|
|
|
|
:: Int -- ^ Sound id
|
|
|
|
|
-> (Item -> Creature -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World -> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
withSoundI soundid f item cr = soundOncePos soundid (_crPos cr) . f item cr
|
|
|
|
|
|
|
|
|
|
{- | Adds a sound to a creature based world effect.
|
|
|
|
|
The sound is emitted from the creature's position. -}
|
|
|
|
|
withSoundForI
|
|
|
|
|
:: Int -- ^ Sound id
|
|
|
|
|
-> Int -- ^ Frames to play
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
withSoundForI soundid playTime f item cr
|
|
|
|
|
= soundFromPos (CrWeaponSound (_crID cr)) (_crPos cr) soundid playTime 0
|
|
|
|
|
. f item cr
|
|
|
|
|
|
|
|
|
|
withRecoilI
|
|
|
|
|
:: Float -- ^ Recoil amount
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World -> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
withRecoilI recoilAmount eff item cr = eff item cr . over (creatures . ix cid) pushback
|
|
|
|
|
where
|
|
|
|
|
cid = _crID cr
|
|
|
|
@@ -170,11 +161,7 @@ withRecoilI recoilAmount eff item cr = eff item cr . over (creatures . ix cid) p
|
|
|
|
|
Applied before the underlying effect. -}
|
|
|
|
|
withSidePushI
|
|
|
|
|
:: Float -- ^ Maximal possible side push amount
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-- ^ Underlying world effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World -> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
withSidePushI maxSide eff item cr w = eff item cr $
|
|
|
|
|
w & creatures . ix cid %~ push
|
|
|
|
|
where
|
|
|
|
@@ -186,76 +173,20 @@ withSidePushI maxSide eff item cr w = eff item cr $
|
|
|
|
|
Applied after the underlying effect. -}
|
|
|
|
|
withSidePushAfterI
|
|
|
|
|
:: Float -- ^ Maximal possible side push amount
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature -- ^ Creature id
|
|
|
|
|
-> World -> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
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
|
|
|
|
|
{- | Applies a world effect and sound effect after an ammo check. -}
|
|
|
|
|
shootWithSoundForI
|
|
|
|
|
:: Int -- ^ Sound identifier
|
|
|
|
|
-> Int -- ^ Frames to play
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-- ^ underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
shootWithSoundForI soundid playTime f item cr w
|
|
|
|
|
| fireCondition = soundFromPos (CrWeaponSound cid) cpos soundid playTime 0
|
|
|
|
|
$ f item cr
|
|
|
|
|
$ w
|
|
|
|
|
& pointerToItem %~
|
|
|
|
|
( ( wpLoadedAmmo -~ 1 )
|
|
|
|
|
. ( itUseTime .~ _itUseRate item)
|
|
|
|
|
)
|
|
|
|
|
| reloadCondition = fromMaybe w $ startReloadingWeapon cr w
|
|
|
|
|
| otherwise = w
|
|
|
|
|
where
|
|
|
|
|
cid = _crID cr
|
|
|
|
|
cpos = _crPos 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 and sound effect after an ammo check. -}
|
|
|
|
|
shootWithSoundI
|
|
|
|
|
:: Int -- ^ Sound identifier
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-- ^ Shoot effect, takes creature id as input
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
shootWithSoundI soundid f item cr w
|
|
|
|
|
| fireCondition = over (pointerToItem . wpLoadedAmmo) (\ammo -> ammo-1)
|
|
|
|
|
$ soundOncePos soundid (_crPos cr)
|
|
|
|
|
$ set (pointerToItem . itUseTime) (_itUseRate item)
|
|
|
|
|
$ f item cr w
|
|
|
|
|
| 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
|
|
|
|
|
useAmmo
|
|
|
|
|
:: Int -- ^ amount of ammo to use
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
useAmmo amAmount eff item cr = eff item cr .
|
|
|
|
|
(creatures . ix (_crID cr) . crInv . ix (_crInvSel cr) . wpLoadedAmmo -~ amAmount)
|
|
|
|
|
{- |
|
|
|
|
|
Applies a world effect after an item use cooldown check. -}
|
|
|
|
|
useTimeCheckI
|
|
|
|
|
:: (Item -> Creature -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
useTimeCheckI :: ChainEffect
|
|
|
|
|
useTimeCheckI f item cr w = case item ^? itUseTime of
|
|
|
|
|
Just 0 -> f item cr $ setUseTime w
|
|
|
|
|
_ -> w
|
|
|
|
@@ -264,12 +195,7 @@ useTimeCheckI f item cr w = case item ^? itUseTime of
|
|
|
|
|
setUseTime = creatures . ix cid . crInv . ix (_crInvSel cr) . itUseTime +~ useRate
|
|
|
|
|
useRate = fromMaybe 0 $ item ^? itUseRate
|
|
|
|
|
{- | Applies a world effect after a hammer position check. -}
|
|
|
|
|
hammerCheckI
|
|
|
|
|
:: (Item -> Creature -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
hammerCheckI :: ChainEffect
|
|
|
|
|
hammerCheckI f it cr w = case it ^? itHammer of
|
|
|
|
|
Just HammerUp -> f it cr $ setHammerDown w
|
|
|
|
|
_ -> setHammerDown w
|
|
|
|
@@ -277,13 +203,7 @@ 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 :: ChainEffect
|
|
|
|
|
ammoUseCheckI f item cr w
|
|
|
|
|
| fireCondition = f item cr w & pointerToItem %~
|
|
|
|
|
( (wpLoadedAmmo -~ 1) . (itUseTime .~ _itUseRate item) )
|
|
|
|
@@ -333,12 +253,7 @@ shootL f cr invid w
|
|
|
|
|
&& _itUseTime item == 0
|
|
|
|
|
&& _wpLoadedAmmo item > 0
|
|
|
|
|
reloadCondition = _wpLoadedAmmo item == 0
|
|
|
|
|
withMuzFlareI
|
|
|
|
|
:: (Item -> Creature -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
withMuzFlareI :: ChainEffect
|
|
|
|
|
withMuzFlareI f it cr w = tempLightForAt 3 pos . muzzleFlashAt pos2 $ f it cr w
|
|
|
|
|
where
|
|
|
|
|
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
|
|
|
|
@@ -346,38 +261,19 @@ withMuzFlareI f it cr w = tempLightForAt 3 pos . muzzleFlashAt pos2 $ f it cr w
|
|
|
|
|
{- | Applies the effect to a randomly rotated creature. -}
|
|
|
|
|
withRandomDirI
|
|
|
|
|
:: Float -- ^ Max possible rotation
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
withRandomDirI acc f it cr w = f it (cr & crDir +~ a) $ set randGen g w
|
|
|
|
|
where
|
|
|
|
|
(a, g) = randomR (-acc,acc) $ _randGen w
|
|
|
|
|
{- | Creates a bullet with a given velocity, width, and 'HitEffect' -}
|
|
|
|
|
withVelWthHiteff
|
|
|
|
|
:: Point2 -- ^ Velocity, x direction is forward with respect to the creature
|
|
|
|
|
-> Float -- ^ Bullet width
|
|
|
|
|
-> HitEffect -- ^ Bullet effect when hitting creature, wall etc
|
|
|
|
|
-> Creature -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
withVelWthHiteff vel width hiteff cr = over particles (newbul : )
|
|
|
|
|
where
|
|
|
|
|
cid = _crID cr
|
|
|
|
|
newbul = aGenBulAt (Just cid) pos (rotateV dir vel) hiteff width
|
|
|
|
|
dir = _crDir cr
|
|
|
|
|
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
|
|
|
|
|
withOldDir
|
|
|
|
|
:: Float -- ^ The fraction of the old direction
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
withOldDir aFrac eff item cr w
|
|
|
|
|
= eff item (cr & crDir %~ tweenAngles aFrac (_crOldDir cr)) w
|
|
|
|
|
{- | Apply the effect to a translated creature. -}
|
|
|
|
|
withRandomOffsetI
|
|
|
|
|
:: Float -- ^ Max possible translate
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
withRandomOffsetI offsetAmount f item cr w = f item (cr & crPos %~ (+.+ offV)) $ set randGen g w
|
|
|
|
|
where
|
|
|
|
|
(offsetVal , g) = randomR (-offsetAmount,offsetAmount) $ _randGen w
|
|
|
|
@@ -386,12 +282,7 @@ withRandomOffsetI offsetAmount f item cr w = f item (cr & crPos %~ (+.+ offV)) $
|
|
|
|
|
-- Rotates the player creature before applying the effect, other creatures after.
|
|
|
|
|
torqueBeforeForcedI
|
|
|
|
|
:: Float -- ^ Max possible rotation (less the 0.1 forced rotation)
|
|
|
|
|
-> (Item -> Creature -> World -> World)
|
|
|
|
|
-- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
torqueBeforeForcedI torque feff item cr w
|
|
|
|
|
| cid == 0 = feff item (cr & crDir +~ rot') $ w
|
|
|
|
|
& randGen .~ g
|
|
|
|
@@ -406,11 +297,7 @@ torqueBeforeForcedI torque feff item cr w
|
|
|
|
|
-- | Rotate a randomly creature after applying an effect.
|
|
|
|
|
torqueAfterI
|
|
|
|
|
:: Float -- ^ Max possible rotation
|
|
|
|
|
-> (Item -> Creature -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
-> ChainEffect
|
|
|
|
|
torqueAfterI torque feff item cr w
|
|
|
|
|
| cid == 0 = rotateScope $ set randGen g $ over cameraRot (+rot) $ feff item cr w
|
|
|
|
|
| otherwise = set randGen g $ over (creatures . ix cid . crDir) (+rot) $ feff item cr w
|
|
|
|
@@ -419,12 +306,7 @@ torqueAfterI torque feff item 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 :: ChainEffect
|
|
|
|
|
spreadNumI eff item cr w = foldr f w dirs
|
|
|
|
|
where
|
|
|
|
|
dirs = zipWith (+)
|
|
|
|
@@ -433,12 +315,7 @@ spreadNumI eff item cr w = foldr f w dirs
|
|
|
|
|
f dir = eff item (cr & crDir +~ dir)
|
|
|
|
|
spread = _wpSpread item
|
|
|
|
|
numBul = _wpNumBarrels item
|
|
|
|
|
numI
|
|
|
|
|
:: (Item -> Creature -> World -> World)
|
|
|
|
|
-> Item
|
|
|
|
|
-> Creature
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
numI :: ChainEffect
|
|
|
|
|
numI eff item cr w = foldr f w poss
|
|
|
|
|
where
|
|
|
|
|
cp :: Float
|
|
|
|
|