{-# LANGUAGE LambdaCase #-} module Dodge.Creature.Impulse.UseItem ( useItem, ) where import Control.Lens 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 Dodge.Item.Location 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 | HeldPlatformSF <- sf , fromMaybe False $ loc ^? locLDT . ldtValue . _1 . itLocation . ilIsRoot -- , cr ^. crStance . posture == Aiming = , Aiming {} <- cr ^. crStance . posture = return $ heldEffect pt (bimap _iatType (^. _1) ldt) cr w | GadgetPlatformSF <- sf = return $ gadgetEffect pt loc cr w | UnderBarrelPlatformSF <- sf , fromMaybe False $ loc ^? locLDT . ldtValue . _1 . itLocation . ilIsAttached -- , cr ^. crStance . posture == Aiming = , Aiming {} <- cr ^. crStance . posture = return $ heldEffect pt (bimap _iatType (^. _1) ldt) cr w | RemoteDetonatorSF <- sf , pt == InitialPress = return $ activateDetonator ldt w | ITEMSCAN <- itm ^. itType , pt == InitialPress = return $ toggleExamineInv w | MAPPER <- itm ^. itType , pt == InitialPress = return $ toggleMapperInv itm w | Just b <- itm ^? itUse . useToggle , pt == InitialPress = return $ w & pointerToItem itm . itUse . useToggle .~ not b | isJust $ itm ^? itUse . uequipEffect , pt == InitialPress , Just invid' <- itm ^? itLocation . ilInvID = return $ toggleEquipmentAt invid' cr w | otherwise = Nothing where sf = loc ^. locLDT . ldtValue . _2 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 GadgetPlatformSF -> True MapperSF -> 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' toggleExamineInv :: World -> World toggleExamineInv w = case w ^? hud . hudElement . subInventory of Just ExamineInventory{} -> w & hud . hudElement . subInventory .~ NoSubInventory _ -> w & hud . hudElement . subInventory .~ ExamineInventory toggleMapperInv :: Item -> World -> World toggleMapperInv itm w = case w ^? hud . hudElement . subInventory of Just MapperInventory{} -> w & hud . hudElement . subInventory .~ NoSubInventory _ -> w & hud . hudElement . subInventory .~ MapperInventory 0 1 (_itID itm)