diff --git a/src/Dodge/Item/Weapon.hs b/src/Dodge/Item/Weapon.hs index ef1426d39..adfeef0e8 100644 --- a/src/Dodge/Item/Weapon.hs +++ b/src/Dodge/Item/Weapon.hs @@ -275,8 +275,10 @@ hvAutoGun = defaultAutoGun , _wpReloadState = 0 , _itUseRate = 25 , _itUseTime = 0 - , _itUse = \it -> rateIncAB 24 10 (torqueBeforeForced 0.1 (mkHvBul it)) - (torqueAfter 0.2 (mkHvBul it)) + , _itUse = \it -> mkHvBul it + , _itUseModifiers = + [ rateIncABI 24 10 (torqueBeforeForcedI 0.1) (torqueAfterI 0.2) + ] , _wpRange = 20 , _itFloorPict = onLayer FlItLayer hvAutoGunPic , _itAimingSpeed = 0.2 diff --git a/src/Dodge/Item/Weapon/TriggerType.hs b/src/Dodge/Item/Weapon/TriggerType.hs index 3b3067792..38837b720 100644 --- a/src/Dodge/Item/Weapon/TriggerType.hs +++ b/src/Dodge/Item/Weapon/TriggerType.hs @@ -41,6 +41,8 @@ withThickSmoke eff cr w = eff cr $ foldl' (flip $ makeThickSmokeAt . (+.+ pos)) dir = _crDir cr pos = _crPos cr +.+ (_crRad cr + 15) *.* unitVectorAtAngle dir ps = (replicateM 20 . randInCirc) 8 & evalState $ _randGen w +-- TODO create a trigger that does different things on first and continued +-- fire. {- | Fires at an increasing rate. Has different effect after first fire. @@ -48,22 +50,23 @@ Applies ammo check and use cooldown check. -} rateIncAB :: Int -- ^ Start rate -> Int -- ^ End rate - -> (Creature -> World -> World) -- ^ Effect on first fire - -> (Creature -> World -> World) -- ^ Effect on continued fire + -> ((Creature -> World -> World) -> Creature -> World -> World) -- ^ Extra effect on first fire + -> ((Creature -> World -> World) -> Creature -> World -> World) -- ^ Extra effect on continued fire + -> (Creature -> World -> World) -- ^ Extra effect (always applied) -> Creature -- ^ Creature id -> World -> World -rateIncAB startRate fastRate shooteff1 shooteff2 cr w +rateIncAB startRate fastRate exeffFirst exeffCont eff cr w | repeatFire = w & pointItem %~ ( (itUseRate .~ max fastRate (currentRate - 1)) . (wpLoadedAmmo -~ 1) . (itUseTime .~ currentRate) ) - & shooteff2 cr + & exeffCont eff cr | firstFire = w & pointItem %~ ( (itUseRate .~ startRate - 1) . (wpLoadedAmmo -~ 1) . (itUseTime .~ startRate) ) - & shooteff1 cr + & exeffFirst eff cr | reloadCondition = fromMaybe w $ startReloadingWeapon cr w | otherwise = w where @@ -80,6 +83,45 @@ rateIncAB startRate fastRate shooteff1 shooteff2 cr w && _wpLoadedAmmo item > 0 reloadCondition = _wpLoadedAmmo item == 0 {- | +Fires at an increasing rate. +Has different effect after first fire. +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 +rateIncABI startRate fastRate exeffFirst exeffCont eff item cr w + | repeatFire = w + & pointItem %~ ( (itUseRate .~ max fastRate (currentRate - 1)) + . (wpLoadedAmmo -~ 1) + . (itUseTime .~ currentRate) ) + & exeffCont eff item cr + | firstFire = w + & pointItem %~ ( (itUseRate .~ startRate - 1) + . (wpLoadedAmmo -~ 1) + . (itUseTime .~ startRate) ) + & exeffFirst eff item cr + | reloadCondition = fromMaybe w $ startReloadingWeapon cr w + | otherwise = w + where + cid = _crID cr + itRef = _crInvSel cr + pointItem = creatures . ix cid . crInv . ix itRef + currentRate = _itUseRate item + repeatFire = _wpReloadState item == 0 + && _itUseTime item == 1 + && _wpLoadedAmmo item > 0 + firstFire = _wpReloadState item == 0 + && _itUseTime item == 0 + && _wpLoadedAmmo item > 0 + reloadCondition = _wpLoadedAmmo item == 0 +{- | Shoot a weapon rapidly after a warm up. Applies ammo check as well. -} withWarmUp @@ -439,6 +481,27 @@ withRandomOffset offsetAmount f cr w = f (cr & crPos %~ (+.+ offV)) $ set randGe offV = rotateV (_crDir cr) (V2 0 offsetVal) -- | Rotates a creature with minimum rotation at least 0.1. -- 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 +torqueBeforeForcedI torque feff item cr w + | cid == 0 = feff item (cr & crDir +~ rot') $ w + & randGen .~ g + & creatures . ix cid . crDir +~ rot' + & cameraRot +~ rot' + | otherwise = feff item cr $ set randGen g $ over (creatures . ix cid . crDir) (+rot') w + where + cid = _crID cr + (rot, g) = randomR (-torque,torque) $ _randGen w + rot' | rot < 0 = rot - 0.1 + | otherwise = rot + 0.1 +-- | Rotates a creature with minimum rotation at least 0.1. +-- Rotates the player creature before applying the effect, other creatures after. torqueBeforeForced :: Float -- ^ Max possible rotation (less the 0.1 forced rotation) -> (Creature -> World -> World) @@ -475,6 +538,22 @@ torqueBefore torque feff cr w cid = _crID cr (rot, g) = randomR (-torque,torque) $ _randGen 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 +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 + where + cid = _crID cr + (rot, g) = randomR (-torque,torque) $ _randGen w + rotateScope = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0)) + . itAttachment . _Just . scopePos %~ rotateV rot +-- | Rotate a randomly creature after applying an effect. torqueAfter :: Float -- ^ Max possible rotation -> (Creature -> World -> World) -- ^ Underlying effect