module Dodge.Event where import Dodge.Event.Keyboard import Dodge.Data import Dodge.Base import Dodge.CreatureAction import Dodge.SoundLogic import Dodge.Inventory import Geometry import Control.Lens import Data.Maybe import Data.Char import Data.List import Data.Function (on) import qualified Data.Set as S import qualified Data.IntMap.Strict as IM import SDL -- Deals with direct events -- This includes individual key/mouse presses, but /not/ continuous held down input -- We cannot handle multiple keys held down at once here, -- (eg left mouse button + right mouse button) -- because these are separate events -- Instead we store the events in a set, and deal with the combinations in -- Update handleEvent :: Event -> World -> Maybe World handleEvent e = case eventPayload e of KeyboardEvent kev -> handleKeyboardEvent kev MouseMotionEvent mmev -> handleMouseMotionEvent mmev MouseButtonEvent mbev -> handleMouseButtonEvent mbev MouseWheelEvent mwev -> handleMouseWheelEvent mwev WindowSizeChangedEvent sev -> handleResizeEvent sev _ -> Just handleMouseMotionEvent :: MouseMotionEventData -> World -> Maybe World handleMouseMotionEvent mmev w = Just $ w & mousePos .~ (fromIntegral x - 0.5*_windowX w ,0.5*_windowY w - fromIntegral y ) where P (V2 x y) = mouseMotionEventPos mmev handleMouseButtonEvent :: MouseButtonEventData -> World -> Maybe World handleMouseButtonEvent mbev w = case mouseButtonEventMotion mbev of Released -> Just $ over mouseButtons (S.delete but) w Pressed -> handlePressedMouseButton but $ over mouseButtons (S.insert but) w where but = mouseButtonEventButton mbev handleMouseWheelEvent :: MouseWheelEventData -> World -> Maybe World handleMouseWheelEvent mwev = case mouseWheelEventPos mwev of V2 x y | y > 0 -> Just . wheelUpEvent | y < 0 -> Just . wheelDownEvent | otherwise -> Just handleResizeEvent :: WindowSizeChangedEventData -> World -> Maybe World handleResizeEvent sev = Just . set windowX (fromIntegral x) . set windowY (fromIntegral y) where V2 x y = windowSizeChangedEventSize sev handlePressedMouseButton :: MouseButton -> World -> Maybe World handlePressedMouseButton but w | but == ButtonMiddle || _carteDisplay w = Just $ w & clickMousePos .~ _mousePos w | otherwise = Just w wheelUpEvent :: World -> World wheelUpEvent w = case _carteDisplay w of True | rbDown -> w & carteZoom .~ min 0.75 (z+(0.1*z)) | otherwise -> w & selLocation %~ (`mod` numLocs) . (\i -> i - 1) _ | rbDown -> fromMaybe (closeObjScrollUp w) $ (yourItem w ^? itScrollUp) <*> pure (_crInvSel (you w)) <*> pure w | lbDown -> w & cameraZoom +~ 0.1 | otherwise -> upInvPos w where rbDown = ButtonRight `S.member` _mouseButtons w lbDown = ButtonLeft `S.member` _mouseButtons w z = _carteZoom w numLocs = (fst . IM.findMax $ _seenLocations w) + 1 wheelDownEvent :: World -> World wheelDownEvent w = case _carteDisplay w of True | rbDown -> w & carteZoom .~ max 0.05 (z-(0.1*z)) | otherwise -> w & selLocation %~ (`mod` numLocs) . (\i -> i + 1) False | rbDown -> fromMaybe (closeObjScrollDown w) $ (yourItem w ^? itScrollDown) <*> pure (_crInvSel (you w)) <*> pure w | lbDown -> w {_cameraZoom = max (_cameraZoom w - 0.1) 0.01} | otherwise -> downInvPos w where rbDown = ButtonRight `S.member` _mouseButtons w lbDown = ButtonLeft `S.member` _mouseButtons w z = _carteZoom w numLocs = (fst . IM.findMax $ _seenLocations w) + 1 upInvPos :: World -> World upInvPos w = stopSoundFrom (CrReloadSound 0) $ set (creatures . ix (_yourID w) . crInvSel) x w where is = IM.keys $ _crInv $ _creatures w IM.! _yourID w isis = is ++ is x = before (_crInvSel (you w)) isis downInvPos :: World -> World downInvPos w = stopSoundFrom (CrReloadSound 0) $ set (creatures . ix (_yourID w) . crInvSel) x w where is = IM.keys $ _crInv $ _creatures w IM.! _yourID w isis = is ++ is x = after (_crInvSel (you w)) isis -- these are incomplete: should put in error case here! before y (x:z:ys) | y == z = x | otherwise = before y (z:ys) after y (x:z:ys) | y == x = z | otherwise = after y (z:ys) mouseActionsCr :: S.Set MouseButton -> Creature -> Creature mouseActionsCr keys cr | rbPressed = set ( crState . stance . posture) Aiming cr | otherwise = set ( crState . stance . posture) AtEase cr where lbPressed = ButtonLeft `S.member` keys rbPressed = ButtonRight `S.member` keys