module Dodge.HeldUse where import Dodge.Data.ComposedItem import Dodge.Data.DoubleTree import Color import Data.Maybe import Data.Traversable import Dodge.Base.Coordinate import Dodge.Bullet import Dodge.Creature.HandPos import Dodge.Data.World import Dodge.Gas import Dodge.Item.Weapon.BatteryGuns import Dodge.Item.Weapon.Launcher import Dodge.Item.Weapon.Radar import Dodge.Item.Weapon.Shatter import Dodge.Item.Weapon.TriggerType import Dodge.Projectile.Create import Dodge.SoundLogic import Dodge.Tesla.Arc import Dodge.Wall.ForceField import Dodge.Wall.Move import Dodge.WorldEvent.Flash import Geometry import qualified IntMapHelp as IM import LensHelp import RandomHelp import Sound.Data import Data.Foldable heldEffect :: HeldMod -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World heldEffect effecttype = case effecttype of -- HeldModNothing -> const $ const id PoisonSprayerMod -> gasEffect [ useAmmoAmount 1 , withSoundForI foamSprayLoopS 5 , ammoCheckI ] FlameSpitterMod -> gasEffect [ withSidePushAfterI 20 , withSidePushI 5 , useAmmoAmount 1 , withRandomItemParams f , repeatOnFrames [1 .. 9] FlameSpitterRepeatMod , lockInvFor 10 , useTimeCheck , ammoCheckI ] FlameSpitterRepeatMod -> gasEffect [ withSidePushAfterI 20 , withSidePushI 5 , useAmmoAmount 1 , withRandomItemParams f , ammoCheckI ] FlameThrowerMod -> gasEffect [ withSidePushAfterI 20 , --, withTempLight 1 100 (V3 1 0 0) withSidePushI 5 , useAmmoAmount 1 , ammoCheckI ] LauncherMod -> foldl' (&) usePjCreation --[ useAmmoAmount 1 -- , withSoundStart tap4S [ useTimeCheck -- , ammoCheckI , blCheck ] TeslaMod -> foldl' (&) (shootTeslaArc . _ldtValue) [ useAmmoAmount 1 , withSoundForI elecCrackleS 1 , withTempLight 1 100 (V3 0 0 1) , ammoCheckI ] LasWideMod n -> foldl' (&) (shootLaser . _ldtValue) [ useAmmoAmount 1 , withItem $ \it -> duplicateNumBarrels -- ( min -- (it ^?! itUse . heldConsumption . laSource . _InternalSource . iaLoaded) (it ^?! itParams . lasCycle `div` lasWideRate) -- ) , withItem $ \it -> withCrPos $ flareCircleAt (_lasColor $ _itParams it) 0.8 , withItem $ \it -> withTempLight 1 100 (xyzV4 (_lasColor $ _itParams it)) , withSoundForI tone440sawtoothquietS 2 , withItemUpdateFirst (increasecycleLasWide n) , ammoCheckI ] DualBeamMod -> foldl' (&) (shootDualLaser . _ldtValue) [ useAmmoAmount 1 , withSoundForI tone440sawtoothquietS 2 , withItem $ \it -> withCrPosShift (V2 0 (- thegapDualBeam it)) $ flareCircleAt (_lasColor2 $ _itParams it) 0.8 , withItem $ \it -> withCrPosShift (V2 0 (thegapDualBeam it)) $ flareCircleAt (_lasColor $ _itParams it) 0.8 , ammoCheckI ] LasMod -> foldl' (&) (shootLaser . _ldtValue) [ useAmmoAmount 1 , withItem $ \it -> withCrPos $ flareCircleAt (_lasColor $ _itParams it) 0.8 , withSoundForI tone440sawtoothquietS 2 , withItem $ \it -> withTempLight 1 100 (xyzV4 (_lasColor $ _itParams it)) , duplicateLoadedBarrels , ammoCheckI ] LauncherXMod _ -> foldl' (&) usePjCreationX --[ useAmmoAmount i --, withSoundStart tap4S [ useTimeCheck --, ammoCheckI , blCheck ] ShatterMod -> foldl' (&) (shootShatter . _ldtValue) [ useAmmoAmount 1 , -- , withSoundStart tap3S useTimeCheck , ammoCheckI , blCheck ] BangCaneMod -> bulletGunEffect [ withFlare , withSmoke 1 black 20 200 5 , withRecoil , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart tap3S , useTimeCheck , ammoCheckI , blCheck ] VolleyGunMod -> bulletGunEffect [ withRecoil , withFlare , duplicateLoadedBarrels , withTorqueAfter , useAllAmmo , withSoundItemChoiceStart caneStickSoundChoice , useTimeCheck , ammoCheckI , blCheck ] MultiGunMod -> bulletGunEffect [ withRecoil , withFlare , duplicateLoadedBarrels , withTorqueAfter , useAllAmmo , withSoundItemChoiceStart caneStickSoundChoice , useTimeCheck , ammoCheckI , blCheck ] AutoRifleMod -> bulletGunEffect -- note this is the same as BangCanemMod with the first changed [ withFlare , withSmoke 1 black 20 200 5 , withRecoil , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart tap3S , useTimeCheck , ammoCheckI ] BangRodMod -> bulletGunEffect [ withRecoil , withFlare , withThickSmokeI , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart bangEchoS , useTimeCheck , ammoCheckI , blCheck ] ElephantGunMod -> bulletGunEffect [ withRecoil , withFlare , withThickSmokeI , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart bangEchoS , useTimeCheck , ammoCheckI , blCheck ] AutoAmrMod -> bulletGunEffect [ withRecoil , withFlare , withThickSmokeI , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart bangEchoS , useTimeCheck , ammoCheckI -- cf ElephantGun ] MachineGunMod -> bulletGunEffect [ withFlare , withThinSmokeI , withSoundStart bangEchoS , rateIncAB (torqueBeforeAtLeast 0.1 0.1) withTorqueAfter , ammoCheckI ] BangStickMod -> bulletGunEffect [ withRecoil , useAllAmmo , withSoundItemChoiceStart bangStickSoundChoice , duplicateLoadedBarrels , withTorqueAfter , withFlare , useTimeCheck , ammoCheckI , blCheck ] PistolMod -> bulletGunEffect [ withSidePushI 50 , withRecoil , withFlare , withTorqueAfter , duplicateLoadedBarrels , withSoundStart tap3S , useAmmoAmount 1 , useTimeCheck , ammoCheckI , blCheck ] AutoPistolMod -> bulletGunEffect [ withFlare , withSidePushI 50 , withRecoil , withTorqueAfter , duplicateLoadedBarrels , withSoundStart tap3S , useAmmoAmount 1 , useTimeCheck , ammoCheckI ] MachinePistolMod -> bulletGunEffect [ withFlare , withRecoil , withSidePushI 50 , withTorqueAfter , duplicateLoadedBarrels , withSoundStart tap1S , useAmmoAmount 1 , useTimeCheck , ammoCheckI ] BurstRifleMod -> bulletGunEffect [ withRecoil , withFlare , duplicateLoadedBarrels , useAmmoAmount 1 , withSoundStart tap3S , repeatOnFrames [3, 6] BurstRifleRepeatMod , lockInvFor 7 , sideEffectOnFrame 7 (\_ cr -> TorqueCr 0.2 (_crID cr)) --(torqueSideEffect 0.2) , useTimeCheck , ammoCheckI , blCheck ] BurstRifleRepeatMod -> bulletGunEffect [ withRecoil , withFlare , duplicateLoadedBarrels , useAmmoAmount 1 , withSoundStart tap3S , sideEffectOnFrame 7 (\_ cr -> TorqueCr 0.2 (_crID cr)) --(torqueSideEffect 0.2) , ammoCheckI ] MiniGunMod i -> bulletGunEffect [ duplicateNumBarrels 1 , repeatTransformed [ (id, modcrpos x) | x <- map ((/ (fromIntegral i - 1)) . fromIntegral) [0 .. i -1] ] , afterRecoil (fromIntegral i * 5) , torqueBefore (fromIntegral i * 0.05) , withSidePushI (fromIntegral i * 25) , withMuzFlare , withSmoke 1 black 20 200 5 , useAmmoAmount i , withSoundForI mini1S 2 , withWarmUp crankSlowS , ammoCheckI ] SmgMod -> bulletGunEffect [ withFlare , withSidePushI 30 , withRecoil , withTorqueAfter , duplicateLoadedBarrels , withSoundStart tap3S , useAmmoAmount 1 , useTimeCheck , ammoCheckI ] BangConeMod -> bulletGunEffect [ withRandomItem coneRandItemParams , withRandomItemUpdate coneRandItemUpdate , withRandomOffset , duplicateLoadedBarrels , duplicateLoaded , withMuzFlare , withRecoil , withTorqueAfter , useAllAmmo , withSoundStart bangEchoS , useTimeCheck , ammoCheckI , blCheck ] TractorMod -> foldl' (&) (aTractorBeam . _ldtValue) [ammoCheckI] where f = do nzpres <- state $ randomR (3, 4) return $ sprayNozzles . ix 0 . nzPressure .~ nzpres increasecycleLasWide n it = case _heldHammer (_itUse it) of HammerUp -> it & itParams . lasCycle .~ 1 _ -> it & itParams . lasCycle %~ (min (n * lasWideRate) . (+ 1)) thegapDualBeam = _dbGap . _itParams directedTelPos _ cr w = (p, a) where p = fromMaybe (_crPos cr) $ cr ^? crTargeting . ctPos . _Just a = argV (mouseWorldPos (w ^. input) (w ^. wCam) -.- p) modcrpos x cr = fromMaybe cr $ do invid <- cr ^? crManipulation . manObject . inInventory . ispItem return $ cr & crDir %~ tweenAngles x (_crOldDir cr) & crPos %~ alongSegBy x (_crOldPos cr) & crInv . ix (invid + 1) . itUse . amagParams . ampBullet . buDelayFraction .~ x gasEffect = foldl' (&) (overNozzles useGasParams) bulletGunEffect = foldl' (&) shootBullet useMod :: HeldMod -> [(LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World) -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World] useMod hm = case hm of -- HeldModNothing -> [] PoisonSprayerMod -> [ useAmmoAmount 1 , withSoundForI foamSprayLoopS 5 , ammoCheckI ] FlameSpitterMod -> [ withSidePushAfterI 20 , withSidePushI 5 , useAmmoAmount 1 , withRandomItemParams f , repeatOnFrames [1 .. 9] FlameSpitterRepeatMod , lockInvFor 10 , useTimeCheck , ammoCheckI ] FlameSpitterRepeatMod -> [ withSidePushAfterI 20 , withSidePushI 5 , useAmmoAmount 1 , withRandomItemParams f , ammoCheckI ] FlameThrowerMod -> [ withSidePushAfterI 20 , --, withTempLight 1 100 (V3 1 0 0) withSidePushI 5 , useAmmoAmount 1 , ammoCheckI ] LauncherMod -> --[ useAmmoAmount 1 -- , withSoundStart tap4S [ useTimeCheck -- , ammoCheckI , blCheck ] TeslaMod -> [ useAmmoAmount 1 , withSoundForI elecCrackleS 1 , withTempLight 1 100 (V3 0 0 1) , ammoCheckI ] -- CircleLaserMod -> -- [ duplicateItem fLasCircle -- , useAmmoAmount 1 -- , withSoundForI tone440sawtoothquietS 2 -- , withItem $ \it -> withCrPos $ flareCircleAt (_lasColor $ _itParams it) 0.8 -- , withItem $ \it -> withTempLight 1 100 (xyzV4 (_lasColor $ _itParams it)) -- , withItemUpdateFirst increasecycleLasCircle -- , ammoCheckI -- ] LasWideMod n -> [ useAmmoAmount 1 , withItem $ \it -> duplicateNumBarrels -- ( min -- (it ^?! itUse . heldConsumption . laSource . _InternalSource . iaLoaded) (it ^?! itParams . lasCycle `div` lasWideRate) -- ) , withItem $ \it -> withCrPos $ flareCircleAt (_lasColor $ _itParams it) 0.8 , withItem $ \it -> withTempLight 1 100 (xyzV4 (_lasColor $ _itParams it)) , withSoundForI tone440sawtoothquietS 2 , withItemUpdateFirst (increasecycleLasWide n) , ammoCheckI ] DualBeamMod -> [ useAmmoAmount 1 , withSoundForI tone440sawtoothquietS 2 , withItem $ \it -> withCrPosShift (V2 0 (- thegapDualBeam it)) $ flareCircleAt (_lasColor2 $ _itParams it) 0.8 , withItem $ \it -> withCrPosShift (V2 0 (thegapDualBeam it)) $ flareCircleAt (_lasColor $ _itParams it) 0.8 , ammoCheckI ] LasMod -> [ useAmmoAmount 1 , withItem $ \it -> withCrPos $ flareCircleAt (_lasColor $ _itParams it) 0.8 , withSoundForI tone440sawtoothquietS 2 , withItem $ \it -> withTempLight 1 100 (xyzV4 (_lasColor $ _itParams it)) , duplicateLoadedBarrels , ammoCheckI ] LauncherXMod _ -> --[ useAmmoAmount i --, withSoundStart tap4S [ useTimeCheck --, ammoCheckI , blCheck ] ShatterMod -> [ useAmmoAmount 1 , -- , withSoundStart tap3S useTimeCheck , ammoCheckI , blCheck ] -- AmmoCheckMod -> [ammoCheckI] -- AmmoUseCheckMod -> [useAmmoAmount 1, useTimeCheck, ammoCheckI] -- AmmoHammerTimeUseOneMod -> -- [ useAmmoAmount 1 -- , useTimeCheck -- , ammoCheckI -- , blCheck -- ] BangCaneMod -> [ withFlare , withSmoke 1 black 20 200 5 , withRecoil , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart tap3S , useTimeCheck , ammoCheckI , blCheck ] VolleyGunMod -> [ withRecoil , withFlare , duplicateLoadedBarrels , withTorqueAfter , useAllAmmo , withSoundItemChoiceStart caneStickSoundChoice , useTimeCheck , ammoCheckI , blCheck ] MultiGunMod -> [ withRecoil , withFlare , duplicateLoadedBarrels , withTorqueAfter , useAllAmmo , withSoundItemChoiceStart caneStickSoundChoice , useTimeCheck , ammoCheckI , blCheck ] AutoRifleMod -> -- note this is the same as BangCanemMod with the first changed [ withFlare , withSmoke 1 black 20 200 5 , withRecoil , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart tap3S , useTimeCheck , ammoCheckI ] BangRodMod -> [ withRecoil , withFlare , withThickSmokeI , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart bangEchoS , useTimeCheck , ammoCheckI , blCheck ] ElephantGunMod -> [ withRecoil , withFlare , withThickSmokeI , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart bangEchoS , useTimeCheck , ammoCheckI , blCheck ] AutoAmrMod -> [ withRecoil , withFlare , withThickSmokeI , duplicateLoadedBarrels , withTorqueAfter , useAmmoAmount 1 , withSoundStart bangEchoS , useTimeCheck , ammoCheckI -- cf ElephantGun ] MachineGunMod -> [ withFlare , withThinSmokeI , withSoundStart bangEchoS , rateIncAB (torqueBeforeAtLeast 0.1 0.1) withTorqueAfter , ammoCheckI ] -- ModWithDirectedTeleport hm' -> -- reverse $ withPosDirWallCheck directedTelPos : useMod hm' BangStickMod -> [ withRecoil , useAllAmmo , withSoundItemChoiceStart bangStickSoundChoice , duplicateLoadedBarrels , withTorqueAfter , withFlare , useTimeCheck , ammoCheckI , blCheck ] PistolMod -> [ withSidePushI 50 , withRecoil , withFlare , withTorqueAfter , duplicateLoadedBarrels , withSoundStart tap3S , useAmmoAmount 1 , useTimeCheck , ammoCheckI , blCheck ] AutoPistolMod -> [ withFlare , withSidePushI 50 , withRecoil , withTorqueAfter , duplicateLoadedBarrels , withSoundStart tap3S , useAmmoAmount 1 , useTimeCheck , ammoCheckI ] MachinePistolMod -> [ withFlare , withRecoil , withSidePushI 50 , withTorqueAfter , duplicateLoadedBarrels , withSoundStart tap1S , useAmmoAmount 1 , useTimeCheck , ammoCheckI ] BurstRifleMod -> [ withRecoil , withFlare , duplicateLoadedBarrels , useAmmoAmount 1 , withSoundStart tap3S , repeatOnFrames [3, 6] BurstRifleRepeatMod , lockInvFor 7 , sideEffectOnFrame 7 (\_ cr -> TorqueCr 0.2 (_crID cr)) --(torqueSideEffect 0.2) , useTimeCheck , ammoCheckI , blCheck ] BurstRifleRepeatMod -> [ withRecoil , withFlare , duplicateLoadedBarrels , useAmmoAmount 1 , withSoundStart tap3S , sideEffectOnFrame 7 (\_ cr -> TorqueCr 0.2 (_crID cr)) --(torqueSideEffect 0.2) , ammoCheckI ] MiniGunMod i -> [ duplicateNumBarrels 1 , repeatTransformed [ (id, modcrpos x) | x <- map ((/ (fromIntegral i - 1)) . fromIntegral) [0 .. i -1] ] , afterRecoil (fromIntegral i * 5) , torqueBefore (fromIntegral i * 0.05) , withSidePushI (fromIntegral i * 25) , withMuzFlare , withSmoke 1 black 20 200 5 , useAmmoAmount i , withSoundForI mini1S 2 , withWarmUp crankSlowS , ammoCheckI ] SmgMod -> [ withFlare , withSidePushI 30 , withRecoil , withTorqueAfter , duplicateLoadedBarrels , withSoundStart tap3S , useAmmoAmount 1 , useTimeCheck , ammoCheckI ] BangConeMod -> [ withRandomItem coneRandItemParams , withRandomItemUpdate coneRandItemUpdate , withRandomOffset , duplicateLoadedBarrels , duplicateLoaded , withMuzFlare , withRecoil , withTorqueAfter , useAllAmmo , withSoundStart bangEchoS , useTimeCheck , ammoCheckI , blCheck ] where f = do nzpres <- state $ randomR (3, 4) return $ sprayNozzles . ix 0 . nzPressure .~ nzpres increasecycleLasCircle it = it & itParams . lasCycle %~ (flip mod 2000 . (+ 1)) --f it = [it & itParams . lasCycle +~ x | x <- [0,100 .. 1900] ] fLasCircle it = [it & itParams . lasCycle +~ x | x <- [0, 50 .. 1999]] increasecycleLasWide n it = case _heldHammer (_itUse it) of HammerUp -> it & itParams . lasCycle .~ 1 _ -> it & itParams . lasCycle %~ (min (n * lasWideRate) . (+ 1)) thegapDualBeam = _dbGap . _itParams directedTelPos _ cr w = (p, a) where p = fromMaybe (_crPos cr) $ cr ^? crTargeting . ctPos . _Just a = argV (mouseWorldPos (w ^. input) (w ^. wCam) -.- p) modcrpos x cr = fromMaybe cr $ do invid <- cr ^? crManipulation . manObject . inInventory . ispItem return $ cr & crDir %~ tweenAngles x (_crOldDir cr) & crPos %~ alongSegBy x (_crOldPos cr) & crInv . ix (invid + 1) . itUse . amagParams . ampBullet . buDelayFraction .~ x lasWideRate :: Int lasWideRate = 2 mcUseHeld :: HeldItemType -> Item -> Machine -> World -> World mcUseHeld hit = case hit of LASGUN -> mcShootLaser _ -> \_ _ -> id useHeld :: Huse -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World useHeld hu = case hu of HeldDoNothing -> const $ const id HeldUseAmmoParams -> shootBullet HeldOverNozzlesUseGasParams -> overNozzles useGasParams HeldPJCreation -> usePjCreation HeldPJCreationX _ -> usePjCreationX HeldFireRemoteShell -> fireRemoteShell HeldDetectorEffect dt -> detectorEffect dt . _ldtValue HeldTeslaArc -> shootTeslaArc . _ldtValue HeldLaser -> shootLaser . _ldtValue HeldCircleLaser -> circleLaser . _ldtValue HeldDualLaser -> shootDualLaser . _ldtValue HeldTractor -> aTractorBeam . _ldtValue -- HeldSonicWave -> aSonicWave HeldForceField -> useForceFieldGun . _ldtValue HeldShatter -> shootShatter . _ldtValue HeldExplodeRemoteShell itid pjid -> const $ const $ explodeRemoteRocket itid pjid usePjCreation :: LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World usePjCreation itm cr = fromMaybe id $ do atype <- itm ^? ldtValue . itUse . heldAmmoTypes . ix 0 leftitms <- itm ^? ldtLeft mag <- lookup (AmmoInLink atype) leftitms apm <- mag ^? ldtValue muz <- itm ^? ldtValue . itUse . heldAim . aimMuzzles . ix 0 return $ createProjectile apm muz (_ldtValue itm) cr usePjCreationX :: LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World usePjCreationX itm cr = undefined --usePjCreationX ams itm cr = fromMaybe id $ do -- muzs <- itm ^? itUse . heldAim . aimMuzzles -- return $ foldr -- f id (zip muzs ams) -- where -- f (muz,am) = (createProjectile am muz itm cr .) overNozzles :: (Nozzle -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World) -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World overNozzles = overNozzles' . overNozzle overNozzles' :: (LabelDoubleTree ComposeLinkType Item -> Creature -> World -> Nozzle -> (World, Nozzle)) -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World overNozzles' eff itm cr w = neww & cWorld . lWorld . creatures . ix cid . crInv . ix i . itParams . sprayNozzles .~ newNozzles where it = itm ^. ldtValue cid = _crID cr i = w ^?! cWorld . lWorld . creatures . ix cid . crManipulation . manObject . inInventory . ispItem (neww, newNozzles) = mapAccumR (eff itm cr) w $ _sprayNozzles (_itParams it) overNozzle :: (Nozzle -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World) -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> Nozzle -> (World, Nozzle) overNozzle eff itm cr w nz = ( eff nz itm (cr & crDir +~ wa + na) w & randGen .~ g , nz & nzCurrentWalkAngle .~ wa ) where na = _nzDir nz (walkamount, g) = randomR (- aspeed, aspeed) (_randGen w) aspeed = _nzWalkSpeed nz maxa = _nzMaxWalkAngle nz wa = min maxa $ max (negate maxa) (_nzCurrentWalkAngle nz + walkamount) getAmmoMagazine :: Item -> Creature -> Maybe ItemUse getAmmoMagazine itm cr = do invid <- itm ^? itLocation . ipInvID amtype <- itm ^? itUse . heldAmmoTypes . ix 0 mag <- cr ^? crInv . ix (invid + 1) . itUse magtype <- mag ^? amagType guard $ amtype == magtype return mag useGasParams :: Nozzle -> LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World useGasParams nz itm cr = createGas gastype (_nzPressure nz) pos dir cr where gastype = fromMaybe (error "cannot find gas ammo") $ do atype <- itm ^? ldtValue . itUse . heldAmmoTypes . ix 0 leftitms <- itm ^? ldtLeft mag <- lookup (AmmoInLink atype) leftitms mag ^? ldtValue . itUse . amagParams . ampCreateGas dir = _crDir cr pos = _crPos cr +.+ (_nzLength nz *.* unitVectorAtAngle (_crDir cr)) fireRemoteShell :: LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World fireRemoteShell it cr w = undefined --fireRemoteShell :: [Item] -> Item -> Creature -> World -> World --fireRemoteShell ams it cr w = -- set -- (cWorld . lWorld . creatures . ix cid . crInv . ix j . itUse . heldUse) -- (HeldExplodeRemoteShell itid i) -- $ addRemRocket w -- where -- itid = _itID it -- i = IM.newKey $ w ^. cWorld . lWorld . props -- cid = _crID cr -- apm = fromMaybe (error "cannot find shell ammo projectile") $ do -- ams ^? ix 0 -- addRemRocket = -- makeShell apm -- -- the following is unsafe! -- (it ^?! itUse . heldAim . aimMuzzles . ix 0) -- it -- cr -- [ PJRemoteShellCollisionCheck -- , PJSetScope itid -- , PJDecTimMvVel -- , PJThrust 330 0 -- , PJRemoteDirection 340 0 cid itid -- ] -- j = cr ^?! crManipulation . manObject . inInventory . ispItem -- unsafe!! TODO change caneStickSoundChoice :: Item -> SoundID caneStickSoundChoice _ = tap3S -- -- | (it ^?! itUse . heldConsumption . laSource . _InternalSource . iaLoaded) < 2 = tap3S -- -- | otherwise = shotgunS bangStickSoundChoice :: Item -> SoundID bangStickSoundChoice = caneStickSoundChoice coneRandItemUpdate :: State StdGen (Item -> Item) coneRandItemUpdate = return id -- do -- wth <- state $ randomR (1, 5) -- return (itUse . heldConsumption . laAmmoType . amBullet . buWidth .~ wth) coneRandItemParams :: State StdGen (Item -> Item) coneRandItemParams = do muzv <- state $ randomR (0.5, 1) rifl <- state $ randomR (0.3, 0.9) return $ \it -> it & itUse . heldParams . muzVel .~ muzv & itUse . heldParams . rifling .~ rifl mcShootLaser :: Item -> Machine -> World -> World mcShootLaser it mc = cWorld . lWorld . lasers .:~ lasRayAt (_lasColor $ _itParams it) dam phasev pos dir where pos = _mcPos mc +.+ 20 *.* unitVectorAtAngle dir dir = mc ^?! mcType . _McTurret . tuDir phasev = _phaseV . _itParams $ it dam = _lasDamage $ _itParams it -- | assumes that the item is held shootTeslaArc :: Item -> Creature -> World -> World shootTeslaArc it cr w = w' & cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix itRef . itParams .~ ip where itRef = cr ^?! crManipulation . manObject . inInventory . ispItem -- unsafe!! TODO change (w', ip) = makeTeslaArc (_itParams it) pos dir w pos = _crPos cr +.+ aimingMuzzleLength cr it *.* unitVectorAtAngle dir dir = _crDir cr -- I believe because the targeting returns to nothing straight after you release -- the rmb, it is possible for this to do nothing -- TODO investigate more and fix useForceFieldGun :: Item -> Creature -> World -> World useForceFieldGun itm cr w = fromMaybe w $ do a <- cr ^? crTargeting . ctPos . _Just let mwp = mouseWorldPos (w ^. input) (w ^. wCam) b = if dist a mwp < 100 then mwp else a +.+ 100 *.* normalizeV (mwp -.- a) wlline = (a, b) return $ w & cWorld . lWorld . walls %~ IM.insertWith (\_ x -> x) i forceField{_wlID = i} & cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itLocation itm)) . itParams . paramMID ?~ i & moveWallIDUnsafe i wlline where i = fromMaybe (IM.newKey (_walls (_lWorld (_cWorld w)))) $ itm ^? itParams . paramMID . _Just