{-# LANGUAGE LambdaCase #-} module Dodge.Creature.Impulse.UseItem ( useItem, ) where import Control.Lens import Control.Monad import Data.Maybe import Dodge.Data.ComposedItem import Dodge.Data.DoubleTree import Dodge.Data.World import Dodge.DoubleTree import Dodge.Euse import Dodge.HeldUse import Dodge.Inventory import Dodge.Item.Grammar import qualified IntMapHelp as IM useItem :: Int -> PressType -> World -> Maybe World useItem invid pt w = fmap (worldEventFlags . at InventoryChange ?~ ()) $ do cr <- w ^? cWorld . lWorld . creatures . ix 0 itmloc <- allInvLocs (_crInv cr) ^? ix invid . _2 let usedloc = useLocation itmloc useItemLoc cr usedloc pt w useItemLoc :: Creature -> LocationLDT ItemLink ComposedItem -> PressType -> World -> Maybe World useItemLoc cr loc pt w = case loc ^. locLDT . ldtValue . _2 of HeldPlatformSF -> do guard $ fromMaybe False $ loc ^? locLDT . ldtValue . _1 . itLocation . ilIsRoot guard $ cr ^. crStance . posture == Aiming return $ heldEffect pt (bimap _iatType (^. _1) ldt) cr w GadgetPlatformSF -> return $ heldEffect pt (bimap _iatType (^. _1) ldt) cr w UnderBarrelPlatformSF -> do guard $ fromMaybe False $ loc ^? locLDT . ldtValue . _1 . itLocation . ilIsAttached guard $ cr ^. crStance . posture == Aiming return $ heldEffect pt (bimap _iatType (^. _1) ldt) cr w RemoteDetonatorSF -> do guard $ pt == InitialPress return $ activateDetonator ldt w _ | isJust $ itm ^? itUse . uequipEffect -> do guard $ pt == InitialPress invid' <- itm ^? itLocation . ilInvID return $ toggleEquipmentAt invid' cr w _ -> Nothing where ldt = loc ^. locLDT itm = ldt ^. ldtValue . _1 useLocation :: LocationLDT ItemLink ComposedItem -> LocationLDT ItemLink ComposedItem useLocation loc | isJust $ loc ^? locLDT . ldtValue . _1 . itUse . uequipEffect = loc | isJust $ loc ^? locLDT . ldtValue . _1 . itUse . uaParams . apProjectiles . ix 0 = loc | sf <- loc ^. locLDT . ldtValue . _2 , structureUseAtLoc sf = loc | otherwise = locToTop loc structureUseAtLoc :: ItemStructuralFunction -> Bool structureUseAtLoc = \case HeldPlatformSF -> True UnderBarrelPlatformSF -> True _ -> False activateDetonator :: LabelDoubleTree ItemLink ComposedItem -> World -> World activateDetonator det = fromMaybe id $ do pjid <- det ^? ldtValue . _1 . itUse . uaParams . apProjectiles . ix 0 return $ cWorld . lWorld . projectiles . ix pjid . pjTimer .~ 0 toggleEquipmentAt :: Int -> Creature -> World -> World toggleEquipmentAt invid cr w = case getEquipmentAllocation invid w of DoNotMoveEquipment -> w PutOnEquipment{_allocNewPos = newp} -> w & crpoint . crEquipment . at newp ?~ invid & crpoint . crInv . ix invid . itLocation . ilEquipSite ?~ newp & onequip itm cr MoveEquipment{_allocNewPos = newp, _allocOldPos = oldp} -> w & crpoint . crEquipment . at newp ?~ invid & crpoint . crEquipment . at oldp .~ Nothing & crpoint . crInv . ix invid . itLocation . ilEquipSite ?~ newp SwapEquipment{_allocNewPos = newp, _allocOldPos = oldp, _allocSwapID = sid} -> w & crpoint . crEquipment . at newp ?~ invid & crpoint . crEquipment . at oldp ?~ sid & crpoint . crInv . ix invid . itLocation . ilEquipSite ?~ newp & crpoint . crInv . ix sid . itLocation . ilEquipSite ?~ oldp ReplaceEquipment{_allocNewPos = newp, _allocRemoveID = rid} -> w & crpoint . crEquipment . at newp ?~ invid & crpoint . crInv . ix invid . itLocation . ilEquipSite ?~ newp & crpoint . crInv . ix rid . itLocation . ilEquipSite .~ Nothing & onremove (itmat rid) cr & onequip itm cr RemoveEquipment{_allocOldPos = oldp} -> w & crpoint . crEquipment . at oldp .~ Nothing & crpoint . crInv . ix invid . itLocation . ilEquipSite .~ Nothing & onremove itm cr where crpoint = cWorld . lWorld . creatures . ix (_crID cr) itmat i = _crInv cr IM.! i itm = itmat invid onequip itm' = doItmCrWdWd ((_eeOnEquip . _uequipEffect . _itUse) itm') itm' onremove itm' = doItmCrWdWd ((_eeOnRemove . _uequipEffect . _itUse) itm') itm'