{-# 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