Move towards working implementation of attachment tree ammo

This commit is contained in:
2024-09-14 10:44:35 +01:00
parent 51e133ebc1
commit cde7bc9aef
13 changed files with 496 additions and 351 deletions
+10
View File
@@ -103,6 +103,16 @@ invAdj = IM.unions . fmap (dtToUpDownAdj getid . ldtToDT) . invLDT
invIndentIM :: IM.IntMap Item -> IM.IntMap (Item,Int, LabelDoubleTreeNodeType ComposeLinkType )
invIndentIM = IM.fromAscList . zip [0..] . reverse . map (over _1 cisToItem) . concatMap ldtToIndentList . invLDT
--invTrees :: IM.IntMap Item -> [(LabelDoubleTree ComposeLinkType Item)]
invTrees :: IM.IntMap Item -> IM.IntMap (LabelDoubleTree ComposeLinkType Item)
--invTrees = map (ldtToIM getindex) . map (fmap cisToItem) . invLDT
--invTrees = map (ldtToIM getindex) . map (fmap cisToItem) . invLDT
invTrees = IM.unions . map (ldtToIM getindex) . map (fmap cisToItem) . invLDT
where
getindex :: Item -> Int
getindex i = fromMaybe (error "in invTrees try to get non-inventory item tree") $
i ^? itLocation . ipInvID
--indentInv :: IM.IntMap Item -> [String]
--indentInv = concat . fmap (flattenDT . indentDoubleTreeWith (' ':) ('|':) ('+':) . fmap const "")
-- . joinItemsInList joinItems
+2 -2
View File
@@ -74,8 +74,8 @@ import Picture
-- x' = _lasCycle $ _itParams it
shootLaser :: [Item] -> Item -> Creature -> World -> World
shootLaser _ it cr =
shootLaser :: Item -> Creature -> World -> World
shootLaser it cr =
cWorld . lWorld . lasers
.:~ lasRayAt
(_lasColor $ _itParams it)
+163 -150
View File
@@ -6,7 +6,7 @@ Weapon effects when pulling the trigger.
module Dodge.Item.Weapon.TriggerType (
useAmmoAmount,
useAllAmmo,
useAmmoUpTo,
-- useAmmoUpTo,
lockInvFor,
withFlare,
withMuzFlare,
@@ -61,6 +61,8 @@ module Dodge.Item.Weapon.TriggerType (
repeatTransformed,
) where
import Dodge.Data.ComposedItem
import Dodge.Data.DoubleTree
import Dodge.Creature.HandPos
import Data.Foldable
import Data.Maybe
@@ -79,31 +81,30 @@ import qualified SDL
import Sound.Data
type ChainEffect =
([Item] -> Item -> Creature -> World -> World) ->
[Item] ->
Item ->
(LabelDoubleTree ComposeLinkType Item -> Creature -> World -> World) ->
LabelDoubleTree ComposeLinkType Item ->
Creature ->
World ->
World
lockInvFor :: Int -> ChainEffect
lockInvFor i f ams it cr =
f ams it cr . (cWorld . lWorld . delayedEvents .:~ (i, UnlockInv (_crID cr)))
lockInvFor i f it cr =
f it cr . (cWorld . lWorld . delayedEvents .:~ (i, UnlockInv (_crID cr)))
. lockInv (_crID cr)
repeatTransformed ::
[(Item -> Item,Creature -> Creature)] ->
ChainEffect
repeatTransformed xs f ams itm cr w = foldr g w xs
repeatTransformed xs f itm cr w = foldr g w xs
where
g (fit,fcr) = f ams (fit itm) (fcr cr)
g (fit,fcr) = f (over ldtValue fit itm) (fcr cr)
trigDoAlso ::
(Item -> Item) ->
(Creature -> Creature) ->
(Item -> Creature -> World -> World) ->
ChainEffect
trigDoAlso fit fcr f g ams itm cr = g ams itm cr . f (fit itm) (fcr cr)
trigDoAlso fit fcr f g itm cr = g itm cr . f (fit $ itm ^. ldtValue) (fcr cr)
-- Note that this uses the "base" creature and item values
--trigDoAlso ::
@@ -112,8 +113,8 @@ trigDoAlso fit fcr f g ams itm cr = g ams itm cr . f (fit itm) (fcr cr)
--trigDoAlso afterEff eff item cr = afterEff item cr . eff item cr
withSmoke :: Int -> Point4 -> Float -> Int -> Float -> ChainEffect
withSmoke num col rad t alt eff ams item cr w =
eff ams item cr $
withSmoke num col rad t alt eff item cr w =
eff item cr $
foldl' (flip $ smokeCloudAt col rad t alt . (+.+.+ pos) . (* 8)) w ps
where
dir = _crDir cr
@@ -121,8 +122,8 @@ withSmoke num col rad t alt eff ams item cr w =
ps = replicateM num randOnUnitSphere & evalState $ _randGen w
withThinSmokeI :: ChainEffect
withThinSmokeI eff ams item cr w =
eff ams item cr $
withThinSmokeI eff item cr w =
eff item cr $
foldl' (flip $ makeThinSmokeAt . (+.+.+ pos) . (* 8)) w ps
where
dir = _crDir cr
@@ -130,8 +131,8 @@ withThinSmokeI eff ams item cr w =
ps = replicateM 5 randOnUnitSphere & evalState $ _randGen w
withThickSmokeI :: ChainEffect
withThickSmokeI eff ams item cr w =
eff ams item cr $
withThickSmokeI eff item cr w =
eff item cr $
foldl' (flip $ makeThickSmokeAt . (+.+.+ pos) . (* 8)) w ps
where
dir = _crDir cr
@@ -141,13 +142,13 @@ withThickSmokeI eff ams item cr w =
-- TODO create a trigger that does different things on first and continued
-- fire.
ammoCheckI :: ChainEffect
ammoCheckI eff ams itm cr w = fromMaybe (failsound w) $ do
x <- ams ^? ix 0 . itUse . amagLoadStatus . iaLoaded
ammoCheckI eff itm cr w = fromMaybe (failsound w) $ do
atype <- itm ^? ldtValue . itUse . heldAmmoTypes . ix 0
leftitms <- itm ^? ldtLeft
mag <- lookup (AmmoInLink atype) leftitms
x <- mag ^? ldtValue . itUse . amagLoadStatus . iaLoaded
guard $ x > 0
matype <- ams ^? ix 0 . itUse . amagType
iatype <- itm ^? itUse . heldAmmoTypes . ix 0
guard $ matype == iatype
return $ eff ams itm cr $ w -- & cWorld . lWorld . creatures . ix (_crID cr) %~ crCancelReloading
return $ eff itm cr $ w -- & cWorld . lWorld . creatures . ix (_crID cr) %~ crCancelReloading
where
failsound = case w ^? input . mouseButtons . ix SDL.ButtonLeft of
Just 0 -> soundStart (CrWeaponSound (_crID cr) 0) (_crPos cr) click1S Nothing
@@ -169,7 +170,7 @@ rateIncAB ::
-- | Extra effect on continued fire
ChainEffect ->
ChainEffect
rateIncAB exeffFirst exeffCont eff ams item cr w
rateIncAB exeffFirst exeffCont eff item cr w
| repeatFire =
w
& pointItem
@@ -177,7 +178,7 @@ rateIncAB exeffFirst exeffCont eff ams item cr w
-- . itUseAmmo 1
. (itUse . heldDelay . rateTime .~ currentRate)
)
& exeffCont eff ams item cr
& exeffCont eff item cr
| firstFire =
w
& pointItem
@@ -185,17 +186,18 @@ rateIncAB exeffFirst exeffCont eff ams item cr w
-- . itUseAmmo 1
. (itUse . heldDelay . rateTime .~ startRate)
)
& exeffFirst eff ams item cr
& exeffFirst eff item cr
| otherwise = w
where
fastRate = _rateMinMax . _heldDelay $ _itUse item
startRate = _rateMaxMax . _heldDelay $ _itUse item
item' = _ldtValue item
fastRate = _rateMinMax . _heldDelay $ _itUse item'
startRate = _rateMaxMax . _heldDelay $ _itUse item'
cid = _crID cr
itRef = cr ^?! crManipulation . manObject . inInventory . ispItem -- unsafe!! TODO change
pointItem = cWorld . lWorld . creatures . ix cid . crInv . ix itRef
currentRate = _rateMax (_heldDelay (_itUse item))
repeatFire = crWeaponReady cr && _rateTime (_heldDelay (_itUse item)) == 1
firstFire = crWeaponReady cr && _rateTime (_heldDelay (_itUse item)) == 0
currentRate = _rateMax (_heldDelay (_itUse item'))
repeatFire = crWeaponReady cr && _rateTime (_heldDelay (_itUse item')) == 1
firstFire = crWeaponReady cr && _rateTime (_heldDelay (_itUse item')) == 0
-- | Apply effect after a warm up.
@@ -204,7 +206,7 @@ withWarmUp ::
-- | warm up sound id
SoundID ->
ChainEffect
withWarmUp soundID f ams item cr w
withWarmUp soundID f item cr w
| curWarmUp < maxWarmUp && crWeaponReady cr =
w
& pointertoitem . itUse . heldDelay . warmTime +~ 2
@@ -212,24 +214,25 @@ withWarmUp soundID f ams item cr w
| otherwise =
w
& pointertoitem . itUse . heldDelay . warmTime .~ maxWarmUp
& f ams item cr
& f item cr
where
item' = _ldtValue item
cid = _crID cr
itRef = cr ^?! crManipulation . manObject . inInventory . ispItem -- unsafe!! TODO change
pointertoitem = cWorld . lWorld . creatures . ix cid . crInv . ix itRef
curWarmUp = _warmTime . _heldDelay $ _itUse item
maxWarmUp = _warmMax . _heldDelay $ _itUse item
curWarmUp = _warmTime . _heldDelay $ _itUse item'
maxWarmUp = _warmMax . _heldDelay $ _itUse item'
withSoundItemChoiceStart ::
(Item -> SoundID) ->
ChainEffect
withSoundItemChoiceStart soundf f ams it cr =
withSoundItemChoiceStart soundf f it cr =
soundMultiFrom
[CrWeaponSound cid 0, CrWeaponSound cid 1, CrWeaponSound cid 2]
(_crPos cr)
(soundf it)
(soundf $ _ldtValue it)
Nothing
. f ams it cr
. f it cr
where
cid = _crID cr
@@ -240,9 +243,9 @@ withSoundStart ::
-- | Sound id
SoundID ->
ChainEffect
withSoundStart soundid f ams item cr =
withSoundStart soundid f item cr =
soundMultiFrom [CrWeaponSound cid j | j <- [0..3]] (_crPos cr) soundid Nothing
. f ams item cr
. f item cr
where
cid = _crID cr
@@ -253,9 +256,9 @@ withSoundContinue ::
-- | Sound id
SoundID ->
ChainEffect
withSoundContinue soundid f ams item cr =
withSoundContinue soundid f item cr =
soundContinue (CrWeaponSound cid 0) (_crPos cr) soundid Nothing
. f ams item cr
. f item cr
where
cid = _crID cr
@@ -268,9 +271,9 @@ withSoundForI ::
-- | Frames to play
Int ->
ChainEffect
withSoundForI soundid playTime f ams item cr =
withSoundForI soundid playTime f item cr =
soundContinue (CrWeaponSound (_crID cr) 0) (_crPos cr) soundid (Just playTime)
. f ams item cr
. f item cr
{- | Adds a sound to a creature based world effect.
The sound is emitted from the creature's position.
@@ -283,24 +286,24 @@ withSoundForVol ::
-- | Frames to play
Int ->
ChainEffect
withSoundForVol vol soundid playTime f ams item cr =
withSoundForVol vol soundid playTime f item cr =
soundContinueVol vol (CrWeaponSound (_crID cr) 0) (_crPos cr) soundid (Just playTime)
. f ams item cr
. f item cr
afterRecoil ::
-- | Recoil amount
Float ->
ChainEffect
afterRecoil recoilAmount eff ams item cr = eff ams item (pushback cr) . over (cWorld . lWorld . creatures . ix cid) pushback
afterRecoil recoilAmount eff item cr = eff item (pushback cr) . over (cWorld . lWorld . creatures . ix cid) pushback
where
cid = _crID cr
pushback = over crPos (+.+ rotateV (_crDir cr) (V2 ((- recoilAmount) / _crMass cr) 0))
withRecoil :: ChainEffect
withRecoil eff ams it cr = eff ams it cr . over (cWorld . lWorld . creatures . ix cid) pushback
withRecoil eff it cr = eff it cr . over (cWorld . lWorld . creatures . ix cid) pushback
where
cid = _crID cr
recoilAmount = fromMaybe 0 $ it ^? itUse . heldParams . recoil
recoilAmount = fromMaybe 0 $ it ^? ldtValue . itUse . heldParams . recoil
pushback = over crPos (+.+ rotateV (_crDir cr) (V2 ((- recoilAmount) / _crMass cr) 0))
{- | Pushes a creature sideways by a random amount.
@@ -310,8 +313,8 @@ withSidePushI ::
-- | Maximal possible side push amount
Float ->
ChainEffect
withSidePushI maxSide eff ams item cr w =
eff ams item (push cr) $
withSidePushI maxSide eff item cr w =
eff item (push cr) $
w
& cWorld . lWorld . creatures . ix cid %~ push
& randGen .~ g
@@ -329,8 +332,8 @@ withSidePushAfterI ::
-- | Maximal possible side push amount
Float ->
ChainEffect
withSidePushAfterI maxSide eff ams item cr w =
over (cWorld . lWorld . creatures . ix cid) push . eff ams item cr $
withSidePushAfterI maxSide eff item cr w =
over (cWorld . lWorld . creatures . ix cid) push . eff item cr $
w
& randGen .~ g
where
@@ -339,27 +342,32 @@ withSidePushAfterI maxSide eff ams item cr w =
(pushAmount, g) = randomR (- maxSide, maxSide) $ _randGen w
useAllAmmo :: ChainEffect
useAllAmmo eff ams item cr w = fromMaybe w $ do
let invids = ams ^.. traverse . itLocation . ipInvID
return . eff ams item cr $ foldl' f w invids
where
f w' invid = w' & cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix invid
. itUse . amagLoadStatus . iaLoaded .~ 0
useAllAmmo eff item cr w = error "use all ammo"
--useAllAmmo eff ams item cr w = fromMaybe w $ do
-- let invids = ams ^.. traverse . itLocation . ipInvID
-- return . eff ams item cr $ foldl' f w invids
-- where
-- f w' invid = w' & cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix invid
-- . itUse . amagLoadStatus . iaLoaded .~ 0
useAmmoUpTo :: Int -> ChainEffect
useAmmoUpTo amAmount eff ams itm cr = fromMaybe id $ do
_ <- ams ^? ix 0 . itUse . amagLoadStatus . iaLoaded
invid <- ams ^? ix 0 . itLocation . ipInvID
return $ eff ams itm cr
. ( cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix invid . itUse . amagLoadStatus . iaLoaded
%~ (max 0 . subtract amAmount)
)
--useAmmoUpTo :: Int -> ChainEffect
--useAmmoUpTo amAmount eff ams itm cr = fromMaybe id $ do
-- _ <- ams ^? ix 0 . itUse . amagLoadStatus . iaLoaded
-- invid <- ams ^? ix 0 . itLocation . ipInvID
-- return $ eff ams itm cr
-- . ( cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix invid . itUse . amagLoadStatus . iaLoaded
-- %~ (max 0 . subtract amAmount)
-- )
useAmmoAmount :: Int -> ChainEffect
useAmmoAmount amAmount eff ams item cr = fromMaybe id $ do
invid <- ams ^? ix 0 . itLocation . ipInvID
return $ eff ams item cr
. (cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix invid . itUse . amagLoadStatus . iaLoaded -~ amAmount)
useAmmoAmount amAmount eff item cr = fromMaybe id $ do
atype <- item ^? ldtValue . itUse . heldAmmoTypes . ix 0
leftitms <- item ^? ldtLeft
mag <- lookup (AmmoInLink atype) leftitms
magid <- mag ^? ldtValue . itLocation . ipInvID
-- invid <- ams ^? ix 0 . itLocation . ipInvID
return $ eff item cr
. (cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix magid . itUse . amagLoadStatus . iaLoaded -~ amAmount)
-- . crInv . ix itRef . itUse . heldConsumption . laSource
@@ -367,19 +375,19 @@ useAmmoAmount amAmount eff ams item cr = fromMaybe id $ do
Applies a world effect after an item use cooldown check.
-}
useTimeCheck :: ChainEffect
useTimeCheck f ams item cr w = case item ^? itUse . heldDelay . rateTime of
Just 0 -> f ams item cr $ setUseTime w
useTimeCheck f item cr w = case item ^? ldtValue . itUse . heldDelay . rateTime of
Just 0 -> f item cr $ setUseTime w
_ -> w
where
cid = _crID cr
setUseTime = cWorld . lWorld . creatures . ix cid . crInv . ix itRef . itUse . heldDelay . rateTime +~ userate
itRef = cr ^?! crManipulation . manObject . inInventory . ispItem -- unsafe!! TODO change
userate = fromMaybe 0 $ item ^? itUse . heldDelay . rateMax
userate = fromMaybe 0 $ item ^? ldtValue . itUse . heldDelay . rateMax
-- | Applies a world effect after a hammer position check.
blCheck :: ChainEffect
blCheck f ams it cr w = case w ^? input . mouseButtons . ix SDL.ButtonLeft of
Just 0 -> f ams it cr w
blCheck f it cr w = case w ^? input . mouseButtons . ix SDL.ButtonLeft of
Just 0 -> f it cr w
_ -> w
{- | Applies a world effect after a hammer position check.
@@ -423,56 +431,56 @@ shootL f item cr w
-- reloadCondition = _laLoaded (_itConsumption item) == 0
withItem :: (Item -> ChainEffect) -> ChainEffect
withItem g f ams it = g it f ams it
withItem g f it = g (_ldtValue it) f it
-- not ideal
withItemUpdateFirst :: (Item -> Item) -> ChainEffect
withItemUpdateFirst up f ams it cr = f ams (up it) cr . (cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix itRef %~ up)
withItemUpdateFirst up f it cr = f (over ldtValue up it) cr . (cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix itRef %~ up)
where
itRef = cr ^?! crManipulation . manObject . inInventory . ispItem -- unsafe!! TODO change
withItemUpdate :: (Item -> Item) -> (Item -> ChainEffect) -> ChainEffect
withItemUpdate up g f ams it cr = g it f ams it cr . (cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix itRef %~ up)
withItemUpdate up g f it cr = g (_ldtValue it) f it cr . (cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix itRef %~ up)
where
itRef = cr ^?! crManipulation . manObject . inInventory . ispItem -- unsafe!! TODO change
withTempLight :: Int -> Float -> V3 Float -> ChainEffect
withTempLight time rad col eff ams item cr =
eff ams item cr
withTempLight time rad col eff item cr =
eff item cr
. over (cWorld . lWorld . tempLightSources) (theTLS :)
where
theTLS = tlsTimeRadColPos time rad col (V3 x y 10)
V2 x y = _crPos cr +.+ 15 *.* unitVectorAtAngle (_crDir cr)
modClock :: Int -> ChainEffect -> ChainEffect
modClock n chainEff eff ams it cr w
| (w ^. cWorld . lWorld . lClock) `mod` n == 0 = chainEff eff ams it cr w
| otherwise = eff ams it cr w
modClock n chainEff eff it cr w
| (w ^. cWorld . lWorld . lClock) `mod` n == 0 = chainEff eff it cr w
| otherwise = eff it cr w
withFlare :: ChainEffect
withFlare f ams it cr =
withFlare f it cr =
makeTlsTimeRadColPos 2 100 (V3 1 1 0.5) (cpos `v2z` 20)
-- . muzFlareAt (V4 5 5 0 2) (cpos `v2z` 20) cdir
. muzFlareAt (V4 10 10 1 3) (cpos `v2z` 20) cdir
. muzFlareAt (V4 10 10 1 3) (cpos `v2z` 20) cdir
. muzFlareAt (V4 10 10 1 3) (cpos `v2z` 20) cdir
. f ams it cr
. f it cr
where
cdir = _crDir cr
cpos = _crPos cr
withMuzFlare :: ChainEffect
withMuzFlare f ams itm cr =
withMuzFlare f itm cr =
makeTlsTimeRadColPos 2 100 (V3 1 1 0.5) (cpos `v2z` 20)
-- . muzFlareAt (V4 5 5 0 2) (cpos `v2z` 20) cdir
. muzFlareAt (V4 10 10 1 3) (cpos `v2z` 20) cdir
. muzFlareAt (V4 10 10 1 3) (cpos `v2z` 20) cdir
. muzFlareAt (V4 10 10 1 3) (cpos `v2z` 20) cdir
. f ams itm cr
. f itm cr
where
cdir = _crDir cr
cpos = _crPos cr + rotateV (_crDir cr) (_mzPos brl + aimingWeaponZeroPos cr itm)
brl = itm ^?! itUse . heldAim . aimMuzzles . ix 0
cpos = _crPos cr + rotateV (_crDir cr) (_mzPos brl + aimingWeaponZeroPos cr (_ldtValue itm))
brl = itm ^?! ldtValue . itUse . heldAim . aimMuzzles . ix 0
--muzzleOffset :: Creature -> Item -> Point3
--muzzleOffset cr it = V3 (holdOffset + 5 + _aimMuzPos dimPort - _aimHandlePos dimPort) 0 0
@@ -486,7 +494,7 @@ withCrPos :: (Point3 -> World -> World) -> ChainEffect
withCrPos = withCrPosShift (V2 0 0)
withCrPosShift :: Point2 -> (Point3 -> World -> World) -> ChainEffect
withCrPosShift p g f ams it cr = g thepos . f ams it cr
withCrPosShift p g f it cr = g thepos . f it cr
where
thepos = (_crPos cr +.+ rotateV (_crDir cr) p) `v2z` 20
@@ -495,7 +503,7 @@ withRandomDirI ::
-- | Max possible rotation
Float ->
ChainEffect
withRandomDirI acc f ams it cr w = f ams it (cr & crDir +~ a) $ set randGen g w
withRandomDirI acc f it cr w = f it (cr & crDir +~ a) $ set randGen g w
where
(a, g) = randomR (- acc, acc) $ _randGen w
@@ -503,73 +511,73 @@ withOldDir ::
-- | The fraction of the old direction
Float ->
ChainEffect
withOldDir aFrac eff ams item cr =
eff ams item (cr & crDir %~ tweenAngles aFrac (_crOldDir cr))
withOldDir aFrac eff item cr =
eff item (cr & crDir %~ tweenAngles aFrac (_crOldDir cr))
withRandomItemUpdate ::
State StdGen (Item -> Item) ->
ChainEffect
withRandomItemUpdate randItUp eff ams it cr w = eff ams (f it) cr $ w & randGen .~ g
withRandomItemUpdate randItUp eff it cr w = eff (over ldtValue f it) cr $ w & randGen .~ g
where
(f, g) = runState randItUp (_randGen w)
withRandomItemParams :: State StdGen (ItemParams -> ItemParams) -> ChainEffect
withRandomItemParams rip eff ams it cr w = eff ams (it & itParams %~ f) cr $ w & randGen .~ g
withRandomItemParams rip eff it cr w = eff (it & ldtValue . itParams %~ f) cr $ w & randGen .~ g
where
(f, g) = runState rip (_randGen w)
withRandomItem :: State StdGen (Item -> Item) -> ChainEffect
withRandomItem rip eff ams it cr w = eff ams (f it) cr $ w & randGen .~ g
withRandomItem rip eff it cr w = eff (over ldtValue f it) cr $ w & randGen .~ g
where
(f, g) = runState rip (_randGen w)
withPositionOffset ::
(Item -> Creature -> World -> (Point2, Float)) ->
ChainEffect
withPositionOffset h f ams it cr w = f ams it (cr & crPos .+.+~ p & crDir +~ a) w
withPositionOffset h f it cr w = f it (cr & crPos .+.+~ p & crDir +~ a) w
where
(p, a) = h it cr w
(p, a) = h (_ldtValue it) cr w
withPositionWallCheck ::
(Item -> Creature -> World -> Point2) ->
ChainEffect
withPositionWallCheck h f ams it cr w
| hasLOS p (_crPos cr) w = f ams it (cr & crPos .~ p) w
withPositionWallCheck h f it cr w
| hasLOS p (_crPos cr) w = f it (cr & crPos .~ p) w
| otherwise = w
where
p = h it cr w
p = h (_ldtValue it) cr w
withPosDirWallCheck ::
(Item -> Creature -> World -> (Point2, Float)) ->
ChainEffect
withPosDirWallCheck h f ams it cr w
| hasLOS p (_crPos cr) w = f ams it (cr & crPos .~ p & crDir .~ a) w
withPosDirWallCheck h f it cr w
| hasLOS p (_crPos cr) w = f it (cr & crPos .~ p & crDir .~ a) w
| otherwise = w
where
(p, a) = h it cr w
(p, a) = h (_ldtValue it) cr w
-- | Apply the effect to a translated creature.
withRandomOffset :: ChainEffect
withRandomOffset f ams item cr w = f ams item (cr & crPos %~ (+.+ offV)) $ set randGen g w
withRandomOffset f item cr w = f item (cr & crPos %~ (+.+ offV)) $ set randGen g w
where
(offsetVal, g) = randomR (- offsetAmount, offsetAmount) $ _randGen w
offV = rotateV (_crDir cr) (V2 0 offsetVal)
offsetAmount = fromMaybe 0 $ item ^? itUse . heldParams . randomOffset
offsetAmount = fromMaybe 0 $ item ^? ldtValue . itUse . heldParams . randomOffset
-- | Rotates a creature
torqueBefore ::
-- | Max possible rotation
Float ->
ChainEffect
torqueBefore torque feff ams item cr w
torqueBefore torque feff item cr w
| cid == 0 =
feff ams item (cr & crDir +~ rot) $
feff item (cr & crDir +~ rot) $
w
& randGen .~ g
& cWorld . lWorld . creatures . ix cid . crDir +~ rot
& wCam . camRot +~ rot
& rotateScope
| otherwise = feff ams item cr $ set randGen g $ over (cWorld . lWorld . creatures . ix cid . crDir) (+ rot) w
| otherwise = feff item cr $ set randGen g $ over (cWorld . lWorld . creatures . ix cid . crDir) (+ rot) w
where
cid = _crID cr
(rot, g) = randomR (- torque, torque) $ _randGen w
@@ -586,15 +594,15 @@ torqueBeforeAtLeast ::
-- | Extra possible rotation
Float ->
ChainEffect
torqueBeforeAtLeast minTorque exTorque feff ams item cr w
torqueBeforeAtLeast minTorque exTorque feff item cr w
| cid == 0 =
feff ams item (cr & crDir +~ rot') $
feff item (cr & crDir +~ rot') $
w
& randGen .~ g
& cWorld . lWorld . creatures . ix cid . crDir +~ rot'
& wCam . camRot +~ rot'
& rotateScope
| otherwise = feff ams item cr $ set randGen g $ over (cWorld . lWorld . creatures . ix cid . crDir) (+ rot') w
| otherwise = feff item cr $ set randGen g $ over (cWorld . lWorld . creatures . ix cid . crDir) (+ rot') w
where
cid = _crID cr
(rot, g) = randomR (- exTorque, exTorque) $ _randGen w
@@ -607,11 +615,11 @@ torqueBeforeAtLeast minTorque exTorque feff ams item cr w
-- | Rotate a randomly creature after applying an effect.
withTorqueAfter :: ChainEffect
withTorqueAfter feff ams item cr w
withTorqueAfter feff item cr w
-- | cid == 0 = rotateScope . set randGen g $ over (wCam . camRot) (+ rot) $ feff item cr w
-- | otherwise = set randGen g $ over (cWorld . lWorld . creatures . ix cid . crDir) (+ rot) $ feff item cr w
| cid == 0 = w
& feff ams item cr
& feff item cr
& wCam . camRot +~ rot
& rotateScope
& randGen .~ g
@@ -621,7 +629,7 @@ withTorqueAfter feff ams item cr w
where
cid = _crID cr
(rot, g) = randomR (- torque, torque) $ _randGen w
torque = fromMaybe 0 $ item ^? itUse . heldParams . torqueAfter
torque = fromMaybe 0 $ item ^? ldtValue . itUse . heldParams . torqueAfter
rotateScope = fromMaybe id $ do
i <- yourScopeInvID w
return $ cWorld . lWorld . creatures . ix cid . crInv . ix i . itUse . attachParams . scrollAttachParams . opticPos %~ rotateV rot
@@ -631,9 +639,9 @@ sideEffectOnFrame ::
Int ->
(Item -> Creature -> WdWd) ->
ChainEffect
sideEffectOnFrame i sf f ams it cr w =
f ams it cr w
& cWorld . lWorld . delayedEvents .:~ (i, sf it cr)
sideEffectOnFrame i sf f it cr w =
f it cr w
& cWorld . lWorld . delayedEvents .:~ (i, sf (_ldtValue it) cr)
torqueSideEffect :: Float -> Item -> Creature -> World -> World
torqueSideEffect torque _ cr w
@@ -649,10 +657,10 @@ torqueSideEffect torque _ cr w
-- pump the updated creature into the chain in later frames
repeatOnFrames :: [Int] -> HeldMod -> ChainEffect
--repeatOnFrames is hm f it cr w = f it cr w
repeatOnFrames is hm f ams it cr w =
f ams it cr $
repeatOnFrames is hm f it cr w =
f it cr $
w
& cWorld . lWorld . delayedEvents .++~ (is <&> (,WdWdFromItCrixWdWd (it & itUse . heldMods .~ hm) (_crID cr) ItCrWdItemEffect))
& cWorld . lWorld . delayedEvents .++~ (is <&> (,WdWdFromItCrixWdWd (it & ldtValue . itUse . heldMods .~ hm) (_crID cr) ItCrWdItemEffect))
-- where
-- f' = fromMaybe w' $ do
@@ -660,42 +668,47 @@ repeatOnFrames is hm f ams it cr w =
-- return $ f it cr' w'
duplicateLoaded :: ChainEffect
duplicateLoaded eff ams it cr w = foldr f w (take numbul [1::Int .. ])
where
f _ = eff ams it cr
numbul = fromMaybe 0 $ do
i <- ams ^? ix 0 . itLocation . ipInvID
cr ^? crInv . ix i . itUse . amagLoadStatus . iaLoaded
duplicateLoaded eff it cr w = error "duplicateLoaded"
--duplicateLoaded :: ChainEffect
--duplicateLoaded eff ams it cr w = foldr f w (take numbul [1::Int .. ])
-- where
-- f _ = eff ams it cr
-- numbul = fromMaybe 0 $ do
-- i <- ams ^? ix 0 . itLocation . ipInvID
-- cr ^? crInv . ix i . itUse . amagLoadStatus . iaLoaded
duplicateNumBarrels :: Int -> ChainEffect
duplicateNumBarrels n eff ams itm cr w = foldr f w (take n $ itm ^?! itUse . heldAim . aimMuzzles)
where
f brl w' =
eff ams
itm
( cr & crPos +~ rotateV (_crDir cr) (_mzPos brl + aimingWeaponZeroPos cr itm)
& crDir +~ (_mzRot brl + a)
)
(w' & randGen .~ g)
where
inacc = _mzInaccuracy brl
(a,g) = randomR (-inacc,inacc) $ _randGen w'
duplicateNumBarrels n eff itm cr w = error "duplicateNumBarrels"
--duplicateNumBarrels :: Int -> ChainEffect
--duplicateNumBarrels n eff ams itm cr w = foldr f w (take n $ itm ^?! itUse . heldAim . aimMuzzles)
-- where
-- f brl w' =
-- eff ams
-- itm
-- ( cr & crPos +~ rotateV (_crDir cr) (_mzPos brl + aimingWeaponZeroPos cr itm)
-- & crDir +~ (_mzRot brl + a)
-- )
-- (w' & randGen .~ g)
-- where
-- inacc = _mzInaccuracy brl
-- (a,g) = randomR (-inacc,inacc) $ _randGen w'
duplicateLoadedBarrels :: ChainEffect
duplicateLoadedBarrels eff ams itm cr = duplicateNumBarrels numbul eff ams itm cr
where
numbul :: Int
numbul = fromMaybe 0 $ do
i <- ams ^? ix 0 . itLocation . ipInvID
cr ^? crInv . ix i . itUse . amagLoadStatus . iaLoaded
duplicateLoadedBarrels eff itm cr = error "duplicateLoadedBarrels"
-- = duplicateNumBarrels numbul eff ams itm cr
-- where
-- numbul :: Int
-- numbul = fromMaybe 0 $ do
-- i <- ams ^? ix 0 . itLocation . ipInvID
-- cr ^? crInv . ix i . itUse . amagLoadStatus . iaLoaded
duplicateOffsetsFocus :: [Float] -> ChainEffect
duplicateOffsetsFocus xs eff ams item cr w = foldr f w poss
duplicateOffsetsFocus xs eff item cr w = foldr f w poss
where
poss :: [V2 Float]
poss = map (rotateV (_crDir cr) . V2 0) xs
f pos =
eff ams item $
eff item $
cr
& crPos %~ (+.+ pos)
& crDir .~ thedir pos
@@ -709,12 +722,12 @@ duplicateOffsetsFocus xs eff ams item cr w = foldr f w poss
thedir pos = argV (mouseWorldPos (w ^. input) (w ^. wCam) -.- (_crPos cr +.+ pos))
duplicateItem :: (Item -> [Item]) -> ChainEffect
duplicateItem fit eff ams itm cr w = foldr f w (fit itm)
duplicateItem fit eff itm cr w = foldr f w (ldtValue fit itm)
where
f itm' = eff ams itm' cr
f itm' = eff itm' cr
duplicateOffsetsV2 :: [Point2] -> ChainEffect
duplicateOffsetsV2 xs eff ams item cr w = foldr f w poss
duplicateOffsetsV2 xs eff item cr w = foldr f w poss
where
poss = map (rotateV (_crDir cr)) xs
f pos = eff ams item (cr & crPos +.+.~ pos)
f pos = eff item (cr & crPos +.+.~ pos)