|
|
|
@@ -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
|
|
|
|
|