576 lines
22 KiB
Haskell
576 lines
22 KiB
Haskell
{-# LANGUAGE LambdaCase #-}
|
|
|
|
module Dodge.Update.Input.InGame (
|
|
updateUseInputInGame,
|
|
updateMouseInGame,
|
|
) where
|
|
|
|
import Control.Applicative
|
|
import Control.Monad
|
|
import Data.Foldable
|
|
import qualified Data.IntMap.Strict as IM
|
|
import qualified Data.IntSet as IS
|
|
import Data.List (sort)
|
|
import qualified Data.Map.Strict as M
|
|
import Data.Maybe
|
|
import Data.Monoid
|
|
import Dodge.Camera
|
|
import Dodge.Creature.Action
|
|
import Dodge.Data.Combine
|
|
import Dodge.Data.Universe
|
|
import Dodge.DisplayInventory
|
|
import Dodge.Event.Test
|
|
import Dodge.Inventory
|
|
import Dodge.Inventory.Add
|
|
import Dodge.Item.Display
|
|
import Dodge.Item.InvSize
|
|
import Dodge.ListDisplayParams
|
|
import Dodge.Menu
|
|
import Dodge.Save
|
|
import Dodge.SelectedClose
|
|
import Dodge.SelectionSections
|
|
import Dodge.SoundLogic
|
|
import Dodge.Terminal
|
|
import Dodge.Update.Input.DebugTest
|
|
import Dodge.Update.Input.Text
|
|
--import Dodge.WorldPos
|
|
--import Geometry
|
|
import LensHelp
|
|
import NewInt
|
|
import SDL
|
|
|
|
updateUseInputInGame :: Universe -> Universe
|
|
updateUseInputInGame u = updateFunctionKeys $ case u ^. uvWorld . hud . hudElement of
|
|
DisplayInventory{_subInventory = si, _diSelection = disel} -> case si of
|
|
DisplayTerminal tmid -> updateKeysInTerminal tmid u
|
|
CombineInventory{_ciSections = sss, _ciSelection = msel@(Just (-1, _, _))} ->
|
|
u
|
|
& uvWorld . hud . hudElement . subInventory
|
|
%~ docombineregexinput sss msel
|
|
& uvWorld . worldEventFlags . at CombineInventoryChange ?~ ()
|
|
_
|
|
| disel ^? _Just . _1 == Just (-1) ->
|
|
u
|
|
& uvWorld . hud . hudElement
|
|
%~ dodisplayregexinput diInvFilter diInvFilter (-1)
|
|
& uvWorld . worldEventFlags . at InventoryChange ?~ ()
|
|
& uvWorld %~ setInvPosFromSS
|
|
_
|
|
| disel ^? _Just . _1 == Just 2 ->
|
|
u
|
|
& uvWorld . hud . hudElement
|
|
%~ dodisplayregexinput diCloseFilter diCloseFilter 2
|
|
& uvWorld . worldEventFlags . at InventoryChange ?~ ()
|
|
& uvWorld %~ setInvPosFromSS
|
|
_ -> M.foldlWithKey' updateKeyInGame u pkeys
|
|
where
|
|
pkeys = u ^. uvWorld . input . pressedKeys
|
|
dodisplayregexinput filterprism filterlens x di = fromMaybe di $ do
|
|
sss <- di ^? diSections
|
|
msel <- di ^? diSelection
|
|
filts <- di ^? filterprism
|
|
let (sss', msel', filts') = doRegexInput (u ^. uvWorld . input) x sss msel filts
|
|
return $
|
|
di & diSections .~ sss'
|
|
& diSelection .~ msel'
|
|
& filterlens .~ filts'
|
|
docombineregexinput sss msel ci = fromMaybe ci $ do
|
|
filts <- ci ^? ciFilter
|
|
let (sss', msel', filts') = doRegexInput (u ^. uvWorld . input) (-1) sss msel filts
|
|
return $
|
|
ci & ciSections .~ sss'
|
|
& ciSelection .~ msel'
|
|
& ciFilter .~ filts'
|
|
|
|
updateMouseInGame :: Configuration -> World -> World
|
|
updateMouseInGame cfig w
|
|
| Just 0 <- lbpress = updateMouseClickInGame cfig w
|
|
| Just _ <- lbpress = updateMouseHeldInGame cfig w
|
|
| Just 0 <- lbrelease = updateMouseReleaseInGame w
|
|
| otherwise = w
|
|
where
|
|
lbpress = w ^? input . mouseButtons . ix ButtonLeft
|
|
lbrelease = w ^? input . mouseButtonsReleased . ix ButtonLeft
|
|
|
|
updateMouseHeldInGame :: Configuration -> World -> World
|
|
updateMouseHeldInGame cfig w = case w ^. input . mouseContext of
|
|
OverInvDragSelect sstart _ -> fromMaybe w $ do
|
|
sss <- w ^? hud . hudElement . diSections
|
|
let msel = inverseSelNumPos cfig invDP sss (w ^. input . mousePos)
|
|
guard $ Just (fst sstart) == fmap fst msel || isNothing msel
|
|
return $ w & input . mouseContext . mcoSelEnd .~ fmap snd msel
|
|
OverInvDrag k mmouseover ab bn -> doDrag 30 k mmouseover ab bn w
|
|
_ -> w
|
|
|
|
doDrag ::
|
|
Int ->
|
|
Int ->
|
|
Maybe (Int, Int) ->
|
|
Maybe (Int, Int) ->
|
|
Maybe (Int, Int) ->
|
|
World ->
|
|
World
|
|
doDrag 0 _ _ _ _ w = w
|
|
doDrag n k mmouseover ab bn w = fromMaybe w $ do
|
|
ss <- w ^? hud . hudElement . diSections . ix k . ssItems
|
|
x <- mmouseover
|
|
is <- w ^? hud . hudElement . diSelection . _Just . _3
|
|
return $
|
|
if concurrentIS is
|
|
then shiftInvItems n k x ab bn is ss w
|
|
else collectInvItems k is w
|
|
|
|
tryDropSelected :: Maybe (Int, Int) -> World -> Maybe World
|
|
tryDropSelected mpos w = do
|
|
guard $ maybe True (\(i, _) -> i == 3) mpos
|
|
cr <- w ^? cWorld . lWorld . creatures . ix 0
|
|
(0, _, xs) <- w ^? hud . hudElement . diSelection . _Just
|
|
return . foldl' (flip $ dropItem cr) w . IS.toDescList $ xs
|
|
|
|
tryPickupSelected :: Int -> Maybe (Int, Int) -> World -> Maybe World
|
|
tryPickupSelected k mpos w = do
|
|
guard $ k == 3
|
|
guard $ maybe True (\(i, _) -> i == 0 || i == 1) mpos
|
|
cr <- w ^? cWorld . lWorld . creatures . ix 0
|
|
let nfreeslots = crNumFreeSlots cr
|
|
xs <- w ^? hud . hudElement . diSelection . _Just . _3
|
|
let itmstopickup = mapMaybe g $ IS.toList xs
|
|
let slotsneeded = alaf Sum foldMap (itInvHeight . _flIt) itmstopickup
|
|
guard $ nfreeslots >= slotsneeded
|
|
return $ case mpos of
|
|
Just (0, j) ->
|
|
foldr (pickUpItemAt j 0) w itmstopickup
|
|
& hud . hudElement . diSelection
|
|
?~ ( 0
|
|
, j
|
|
, IS.fromDistinctAscList [j .. j + IS.size xs -1]
|
|
)
|
|
_ ->
|
|
foldl' (flip $ pickUpItem 0) w itmstopickup
|
|
& hud . hudElement . diSelection . _Just . _3 %~ const mempty
|
|
where
|
|
g i = do
|
|
NInt j <- w ^? hud . closeItems . ix i
|
|
w ^? cWorld . lWorld . floorItems . unNIntMap . ix j
|
|
|
|
updateMouseReleaseInGame :: World -> World
|
|
updateMouseReleaseInGame w = case w ^. input . mouseContext of
|
|
OverInvDrag k mpos _ _ ->
|
|
input . mouseContext .~ MouseInGame $
|
|
fromMaybe w $ tryDropSelected mpos w <|> tryPickupSelected k mpos w
|
|
OverInvDragSelect ssel mesel
|
|
| ScancodeLShift `M.member` (w ^. input . pressedKeys) ->
|
|
w & input . mouseContext .~ MouseInGame
|
|
& hud . hudElement . diSelection . _Just . _3
|
|
%~ getuniques
|
|
( maybe
|
|
mempty
|
|
(h ssel)
|
|
( guard (ssel ^? _1 == w ^? hud . hudElement . diSelection . _Just . _1)
|
|
>> mesel ^? _Just
|
|
)
|
|
)
|
|
OverInvDragSelect _ Nothing ->
|
|
w & input . mouseContext .~ MouseInGame
|
|
& hud . hudElement . diSelection . _Just . _3 %~ const mempty
|
|
OverInvDragSelect ssel (Just esel) ->
|
|
w & input . mouseContext .~ MouseInGame
|
|
& augInvDirectSelect (f (fst ssel, esel) (h ssel esel))
|
|
_ -> w
|
|
where
|
|
getuniques x y = IS.union x y IS.\\ IS.intersection x y
|
|
f (x, y) z = (x, y, z)
|
|
h (k, i) j = fold $ do
|
|
sss <- w ^? hud . hudElement . diSections . ix k . ssItems
|
|
let (_, xss) = IM.split (min i j -1) sss
|
|
(yss, _) = IM.split (max i j + 1) xss
|
|
return . IM.keysSet $ yss
|
|
|
|
isGroupSelectableSection :: Int -> Bool
|
|
isGroupSelectableSection = \case
|
|
0 -> True
|
|
3 -> True
|
|
_ -> False
|
|
|
|
updateMouseClickInGame :: Configuration -> World -> World
|
|
updateMouseClickInGame cfig w = case w ^. input . mouseContext of
|
|
MouseInGame -> fromMaybe w $ do
|
|
sss <- w ^? hud . hudElement . diSections
|
|
ysel <- inverseSelSecYint
|
|
(posSelSecYint cfig invDP (w ^. input . mousePos . _y)) sss
|
|
guard (isGroupSelectableSection $ fst ysel)
|
|
return $ w & input . mouseContext .~ OverInvDragSelect ysel Nothing
|
|
OverInvSelect (-1, _)
|
|
| selsec == Just (-1) ->
|
|
w
|
|
& hud . hudElement . diSelection %~ endRegex (-1) w
|
|
& hud . hudElement . diInvFilter .~ Nothing
|
|
OverInvSelect (2, _)
|
|
| selsec == Just 2 ->
|
|
w
|
|
& hud . hudElement . diSelection %~ endRegex 2 w
|
|
& hud . hudElement . diCloseFilter .~ Nothing
|
|
OverInvSelect x
|
|
| ScancodeLShift `M.member` (w ^. input . pressedKeys)
|
|
&& (isGroupSelectableSection $ fst x) ->
|
|
w & input . mouseContext .~ OverInvDragSelect x (Just $ snd x)
|
|
OverInvSelect x -> startDrag x cfig w
|
|
OverTerminalReturn tmid -> terminalReturnEffect tmid w
|
|
OverTerminalEscape -> w & hud . hudElement . subInventory .~ NoSubInventory
|
|
OverCombSelect x ->
|
|
w & hud . hudElement . subInventory . ciSelection ?~ f x
|
|
& worldEventFlags . at CombineInventoryChange ?~ ()
|
|
OverCombFilter ->
|
|
w & hud . hudElement . subInventory . ciFilter .~ Nothing
|
|
& worldEventFlags . at CombineInventoryChange ?~ ()
|
|
& hud . hudElement . subInventory . ciSelection %~ endCombineRegex w
|
|
OverCombCombine x ->
|
|
w
|
|
& tryCombine x
|
|
& worldEventFlags . at CombineInventoryChange ?~ ()
|
|
& worldEventFlags . at InventoryChange ?~ ()
|
|
& maybeExitCombine
|
|
OverCombEscape ->
|
|
w
|
|
& worldEventFlags . at InventoryChange ?~ ()
|
|
& hud . hudElement . subInventory .~ NoSubInventory
|
|
OverCombFiltInv (0, j) -> fromMaybe w $ do
|
|
str <-
|
|
fmap (take 5) $
|
|
w ^? cWorld . lWorld . creatures . ix 0 . crInv . ix j
|
|
>>= (listToMaybe . basicItemDisplay)
|
|
return . (worldEventFlags . at CombineInventoryChange ?~ ()) $
|
|
case w ^? hud . hudElement . subInventory . ciFilter . _Just of
|
|
Just ('#' : xs) | str == xs ->
|
|
w & hud . hudElement . subInventory . ciFilter .~ Nothing
|
|
_ -> w & hud . hudElement . subInventory . ciFilter ?~ ("#" ++ str)
|
|
_ -> w
|
|
where
|
|
f (x, y) = (x, y, mempty)
|
|
selsec = w ^? hud . hudElement . diSelection . _Just . _1
|
|
|
|
endRegex ::
|
|
Int ->
|
|
World ->
|
|
Maybe (Int, Int, IS.IntSet) ->
|
|
Maybe (Int, Int, IS.IntSet)
|
|
endRegex i w = fromMaybe id $ do
|
|
sss <- w ^? hud . hudElement . diSections
|
|
let j = fromMaybe 0 $ do
|
|
itms <- sss ^? ix i . ssItems
|
|
(k, _) <- IM.lookupMin itms
|
|
return k
|
|
return $ ssSetCursor (ssLookupDown i j) sss
|
|
|
|
endCombineRegex ::
|
|
World ->
|
|
Maybe (Int, Int, IS.IntSet) ->
|
|
Maybe (Int, Int, IS.IntSet)
|
|
endCombineRegex w = fromMaybe id $ do
|
|
sss <- w ^? hud . hudElement . subInventory . ciSections
|
|
let j = fromMaybe 0 $ do
|
|
itms <- sss ^? ix 0 . ssItems
|
|
(k, _) <- IM.lookupMin itms
|
|
return (k -1)
|
|
return $ ssSetCursor (ssLookupDown 0 j) sss
|
|
|
|
startDrag :: (Int, Int) -> Configuration -> World -> World
|
|
startDrag (a, b) cfig w = setcontext
|
|
$ case w ^? hud . hudElement . diSelection . _Just of
|
|
Just (i,_,xs) | i == a && b `IS.member` xs -> w
|
|
_ -> augInvDirectSelect (a, b, IS.singleton b) w
|
|
where
|
|
setcontext = input . mouseContext .~ OverInvDrag a (Just (a, b)) above bneath
|
|
above = inverseSelSecYint (yint - 1) =<< w ^? hud . hudElement . diSections
|
|
bneath = inverseSelSecYint (yint + 1) =<< w ^? hud . hudElement . diSections
|
|
yint = posSelSecYint cfig invDP (w ^. input . mousePos . _y)
|
|
|
|
concurrentIS :: IS.IntSet -> Bool
|
|
concurrentIS = go . IS.minView
|
|
where
|
|
go Nothing = True
|
|
go (Just (i, is)) = fromMaybe True $ do
|
|
(j, js) <- IS.minView is
|
|
return $ i + 1 == j && go (Just (j, js))
|
|
|
|
collectInvItems :: Int -> IS.IntSet -> World -> World
|
|
collectInvItems secid is w = fromMaybe w $ do
|
|
guard $ secid == 0
|
|
(j, js) <- IS.minView is
|
|
return $ h j js w
|
|
where
|
|
h j js w' = fromMaybe w' $ do
|
|
(k, ks) <- IS.minView js
|
|
return . h (j + 1) ks $ swapInvItems (\_ _ -> Just (j + 1)) k w'
|
|
|
|
shiftInvItems ::
|
|
Int -> -- recurse limit
|
|
Int -> -- section where drag started
|
|
(Int, Int) -> -- selection item mouse is over
|
|
Maybe (Int, Int) -> -- selection item "above" mouse position (can be same as over)
|
|
Maybe (Int, Int) -> -- selection item "below" mouse position (can be same as over)
|
|
IS.IntSet ->
|
|
IM.IntMap (SelectionItem a) ->
|
|
World ->
|
|
World
|
|
shiftInvItems n k x ab bn xs ss w = setSelWhileDragging . fromMaybe w $ do
|
|
let xk = fst x
|
|
guard $ xk == k || xk + 1 == k || xk -1 == k
|
|
(maxi, _) <- IS.maxView xs
|
|
(mini, _) <- IS.minView xs
|
|
case True of
|
|
_ | x < (k, mini) -> do
|
|
guard $ not . null . fst $ IM.split mini ss
|
|
guard $ Just (k, mini -1) /= ab
|
|
return . doDrag (n -1) k (Just x) ab bn $ shiftInvItemsUp k xs w
|
|
_ | x > (k, maxi) -> do
|
|
guard $ not . null . snd $ IM.split maxi ss
|
|
guard $ Just (k, maxi + 1) /= bn
|
|
return . doDrag (n -1) k (Just x) ab bn $ shiftInvItemsDown k xs w
|
|
_ -> Nothing
|
|
|
|
setSelWhileDragging :: World -> World
|
|
setSelWhileDragging w = fromMaybe w $ do
|
|
(i, _, xs) <- w ^? hud . hudElement . diSelection . _Just
|
|
(k, j) <- w ^? input . mouseContext . mcoMaybeSelect . _Just
|
|
guard $ i == k && j `IS.member` xs
|
|
return $ w & hud . hudElement . diSelection . _Just . _2 .~ j
|
|
|
|
shiftInvItemsUp :: Int -> IS.IntSet -> World -> World
|
|
shiftInvItemsUp j is w = IS.foldl' f w is
|
|
where
|
|
f w' i' = swapItemWith g (j, i') w'
|
|
g i' m = fst <$> IM.lookupLT i' m
|
|
|
|
shiftInvItemsDown :: Int -> IS.IntSet -> World -> World
|
|
shiftInvItemsDown j is w = fromMaybe w $ do
|
|
let i = IS.findMax is
|
|
guard . isJust $
|
|
w ^? hud . hudElement . diSections . ix j . ssItems . ix i
|
|
return $ IS.foldr f w is
|
|
where
|
|
f i' w' = swapItemWith g (j, i') w'
|
|
g i' m = fst <$> IM.lookupGT i' m
|
|
|
|
updateFunctionKeys :: Universe -> Universe
|
|
updateFunctionKeys u =
|
|
M.foldlWithKey'
|
|
updateFunctionKey
|
|
u
|
|
(u ^. uvWorld . input . pressedKeys)
|
|
|
|
updateFunctionKey :: Universe -> Scancode -> PressType -> Universe
|
|
updateFunctionKey uv sc InitialPress = case sc of
|
|
ScancodeF1 -> useNormalCamera uv
|
|
ScancodeF2 -> pauseAndFloatCam uv
|
|
ScancodeF5 -> doQuicksave uv
|
|
ScancodeF9 -> doQuickload uv
|
|
ScancodeF6 -> doDebugTestF6 uv
|
|
ScancodeF7 -> doDebugTestF7 uv
|
|
ScancodeF8 -> doDebugTestF8 uv
|
|
ScancodeF10 -> doDebugTestF10 uv
|
|
ScancodeF11 -> doDebugTestF11 uv
|
|
ScancodeF12 -> doDebugTestF12 uv
|
|
ScancodeEscape -> pauseGame uv
|
|
_ -> uv
|
|
updateFunctionKey uv ScancodeF3 _ = doDebugTest uv
|
|
updateFunctionKey uv ScancodeF4 _ = doDebugTest2 uv
|
|
updateFunctionKey uv _ _ = uv
|
|
|
|
--updatePressedButtonsCarte :: World -> World
|
|
--updatePressedButtonsCarte w = updatePressedButtonsCarte' (_mouseButtons (_input w)) w
|
|
|
|
--updatePressedButtonsCarte' :: M.Map MouseButton Int -> World -> World
|
|
--updatePressedButtonsCarte' pkeys w
|
|
-- | isDown ButtonRight =
|
|
-- w & hud . carteCenter %~ (-.- trans)
|
|
-- | isDown ButtonLeft =
|
|
-- w
|
|
-- & hud . carteRot -~ rot
|
|
-- & hud . carteZoom *~ czoom
|
|
-- | otherwise = w
|
|
-- where
|
|
-- isDown but = but `M.member` pkeys
|
|
-- mbutpos but = theinput ^. heldPos . at but
|
|
-- rot = maybe 0 (angleBetween (_mousePos (_input w))) $ mbutpos SDL.ButtonLeft
|
|
-- czoom = fromMaybe 1 $ do
|
|
-- p <- mbutpos SDL.ButtonLeft
|
|
-- return $ magV (_mousePos theinput) / magV p
|
|
-- theinput = w ^. input
|
|
-- trans = fromMaybe 0 $ do
|
|
-- p <- mbutpos SDL.ButtonRight
|
|
-- return . rotateV (w ^. hud . carteRot) $
|
|
-- 1 / (w ^. hud . carteZoom) *.* (_mousePos (_input w) -.- p)
|
|
|
|
updateKeysInTerminal :: Int -> Universe -> Universe
|
|
updateKeysInTerminal tmid u =
|
|
u
|
|
& doTextInputOverUniverse
|
|
(uvWorld . cWorld . lWorld . terminals . ix tmid . tmInput . tiText)
|
|
& checkEndStatus
|
|
where
|
|
checkEndStatus
|
|
| u ^. uvWorld . input . pressedKeys . at ScancodeReturn == Just InitialPress =
|
|
uvWorld %~ terminalReturnEffect tmid
|
|
| otherwise = id
|
|
|
|
updateKeyInGame :: Universe -> Scancode -> PressType -> Universe
|
|
updateKeyInGame uv sc pt = case pt of
|
|
InitialPress -> updateInitialPressInGame uv sc
|
|
LongPress -> updateLongPressInGame uv sc
|
|
_ -> uv
|
|
|
|
updateInitialPressInGame :: Universe -> Scancode -> Universe
|
|
updateInitialPressInGame uv sc = case sc of
|
|
ScancodeSpace -> over uvWorld spaceAction uv
|
|
ScancodeP -> pauseGame uv
|
|
ScancodeF -> over uvWorld youDropItem uv
|
|
-- ScancodeM -> toggleMap uv
|
|
ScancodeT -> over uvWorld testEvent uv
|
|
ScancodeC -> toggleCombineInv uv
|
|
-- the following should be put in a more sensible place
|
|
ScancodeSlash -> uv & uvWorld %~ updateEnterRegex
|
|
ScancodeBackspace -> uv & uvWorld %~ updateBackspaceRegex
|
|
_ -> uv
|
|
|
|
updateLongPressInGame :: Universe -> Scancode -> Universe
|
|
updateLongPressInGame uv sc = case sc of
|
|
ScancodeF -> over uvWorld youDropItem uv
|
|
ScancodeSpace -> over uvWorld spaceAction uv
|
|
_ -> uv
|
|
|
|
doRegexInput ::
|
|
Input ->
|
|
Int ->
|
|
IM.IntMap (SelectionSection a) ->
|
|
Maybe (Int, Int, IS.IntSet) ->
|
|
Maybe String ->
|
|
(IM.IntMap (SelectionSection a), Maybe (Int, Int, IS.IntSet), Maybe String)
|
|
doRegexInput inp i sss msel filts
|
|
| backspacetonothing || escapekey = endregex i 0
|
|
| endkeys = endregex (i + 1) (j -1)
|
|
| otherwise =
|
|
( sss
|
|
, msel
|
|
, filts & doTextInputOver inp _Just
|
|
)
|
|
where
|
|
endregex a b =
|
|
( sss
|
|
, msel & ssSetCursor (ssLookupDown a b) sss
|
|
, Nothing
|
|
)
|
|
j = fromMaybe 0 $ do
|
|
itms <- sss ^? ix (i + 1) . ssItems
|
|
fst <$> IM.lookupMin itms
|
|
escapekey = ScancodeEscape `M.lookup` pkeys == Just InitialPress
|
|
endkeys =
|
|
any
|
|
((== Just InitialPress) . (`M.lookup` pkeys))
|
|
[ScancodeReturn, ScancodeSlash]
|
|
backspacetonothing =
|
|
filts == Just ""
|
|
&& ScancodeBackspace `M.lookup` pkeys == Just InitialPress
|
|
pkeys = inp ^. pressedKeys
|
|
|
|
updateBackspaceRegex :: World -> World
|
|
updateBackspaceRegex w = case di ^? subInventory of
|
|
Just NoSubInventory{}
|
|
| secfocus (-1) 0 ->
|
|
w & hud . hudElement %~ trybackspace (-1) diInvFilter diInvFilter diSelection
|
|
& worldEventFlags . at InventoryChange ?~ ()
|
|
Just NoSubInventory{}
|
|
| secfocus 2 3 ->
|
|
w & hud . hudElement %~ trybackspace 2 diCloseFilter diCloseFilter diSelection
|
|
& worldEventFlags . at InventoryChange ?~ ()
|
|
Just CombineInventory{} ->
|
|
w & hud . hudElement . subInventory %~ trybackspace (-1) ciFilter ciFilter ciSelection
|
|
& worldEventFlags . at InventoryChange ?~ ()
|
|
_ -> w
|
|
where
|
|
secfocus a b = fromMaybe False $ do
|
|
i <- di ^? diSelection . _Just . _1
|
|
return $ i == a || i == b
|
|
trybackspace x filtget filtset selset he = fromMaybe he $ do
|
|
str <- he ^? filtget . _Just
|
|
return $ case str of
|
|
(_ : _) ->
|
|
he & filtset . _Just %~ init
|
|
& selset ?~ (x, 0, mempty)
|
|
[] -> he & filtset .~ Nothing
|
|
di = w ^. hud . hudElement
|
|
|
|
updateEnterRegex :: World -> World
|
|
updateEnterRegex w = case w ^? hud . hudElement . subInventory of
|
|
Just NoSubInventory{}
|
|
| secfocus [-1, 0, 1] ->
|
|
w & hud . hudElement . diSelection ?~ (-1, 0, mempty)
|
|
& hud . hudElement . diInvFilter %~ enterregex
|
|
Just NoSubInventory{}
|
|
| secfocus [2, 3] ->
|
|
w & hud . hudElement . diSelection ?~ (2, 0, mempty)
|
|
& hud . hudElement . diCloseFilter %~ enterregex
|
|
Just CombineInventory{} ->
|
|
w & hud . hudElement . subInventory . ciFilter %~ enterregex
|
|
& hud . hudElement . subInventory . ciSelection ?~ (-1, 0, mempty)
|
|
_ -> w
|
|
where
|
|
di = w ^. hud . hudElement
|
|
secfocus xs = fromMaybe False $ do
|
|
i <- di ^? diSelection . _Just . _1
|
|
return $ i `elem` xs
|
|
enterregex = (<|> Just "")
|
|
|
|
pauseGame :: Universe -> Universe
|
|
pauseGame u = u & uvScreenLayers .~ [pauseMenu u]
|
|
|
|
spaceAction :: World -> World
|
|
spaceAction w = case w ^. hud . hudElement of
|
|
DisplayInventory{_subInventory = NoSubInventory{}} ->
|
|
maybe id interactWithCloseObj (getCloseObj w) w
|
|
DisplayInventory{_subInventory = DisplayTerminal{}} ->
|
|
w
|
|
& hud . hudElement . subInventory .~ NoSubInventory
|
|
& worldEventFlags . at InventoryChange ?~ ()
|
|
_ -> w & hud . hudElement . subInventory .~ NoSubInventory
|
|
|
|
getCloseObj :: World -> Maybe (Either FloorItem Button)
|
|
getCloseObj w = getSelectedCloseObj w <|> firstcitem <|> firstcbut
|
|
where
|
|
firstcitem = do
|
|
k' <- (w ^? hud . hudElement . diSections . ix 3 . ssItems) >>= (fmap fst . IM.lookupMin)
|
|
NInt k <- w ^? hud . closeItems . ix k'
|
|
fmap Left $ w ^? cWorld . lWorld . floorItems . unNIntMap . ix k
|
|
firstcbut = do
|
|
k <- w ^? hud . closeButtons . ix 0
|
|
fmap Right $ w ^? cWorld . lWorld . buttons . ix k
|
|
|
|
--toggleMap :: Universe -> Universe
|
|
--toggleMap u = case u ^. uvWorld . hud . hudElement of
|
|
-- DisplayCarte ->
|
|
-- u & uvWorld . hud . hudElement
|
|
-- .~ DisplayInventory
|
|
-- { _subInventory = NoSubInventory
|
|
-- , _diSections = mempty
|
|
-- , _diSelection = Nothing
|
|
-- , _diInvFilter = mempty
|
|
-- , _diCloseFilter = mempty
|
|
-- }
|
|
-- _ -> u & uvWorld . hud . hudElement .~ DisplayCarte
|
|
|
|
tryCombine :: (Int, Int) -> World -> World
|
|
tryCombine (i, j) w = fromMaybe w $ do
|
|
sss <- w ^? hud . hudElement . subInventory . ciSections
|
|
CombinableItem is it <- sss ^? ix i . ssItems . ix j . siPayload
|
|
p <- w ^? cWorld . lWorld . creatures . ix 0 . crPos
|
|
return $
|
|
snd (createItemYou it (foldr (destroyInvItem 0) w (sort is)))
|
|
& soundStart InventorySound p wrench1S Nothing
|
|
& hud . hudElement . diSelection . _Just . _3 .~ mempty
|
|
|
|
maybeExitCombine :: World -> World
|
|
maybeExitCombine w
|
|
| ButtonRight `M.member` (w ^. input . mouseButtons) = w
|
|
| otherwise =
|
|
w & hud . hudElement . subInventory .~ NoSubInventory
|