Files
loop/src/Dodge/Event.hs
T
2021-05-20 21:25:42 +02:00

136 lines
4.8 KiB
Haskell

{- |
Module : Dodge.Event
Description : Direct event handling
Deals with direct events.
This includes individual key or 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
"Dodge.Update".
-}
module Dodge.Event
( handleEvent
) where
import Dodge.Event.Keyboard
--import Dodge.Event.Menu
import Dodge.Data
import Dodge.Base
--import Dodge.Creature.Action
import Dodge.SoundLogic
import Dodge.Inventory
import Dodge.Config.Data
--import Geometry
import Preload.Update
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
handleEvent :: World -> Event -> Maybe World
handleEvent = flip handleEvent'
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*getWindowX w
,0.5*getWindowY 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 w = case _menuLayers w of
[] -> case mouseWheelEventPos mwev of
V2 _ y
| y > 0 -> Just (wheelUpEvent w)
| y < 0 -> Just (wheelDownEvent w)
| otherwise -> Just w
_ -> Just w
{- |
Resets the world window size, and resizes the fbo that gets the light map drawn into it.
-}
handleResizeEvent :: WindowSizeChangedEventData -> World -> Maybe World
handleResizeEvent sev w = Just
. set (config . windowX) (fromIntegral x)
. set (config . windowY) (fromIntegral y)
$ over sideEffects ( resizeSpareFBO (x `div` divRes) (y `div` divRes) x y : )
w
where
x = fromIntegral x'
y = fromIntegral y'
V2 x' y' = windowSizeChangedEventSize sev
divRes = w ^. config . shadow_resolution
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) . (+ 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) $ w
& creatures . ix (_yourID w) . crInvSel %~ (`mod` n) . subtract 1
where
n = length $ IM.keys $ _crInv $ _creatures w IM.! _yourID w
downInvPos :: World -> World
downInvPos w = stopSoundFrom (CrReloadSound 0) $ w
& creatures . ix (_yourID w) . crInvSel %~ (`mod` n) . (+ 1)
where
n = length $ IM.keys $ _crInv $ _creatures w IM.! _yourID w