110 lines
3.5 KiB
Haskell
110 lines
3.5 KiB
Haskell
module Dodge.Inventory
|
|
( checkInvSlotsYou
|
|
, rmSelectedInvItem
|
|
, rmInvItem
|
|
, updateCloseObjects
|
|
, closeObjScrollDir
|
|
, swapInvDir
|
|
, dirInvPos
|
|
)
|
|
where
|
|
import Dodge.Data
|
|
import Dodge.Base
|
|
import Dodge.Base.Collide
|
|
import Geometry
|
|
import FoldableHelp
|
|
import Padding
|
|
import qualified IntMapHelp as IM
|
|
|
|
--import Data.Maybe
|
|
import Data.List
|
|
--import System.Random
|
|
import Control.Lens
|
|
|
|
-- | checks whether or not an item will fit in your inventory
|
|
-- if so return Just the next slot to be used
|
|
checkInvSlotsYou :: Item -> World -> Maybe Int
|
|
checkInvSlotsYou it w
|
|
| _crInvCapacity ycr >= curinvsize + _itInvSize it
|
|
= Just $ maybe 0 ((+1) . fst) $ IM.lookupMax inv
|
|
| otherwise = Nothing
|
|
where
|
|
ycr = you w
|
|
inv = _crInv ycr
|
|
curinvsize = sum $ fmap _itInvSize inv
|
|
|
|
---- | Finds first available slot where a new item may be placed in the inventory
|
|
--checkInvSlots :: Item -> IM.IntMap Item -> Maybe Int
|
|
--checkInvSlots it = checkInvSlotsH it . IM.toList
|
|
|
|
itNotFull :: Item -> Bool
|
|
itNotFull it = case it ^? itMaxStack of
|
|
Just themax -> themax > _itAmount it
|
|
Nothing -> False
|
|
|
|
rmInvItem
|
|
:: Int -- ^ Creature id
|
|
-> Int -- ^ Inventory position
|
|
-> World
|
|
-> World
|
|
rmInvItem cid invid w = case w ^? creatures . ix cid . crInv . ix invid . itAmount of
|
|
Just x | x > 1 -> w & creatures . ix cid . crInv . ix invid . itAmount %~ subtract 1
|
|
_ -> w & creatures . ix cid . crInv %~ f
|
|
& creatures . ix cid . crInvSel %~ g
|
|
& creatures . ix cid . crLeftInvSel . _Just %~ g
|
|
where
|
|
maxk = fmap fst $ IM.lookupMax $ _crInv $ _creatures w IM.! cid
|
|
f inv = let (xs,ys) = IM.split invid inv
|
|
in xs `IM.union` IM.mapKeys (subtract 1) ys
|
|
g x | x > invid || Just x == maxk = x - 1
|
|
| otherwise = x
|
|
{- Delete a creature's selected item, the item will no longer exist. -}
|
|
rmSelectedInvItem
|
|
:: Int -- ^ Creature id
|
|
-> World
|
|
-> World
|
|
rmSelectedInvItem cid w = rmInvItem cid (_crInvSel (_creatures w IM.! cid)) w
|
|
|
|
updateCloseObjects :: World -> World
|
|
updateCloseObjects w = w & closeObjects .~ unionBy eTest oldCloseFiltered currentClose
|
|
where
|
|
filt = filter $ \obj -> dist ypos (pos obj) < 40 && hasLOS ypos (pos obj) w
|
|
ypos = _crPos $ you w
|
|
objs = map Left (IM.elems $ _floorItems w) ++ activeButtons
|
|
activeButtons = map Right
|
|
. filter ( (/=) BtNoLabel . _btState)
|
|
. IM.elems
|
|
$ _buttons w
|
|
pos (Right x) = _btPos x
|
|
pos (Left x) = _flItPos x
|
|
eTest (Right x) (Right y) = _btID x == _btID y
|
|
eTest (Left x) (Left y) = _flItID x == _flItID y
|
|
eTest _ _ = False
|
|
currentClose = filt objs
|
|
oldClose = filt $ _closeObjects w
|
|
oldCloseFiltered = intersectBy eTest oldClose currentClose
|
|
|
|
closeObjScrollDir :: Float -> World -> World
|
|
closeObjScrollDir x
|
|
| x > 0 = over closeObjects rotU
|
|
| x < 0 = over closeObjects rotD
|
|
| otherwise = id
|
|
|
|
swapInvDir :: Int -> World -> World
|
|
swapInvDir k w = w & creatures . ix (_yourID w) %~ updatecreature
|
|
where
|
|
updatecreature = ( crInv %~ IM.swapKeys (i `mod` n) swapi )
|
|
. (crLeftInvSel . _Just %~ updateLeftInvSel)
|
|
swapi = (i + k) `mod` n
|
|
updateLeftInvSel li | i == li = swapi
|
|
| swapi == li = i
|
|
| otherwise = li
|
|
i = _crInvSel $ you w
|
|
n = length $ IM.keys $ _crInv $ _creatures w IM.! _yourID w
|
|
|
|
dirInvPos :: Int -> World -> World
|
|
dirInvPos i w = w
|
|
& creatures . ix (_yourID w) . crInvSel %~ (`mod` n) . subtract i
|
|
where
|
|
n = length $ IM.keys $ _crInv $ _creatures w IM.! _yourID w
|