104 lines
3.5 KiB
Haskell
104 lines
3.5 KiB
Haskell
{-# LANGUAGE TupleSections #-}
|
|
module Dodge.Creature.Action.Blink (
|
|
blinkActionMousePos,
|
|
blinkActionFail,
|
|
unsafeBlinkAction,
|
|
) where
|
|
|
|
import qualified Data.IntMap.Strict as IM
|
|
import Linear
|
|
import Dodge.Creature.Radius
|
|
import Dodge.Zoning.Wall
|
|
import Data.Maybe
|
|
import Dodge.Base
|
|
import Dodge.Data.World
|
|
import Dodge.SoundLogic
|
|
import Dodge.WorldEvent.Shockwave
|
|
import Geometry
|
|
import LensHelp
|
|
import Picture
|
|
|
|
-- note collideCircWalls doesn't always correctly zone walls, this should be
|
|
-- replaced.
|
|
-- I think the test circHitWall DOES work
|
|
-- | Teleport a creature to the mouse position
|
|
blinkActionMousePos :: Creature -> World -> World
|
|
blinkActionMousePos cr w =
|
|
w
|
|
& soundMultiFrom [TeleSound 0, TeleSound 1] p3 teleS Nothing
|
|
& blinkDistortions cpos p3
|
|
& cWorld . lWorld . creatures . ix cid . crPos . _xy .~ p3
|
|
& blinkShockwave cid p3
|
|
& inverseShockwaveAt (cpos `v2z` 20) 40 2 2
|
|
where
|
|
cid = _crID cr
|
|
p1 = w ^. cWorld . lWorld . lAimPos
|
|
cpos = cr ^. crPos . _xy
|
|
--p2 = bouncePoint (const True) 1 cpos p1 w
|
|
p2 = pushIntoMaybe $ collideCircWalls cpos p1 r (IM.elems $ wlsNearSeg cpos p1 w)
|
|
r = crRad $ cr ^. crType
|
|
p3 = maybe p1 ((+.+ squashNormalizeV (cpos -.- p1)) . fst) p2
|
|
--p3 = maybe p1 (const 0) p2
|
|
--p3 = maybe p1 fst p2
|
|
pushIntoMaybe :: (a, Maybe b) -> Maybe (a,b)
|
|
pushIntoMaybe (x,my) = (x,) <$> my
|
|
|
|
blinkDistortions :: Point2 -> Point2 -> World -> World
|
|
blinkDistortions _ _ = id
|
|
--blinkDistortions sp ep = cWorld . lWorld . distortions .++~ distortionBulge
|
|
-- where
|
|
-- distR = 120
|
|
-- distortionBulge =
|
|
-- [ RadialDistortion ep (ep +.+ V2 distR 0) (ep +.+ V2 0 distR) 0.1
|
|
-- , RadialDistortion sp (sp +.+ V2 distR 0) (sp +.+ V2 0 distR) 1.9
|
|
-- ]
|
|
|
|
{- | Teleport a creature to the mouse position.
|
|
Can go through walls, if ending up in wall does big damage.
|
|
-}
|
|
unsafeBlinkAction :: Creature -> World -> World
|
|
unsafeBlinkAction cr w
|
|
| success =
|
|
soundMultiFrom [TeleSound 0, TeleSound 1] mwp teleS Nothing
|
|
. blinkDistortions cpos mwp
|
|
. set (cWorld . lWorld . creatures . ix cid . crPos . _xy) mwp
|
|
. blinkShockwave cid mwp
|
|
$ inverseShockwaveAt (cpos `v2z` 20) 40 2 2 w
|
|
| otherwise =
|
|
w
|
|
& blinkActionFail cr
|
|
& cWorld . lWorld . creatures . ix cid . crDamage .:~ Enterrement 100000000
|
|
where
|
|
success = fromMaybe True $ do
|
|
wl <- snd $ collidePointWallsFilter (const True) mwp cpos w
|
|
return (isLHS mwp `uncurry` _wlLine wl)
|
|
cid = _crID cr
|
|
mwp = w ^. cWorld . lWorld . lAimPos
|
|
cpos = cr ^. crPos . _xy
|
|
|
|
blinkShockwave ::
|
|
-- | Blinking creature ID.
|
|
Int ->
|
|
Point2 ->
|
|
World ->
|
|
World
|
|
blinkShockwave i p = makeShockwaveAt [i] (p `v2z` 20) 60 1 2 cyan
|
|
|
|
-- | Like a blink action, but no ingoing distortion
|
|
blinkActionFail :: Creature -> World -> World
|
|
blinkActionFail cr w =
|
|
w
|
|
& soundMultiFrom [TeleSound 0, TeleSound 1] p3 teleS Nothing
|
|
-- & cWorld . lWorld . distortions .:~ distortionBulge
|
|
& cWorld . lWorld . creatures . ix cid . crPos . _xy .~ p3
|
|
& inverseShockwaveAt (cpos `v2z` 20) 40 2 2
|
|
where
|
|
-- distR = 120
|
|
-- distortionBulge = RadialDistortion cpos (cpos +.+ V2 distR 0) (cpos +.+ V2 0 distR) 1.9
|
|
cid = _crID cr
|
|
p1 = w ^. cWorld . lWorld . lAimPos
|
|
cpos = cr ^. crPos . _xy
|
|
p2 = bouncePoint (const True) 1 cpos p1 w
|
|
r = 1.5 * crRad (cr ^. crType)
|
|
p3 = maybe p1 (mvPointTowardAtSpeed r cpos . fst) p2
|