Files
loop/src/Dodge/Item/Weapon/ExtraEffect.hs
T
2022-04-10 10:48:17 +01:00

162 lines
5.7 KiB
Haskell

--{-# LANGUAGE BangPatterns #-}
{- |
Extra weapon effects, supplementing explicit use effects.
-}
module Dodge.Item.Weapon.ExtraEffect
(-- itemLaserScopeEffect
autoSonarEffect
, autoRadarEffect
, targetRBPress
, targetRBCreature
, targetCursor
, targetLaser
-- , rbSetTarget
) where
import Dodge.Data
import Dodge.Base
--import Dodge.Item.Weapon.Decoration
import Dodge.Item.Weapon.UseEffect
import Dodge.Item.Weapon.LaserPath
--import Dodge.Item.Attachment.Data
import Dodge.Creature.Test
import Dodge.WorldEvent.HelperParticle
import Picture
import Geometry.Vector
import Geometry.Data
import LensHelp
import Data.Maybe
import qualified Data.Set as S
import qualified SDL
{- | Automatically send out radar pulses that detect walls. -}
autoRadarEffect :: ItEffect
autoRadarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 }
where
f :: Int -> ItEffect -> Creature -> Int -> World -> World
f 0 _ cr i w = aRadarPulse cr w
& creatures . ix (_crID cr) . crInv . ix i
. itEffect . itInvEffect .~ f 100
f t _ cr i w = w
& creatures . ix (_crID cr) . crInv . ix i
. itEffect . itInvEffect .~ f (t-1)
{- | Automatically send out sonar pulses that detect creatures. -}
autoSonarEffect :: ItEffect
autoSonarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 }
where
f :: Int -> ItEffect -> Creature -> Int -> World -> World
f 0 _ cr i w = aSonarPulse cr w
& creatures . ix (_crID cr) . crInv . ix i . itEffect . itInvEffect .~ f 140
f t _ cr i w = w
& creatures . ix (_crID cr) . crInv . ix i . itEffect . itInvEffect .~ f (t-1)
defaultTargeting :: Targeting
defaultTargeting = TargetingOnHeld
{ _tgPos = Nothing
, _tgUpdate = \_ _ w t -> (w,t)
, _tgDraw = \_ _ _ _ -> mempty
, _tgID = Nothing
, _tgActive = False
}
targetLaser :: Targeting
targetLaser = defaultTargeting
& tgUpdate .~ targetLaserUpdate
targetRBPress :: Targeting
targetRBPress = defaultTargeting
& tgUpdate .~ targetUpdateWith targetRBPressUpdate
& tgDraw .~ targetSimpleDraw
targetRBCreature :: Targeting
targetRBCreature = defaultTargeting
& tgUpdate .~ targetUpdateWith targetRBCreatureUpdate
& tgDraw .~ targetRBCreatureDraw
targetCursor :: Targeting
targetCursor = defaultTargeting
& tgUpdate .~ targetUpdateWith targetCursorUpdate
& tgDraw .~ targetSimpleDraw
targetSimpleDraw :: Int -> Item -> Creature -> World -> Picture
targetSimpleDraw _ it _ w = fromMaybe mempty $ do
mwp <- it ^? itTargeting . tgPos . _Just
return $ setLayer TopLayer $ color red $ setDepth 50 $ uncurryV translate mwp
$ rotate (_cameraRot w)
$ pictures
[line [V2 x x, V2 (-x) (-x)]
,line [V2 (-x) x, V2 x (-x)]
]
where
x = 5 / _cameraZoom w
targetRBCreatureDraw :: Int -> Item -> Creature -> World -> Picture
targetRBCreatureDraw _ it _ w = fromMaybe mempty $ do
mwp <- it ^? itTargeting . tgPos . _Just
return $ setLayer TopLayer $ color thecolor $ setDepth 50 $ uncurryV translate mwp
$ rotate (_cameraRot w)
$ pictures
[line [V2 x x, V2 (-x) (-x)]
,line [V2 (-x) x, V2 x (-x)]
]
where
x = 5 / _cameraZoom w
thecolor | _tgActive $ _itTargeting it = red
| otherwise = blue
targetUpdateWith :: (World -> Targeting -> Targeting)
-> Item -> Creature -> World -> Targeting -> (World,Targeting)
targetUpdateWith f _ _ w t = (w, f w t)
targetCursorUpdate :: World -> Targeting -> Targeting
targetCursorUpdate w t
| SDL.ButtonRight `S.member` _mouseButtons w = t
& tgPos . _Just .~ mouseWorldPos w
& tgActive .~ True
| otherwise = t & tgPos %~ const Nothing
& tgActive .~ False
targetRBPressUpdate :: World -> Targeting -> Targeting
targetRBPressUpdate w t
| SDL.ButtonRight `S.member` _mouseButtons w = t
& tgPos %~ maybe (Just $ mouseWorldPos w) Just
& tgActive .~ True
| otherwise = t & tgPos %~ const Nothing
& tgActive .~ False
targetRBCreatureUpdate :: World -> Targeting -> Targeting
targetRBCreatureUpdate w t
| SDL.ButtonRight `S.member` _mouseButtons w && isJust (t ^? tgID . _Just)
= t & updatePos
& tgActive .~ True
| otherwise = t & tgID .~ fmap _crID (creatureNearPointI 3 mwp w)
& updatePos
& tgActive .~ False
where
mwp = mouseWorldPos w
updatePos t' = t' & tgPos .~ posFromMaybeID (_tgID t')
posFromMaybeID Nothing = Nothing
posFromMaybeID (Just i) = w ^? creatures . ix i . crPos
targetLaserUpdate :: Item -> Creature -> World -> Targeting -> (World,Targeting)
targetLaserUpdate it cr w t
| crIsAiming cr = (addLaserPic w,t
& tgPos .~ fmap fst mp
& tgActive .~ True
)
| otherwise = (w,t & tgPos %~ const Nothing
& tgActive .~ False
)
where
(mp, ps) = reflectLaserAlong 0.2 [] sp ep w
sp = _crPos cr +.+ 15 *.* unitVectorAtAngle (_crDir cr)
ep = sp +.+ 5000 *.* normalizeV (mouseWorldPos w -.- sp)
addLaserPic = instantParticles .:~ Particle
{ _ptDraw = const $ setLayer BloomNoZWrite $ pictures
[ setDepth 19 . color (brightX 0 0.5 col) $ thickLine 5 (sp:ps)
, setDepth 19.5 . color (brightX 5 1 col) $ thickLine 1 (sp:ps)
]
, _ptUpdate = ptSimpleTime 1
}
wpammo = _itConsumption it
reloadFrac
| _ammoLoaded wpammo == 0 = 1
| otherwise = case _reloadState wpammo of
Just' rs -> fromIntegral rs / fromIntegral (_reloadTime wpammo)
Nothing' -> 1
col = mixColors reloadFrac (1-reloadFrac) blue red