{- | Deals with keyboard events. -} module Dodge.Event.Keyboard ( handleKeyboardEvent ) where import Dodge.Data import Dodge.Data.Menu import Dodge.Picture.Layer import Dodge.Base import Dodge.Creature.Action import Dodge.Config.KeyConfig --import Dodge.Room.Placement import Dodge.LightSources import Dodge.LevelGen import Dodge.Creature.Inanimate import qualified Data.IntMap.Strict as IM import Dodge.Event.Test import Dodge.Event.Menu import SDL import Data.Maybe import qualified Data.Set as S import Control.Lens import Picture {- | Handles keyboard press and release. On release, remove scancode from the 'Set' of pressed keys. On press, adds the scancode, and perhaps applies a direct effect: see 'handlePressedKeyInGame'. -} handleKeyboardEvent :: KeyboardEventData -> World -> Maybe World handleKeyboardEvent kev w = case keyboardEventKeyMotion kev of Released -> Just $ w & keys %~ S.delete kcode Pressed -> handlePressedKey (keyboardEventRepeat kev) kcode (w & keys %~ S.insert kcode) where kcode = (keysymScancode . keyboardEventKeysym) kev handlePressedKey :: Bool -> Scancode -> World -> Maybe World handlePressedKey True _ w = Just w handlePressedKey _ ScancodeSemicolon w | not (inTerminal w) = Just $ gotoTerminal w handlePressedKey _ scode w | null (_menuLayers w) = handlePressedKeyInGame scode w | otherwise = handlePressedKeyInMenu (head $ _menuLayers w) scode w handlePressedKeyInGame :: Scancode -> World -> Maybe World handlePressedKeyInGame scode w | scode == escapeKey (_keyConfig w) = Nothing | scode == pauseKey (_keyConfig w) = Just $ pauseGame $ escapeMap w | scode == dropItemKey (_keyConfig w) = Just $ youDropItem w | scode == toggleMapKey (_keyConfig w) = Just $ toggleMap w | scode == reloadKey (_keyConfig w) = Just $ fromMaybe w $ startReloadingWeapon (you w) w | scode == testEventKey (_keyConfig w) = Just $ testEvent w | scode == spaceActionKey (_keyConfig w) = Just $ spaceAction w | scode == rotateCameraPlusKey (_keyConfig w) = Just $ w & cameraRot +~ 0.01 | scode == rotateCameraMinusKey (_keyConfig w) = Just $ w & cameraRot -~ 0.01 | scode == ScancodeF5 = Just $ dropLight w | scode == ScancodeF6 = Just $ dropLight' w | scode == ScancodeX = Just $ w & inventoryMode %~ toggleInv TweakInventory | scode == ScancodeC = Just $ w & inventoryMode %~ toggleInv CombineInventory | scode == ScancodeI = Just $ w & inventoryMode %~ toggleInv InspectInventory handlePressedKeyInGame _ w = Just w toggleInv :: InventoryMode -> InventoryMode -> InventoryMode toggleInv x y | x == y = TopInventory | otherwise = x inTerminal :: World -> Bool inTerminal w = case _menuLayers w of (Terminal _ : _) -> True _ -> False gotoTerminal :: World -> World gotoTerminal w = case _menuLayers w of (Terminal _ : _ ) -> w _ -> w & menuLayers %~ (Terminal [] :) spaceAction :: World -> World spaceAction w = if _carteDisplay w then w & carteCenter .~ theLoc else case (_inventoryMode w, listToMaybe $ _closeActiveObjects w) of (TopInventory,Just (Left flit)) -> pickUpItem 0 flit w (TopInventory,Just (Right but)) -> updateTopCloseObject (_btID but) $ _btEvent but but w _ -> w & inventoryMode .~ TopInventory where theLoc = fst (_seenLocations w IM.! _selLocation w) w updateTopCloseObject i = closeActiveObjects %~ ( Right (_buttons w IM.! i) : ) . tail pauseGame :: World -> World pauseGame w = w {_menuLayers = [PauseMenu]} toggleMap :: World -> World toggleMap w = w & carteDisplay %~ not escapeMap :: World -> World escapeMap w = w & carteDisplay .~ False dropLight :: World -> World dropLight w = placeLS ls dec pos 0 w where --(rot, g) = randomR (-pi,pi) $ _randGen w (x,y) = _crPos(you w) pos = (x,y,0) ls = lightAt pos 0 dec = onLayer PtLayer $ color white $ circleSolid 8 dropLight' :: World -> World dropLight' w = placeCr (lamp 30) pos 0 w where pos = _crPos(you w)