|
|
|
@@ -1,6 +1,5 @@
|
|
|
|
|
{-
|
|
|
|
|
Weapon effects when pulling the trigger.
|
|
|
|
|
-}
|
|
|
|
|
{- |
|
|
|
|
|
Weapon effects when pulling the trigger. -}
|
|
|
|
|
module Dodge.Item.Weapon.TriggerType
|
|
|
|
|
where
|
|
|
|
|
import Dodge.Data
|
|
|
|
@@ -10,6 +9,7 @@ import Dodge.WorldEvent (muzzleFlashAt,tempLightForAt)
|
|
|
|
|
import Dodge.WorldEvent.Cloud
|
|
|
|
|
import Dodge.RandomHelp
|
|
|
|
|
import Dodge.Item.Weapon.Bullet
|
|
|
|
|
import Dodge.Item.Attachment.Data
|
|
|
|
|
import Geometry
|
|
|
|
|
|
|
|
|
|
import System.Random
|
|
|
|
@@ -23,28 +23,27 @@ withThinSmoke
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
withThinSmoke eff cid w = eff cid . foldr makeThinSmokeAt w $ map (+.+ pos) ps
|
|
|
|
|
where
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
dir = _crDir cr
|
|
|
|
|
pos = _crPos cr +.+ ((_crRad cr +0.5) *.* unitVectorAtAngle dir)
|
|
|
|
|
ps = (sequence . replicate 5 . randInCirc) 8 & evalState $ _randGen w
|
|
|
|
|
withThinSmoke eff cid w = eff cid $ foldr (makeThinSmokeAt . (+.+ pos)) w ps
|
|
|
|
|
where
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
dir = _crDir cr
|
|
|
|
|
pos = _crPos cr +.+ (_crRad cr +0.5) *.* unitVectorAtAngle dir
|
|
|
|
|
ps = (replicateM 5 . randInCirc) 8 & evalState $ _randGen w
|
|
|
|
|
|
|
|
|
|
withThickSmoke
|
|
|
|
|
:: (Int -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
withThickSmoke eff cid w = eff cid . foldr makeThickSmokeAt w $ map (+.+ pos) ps
|
|
|
|
|
where
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
dir = _crDir cr
|
|
|
|
|
pos = _crPos cr +.+ ((_crRad cr +15) *.* unitVectorAtAngle dir)
|
|
|
|
|
ps = (sequence . replicate 20 . randInCirc) 8 & evalState $ _randGen w
|
|
|
|
|
|
|
|
|
|
{- Shoot a weapon rapidly after a warm up.
|
|
|
|
|
Applies ammo check as well.
|
|
|
|
|
-}
|
|
|
|
|
withThickSmoke eff cid w = eff cid $ foldr (makeThickSmokeAt . (+.+ pos)) w ps
|
|
|
|
|
where
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
dir = _crDir cr
|
|
|
|
|
pos = _crPos cr +.+ (_crRad cr + 15) *.* unitVectorAtAngle dir
|
|
|
|
|
ps = (replicateM 20 . randInCirc) 8 & evalState $ _randGen w
|
|
|
|
|
{- |
|
|
|
|
|
Shoot a weapon rapidly after a warm up.
|
|
|
|
|
Applies ammo check as well. -}
|
|
|
|
|
withWarmUp
|
|
|
|
|
:: Int -- ^ Warm up time (in frames)
|
|
|
|
|
-> (Int -> World -> World)
|
|
|
|
@@ -79,9 +78,9 @@ withWarmUp t f cid w
|
|
|
|
|
fState = _wpFireState item
|
|
|
|
|
fRate = _wpFireRate item
|
|
|
|
|
reloadCondition = _wpLoadedAmmo item == 0
|
|
|
|
|
|
|
|
|
|
{- Adds a sound to a creature based world effect.
|
|
|
|
|
The sound is emitted from the creature's position. -}
|
|
|
|
|
{- |
|
|
|
|
|
Adds a sound to a creature based world effect.
|
|
|
|
|
The sound is emitted from the creature's position. -}
|
|
|
|
|
withSound
|
|
|
|
|
:: Int -- ^ Sound id
|
|
|
|
|
-> (Int -> World -> World) -- ^ Underlying effect
|
|
|
|
@@ -97,7 +96,7 @@ withRecoil
|
|
|
|
|
-- ^ Underlying world effect, takes creature id as input
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World -> World
|
|
|
|
|
withRecoil recoilAmount eff cid w = eff cid . over (creatures . ix cid) pushback $ w
|
|
|
|
|
withRecoil recoilAmount eff cid = eff cid . over (creatures . ix cid) pushback
|
|
|
|
|
where
|
|
|
|
|
pushback cr = over crPos (+.+ rotateV (_crDir cr) ((-recoilAmount) / _crMass cr ,0)) cr
|
|
|
|
|
|
|
|
|
@@ -109,12 +108,10 @@ withSidePush
|
|
|
|
|
-> World -> World
|
|
|
|
|
withSidePush maxSide eff cid w = eff cid . over (creatures . ix cid) push $ w
|
|
|
|
|
where
|
|
|
|
|
push cr = over crPos (+.+ rotateV (_crDir cr) (0,(pushAmount) / _crMass cr)) cr
|
|
|
|
|
push cr = over crPos (+.+ rotateV (_crDir cr) (0,pushAmount / _crMass cr)) cr
|
|
|
|
|
(pushAmount, _) = randomR (-maxSide,maxSide) $ _randGen w
|
|
|
|
|
|
|
|
|
|
{-
|
|
|
|
|
Applies a world effect and sound effect after an ammo check.
|
|
|
|
|
-}
|
|
|
|
|
{- |
|
|
|
|
|
Applies a world effect and sound effect after an ammo check. -}
|
|
|
|
|
shootWithSound
|
|
|
|
|
:: Int -- ^ Sound identifier
|
|
|
|
|
-> (Int -> World -> World)
|
|
|
|
@@ -129,7 +126,7 @@ shootWithSound soundid f cid w
|
|
|
|
|
| reloadCondition = fromMaybe w $ reloadWeapon cid w
|
|
|
|
|
| otherwise = w
|
|
|
|
|
where
|
|
|
|
|
cr = (_creatures w IM.! cid)
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
itRef = _crInvSel cr
|
|
|
|
|
item = _crInv cr IM.! itRef
|
|
|
|
|
pointerToItem = creatures . ix cid . crInv . ix itRef
|
|
|
|
@@ -137,36 +134,42 @@ shootWithSound soundid f cid w
|
|
|
|
|
&& _wpFireState item == 0
|
|
|
|
|
&& _wpLoadedAmmo item > 0
|
|
|
|
|
reloadCondition = _wpLoadedAmmo item == 0
|
|
|
|
|
{- Applies a world effect after an ammo check. -}
|
|
|
|
|
{- | Applies a world effect after an ammo check. -}
|
|
|
|
|
shoot
|
|
|
|
|
:: (Int -> World -> World)
|
|
|
|
|
-- ^ Underlying effect, takes creature id as input
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World -> World
|
|
|
|
|
shoot f cid w | fireCondition = over (pointerToItem . wpLoadedAmmo) (\ammo -> ammo-1)
|
|
|
|
|
$ set (pointerToItem . wpFireState) (_wpFireRate item)
|
|
|
|
|
$ f cid w
|
|
|
|
|
| reloadCondition = fromMaybe w $ reloadWeapon cid w
|
|
|
|
|
| otherwise = w
|
|
|
|
|
shoot f cid w
|
|
|
|
|
| fireCondition = over (pointerToItem . wpLoadedAmmo) (\ammo -> ammo-1)
|
|
|
|
|
$ set (pointerToItem . wpFireState) (_wpFireRate item)
|
|
|
|
|
$ f cid w
|
|
|
|
|
| reloadCondition = fromMaybe w $ reloadWeapon cid w
|
|
|
|
|
| otherwise = w
|
|
|
|
|
where
|
|
|
|
|
cr = (_creatures w IM.! cid)
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
itRef = _crInvSel cr
|
|
|
|
|
item = _crInv cr IM.! itRef
|
|
|
|
|
pointerToItem = creatures . ix cid . crInv . ix itRef
|
|
|
|
|
fireCondition = _wpReloadState item == 0
|
|
|
|
|
&& _wpFireState item == 0
|
|
|
|
|
&& _wpLoadedAmmo item > 0
|
|
|
|
|
&& _wpFireState item == 0
|
|
|
|
|
&& _wpLoadedAmmo item > 0
|
|
|
|
|
reloadCondition = _wpLoadedAmmo item == 0
|
|
|
|
|
|
|
|
|
|
withMuzFlare :: (Int -> World -> World) -> Int -> World -> World
|
|
|
|
|
withMuzFlare
|
|
|
|
|
:: (Int -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
withMuzFlare f cid w = tempLightForAt 3 pos
|
|
|
|
|
. muzzleFlashAt pos2 $ f cid w
|
|
|
|
|
where cr = _creatures w IM.! cid
|
|
|
|
|
dir = _crDir cr
|
|
|
|
|
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
|
|
|
|
|
pos2 = _crPos cr +.+ (2 * _crRad cr) *.* unitVectorAtAngle (_crDir cr)
|
|
|
|
|
where
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
dir = _crDir cr
|
|
|
|
|
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
|
|
|
|
|
pos2 = _crPos cr +.+ (2 * _crRad cr) *.* unitVectorAtAngle (_crDir cr)
|
|
|
|
|
|
|
|
|
|
{-
|
|
|
|
|
{- |
|
|
|
|
|
Rotates the creature randomly, applies the effect, rotates the creature back.
|
|
|
|
|
-}
|
|
|
|
|
withRandomDir
|
|
|
|
@@ -182,7 +185,7 @@ withRandomDir acc f cid w = over (creatures . ix cid . crDir) (\d -> d - a)
|
|
|
|
|
$ set randGen g
|
|
|
|
|
w
|
|
|
|
|
where (a, g) = randomR (-acc,acc) $ _randGen w
|
|
|
|
|
{- Creates a bullet with a given velocity, width, and 'HitEffect'
|
|
|
|
|
{- | Creates a bullet with a given velocity, width, and 'HitEffect'
|
|
|
|
|
-}
|
|
|
|
|
withVelWthHiteff
|
|
|
|
|
:: Point2 -- ^ Velocity, x direction is forward with respect to the creature
|
|
|
|
@@ -200,7 +203,7 @@ withVelWthHiteff vel width hiteff cid w
|
|
|
|
|
dir = _crDir cr
|
|
|
|
|
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
|
|
|
|
|
pos2 = _crPos cr +.+ (2 * _crRad cr) *.* unitVectorAtAngle (_crDir cr)
|
|
|
|
|
{- Translate the creature sideways a random amount, apply the effect, translate back. -}
|
|
|
|
|
{- | Translate the creature sideways a random amount, apply the effect, translate back. -}
|
|
|
|
|
withRandomOffset
|
|
|
|
|
:: Float -- ^ Max possible translate
|
|
|
|
|
-> (Int -> World -> World)
|
|
|
|
@@ -229,36 +232,37 @@ torqueBeforeForced
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
torqueBeforeForced torque feff cid w
|
|
|
|
|
| cid == 0 = feff cid $ set randGen g $ over (creatures . ix cid . crDir) (+rot')
|
|
|
|
|
$ over cameraRot (+rot') w
|
|
|
|
|
| cid == 0 = feff cid $ w
|
|
|
|
|
& randGen .~ g
|
|
|
|
|
& creatures . ix cid . crDir +~ rot'
|
|
|
|
|
& cameraRot +~ rot'
|
|
|
|
|
| otherwise = feff cid $ set randGen g $ over (creatures . ix cid . crDir) (+rot') w
|
|
|
|
|
where
|
|
|
|
|
(rot, g) = randomR (-torque,torque) $ _randGen w
|
|
|
|
|
rot' | rot < 0 = rot - 0.1
|
|
|
|
|
| otherwise = rot + 0.1
|
|
|
|
|
|
|
|
|
|
-- | Rotates the player creature before applying an effect, other creatures after.
|
|
|
|
|
-- | Rotates the player creature before applying an effect.
|
|
|
|
|
-- Note this currently (29/4/2021) rotates other creatures /after/ applying the effect.
|
|
|
|
|
torqueBefore
|
|
|
|
|
:: Float -- ^ Max possible rotation
|
|
|
|
|
-> (Int -> World -> World)
|
|
|
|
|
-- ^ Underlying effect
|
|
|
|
|
-> Int
|
|
|
|
|
-- ^ Creature id
|
|
|
|
|
:: Float -- ^ Max possible rotation
|
|
|
|
|
-> (Int -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
torqueBefore torque feff cid w
|
|
|
|
|
| cid == 0 = feff cid $ set randGen g $ over (creatures . ix cid . crDir) (+rot)
|
|
|
|
|
$ over cameraRot (+rot) w
|
|
|
|
|
| otherwise = feff cid $ set randGen g $ over (creatures . ix cid . crDir) (+rot) w
|
|
|
|
|
| cid == 0 = feff cid $ w
|
|
|
|
|
& randGen .~ g
|
|
|
|
|
& creatures . ix cid . crDir +~ rot
|
|
|
|
|
& cameraRot +~ rot
|
|
|
|
|
| otherwise = set randGen g $ over (creatures . ix cid . crDir) (+rot) $ feff cid w
|
|
|
|
|
where
|
|
|
|
|
(rot, g) = randomR (-torque,torque) $ _randGen w
|
|
|
|
|
-- | Rotate a randomly creature after applying an effect.
|
|
|
|
|
torqueAfter
|
|
|
|
|
:: Float -- ^ Max possible rotation
|
|
|
|
|
-> (Int -> World -> World)
|
|
|
|
|
-- ^ Underlying effect
|
|
|
|
|
-> Int
|
|
|
|
|
-- ^ Creature id
|
|
|
|
|
:: Float -- ^ Max possible rotation
|
|
|
|
|
-> (Int -> World -> World) -- ^ Underlying effect
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
torqueAfter torque feff cid w
|
|
|
|
@@ -268,7 +272,8 @@ torqueAfter torque feff cid w
|
|
|
|
|
(rot, g) = randomR (-torque,torque) $ _randGen w
|
|
|
|
|
rotateScope w = w & creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
|
|
|
|
|
. itAttachment . _Just . scopePos %~ rotateV rot
|
|
|
|
|
{- Create multiple bullets with a given spread, a given amount, given velocity,
|
|
|
|
|
{- |
|
|
|
|
|
Create multiple bullets with a given spread, a given amount, given velocity,
|
|
|
|
|
given width and given 'HitEffect'.
|
|
|
|
|
-}
|
|
|
|
|
spreadNumVelWthHiteff
|
|
|
|
@@ -280,21 +285,20 @@ spreadNumVelWthHiteff
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
spreadNumVelWthHiteff spread num vel wth eff cid w
|
|
|
|
|
= over particles (newbuls ++) w
|
|
|
|
|
spreadNumVelWthHiteff spread num vel wth eff cid w = over particles (newbuls ++) w
|
|
|
|
|
where
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
newbuls = zipWith3 (\pos d colid -> aGenBulAt' (Just cid) (numColor colid)
|
|
|
|
|
pos (rotateV d vel) eff wth
|
|
|
|
|
) poss dirs colids
|
|
|
|
|
newbuls = zipWith3
|
|
|
|
|
(\pos d colid -> aGenBulAt' (Just cid) (numColor colid) pos (rotateV d vel) eff wth)
|
|
|
|
|
poss dirs colids
|
|
|
|
|
poss = map ((+.+) $ _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr))
|
|
|
|
|
$ evalState ((sequence . take num . repeat . randInCirc) 5) $ _randGen w
|
|
|
|
|
$ (replicateM num . randInCirc) 5 & evalState $ _randGen w
|
|
|
|
|
dirs = map ((+) (_crDir cr))
|
|
|
|
|
$ zipWith (+) [-spread,-spread+(2*spread/(fromIntegral num))..]
|
|
|
|
|
$ zipWith (+) [-spread,-spread+(2*spread/fromIntegral num)..]
|
|
|
|
|
$ randomRs (0,spread/5) (_randGen w)
|
|
|
|
|
colids = take num $ randomRs (0,11) (_randGen w)
|
|
|
|
|
|
|
|
|
|
{- Create a number of bullets side by side with a given velocity,
|
|
|
|
|
{- |
|
|
|
|
|
Create a number of bullets side by side with a given velocity,
|
|
|
|
|
given width and given 'HitEffect'.
|
|
|
|
|
-}
|
|
|
|
|
numVelWthHitEff
|
|
|
|
@@ -305,16 +309,15 @@ numVelWthHitEff
|
|
|
|
|
-> Int -- ^ Creature id
|
|
|
|
|
-> World
|
|
|
|
|
-> World
|
|
|
|
|
numVelWthHitEff num vel wth eff cid w
|
|
|
|
|
= over particles (newbuls ++) w
|
|
|
|
|
numVelWthHitEff num vel wth eff cid w = over particles (newbuls ++) w
|
|
|
|
|
where
|
|
|
|
|
cr = _creatures w IM.! cid
|
|
|
|
|
newbuls = zipWith (\pos colid -> aGenBulAt' (Just cid) (numColor colid)
|
|
|
|
|
pos (rotateV d vel) eff wth
|
|
|
|
|
)
|
|
|
|
|
poss colids
|
|
|
|
|
newbuls = zipWith
|
|
|
|
|
(\pos colid -> aGenBulAt' (Just cid) (numColor colid) pos (rotateV d vel) eff wth)
|
|
|
|
|
poss
|
|
|
|
|
colids
|
|
|
|
|
d = _crDir cr
|
|
|
|
|
poss = map (\o -> o +.+ pos) offsets
|
|
|
|
|
poss = map (+.+ pos) offsets
|
|
|
|
|
maxOffset = fromIntegral num * 2.5 - 2.5
|
|
|
|
|
offsets = map (\y -> rotateV d (0,y)) [-maxOffset,5-maxOffset..]
|
|
|
|
|
colids = take num $ randomRs (0,11) (_randGen w)
|
|
|
|
|