80 lines
2.8 KiB
Haskell
80 lines
2.8 KiB
Haskell
module Dodge.Inventory.Swap (
|
|
swapInvItems,
|
|
swapAnyExtraSelection
|
|
) where
|
|
|
|
import Dodge.SoundLogic
|
|
import Dodge.Item.Grammar
|
|
import Dodge.Base.You
|
|
import Dodge.Inventory.Location
|
|
import Dodge.Data.DoubleTree
|
|
import Sound.Data
|
|
import qualified Data.IntSet as IS
|
|
import Data.Maybe
|
|
import Control.Lens
|
|
import Dodge.Data.SelectionList
|
|
import qualified IntMapHelp as IM
|
|
import Dodge.Data.World
|
|
import Control.Monad
|
|
|
|
swapInvItems ::
|
|
(Int -> IM.IntMap (SelectionItem ()) -> Maybe Int) ->
|
|
Int ->
|
|
World ->
|
|
World
|
|
swapInvItems f i w = fromMaybe w $ do
|
|
ss <- w ^? hud . hudElement . diSections . ix 0 . ssItems
|
|
k <- f i ss
|
|
let updateselection = case w ^? hud . hudElement . diSelection . _Just of
|
|
Just (0, j,_) | j == k -> hud . hudElement . diSelection . _Just . _2 .~ i
|
|
Just (0, j,_) | j == i -> hud . hudElement . diSelection . _Just . _2 .~ k
|
|
_ -> id
|
|
return $
|
|
w
|
|
& swapAnyExtraSelection i k
|
|
& checkConnection InventorySound disconnectItemS i k
|
|
& cWorld . lWorld . creatures . ix 0 %~ updatecreature k
|
|
& updateselection
|
|
& worldEventFlags . at InventoryChange ?~ ()
|
|
& cWorld . lWorld %~ crUpdateItemLocations 0
|
|
& setInvPosFromSS
|
|
& cWorld . lWorld %~ crUpdateItemLocations 0 -- the double application is inefficient, but necessary without further changes
|
|
-- a rethink is maybe in order
|
|
& checkConnection InventoryConnectSound connectItemS i k
|
|
where
|
|
updatecreature k =
|
|
(crInv %~ IM.safeSwapKeys i k)
|
|
. (crManipulation . manObject . imSelectedItem .~ k)
|
|
. swapSite i k
|
|
. swapSite k i
|
|
cr = you w
|
|
swapSite a b = case cr ^? crInv . ix a . itLocation . ilEquipSite . _Just of
|
|
Just epos -> crEquipment . ix epos .~ b
|
|
Nothing -> id
|
|
|
|
swapAnyExtraSelection :: Int -> Int -> World -> World
|
|
swapAnyExtraSelection i k w = fromMaybe w $ do
|
|
is <- w ^? hud . hudElement . diSelection . _Just . _3
|
|
let f = if i `IS.member` is then IS.insert k else id
|
|
g = if k `IS.member` is then IS.insert i else id
|
|
return $
|
|
w & hud . hudElement . diSelection . _Just . _3
|
|
%~ (f . g . IS.delete i . IS.delete k)
|
|
|
|
checkConnection :: SoundOrigin -> SoundID -> Int -> Int -> World -> World
|
|
checkConnection so s i j w = fromMaybe w $ do
|
|
inv <- w ^? cWorld . lWorld . creatures . ix 0 . crInv
|
|
cpos <- w ^? cWorld . lWorld . creatures . ix 0 . crPos
|
|
let locs = allInvLocs inv
|
|
iit <- locs ^? ix i . _2
|
|
jit <- locs ^? ix j . _2
|
|
guard $ isConnected iit || isConnected jit
|
|
return $ soundStart so cpos s Nothing w
|
|
|
|
isConnected :: LocationLDT b a -> Bool
|
|
isConnected x = case x ^. locLdtContext of
|
|
TopLDT ->
|
|
not (null $ x ^. locLDT . ldtRight)
|
|
|| not (null $ x ^. locLDT . ldtLeft)
|
|
_ -> True
|