From d88aed10c7f8b7ccd51bf756166af1e67910a5a7 Mon Sep 17 00:00:00 2001 From: justin Date: Sat, 28 Jun 2025 22:32:12 +0100 Subject: [PATCH] Hack together correct positioning of grenades from attached items --- src/Dodge/Creature/Impulse/UseItem.hs | 10 +- src/Dodge/Creature/State.hs | 14 +-- src/Dodge/Creature/Test.hs | 2 +- src/Dodge/DisplayInventory.hs | 2 +- src/Dodge/Euse.hs | 2 +- src/Dodge/HeldUse.hs | 153 ++++++++++++------------- src/Dodge/Item/Grammar.hs | 40 ++++++- src/Dodge/Item/HeldOffset.hs | 6 + src/Dodge/Item/Orientation.hs | 7 +- src/Dodge/Projectile/Create.hs | 8 +- src/Dodge/WorldEffect.hs | 2 +- tags | 157 +++++++++++++------------- 12 files changed, 225 insertions(+), 178 deletions(-) diff --git a/src/Dodge/Creature/Impulse/UseItem.hs b/src/Dodge/Creature/Impulse/UseItem.hs index 0648c28c4..70fd329a6 100644 --- a/src/Dodge/Creature/Impulse/UseItem.hs +++ b/src/Dodge/Creature/Impulse/UseItem.hs @@ -25,7 +25,7 @@ useItem invid pt w = fmap (worldEventFlags . at InventoryChange ?~ ()) $ do useItemLoc cr usedloc pt w useItemLoc :: Creature -> - LocationLDT ItemLink CItem -> + LocationLDT ItemLink OItem -> PressType -> World -> Maybe World @@ -33,13 +33,13 @@ useItemLoc cr loc pt w | HeldPlatformSF <- sf , fromMaybe False $ loc ^? locLDT . ldtValue . _1 . itLocation . ilIsRoot , Aiming {} <- cr ^. crStance . posture = - return $ heldEffect pt (bimap id (^. _1) ldt) cr w + return $ heldEffect pt (bimap id id ldt) cr w | GadgetPlatformSF <- sf = return $ gadgetEffect pt loc cr w | UnderBarrelPlatformSF <- sf , fromMaybe False $ loc ^? locLDT . ldtValue . _1 . itLocation . ilIsAttached , Aiming {} <- cr ^. crStance . posture = - return $ heldEffect pt (bimap id (^. _1) ldt) cr w + return $ heldEffect pt (bimap id id ldt) cr w | RemoteDetonatorSF <- sf , pt == InitialPress = return $ activateDetonator ldt w @@ -62,7 +62,7 @@ useItemLoc cr loc pt w ldt = loc ^. locLDT itm = ldt ^. ldtValue . _1 -useLocation :: LocationLDT ItemLink CItem -> LocationLDT ItemLink CItem +useLocation :: LocationLDT ItemLink OItem -> LocationLDT ItemLink OItem useLocation loc | isJust $ loc ^? locLDT . ldtValue . _1 . itType . ibtEquip = loc | isJust $ loc ^? locLDT . ldtValue . _1 . itUse . uaParams . apProjectiles . ix 0 = @@ -80,7 +80,7 @@ structureUseAtLoc = \case MapperSF -> True _ -> False -activateDetonator :: LDTree ItemLink CItem -> World -> World +activateDetonator :: LDTree ItemLink OItem -> World -> World activateDetonator det = fromMaybe id $ do pjid <- det ^? ldtValue . _1 . itUse . uaParams . apProjectiles . ix 0 return $ cWorld . lWorld . projectiles . ix pjid . pjTimer .~ 0 diff --git a/src/Dodge/Creature/State.hs b/src/Dodge/Creature/State.hs index c0e4106a5..8c6a9b837 100644 --- a/src/Dodge/Creature/State.hs +++ b/src/Dodge/Creature/State.hs @@ -151,9 +151,9 @@ invRootItemEffs cr = appEndo $ foldMap (reduceLocLDT (Endo . invItemLocUpdate cr) . LocLDT TopLDT) - (invLDT (_crInv cr)) + (invLDT' (_crInv cr)) -invItemLocUpdate :: Creature -> LocationLDT ItemLink CItem -> World -> World +invItemLocUpdate :: Creature -> LocationLDT ItemLink OItem -> World -> World invItemLocUpdate cr loc w = doAnyEquipmentEffect loc cr $ case itm ^. itType of ATTACH BULLETSYNTH -> trySynthBullet loc w EQUIP WRIST_ECG | haspulse -> tryUseParent loc w @@ -208,21 +208,21 @@ copierItemUpdate itm cr w = fromMaybe w $ do v <- getItemValue itm' w cr return $ w & pointerToItem itm . itUse . uValue .~ v -doAnyEquipmentEffect :: LocationLDT ItemLink CItem -> Creature -> World -> World +doAnyEquipmentEffect :: LocationLDT ItemLink OItem -> Creature -> World -> World doAnyEquipmentEffect loc cr = case itm ^? itLocation . ilEquipSite . _Just of Just _ -> equipBackgroundEffect loc cr _ -> id where itm = loc ^. locLDT . ldtValue . _1 -tryUseParent :: LocationLDT ItemLink CItem -> World -> World +tryUseParent :: LocationLDT ItemLink OItem -> World -> World tryUseParent loc w = fromMaybe w $ do t <- locUp loc - let t' = bimap id (^. _1) $ t ^. locLDT + let t' = bimap id id $ t ^. locLDT cr <- w ^? cWorld . lWorld . creatures . ix 0 return $ heldEffectNoHammerCheck t' cr w -trySynthBullet :: LocationLDT ItemLink CItem -> World -> World +trySynthBullet :: LocationLDT ItemLink OItem -> World -> World trySynthBullet loc w = fromMaybe w $ do i <- itm ^? itLocation . ilInvID x <- itm ^? itUse . uaParams . apInt @@ -278,7 +278,7 @@ trySynthBullet loc w = fromMaybe w $ do updateHeldRootItem :: Creature -> World -> World updateHeldRootItem cr = fromMaybe id $ do invid <- cr ^? crManipulation . manObject . imRootSelectedItem - itmtree <- invRootTrees (_crInv cr) ^? ix invid + itmtree <- invRootTrees' (_crInv cr) ^? ix invid return $ updateAttachedItems itmtree cr updateAttachedItems :: LDTree ItemLink CItem -> Creature -> World -> World diff --git a/src/Dodge/Creature/Test.hs b/src/Dodge/Creature/Test.hs index b944bb416..383d23031 100644 --- a/src/Dodge/Creature/Test.hs +++ b/src/Dodge/Creature/Test.hs @@ -95,7 +95,7 @@ crInAimStance as cr = crIsAiming cr && mitstance == Just as where mitstance = do i <- cr ^? crManipulation . manObject . imRootSelectedItem - itm <- invRootTrees (cr ^. crInv) ^? ix i + itm <- invRootTrees' (cr ^. crInv) ^? ix i return $ aimStance itm --cr ^? crInv . ix i . itUse . heldAim . aimStance diff --git a/src/Dodge/DisplayInventory.hs b/src/Dodge/DisplayInventory.hs index c8623032e..5f9f5608d 100644 --- a/src/Dodge/DisplayInventory.hs +++ b/src/Dodge/DisplayInventory.hs @@ -162,7 +162,7 @@ updateDisplaySections w cfig = invitems = IM.map (uncurry (invSelectionItem w)) - (allInvLocs $ _crInv cr) + (allInvLocs' $ _crInv cr) filterSectionsPair :: Bool -> -- check for whether filter is in focus, changes string at the end diff --git a/src/Dodge/Euse.hs b/src/Dodge/Euse.hs index 15ac881cc..292aaa347 100644 --- a/src/Dodge/Euse.hs +++ b/src/Dodge/Euse.hs @@ -12,7 +12,7 @@ import Dodge.Wall.Move import Geometry import LensHelp -equipBackgroundEffect :: LocationLDT ItemLink CItem -> Creature -> World -> World +equipBackgroundEffect :: LocationLDT ItemLink OItem -> Creature -> World -> World equipBackgroundEffect loc cr = case eo of EQUIP (MAGSHIELD mt) -> useMagShield mt itm cr EQUIP WRISTARMOUR -> setWristShieldPos itm cr diff --git a/src/Dodge/HeldUse.hs b/src/Dodge/HeldUse.hs index 07513c28f..692b3a3b4 100644 --- a/src/Dodge/HeldUse.hs +++ b/src/Dodge/HeldUse.hs @@ -46,12 +46,12 @@ import RandomHelp import qualified SDL import Sound.Data -gadgetEffect :: PressType -> LocationLDT ItemLink CItem -> Creature -> World -> World +gadgetEffect :: PressType -> LocationLDT ItemLink OItem -> Creature -> World -> World gadgetEffect pt loc | UseHeld{} <- loc ^. locLDT . ldtValue . _1 . itUse = heldEffect pt - (bimap id (^. _1) (loc ^. locLDT)) + (loc ^. locLDT) | DROPPER x <- loc ^. locLDT . ldtValue . _1 . itType , Just i <- loc ^? locLDT . ldtValue . _1 . itUse . uInt , pt == InitialPress = @@ -61,46 +61,46 @@ gadgetEffect pt loc useInventoryPath pt i x loc | otherwise = const id -heldEffect :: PressType -> LDTree ItemLink Item -> Creature -> World -> World +heldEffect :: PressType -> LDTree ItemLink OItem -> Creature -> World -> World heldEffect = useTimeCheck . hammerCheck heldEffectMuzzles -heldEffectNoHammerCheck :: LDTree ItemLink Item -> Creature -> World -> World +heldEffectNoHammerCheck :: LDTree ItemLink OItem -> Creature -> World -> World heldEffectNoHammerCheck = useTimeCheck heldEffectMuzzles type ChainEffect = - (LDTree ItemLink Item -> Creature -> World -> World) -> - LDTree ItemLink Item -> + (LDTree ItemLink OItem -> Creature -> World -> World) -> + LDTree ItemLink OItem -> Creature -> World -> World hammerCheck :: - (LDTree ItemLink Item -> Creature -> World -> World) -> + (LDTree ItemLink OItem -> Creature -> World -> World) -> PressType -> - LDTree ItemLink Item -> + LDTree ItemLink OItem -> Creature -> World -> World hammerCheck f pt it cr w - | BurstTrigger is <- itemTriggerType (it ^. ldtValue) + | BurstTrigger is <- itemTriggerType (it ^. ldtValue . _1) , pt == InitialPress = w & f it cr & cWorld . lWorld . delayedEvents .++~ map g is - | BurstTrigger{} <- itemTriggerType (it ^. ldtValue) = w - | VolleyGunTrigger i <- itemTriggerType (it ^. ldtValue) + | BurstTrigger{} <- itemTriggerType (it ^. ldtValue . _1) = w + | VolleyGunTrigger i <- itemTriggerType (it ^. ldtValue . _1) , pt == InitialPress = let (is, gen) = getVolleyBurst i (w ^. randGen) in w & f it cr & cWorld . lWorld . delayedEvents .++~ map g is & randGen .~ gen - | VolleyGunTrigger{} <- itemTriggerType (it ^. ldtValue) = w - | t <- itemTriggerType (it ^. ldtValue) + | VolleyGunTrigger{} <- itemTriggerType (it ^. ldtValue . _1) = w + | t <- itemTriggerType (it ^. ldtValue . _1) , t == HammerTrigger || t == AlwaysSingleTrigger , isNothing $ lookup MakeAutoLink (it ^. ldtRight) , pt /= InitialPress = w | otherwise = f it cr w where - g x = (x, WdWdBurstFireRepetition (_crID cr) (it ^?! ldtValue . itLocation . ilInvID)) + g x = (x, WdWdBurstFireRepetition (_crID cr) (it ^?! ldtValue . _1 . itLocation . ilInvID)) getVolleyBurst :: (Random a, RandomGen b, Num a) => Int -> b -> ([a], b) getVolleyBurst i g = @@ -111,50 +111,50 @@ getVolleyBurst i g = input buffering? -} useTimeCheck :: ChainEffect -useTimeCheck f item cr w = case useDelay $ item ^. ldtValue of +useTimeCheck f item cr w = case useDelay $ item ^. ldtValue . _1 of FixedRate rate | w ^. cWorld . lWorld . lClock - rate > lastused -> f item cr w -- note that the time last used must be updated later in the chain! FixedRate{} -> w WarmUpNoDelay wm - | _wTime (_itParams $ _ldtValue item) < wm -> + | _wTime (_itParams $ _ldtValue $ fmap (^. _1) item) < wm -> w & setwarming - & soundContinue (CrWeaponSound cid 0) (_crPos cr) (warmupSound $ item ^. ldtValue . itType) (Just 2) + & soundContinue (CrWeaponSound cid 0) (_crPos cr) (warmupSound $ item ^. ldtValue . _1 . itType) (Just 2) & cWorld . lWorld . creatures . ix cid . crInv . ix itRef . itParams . wTime +~ 1 WarmUpNoDelay{} -> f item cr w & setwarming WarmUpCoolDown ws _ _ - | _wTime (_itParams $ _ldtValue item) < ws -> + | _wTime (_itParams $ _ldtValue $ fmap (^. _1) item) < ws -> w & setwarming - & soundContinue (CrWeaponSound cid 0) (_crPos cr) (warmupSound $ item ^. ldtValue . itType) (Just 2) + & soundContinue (CrWeaponSound cid 0) (_crPos cr) (warmupSound $ item ^. ldtValue . _1 . itType) (Just 2) & cWorld . lWorld . creatures . ix cid . crInv . ix itRef . itParams . wTime +~ 1 WarmUpCoolDown _ cs _ - | _wTime (_itParams $ _ldtValue item) < cs -> + | _wTime (_itParams $ _ldtValue $ fmap (^. _1) item) < cs -> f item cr w & setwarming & cWorld . lWorld . creatures . ix cid . crInv . ix itRef . itParams . wTime +~ 1 WarmUpCoolDown{} -> w & setwarming NoDelay -> f item cr w where - lastused = item ^. ldtValue . itTimeLastUsed + lastused = item ^. ldtValue . _1 . itTimeLastUsed cid = _crID cr setwarming = cWorld . lWorld . creatures . ix cid . crInv . ix itRef . itParams . isWarming %~ const True -- the following is unsafe, but if ilInvID isn't correctly set we probably -- will have problems elsewhere also - itRef = item ^?! ldtValue . itLocation . ilInvID + itRef = item ^?! ldtValue . _1 . itLocation . ilInvID -heldEffectMuzzles :: LDTree ItemLink Item -> Creature -> World -> World +heldEffectMuzzles :: LDTree ItemLink OItem -> Creature -> World -> World heldEffectMuzzles t cr w = setusetime . doHeldUseEffect t cr - . uncurry (applyCME (_ldtValue t) cr) + . uncurry (applyCME (_ldtValue t ^. _1) cr) . foldl' (useLoadedAmmo t cr) (False, w) $ loadedmuzzles where - (_, loadedmuzzles) = mapAccumR loadMuzzle t . itemMuzzles $ t ^. ldtValue + (_, loadedmuzzles) = mapAccumR loadMuzzle t . itemMuzzles $ t ^. ldtValue . _1 setusetime = cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix itid . itTimeLastUsed .~ w ^. cWorld . lWorld . lClock - itid = t ^?! ldtValue . itLocation . ilInvID + itid = t ^?! ldtValue . _1 . itLocation . ilInvID itemMuzzles :: Item -> [Muzzle] itemMuzzles itm = case itm ^. itType of @@ -337,8 +337,8 @@ vgunMuzzles i = -- <*> ZipList [0 .. i -1] ) -doHeldUseEffect :: LDTree ItemLink Item -> Creature -> World -> World -doHeldUseEffect t cr w = case t ^. ldtValue . itType of +doHeldUseEffect :: LDTree ItemLink OItem -> Creature -> World -> World +doHeldUseEffect t cr w = case t ^. ldtValue . _1 . itType of HELD (VOLLEYGUN j) -> case itm ^? itParams . unfiredBarrels of Just [_] -> fromMaybe w $ do let (is, g) = runState (shuffle [0 .. j -1]) $ w ^. randGen @@ -360,7 +360,7 @@ doHeldUseEffect t cr w = case t ^. ldtValue . itType of %~ tail _ -> w HELD ALTERIFLE -> fromMaybe w $ do - i <- t ^? ldtValue . itLocation . ilInvID + i <- t ^? ldtValue . _1 . itLocation . ilInvID return $ w & cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix i @@ -373,7 +373,7 @@ doHeldUseEffect t cr w = case t ^. ldtValue . itType of %~ ((`mod` 2) . (+ 1)) _ -> w where - itm = t ^. ldtValue + itm = t ^. ldtValue . _1 --doHeldUseEffect t cr w = case t ^? ldtValue . itUse . heldUseEffect of -- Just (RandomiseMuzzleFrames x) -> fromMaybe w $ do @@ -678,15 +678,15 @@ heldTorqueAmount = \case -- (Muzzle,Int,Int) = (muzzle, amountloaded, id of mag taken from) loadMuzzle :: - LDTree ItemLink Item -> + LDTree ItemLink OItem -> Muzzle -> - (LDTree ItemLink Item, Maybe (Muzzle, Int, LDTree ItemLink Item)) + (LDTree ItemLink OItem, Maybe (Muzzle, Int, LDTree ItemLink OItem)) loadMuzzle t@(LDT _ l _) mz = fromMaybe (t, Nothing) $ do -- guard $ mz ^? mzFrame == t ^? ldtValue . itUse . heldFrame let as = _mzAmmoSlot mz amamount = _mzAmmoPerShot mz (i, (_, mag)) <- findWithIx (isAmmoIntLink as . fst) l - availableammo <- mag ^. ldtValue . itConsumables + availableammo <- mag ^. ldtValue . _1 . itConsumables let usedammo = case amamount of UseUpTo x -> min x availableammo UseExactly x @@ -694,11 +694,11 @@ loadMuzzle t@(LDT _ l _) mz = fromMaybe (t, Nothing) $ do | otherwise -> 0 guard $ usedammo > 0 return - ( t & ldtLeft . ix i . _2 . ldtValue . itConsumables . _Just -~ usedammo + ( t & ldtLeft . ix i . _2 . ldtValue . _1 . itConsumables . _Just -~ usedammo , Just (mz, usedammo, mag) ) -makeMuzzleFlare :: Muzzle -> LDTree ItemLink Item -> Creature -> World -> World +makeMuzzleFlare :: Muzzle -> LDTree ItemLink OItem -> Creature -> World -> World makeMuzzleFlare mz itmtree cr = case mz ^. mzFlareType of NoFlare -> id BasicFlare -> basicMuzFlare pos dir @@ -708,14 +708,14 @@ makeMuzzleFlare mz itmtree cr = case mz ^. mzFlareType of . muzFlareAt (V4 10 10 1 3) (pos `v2z` 20) dir HeavySmokeFlare -> basicMuzFlare pos dir LasGunFlare -> - flareCircleAt (getLaserColor itmtree) 0.8 (pos `v2z` 20) + flareCircleAt (getLaserColor $ fmap (^. _1) itmtree) 0.8 (pos `v2z` 20) . ( cWorld . lWorld . lights - .:~ LSParam (pos `v2z` 10) 100 (xyzV4 $ getLaserColor itmtree) + .:~ LSParam (pos `v2z` 10) 100 (xyzV4 $ getLaserColor $ fmap (^. _1)itmtree) ) TeslaGunFlare -> cWorld . lWorld . lights .:~ LSParam (pos `v2z` 10) 100 (V3 0 0 1) where itm = itmtree ^. ldtValue - (moff, mrot) = heldItemOrient2D itm cr (_mzPos mz) (_mzRot mz) + (moff, mrot) = heldItemOrient2D' itm cr (_mzPos mz) (_mzRot mz) pos = _crPos cr + rotateV (_crDir cr) moff dir = _crDir cr + mrot oddcheck f w @@ -768,10 +768,10 @@ isAmmoIntLink i (AmmoInLink j _) = i == j isAmmoIntLink _ _ = False useLoadedAmmo :: - LDTree ItemLink Item -> + LDTree ItemLink OItem -> Creature -> (Bool, World) -> - Maybe (Muzzle, Int, LDTree ItemLink Item) -> + Maybe (Muzzle, Int, LDTree ItemLink OItem) -> (Bool, World) useLoadedAmmo _ _ (cme, w) Nothing = (cme, w) useLoadedAmmo itmtree cr (_, w) (Just (mz, x, magtree)) = (,) True $ @@ -783,29 +783,29 @@ useLoadedAmmo itmtree cr (_, w) (Just (mz, x, magtree)) = (,) True $ MuzzleRLauncher -> createProjectileR itmtree magtree mz cr w MuzzleGLauncher -> createProjectile - (0, Q.qID) - (Grenade (getGrenadeHitEffect itmtree)) + (itmtree ^. ldtValue . _3) + (Grenade (getGrenadeHitEffect $ fmap (^. _1) itmtree)) magtree - (getPJStabiliser itmtree) + (getPJStabiliser $ fmap (^. _1) itmtree) mz cr w - MuzzleNozzle{} -> useGasParams mid mz itm cr $ walkNozzle mz itm cr w - MuzzleShatter -> shootShatter itm cr w + MuzzleNozzle{} -> useGasParams mid mz (itm ^. _1) cr $ walkNozzle mz (itm ^. _1) cr w + MuzzleShatter -> shootShatter (itm ^. _1) cr w MuzzleDetector -> itemDetectorEffect - itm - (getAttachedSFLink MapperSF itmtree) - (getAttachedSFLink ARHUDSF itmtree) + (itm ^. _1) + (getAttachedSFLink MapperSF $ fmap (^. _1) itmtree) + (getAttachedSFLink ARHUDSF $ fmap (^. _1) itmtree) cr w MuzzleBlink -> unsafeBlinkAction cr w MuzzleUnsafeBlink -> blinkActionMousePos cr w - MuzzleRewind -> useRewindGun (itm ^. itID) w - MuzzleStopper -> useStopWatch itm cr w - MuzzleScroller -> useTimeScrollGun itm cr w + MuzzleRewind -> useRewindGun (itm ^. _1 . itID) w + MuzzleStopper -> useStopWatch (itm ^. _1) cr w + MuzzleScroller -> useTimeScrollGun (itm ^. _1) cr w where - mid = magtree ^? ldtValue . itLocation . ilInvID + mid = magtree ^? ldtValue . _1 . itLocation . ilInvID itm = itmtree ^. ldtValue getAttachedSFLink :: @@ -871,7 +871,7 @@ tractorBeamAt pos outpos dir power = d = unitVectorAtAngle dir * power creatureShootLaser :: - LDTree ItemLink Item -> + LDTree ItemLink OItem -> Creature -> Muzzle -> World -> @@ -881,14 +881,15 @@ creatureShootLaser itmtree cr mz w = & randGen .~ g & shootLaser (CrWeaponSound (_crID cr) 0) - (getLaserDamage itmtree) - (getLaserPhaseV itmtree) + (getLaserDamage istree) + (getLaserPhaseV istree) pos dir - (getLaserColor itmtree) + (getLaserColor istree) where + istree = fmap (\(x,_,_) -> x) itmtree itm = itmtree ^. ldtValue - (moff, mrot) = heldItemOrient2D itm cr (_mzPos mz) (_mzRot mz) + (moff, mrot) = heldItemOrient2D' itm cr (_mzPos mz) (_mzRot mz) pos = _crPos cr + rotateV (_crDir cr) moff dir = _crDir cr + mrot + a (a, g) = randomR (- inacc, inacc) $ _randGen w @@ -981,14 +982,14 @@ magAmmoParams itm = case itm ^. itType of -- _ -> 0 shootBullet :: - LDTree ItemLink Item -> + LDTree ItemLink OItem -> Creature -> - (Muzzle, Int, LDTree ItemLink Item) -> + (Muzzle, Int, LDTree ItemLink OItem) -> World -> World shootBullet itmtree cr (mz, x, magtree) w = fromMaybe w $ do - thebullet <- getBulletType magtree - return $ foldl' (&) w (replicate x (makeBullet' thebullet (itmtree ^. ldtValue) cr mz)) + thebullet <- getBulletType $ fmap (^. _1) magtree + return $ foldl' (&) w (replicate x (makeBullet' thebullet (itmtree ^. ldtValue . _1) cr mz)) makeBullet' :: Bullet -> Item -> Creature -> Muzzle -> World -> World makeBullet' bu itm cr mz w = makeBullet bu itm bulpos dir . (randGen .~ g) $ w @@ -1255,15 +1256,15 @@ mcShootAuto itm mc w dir = mc ^?! mcType . _McTurret . tuDir -- | assumes that the item is held -shootTeslaArc :: Item -> Creature -> Muzzle -> World -> World +shootTeslaArc :: OItem -> Creature -> Muzzle -> World -> World shootTeslaArc itm cr mz w = w' & cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix itRef . itParams .~ ip & soundContinue (CrWeaponSound (_crID cr) 0) pos elecCrackleS (Just 2) where -- use items item location instead itRef = cr ^?! crManipulation . manObject . imRootSelectedItem -- unsafe!! TODO change - (w', ip) = makeTeslaArc (_itParams itm) pos dir w - (moff, mrot) = heldItemOrient2D itm cr (_mzPos mz) (_mzRot mz) + (w', ip) = makeTeslaArc (_itParams (itm ^. _1)) pos dir w + (moff, mrot) = heldItemOrient2D' itm cr (_mzPos mz) (_mzRot mz) pos = _crPos cr + rotateV (_crDir cr) moff dir = _crDir cr + mrot @@ -1282,21 +1283,21 @@ determineProjectileTracking magtree itmtree = return $ HomeUsingTargeting (targetingtree ^. ldtValue . itID) createProjectileR :: - LDTree ItemLink Item -> - LDTree ItemLink Item -> + LDTree ItemLink OItem -> + LDTree ItemLink OItem -> Muzzle -> Creature -> World -> World createProjectileR itmtree magtree = createProjectile - (0, Q.qID) + (itmtree ^. ldtValue . _3) ( Rocket - (determineProjectileTracking magtree itmtree) + (determineProjectileTracking (fmap (^. _1) magtree) $ fmap (^. _1) itmtree) smoke ) magtree - (getPJStabiliser itmtree) + (getPJStabiliser $ fmap (^. _1) itmtree) where smoke | isJust $ lookup SmokeReducerLink (magtree ^. ldtLeft) = Just ReducedRocketSmoke @@ -1320,23 +1321,23 @@ getGrenadeHitEffect t = case lookup GrenadeHitEffectLink (t ^. ldtRight) of createProjectile :: (Point3, Q.Quaternion Float) -> ProjectileType -> - LDTree ItemLink Item -> + LDTree ItemLink OItem -> Maybe PJStabiliser -> Muzzle -> Creature -> World -> World createProjectile x pjtype magtree stab muz cr = fromMaybe failsound $ do - magid <- magtree ^? ldtValue . itLocation . ilInvID + magid <- magtree ^? ldtValue . _1 . itLocation . ilInvID ammoitem <- cr ^? crInv . ix magid let rdetonate = - (^. ldtValue . itID) + (^. ldtValue . _1 . itID) <$> lookup RemoteDetonatorLink (magtree ^. ldtLeft) rscreen = - (^. ldtValue . itID) + (^. ldtValue . _1 . itID) <$> lookup RemoteScreenLink (magtree ^. ldtLeft) aparams <- - ((magtree ^? ldtLeft) >>= lookup AmmoPayloadLink >>= (^? ldtValue . itType . ibtAttach . shellPayload)) + ((magtree ^? ldtLeft) >>= lookup AmmoPayloadLink >>= (^? ldtValue . _1 . itType . ibtAttach . shellPayload)) -- <|> ammoitem ^? itConsumables . magParams . ampPayload <|> magAmmoParams ammoitem ^? _Just . ampPayload return $ @@ -1400,7 +1401,7 @@ useRewindGun i = dropInventoryPath :: Int -> InventoryPathing -> - LocationLDT ItemLink CItem -> + LocationLDT ItemLink OItem -> Creature -> World -> World @@ -1432,7 +1433,7 @@ useInventoryPath :: PressType -> Int -> InventoryPathing -> - LocationLDT ItemLink CItem -> + LocationLDT ItemLink OItem -> Creature -> World -> World diff --git a/src/Dodge/Item/Grammar.hs b/src/Dodge/Item/Grammar.hs index ebafaed23..f2b8f665d 100644 --- a/src/Dodge/Item/Grammar.hs +++ b/src/Dodge/Item/Grammar.hs @@ -1,12 +1,16 @@ module Dodge.Item.Grammar ( invLDT, + invLDT', invAdj, invRootMap, invRootTrees, + invRootTrees', baseCI, allInvLocs, + allInvLocs', ) where +import Dodge.Item.Orientation import Dodge.ItemUseCondition import Dodge.Data.UseCondition import Dodge.Item.MagAmmoType @@ -218,6 +222,9 @@ invLDT = joinItemsInList tryAttachItems . IM.elems . fmap (singleLDT . baseCI) +invLDT' :: IM.IntMap Item -> [LDTree ItemLink OItem] +invLDT' = fmap propagateOrientation . invLDT + -- this assumes the creature inventory is well formed, specifically the -- location ids -- consider explicitly reseting the inventory ids (but this probably really @@ -243,15 +250,42 @@ invAdj = IM.unions . map g . invLDT $ itm ^? itLocation . ilInvID -- returns an intmap with trees for (only!) root items, indexed by inventory position -invRootTrees :: IM.IntMap Item -> IM.IntMap (LDTree ItemLink CItem) -invRootTrees = IM.fromDistinctAscList . reverse . map getid . invLDT +invRootTrees :: IM.IntMap Item -> IM.IntMap (LDTree ItemLink OItem) +invRootTrees = fmap propagateOrientation . IM.fromDistinctAscList . reverse . map getid . invLDT + where + getid :: LDTree ItemLink CItem -> (Int, LDTree ItemLink CItem) + getid t = (t ^?! ldtValue . _1 . itLocation . ilInvID, t) + +invRootTrees' :: IM.IntMap Item -> IM.IntMap (LDTree ItemLink CItem) +invRootTrees' = IM.fromDistinctAscList . reverse . map getid . invLDT where getid :: LDTree ItemLink CItem -> (Int, LDTree ItemLink CItem) getid t = (t ^?! ldtValue . _1 . itLocation . ilInvID, t) -- returns an intmap with indents and locations for all items -allInvLocs :: IM.IntMap Item -> IM.IntMap (Int, LocationLDT ItemLink CItem) +allInvLocs :: IM.IntMap Item -> IM.IntMap (Int, LocationLDT ItemLink OItem) allInvLocs inv = foldMap (f . LocLDT TopLDT) (IM.elems (invRootTrees inv)) mempty + where + f t = cldtPropagateFold h h g 0 t id + h x _ _ _ = x + 1 + g :: + Int -> + LocationLDT ItemLink OItem -> + ( IM.IntMap (Int, LocationLDT ItemLink OItem) -> + IM.IntMap (Int, LocationLDT ItemLink OItem) + ) -> + IM.IntMap (Int, LocationLDT ItemLink OItem) -> + IM.IntMap (Int, LocationLDT ItemLink OItem) + g x ldt = + (.) + ( IM.insert + (ldt ^?! locLDT . ldtValue . _1 . itLocation . ilInvID) + (x, ldt) + ) + +-- returns an intmap with indents and locations for all items +allInvLocs' :: IM.IntMap Item -> IM.IntMap (Int, LocationLDT ItemLink CItem) +allInvLocs' inv = foldMap (f . LocLDT TopLDT) (IM.elems (invRootTrees' inv)) mempty where f t = cldtPropagateFold h h g 0 t id h x _ _ _ = x + 1 diff --git a/src/Dodge/Item/HeldOffset.hs b/src/Dodge/Item/HeldOffset.hs index 05be38494..81ce88dce 100644 --- a/src/Dodge/Item/HeldOffset.hs +++ b/src/Dodge/Item/HeldOffset.hs @@ -5,6 +5,7 @@ module Dodge.Item.HeldOffset ( heldItemOffset, heldItemRelativeOrient, heldItemOrient2D, + heldItemOrient2D', itemRelativeOrient, ) where @@ -36,6 +37,11 @@ heldItemOrient2D itm cr p a = (V2 x y, argV . Q.qToV2 $ q ) where (V3 x y _,q) = heldItemRelativeOrient itm cr (p `v2z` 0, Q.axisAngle (V3 0 0 1) a) +heldItemOrient2D' :: OItem -> Creature -> Point2 -> Float -> (Point2, Float) +heldItemOrient2D' (itm,_,(p1,q1)) cr p a = (V2 x y, argV . Q.qToV2 $ q ) + where + (V3 x y _,q) = heldItemRelativeOrient itm cr (p1 + Q.rotate q1 (p `v2z` 0), q1 * Q.axisAngle (V3 0 0 1) a) + heldItemRelativeOrient :: Item -> Creature -> (Point3, Q.Quaternion Float) -> (Point3, Q.Quaternion Float) heldItemRelativeOrient itm cr (p,q) diff --git a/src/Dodge/Item/Orientation.hs b/src/Dodge/Item/Orientation.hs index 359cd3ecc..a79c0bad1 100644 --- a/src/Dodge/Item/Orientation.hs +++ b/src/Dodge/Item/Orientation.hs @@ -18,8 +18,10 @@ orientChild itm = case _itType itm of HELD TORCH -> (V3 0 5 0, Q.qID) --HELD LASER -> (V3 15 (-5) 0, Q.qID) HELD LASER -> (V3 15 (-5) 0, Q.qID) - ATTACH UNDERBARRELSLOT -> (V3 10 (-8) 0, Q.qID) + ATTACH UNDERBARRELSLOT -> (V3 10 (-8) 0, r) _ -> (0, Q.qID) + where + r = Q.axisAngle (V3 0 0 1) (-pi/4) orientByLink :: Item -> ItemLink -> (Point3, Q.Quaternion Float) orientByLink itm lt = case (_itType itm, lt) of @@ -58,8 +60,7 @@ orientLocation x loc (p1, q1) = (p + Q.rotate q p1, q * q1) where (p, q) = orientLocation' x loc -propagateOrientation :: LDTree ItemLink CItem - -> LDTree ItemLink OItem +propagateOrientation :: LDTree ItemLink CItem -> LDTree ItemLink OItem propagateOrientation = ldtStartPropagate g f where g (x,y) = (x,y,(V3 0 0 0,Q.qID)) diff --git a/src/Dodge/Projectile/Create.hs b/src/Dodge/Projectile/Create.hs index 7fbde70e4..d26d4981a 100644 --- a/src/Dodge/Projectile/Create.hs +++ b/src/Dodge/Projectile/Create.hs @@ -21,6 +21,7 @@ data PJStabiliser | StabSpinIncrease -- assumes the mscreen is in your inventory +-- TODO take into account creature aimstance positioning createShell :: (Point3, Q.Quaternion Float) -> Maybe (NewInt ItmInt) -> @@ -41,9 +42,9 @@ createShell (p,q) mdetonator mscreen stab pjtype payload muz cr w = { _pjPos = pos , _pjZ = 20 , _pjZVel = 5 - , _pjVel = rotateV dir (V2 speed 0) + crvelcomponent + , _pjVel = rotateV dir' (V2 speed 0) + crvelcomponent , _pjID = i - , _pjDir = dir + , _pjDir = dir' , _pjSpin = 0 , _pjSpinFactor = spinfactor , _pjPayload = payload @@ -93,4 +94,5 @@ createShell (p,q) mdetonator mscreen stab pjtype payload muz cr w = .:~ i i = IM.newKey $ w ^. cWorld . lWorld . projectiles dir = _crDir cr + _mzRot muz - pos = _crPos cr + xyV3 p + rotateV dir (_mzPos muz) + pos = _crPos cr + rotateV dir (xyV3 p + rotateV (argV (Q.qToV2 q)) (_mzPos muz)) + dir' = dir + argV (Q.qToV2 q) diff --git a/src/Dodge/WorldEffect.hs b/src/Dodge/WorldEffect.hs index 6e0f8b9bb..d4a641b79 100644 --- a/src/Dodge/WorldEffect.hs +++ b/src/Dodge/WorldEffect.hs @@ -45,7 +45,7 @@ doWdWd we = case we of UseInvItem invid pt -> \w -> fromMaybe w (useItem invid pt w) WdWdBurstFireRepetition cid invid -> \w -> fromMaybe w $ do cr <- w ^? cWorld . lWorld . creatures . ix cid - itree <- bimap id (^. _1) <$> + itree <- bimap id id <$> allInvLocs (cr ^. crInv) ^? ix invid . _2 . locLDT return $ heldEffectMuzzles itree cr w diff --git a/tags b/tags index de96f1990..8ac8f3b52 100644 --- a/tags +++ b/tags @@ -29,7 +29,7 @@ APNothing src/Dodge/Data/Item/Use.hs 48;" C APProjectiles src/Dodge/Data/Item/Use.hs 46;" C AQUAMARINE src/Color/Data.hs 24;" C ARHUD src/Dodge/Data/Item/Combine.hs 35;" C -ARHUDSF src/Dodge/Data/ComposedItem.hs 46;" C +ARHUDSF src/Dodge/Data/ComposedItem.hs 48;" C ATTACH src/Dodge/Data/Item/Combine.hs 20;" C AUTOAMR src/Dodge/Data/Item/Combine.hs 159;" C AUTOPISTOL src/Dodge/Data/Item/Combine.hs 145;" C @@ -58,20 +58,20 @@ AlwaysSingleTrigger src/Dodge/Data/TriggerType.hs 13;" C Ambush src/Dodge/Data/ActionPlan.hs 178;" C Ammo src/Dodge/Data/Item/Use/Consumption/Ammo.hs 3;" m Ammo src/Dodge/Item/Ammo.hs 1;" m -AmmoEffectLink src/Dodge/Data/ComposedItem.hs 18;" C -AmmoEffectSF src/Dodge/Data/ComposedItem.hs 56;" C -AmmoInLink src/Dodge/Data/ComposedItem.hs 13;" C -AmmoMagSF src/Dodge/Data/ComposedItem.hs 47;" C +AmmoEffectLink src/Dodge/Data/ComposedItem.hs 20;" C +AmmoEffectSF src/Dodge/Data/ComposedItem.hs 58;" C +AmmoInLink src/Dodge/Data/ComposedItem.hs 15;" C +AmmoMagSF src/Dodge/Data/ComposedItem.hs 49;" C AmmoMagType src/Dodge/Data/Item/Combine.hs 105;" t -AmmoModLink src/Dodge/Data/ComposedItem.hs 15;" C -AmmoModifierSF src/Dodge/Data/ComposedItem.hs 53;" C +AmmoModLink src/Dodge/Data/ComposedItem.hs 17;" C +AmmoModifierSF src/Dodge/Data/ComposedItem.hs 55;" C AmmoParams src/Dodge/Data/Item/Use.hs 51;" t -AmmoPayloadLink src/Dodge/Data/ComposedItem.hs 17;" C -AmmoPayloadSF src/Dodge/Data/ComposedItem.hs 55;" C +AmmoPayloadLink src/Dodge/Data/ComposedItem.hs 19;" C +AmmoPayloadSF src/Dodge/Data/ComposedItem.hs 57;" C AmmoPerShot src/Dodge/Data/Muzzle.hs 52;" t AmmoSlots src/Dodge/Item/AmmoSlots.hs 3;" m -AmmoTargetingLink src/Dodge/Data/ComposedItem.hs 16;" C -AmmoTargetingSF src/Dodge/Data/ComposedItem.hs 54;" C +AmmoTargetingLink src/Dodge/Data/ComposedItem.hs 18;" C +AmmoTargetingSF src/Dodge/Data/ComposedItem.hs 56;" C AmmoType src/Dodge/Data/AmmoType.hs 3;" m AnRoom src/Dodge/Annotation/Data.hs 18;" C AnTree src/Dodge/Annotation/Data.hs 19;" C @@ -250,7 +250,7 @@ CHARTREUSE src/Color/Data.hs 25;" C CHEMFUELPOUCH src/Dodge/Data/Item/Combine.hs 111;" C CHeal src/Dodge/Data/Item/HeldUse.hs 16;" C CIRCLE src/Dodge/Data/GenParams.hs 20;" C -CItem src/Dodge/Data/ComposedItem.hs 65;" t +CItem src/Dodge/Data/ComposedItem.hs 67;" t CLICKER src/Dodge/Data/Item/Combine.hs 28;" C CME src/Dodge/Data/MuzzleEffect.hs 14;" C COPIER src/Dodge/Data/Item/Combine.hs 29;" C @@ -629,7 +629,7 @@ Equipment src/Dodge/Default/Item/Use/Equipment.hs 1;" m Equipment src/Dodge/Equipment.hs 1;" m Equipment src/Dodge/Item/Equipment.hs 1;" m EquipmentAllocation src/Dodge/Data/RightButtonOptions.hs 18;" t -EquipmentPlatformSF src/Dodge/Data/ComposedItem.hs 40;" C +EquipmentPlatformSF src/Dodge/Data/ComposedItem.hs 42;" C Escape src/Dodge/Data/Scenario.hs 10;" C EscapeMenuOption src/Dodge/Data/Universe.hs 76;" t Essential src/Shape/Data.hs 34;" C @@ -728,8 +728,8 @@ FullRes src/Dodge/Data/Config.hs 97;" C FullShadowFidelity src/Shape/Data.hs 24;" C FullSize src/Dodge/Data/Item/Params.hs 28;" C FullyVisible src/Dodge/Data/CamouflageStatus.hs 6;" C -FunctionChangeLink src/Dodge/Data/ComposedItem.hs 26;" C -FunctionChangeSF src/Dodge/Data/ComposedItem.hs 57;" C +FunctionChangeLink src/Dodge/Data/ComposedItem.hs 28;" C +FunctionChangeSF src/Dodge/Data/ComposedItem.hs 59;" C GBounce src/Dodge/Data/Projectile.hs 57;" C GEqC src/SameConstr.hs 20;" c GIMBAL src/Dodge/Data/Item/Combine.hs 96;" C @@ -742,7 +742,7 @@ GStick src/Dodge/Data/Projectile.hs 58;" C GStuckCreature src/Dodge/Data/Projectile.hs 59;" C GStuckWall src/Dodge/Data/Projectile.hs 60;" C GYROSCOPE src/Dodge/Data/Item/Combine.hs 97;" C -GadgetPlatformSF src/Dodge/Data/ComposedItem.hs 41;" C +GadgetPlatformSF src/Dodge/Data/ComposedItem.hs 43;" C GameOverOptions src/Dodge/Data/Universe.hs 72;" C GameRoom src/Dodge/GameRoom.hs 15;" t GameRoom src/Dodge/GameRoom.hs 8;" m @@ -787,8 +787,8 @@ GraphHelp src/GraphHelp.hs 1;" m GraphVizHelp src/GraphVizHelp.hs 2;" m Grenade src/Dodge/Data/Projectile.hs 42;" C GrenadeHitEffect src/Dodge/Data/Projectile.hs 56;" t -GrenadeHitEffectLink src/Dodge/Data/ComposedItem.hs 31;" C -GrenadeHitEffectSF src/Dodge/Data/ComposedItem.hs 60;" C +GrenadeHitEffectLink src/Dodge/Data/ComposedItem.hs 33;" C +GrenadeHitEffectSF src/Dodge/Data/ComposedItem.hs 62;" C Grid src/Grid.hs 1;" m Gust src/Dodge/Data/Gust.hs 13;" t Gust src/Dodge/Data/Gust.hs 6;" m @@ -823,7 +823,7 @@ Held src/Dodge/Item/Held.hs 1;" m HeldDelay src/Dodge/Data/Item/HeldDelay.hs 6;" m HeldItemType src/Dodge/Data/Item/Combine.hs 138;" t HeldOffset src/Dodge/Item/HeldOffset.hs 2;" m -HeldPlatformSF src/Dodge/Data/ComposedItem.hs 37;" C +HeldPlatformSF src/Dodge/Data/ComposedItem.hs 39;" C HeldScroll src/Dodge/HeldScroll.hs 1;" m HeldUse src/Dodge/Data/Item/HeldUse.hs 6;" m HeldUse src/Dodge/HeldUse.hs 5;" m @@ -911,7 +911,7 @@ Intention src/Dodge/Data/Creature.hs 66;" t Intention src/Dodge/Creature/Intention.hs 1;" m Intersect src/Geometry/Intersect.hs 5;" m IntersectingRoomClipBoundaries src/Dodge/Data/Config.hs 107;" C -IntroScanSF src/Dodge/Data/ComposedItem.hs 44;" C +IntroScanSF src/Dodge/Data/ComposedItem.hs 46;" C IntroScanType src/Dodge/Data/Item/Combine.hs 44;" t InvInt src/Dodge/Data/Item/Location.hs 19;" t InvSize src/Dodge/Item/InvSize.hs 2;" m @@ -944,7 +944,7 @@ ItemCancelExamineInventory src/Dodge/Data/Item/Effect.hs 31;" C ItemClust src/Dodge/Combine/Graph.hs 21;" C ItemCopierUpdate src/Dodge/Data/Item/Effect.hs 32;" C ItemDimension src/Dodge/Data/Item/Misc.hs 13;" t -ItemLink src/Dodge/Data/ComposedItem.hs 12;" t +ItemLink src/Dodge/Data/ComposedItem.hs 14;" t ItemLocation src/Dodge/Data/Item/Location.hs 28;" t ItemParamID src/Dodge/Data/Item/Params.hs 26;" C ItemParams src/Dodge/Data/Item/Params.hs 14;" t @@ -955,7 +955,7 @@ ItemScrollInt src/Dodge/Data/Item.hs 53;" C ItemScrollIntRange src/Dodge/Data/Item.hs 54;" C ItemScrollTimeFlow src/Dodge/Data/World.hs 62;" C ItemSetWarmTime src/Dodge/Data/Item/Effect.hs 34;" C -ItemStructuralFunction src/Dodge/Data/ComposedItem.hs 35;" t +ItemStructuralFunction src/Dodge/Data/ComposedItem.hs 37;" t ItemTargeting src/Dodge/Data/Item.hs 56;" t ItemType src/Dodge/Data/Item/Combine.hs 16;" t ItemUse src/Dodge/Data/Item/Use.hs 30;" t @@ -969,8 +969,8 @@ JGK src/Control/Foldl/JGK.hs 1;" m JOYSTICK src/Dodge/Data/Item/Combine.hs 95;" C JUMPLEGS src/Dodge/Data/Item/Combine.hs 130;" C JoinClust src/Dodge/Combine/Graph.hs 22;" C -JoystickLink src/Dodge/Data/ComposedItem.hs 21;" C -JoystickSF src/Dodge/Data/ComposedItem.hs 49;" C +JoystickLink src/Dodge/Data/ComposedItem.hs 23;" C +JoystickSF src/Dodge/Data/ComposedItem.hs 51;" C Just' src/MaybeHelp.hs 13;" C JustStartedPlaying src/Sound/Data.hs 24;" C Justify src/Justify.hs 1;" m @@ -979,7 +979,7 @@ Kill src/Dodge/Data/ActionPlan.hs 198;" C LASER src/Dodge/Data/Item/Combine.hs 168;" C LDT src/Dodge/Data/DoubleTree.hs 34;" C LDTBottomNode src/Dodge/Data/DoubleTree.hs 29;" C -LDTComb src/Dodge/Item/Grammar.hs 162;" t +LDTComb src/Dodge/Item/Grammar.hs 164;" t LDTMidAboveNode src/Dodge/Data/DoubleTree.hs 27;" C LDTMidBelowNode src/Dodge/Data/DoubleTree.hs 28;" C LDTRootNode src/Dodge/Data/DoubleTree.hs 25;" C @@ -1130,8 +1130,8 @@ MagnetUpdate src/Dodge/Data/Magnet.hs 13;" t MagnetUpdateTimer src/Dodge/Data/Magnet.hs 13;" C Main appDodge/Main.hs 1;" m Make src/Dodge/Corpse/Make.hs 1;" m -MakeAutoLink src/Dodge/Data/ComposedItem.hs 27;" C -MakeAutoSF src/Dodge/Data/ComposedItem.hs 58;" C +MakeAutoLink src/Dodge/Data/ComposedItem.hs 29;" C +MakeAutoSF src/Dodge/Data/ComposedItem.hs 60;" C MakeSound src/Dodge/Data/ActionPlan.hs 43;" C MakeStartCloudAt src/Dodge/Data/WorldEffect.hs 29;" C MakeTempLight src/Dodge/Data/WorldEffect.hs 33;" C @@ -1139,7 +1139,7 @@ ManipulatedObject src/Dodge/Data/Item/Use/Consumption/LoadAction.hs 20;" t Manipulation src/Dodge/Data/Item/Use/Consumption/LoadAction.hs 14;" t Manipulator src/Dodge/Data/Item/Use/Consumption/LoadAction.hs 15;" C MapperInventory src/Dodge/Data/HUD.hs 31;" C -MapperSF src/Dodge/Data/ComposedItem.hs 62;" C +MapperSF src/Dodge/Data/ComposedItem.hs 64;" C Mass src/Dodge/Creature/Mass.hs 2;" m Material src/Dodge/Data/Material.hs 11;" t Material src/Dodge/Creature/Material.hs 3;" m @@ -1288,7 +1288,7 @@ NoParams src/Dodge/Data/Item/Params.hs 15;" C NoResurrection src/Dodge/Data/Corpse.hs 14;" C NoRightButtonOptions src/Dodge/Data/RightButtonOptions.hs 14;" C NoRoomClipBoundaries src/Dodge/Data/Config.hs 107;" C -NoSF src/Dodge/Data/ComposedItem.hs 52;" C +NoSF src/Dodge/Data/ComposedItem.hs 54;" C NoShadowFidelity src/Shape/Data.hs 25;" C NoShadows src/Dodge/Data/Config.hs 103;" C NoSubInventory src/Dodge/Data/HUD.hs 29;" C @@ -1335,6 +1335,7 @@ NumShadowCasters6 src/Dodge/Data/Config.hs 21;" C NumShadowCasters7 src/Dodge/Data/Config.hs 22;" C NumShadowCasters8 src/Dodge/Data/Config.hs 23;" C NumShadowCasters9 src/Dodge/Data/Config.hs 24;" C +OItem src/Dodge/Data/ComposedItem.hs 69;" t ORANGE src/Color/Data.hs 26;" C ObButton src/Dodge/Data/ObjectType.hs 17;" C ObCreature src/Dodge/Data/ObjectType.hs 13;" C @@ -1501,8 +1502,8 @@ Projectile src/Dodge/Data/Projectile.hs 17;" t Projectile src/Dodge/Data/Projectile.hs 6;" m Projectile src/Dodge/Projectile.hs 1;" m ProjectileParams src/Dodge/Data/Item/Use.hs 53;" C -ProjectileStabiliserLink src/Dodge/Data/ComposedItem.hs 28;" C -ProjectileStabiliserSF src/Dodge/Data/ComposedItem.hs 59;" C +ProjectileStabiliserLink src/Dodge/Data/ComposedItem.hs 30;" C +ProjectileStabiliserSF src/Dodge/Data/ComposedItem.hs 61;" C ProjectileType src/Dodge/Data/Projectile.hs 41;" t ProjectileUpdate src/Dodge/Data/Projectile.hs 35;" t Prop src/Dodge/Data/Prop.hs 18;" t @@ -1610,11 +1611,11 @@ ReigonalGovernment src/Dodge/Data/Scenario.hs 50;" C Religion src/Dodge/Data/Scenario.hs 47;" C Reload src/Dodge/Data/ActionPlan.hs 190;" C ReloadStatus src/Dodge/Data/Item/Use/Consumption.hs 20;" t -RemoteDetonatorLink src/Dodge/Data/ComposedItem.hs 23;" C -RemoteDetonatorSF src/Dodge/Data/ComposedItem.hs 50;" C +RemoteDetonatorLink src/Dodge/Data/ComposedItem.hs 25;" C +RemoteDetonatorSF src/Dodge/Data/ComposedItem.hs 52;" C RemoteDirectionPU src/Dodge/Data/Projectile.hs 38;" C -RemoteScreenLink src/Dodge/Data/ComposedItem.hs 22;" C -RemoteScreenSF src/Dodge/Data/ComposedItem.hs 48;" C +RemoteScreenLink src/Dodge/Data/ComposedItem.hs 24;" C +RemoteScreenSF src/Dodge/Data/ComposedItem.hs 50;" C RemoveEquipment src/Dodge/Data/RightButtonOptions.hs 36;" C RemoveShieldWall src/Dodge/Data/Item/Effect.hs 27;" C Remove_LOS src/Dodge/Data/Config.hs 77;" C @@ -1674,7 +1675,7 @@ RoundedFaces src/Shape/Data.hs 18;" C RunPast src/Dodge/Room/RunPast.hs 1;" m RunningSideEffect src/Dodge/Data/Universe.hs 69;" C SCRAPMETAL src/Dodge/Data/Item/Combine.hs 61;" C -SFLink src/Dodge/Data/ComposedItem.hs 32;" C +SFLink src/Dodge/Data/ComposedItem.hs 34;" C SHATTERGUN src/Dodge/Data/Item/Combine.hs 174;" C SHELLMAG src/Dodge/Data/Item/Combine.hs 109;" C SHELLPAYLOAD src/Dodge/Data/Item/Combine.hs 102;" C @@ -1801,8 +1802,8 @@ SkiffBaySS src/Dodge/Data/Scenario.hs 108;" C SleepingQuatersSS src/Dodge/Data/Scenario.hs 90;" C Small src/Shape/Data.hs 31;" C Smoke src/Dodge/Data/Cloud.hs 23;" C -SmokeReducerLink src/Dodge/Data/ComposedItem.hs 24;" C -SmokeReducerSF src/Dodge/Data/ComposedItem.hs 51;" C +SmokeReducerLink src/Dodge/Data/ComposedItem.hs 26;" C +SmokeReducerSF src/Dodge/Data/ComposedItem.hs 53;" C SmoothScroll src/Dodge/SmoothScroll.hs 1;" m SocialUpheaval src/Dodge/Data/Scenario.hs 27;" C SolarGovernment src/Dodge/Data/Scenario.hs 53;" C @@ -2002,7 +2003,7 @@ ToStop src/Sound/Data.hs 28;" C Toggle src/Dodge/Data/Universe.hs 103;" C Toggle2 src/Dodge/Data/Universe.hs 107;" C ToggleExamine src/Dodge/ToggleExamine.hs 1;" m -ToggleSF src/Dodge/Data/ComposedItem.hs 61;" C +ToggleSF src/Dodge/Data/ComposedItem.hs 63;" C TopDT src/Dodge/Data/DoubleTree.hs 85;" C TopDecoration src/Dodge/Placement/TopDecoration.hs 1;" m TopEscapeMenuOption src/Dodge/Data/Universe.hs 78;" C @@ -2020,8 +2021,8 @@ TreeHelp src/TreeHelp.hs 12;" m Triangulate src/Geometry/Triangulate.hs 3;" m Trie src/SimpleTrie.hs 9;" t TriggerDoor src/Dodge/Placement/PlaceSpot/TriggerDoor.hs 1;" m -TriggerLink src/Dodge/Data/ComposedItem.hs 14;" C -TriggerSF src/Dodge/Data/ComposedItem.hs 45;" C +TriggerLink src/Dodge/Data/ComposedItem.hs 16;" C +TriggerSF src/Dodge/Data/ComposedItem.hs 47;" C TriggerType src/Dodge/Data/TriggerType.hs 9;" t TriggerType src/Dodge/Data/TriggerType.hs 4;" m TriggerType src/Dodge/Item/TriggerType.hs 1;" m @@ -2047,10 +2048,10 @@ Type src/Dodge/Terminal/Type.hs 1;" m Typical src/Shape/Data.hs 36;" C UNDERBARRELSLOT src/Dodge/Data/Item/Combine.hs 98;" C UNIGATE src/Dodge/Data/Item/Combine.hs 31;" C -UnderBarrelPlatformLink src/Dodge/Data/ComposedItem.hs 30;" C -UnderBarrelPlatformSF src/Dodge/Data/ComposedItem.hs 39;" C -UnderBarrelSlotLink src/Dodge/Data/ComposedItem.hs 29;" C -UnderBarrelSlotSF src/Dodge/Data/ComposedItem.hs 38;" C +UnderBarrelPlatformLink src/Dodge/Data/ComposedItem.hs 32;" C +UnderBarrelPlatformSF src/Dodge/Data/ComposedItem.hs 41;" C +UnderBarrelSlotLink src/Dodge/Data/ComposedItem.hs 31;" C +UnderBarrelSlotSF src/Dodge/Data/ComposedItem.hs 40;" C UnderGround src/Dodge/Data/Scenario.hs 78;" C UnderRoof src/Dodge/Data/Scenario.hs 79;" C UnderSea src/Dodge/Data/Scenario.hs 77;" C @@ -2058,7 +2059,7 @@ UniRandFloat src/Dodge/Data/GenFloat.hs 12;" C Unimportant src/Shape/Data.hs 37;" C Universe src/Dodge/Data/Universe.hs 31;" t Universe src/Dodge/Data/Universe.hs 6;" m -UnloadedWeaponSF src/Dodge/Data/ComposedItem.hs 36;" C +UnloadedWeaponSF src/Dodge/Data/ComposedItem.hs 38;" C UnlockInv src/Dodge/Data/WorldEffect.hs 27;" C UnusedLink src/Dodge/Data/Room.hs 65;" C Update src/Dodge/Config/Update.hs 4;" m @@ -2195,10 +2196,10 @@ WdWdBurstFireRepetition src/Dodge/Data/WorldEffect.hs 35;" C WdWdNegateTrig src/Dodge/Data/WorldEffect.hs 31;" C WdYouPos src/Dodge/Data/WorldEffect.hs 41;" C Weapon src/Dodge/Item/Weapon.hs 2;" m -WeaponScopeLink src/Dodge/Data/ComposedItem.hs 19;" C -WeaponScopeSF src/Dodge/Data/ComposedItem.hs 42;" C -WeaponTargetingLink src/Dodge/Data/ComposedItem.hs 20;" C -WeaponTargetingSF src/Dodge/Data/ComposedItem.hs 43;" C +WeaponScopeLink src/Dodge/Data/ComposedItem.hs 21;" C +WeaponScopeSF src/Dodge/Data/ComposedItem.hs 44;" C +WeaponTargetingLink src/Dodge/Data/ComposedItem.hs 22;" C +WeaponTargetingSF src/Dodge/Data/ComposedItem.hs 45;" C Weapons src/Dodge/Item/Held/Weapons.hs 1;" m West src/Dodge/Data/CardinalPoint.hs 7;" C West8 src/Dodge/Data/CardinalPoint.hs 17;" C @@ -3035,7 +3036,7 @@ _sensorCoding src/Dodge/Data/GenParams.hs 16;" f _sentinelDir src/Dodge/Data/ActionPlan.hs 199;" f _sentinelPos src/Dodge/Data/ActionPlan.hs 199;" f _sfColor src/Shape/Data.hs 44;" f -_sfLink src/Dodge/Data/ComposedItem.hs 32;" f +_sfLink src/Dodge/Data/ComposedItem.hs 34;" f _sfShadowImportance src/Shape/Data.hs 45;" f _sfSize src/Shape/Data.hs 46;" f _sfType src/Shape/Data.hs 42;" f @@ -3361,7 +3362,8 @@ airlockDoor src/Dodge/Room/Airlock.hs 51;" f airlockDoubleDoor src/Dodge/Room/Airlock.hs 54;" f airlockSimple src/Dodge/Room/Airlock.hs 66;" f airlockZ src/Dodge/Room/Airlock.hs 91;" f -allInvLocs src/Dodge/Item/Grammar.hs 253;" f +allInvLocs src/Dodge/Item/Grammar.hs 261;" f +allInvLocs' src/Dodge/Item/Grammar.hs 282;" f allVisibleWalls src/Dodge/Base/Collide.hs 132;" f alongSegBy src/Geometry.hs 40;" f alteRifle src/Dodge/Item/Held/Cane.hs 22;" f @@ -3462,7 +3464,7 @@ barrel src/Dodge/Creature/Inanimate.hs 17;" f barrelShape src/Dodge/Render/ShapePicture.hs 46;" f baseAMRShape src/Dodge/Item/Draw/SPic.hs 405;" f baseBlockPane src/Dodge/Placement/Instance/Wall.hs 86;" f -baseCI src/Dodge/Item/Grammar.hs 159;" f +baseCI src/Dodge/Item/Grammar.hs 161;" f baseCaneShape src/Dodge/Item/Draw/SPic.hs 311;" f baseDebris src/Dodge/Block/Debris.hs 122;" f baseFloorTileSize src/Tile.hs 45;" f @@ -4314,8 +4316,8 @@ extTrigLitPos src/Dodge/Placement/Instance/Button.hs 84;" f extendAway src/Dodge/Placement/Instance/LightSource.hs 200;" f extendConeToScreenEdge src/Dodge/Debug/Picture.hs 82;" f extraPics src/Dodge/Render/ShapePicture.hs 73;" f -extraWeaponLinks src/Dodge/Item/Grammar.hs 94;" f -extraWeaponLinksBelow src/Dodge/Item/Grammar.hs 103;" f +extraWeaponLinks src/Dodge/Item/Grammar.hs 96;" f +extraWeaponLinksBelow src/Dodge/Item/Grammar.hs 105;" f extractRoomPos src/Dodge/RoomPos.hs 6;" f faceEdges src/Polyhedra.hs 65;" f facesToVF src/Polyhedra/Geodesic.hs 69;" f @@ -4434,11 +4436,11 @@ geometryTests test/Spec.hs 17;" f geometryUnitTests test/Spec.hs 22;" f geqConstr src/SameConstr.hs 21;" f getAimZoom src/Dodge/Update/Camera.hs 135;" f -getAmmoLinks src/Dodge/Item/Grammar.hs 110;" f +getAmmoLinks src/Dodge/Item/Grammar.hs 112;" f getArguments src/Dodge/Update/Scroll.hs 178;" f getArguments' src/Dodge/Update/Scroll.hs 166;" f getAttachedSFLink src/Dodge/HeldUse.hs 811;" f -getAutoSpringLinks src/Dodge/Item/Grammar.hs 89;" f +getAutoSpringLinks src/Dodge/Item/Grammar.hs 91;" f getAvailableListLines src/Dodge/SelectionList.hs 10;" f getBulHitDams src/Dodge/Bullet.hs 171;" f getBulletType src/Dodge/HeldUse.hs 930;" f @@ -4655,16 +4657,17 @@ interweave src/Justify.hs 17;" f introScan src/Dodge/Item/Scope.hs 57;" f introScanValue src/Dodge/Inventory/SelectionList.hs 79;" f intsToPos src/Dodge/Room/Modify/Girder.hs 160;" f -invAdj src/Dodge/Item/Grammar.hs 236;" f +invAdj src/Dodge/Item/Grammar.hs 238;" f invCursorParams src/Dodge/ListDisplayParams.hs 36;" f invDP src/Dodge/ListDisplayParams.hs 30;" f invDimColor src/Dodge/DisplayInventory.hs 192;" f invHead src/Dodge/Render/HUD.hs 405;" f invItemLocUpdate src/Dodge/Creature/State.hs 156;" f -invLDT src/Dodge/Item/Grammar.hs 216;" f +invLDT src/Dodge/Item/Grammar.hs 218;" f invRootItemEffs src/Dodge/Creature/State.hs 149;" f -invRootMap src/Dodge/Item/Grammar.hs 225;" f -invRootTrees src/Dodge/Item/Grammar.hs 246;" f +invRootMap src/Dodge/Item/Grammar.hs 227;" f +invRootTrees src/Dodge/Item/Grammar.hs 248;" f +invRootTrees' src/Dodge/Item/Grammar.hs 254;" f invSelectionItem src/Dodge/Inventory/SelectionList.hs 32;" f invSetSelection src/Dodge/Inventory.hs 185;" f invSetSelectionPos src/Dodge/Inventory.hs 193;" f @@ -4743,8 +4746,8 @@ itemScrollDisplay src/Dodge/Inventory/SelectionList.hs 120;" f itemScrollValue src/Dodge/Inventory/SelectionList.hs 147;" f itemSidePush src/Dodge/HeldUse.hs 433;" f itemString src/Dodge/Item/Display.hs 55;" f -itemToBreakLists src/Dodge/Item/Grammar.hs 34;" f -itemToFunction src/Dodge/Item/Grammar.hs 116;" f +itemToBreakLists src/Dodge/Item/Grammar.hs 36;" f +itemToFunction src/Dodge/Item/Grammar.hs 118;" f itemTreeSPic src/Dodge/Item/Draw/SPic.hs 24;" f itemTriggerType src/Dodge/BaseTriggerType.hs 12;" f itemWeight src/Dodge/Creature/Statistics.hs 66;" f @@ -4756,7 +4759,7 @@ itmSpaceInfo src/Dodge/Item/Info.hs 25;" f itmUsageInfo src/Dodge/Item/Info.hs 230;" f jShape src/Dodge/Placement/Instance/LightSource.hs 85;" f jaggedShape src/Dodge/Block/Debris.hs 191;" f -joinItemsInList src/Dodge/Item/Grammar.hs 206;" f +joinItemsInList src/Dodge/Item/Grammar.hs 208;" f joystick src/Dodge/Item/Scope.hs 149;" f jps0' src/Dodge/LevelGen/PlacementHelper.hs 60;" f jps0PushPS src/Dodge/LevelGen/PlacementHelper.hs 63;" f @@ -4806,10 +4809,10 @@ ldtToIM src/Dodge/DoubleTree.hs 184;" f ldtToIndentList src/Dodge/DoubleTree.hs 187;" f ldtToLoc src/Dodge/DoubleTree.hs 233;" f left src/DoubleStack.hs 16;" f -leftChildList src/Dodge/Item/Grammar.hs 180;" f -leftIsParentCombine src/Dodge/Item/Grammar.hs 164;" f +leftChildList src/Dodge/Item/Grammar.hs 182;" f +leftIsParentCombine src/Dodge/Item/Grammar.hs 166;" f leftPad src/Padding.hs 15;" f -leftRightCombine src/Dodge/Item/Grammar.hs 192;" f +leftRightCombine src/Dodge/Item/Grammar.hs 194;" f legsSPic src/Dodge/Item/Draw/SPic.hs 475;" f liShape src/Dodge/Placement/Instance/LightSource.hs 98;" f light src/Color.hs 104;" f @@ -5156,11 +5159,11 @@ orderAroundFirst src/Geometry/Polygon.hs 82;" f orderAroundFirstReverse src/Geometry/Polygon.hs 78;" f orderPolygon src/Geometry/Polygon.hs 87;" f orderPolygonAround src/Geometry/Polygon.hs 70;" f -orientAttachment src/Dodge/Item/Orientation.hs 30;" f -orientByLink src/Dodge/Item/Orientation.hs 23;" f -orientChild src/Dodge/Item/Orientation.hs 15;" f -orientLocation src/Dodge/Item/Orientation.hs 51;" f -orientLocation' src/Dodge/Item/Orientation.hs 40;" f +orientAttachment src/Dodge/Item/Orientation.hs 31;" f +orientByLink src/Dodge/Item/Orientation.hs 24;" f +orientChild src/Dodge/Item/Orientation.hs 16;" f +orientLocation src/Dodge/Item/Orientation.hs 52;" f +orientLocation' src/Dodge/Item/Orientation.hs 41;" f orthogonalPointOnSeg src/Geometry/Intersect.hs 291;" f outLink src/Dodge/RoomLink.hs 105;" f outsideScreenPolygon src/Dodge/Debug/Picture.hs 44;" f @@ -5380,7 +5383,7 @@ propSPic src/Dodge/Prop/Draw.hs 15;" f propSetToggleAnd src/Dodge/Prop/Update.hs 41;" f propUpdateIf src/Dodge/Prop/Update.hs 25;" f propUpdatePosition src/Dodge/Prop/Update.hs 30;" f -propagateOrientation src/Dodge/Item/Orientation.hs 60;" f +propagateOrientation src/Dodge/Item/Orientation.hs 61;" f ps0 src/Dodge/LevelGen/PlacementHelper.hs 51;" f ps0PushPS src/Dodge/LevelGen/PlacementHelper.hs 79;" f ps0PushPSw src/Dodge/LevelGen/PlacementHelper.hs 83;" f @@ -5547,8 +5550,8 @@ rezText' src/Dodge/Story.hs 17;" f rhombus src/Polyhedra.hs 72;" f rifle src/Dodge/Item/Held/Cane.hs 19;" f right src/DoubleStack.hs 16;" f -rightChildList src/Dodge/Item/Grammar.hs 186;" f -rightIsParentCombine src/Dodge/Item/Grammar.hs 172;" f +rightChildList src/Dodge/Item/Grammar.hs 188;" f +rightIsParentCombine src/Dodge/Item/Grammar.hs 174;" f rightPad src/Padding.hs 19;" f rightPadNoSquash src/Padding.hs 23;" f rlPosDir src/Dodge/RoomLink.hs 94;" f @@ -5952,7 +5955,7 @@ strideRot src/Dodge/Item/HeldOffset.hs 83;" f stringToList src/Picture/Base.hs 313;" f stringToListGrad src/Picture/Text.hs 12;" f stripZ src/Geometry/Vector3D.hs 97;" f -structureToPotentialFunction src/Dodge/Item/Grammar.hs 151;" f +structureToPotentialFunction src/Dodge/Item/Grammar.hs 153;" f structureUseAtLoc src/Dodge/Creature/Impulse/UseItem.hs 75;" f subInvX src/Dodge/ListDisplayParams.hs 48;" f subMap src/TreeHelp.hs 118;" f @@ -6147,7 +6150,7 @@ triggerSwitchSPicLight src/Dodge/Placement/Instance/Button.hs 31;" f truncFaces src/Polyhedra/Geodesic.hs 53;" f truncate src/Polyhedra/Geodesic.hs 38;" f trunkDepth src/TreeHelp.hs 161;" f -tryAttachItems src/Dodge/Item/Grammar.hs 30;" f +tryAttachItems src/Dodge/Item/Grammar.hs 32;" f tryClickUse src/Dodge/Creature/YourControl.hs 221;" f tryCombine src/Dodge/Update/Input/InGame.hs 526;" f tryDropSelected src/Dodge/Update/Input/InGame.hs 125;" f