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