Implement pulse rifle with explodable pulse balls

This commit is contained in:
2025-07-27 11:10:30 +01:00
parent 68a4bc7aab
commit f1fb0ee768
19 changed files with 190 additions and 108 deletions
+19 -22
View File
@@ -135,11 +135,9 @@ heldEffectMuzzles loc cr w =
setusetime . doHeldUseEffect t cr
. uncurry (applyCME loc cr)
$ bw
-- . foldl' (useLoadedAmmo loc cr) (bw)
-- $ loadedmuzzles
where
t = loc ^. locDT
((bw,_), loadedmuzzles) = mapAccumR (loadMuzzle loc cr) ((False,w),t) . locMuzzles $ loc
bw = foldl' (loadMuzzle loc cr) (False,w) (locMuzzles loc)
setusetime =
cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix itid . itTimeLastUsed
.~ w ^. cWorld . lWorld . lClock
@@ -153,10 +151,11 @@ locMuzzles loc
& ix 0 . mzInaccuracy .~ 0
& ix 0 . mzFlareType .~ TeslaGunFlare
& ix 0 . mzEffect .~ MuzzlePulseLaser
& ix 0 . mzAmmoPerShot .~ UseExactly 250
& ix 0 . mzAmmoPerShot .~ UseExactly 200
& ix 0 . mzAmmoSlot .~ CapacitorBelow
| PulseBallSF <- loc ^. locDT . dtValue . _2 = dbwMuzzles
& ix 0 . mzEffect .~ MuzzlePulseBall
& ix 0 . mzAmmoPerShot .~ UseExactly 250
& ix 0 . mzAmmoPerShot .~ UseExactly 200
& ix 0 . mzAmmoSlot .~ CapacitorSelf
& ix 0 . mzInaccuracy .~ 0
& ix 0 . mzFlareType .~ TeslaGunFlare
@@ -642,26 +641,24 @@ heldTorqueAmount = \case
BLINKER -> 0
BLINKERUNSAFE -> 0
loadMuzzle :: LocationDT OItem -> Creature -> ((Bool,World),DTree OItem)
-> Muzzle -> (((Bool,World),DTree OItem), Maybe (Muzzle, Int, DTree OItem))
loadMuzzle loc cr ((b,w),t@(DT _ l _)) mz = fromMaybe (((b,w),t), Nothing) $ do
loadMuzzle :: LocationDT OItem -> Creature -> (Bool,World) -> Muzzle -> (Bool,World)
loadMuzzle loc cr (b,w) mz = fromMaybe (b,w) $ do
let as = _mzAmmoSlot mz
amamount = _mzAmmoPerShot mz
(i, mag) <- case as of
MagBelow mi -> findWithIx (isAmmoIntLink mi . (^. dtValue . _2)) l
_ -> undefined
availableammo <- mag ^. dtValue . _1 . itConsumables
mag <- case as of
MagBelow mi -> find (isAmmoIntLink mi . (^. dtValue . _2)) (loc ^. locDT . dtLeft)
CapacitorSelf -> loc ^? locDT
CapacitorBelow -> find
((== PulseBallSF) . (^. dtValue . _2)) (loc ^. locDT . dtLeft)
mid <- mag ^? dtValue . _1 . itLocation . ilInvID
availableammo <- w ^? cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix mid . itConsumables . _Just
let usedammo = case amamount of
UseUpTo x -> min x availableammo
UseExactly x
| x <= availableammo -> x
| otherwise -> 0
guard $ usedammo > 0
let bw = useLoadedAmmo loc cr (b,w) (Just (mz,usedammo,mag))
return
( (bw,t & dtLeft . ix i . dtValue . _1 . itConsumables . _Just -~ usedammo)
, Just (mz, usedammo, mag)
)
return $ useLoadedAmmo loc cr (b,w) (Just (mz,usedammo,mag))
makeMuzzleFlare :: Muzzle -> LocationDT OItem -> Creature -> World -> World
makeMuzzleFlare mz loc cr = case mz ^. mzFlareType of
@@ -796,9 +793,9 @@ itemDetectorEffect itm mitid armitid cr w = fromMaybe w $ do
DETECTOR dt <- itm ^? itType
return $ aRadarPulse (itm ^. itID) mitid armitid (f dt) cr w
where
f ITEMDETECTOR = ObItem
f CREATUREDETECTOR = ObCreature
f WALLDETECTOR = ObWall
f ITEMDETECTOR = OTItem
f CREATUREDETECTOR = OTCreature
f WALLDETECTOR = OTWall
walkNozzle :: Muzzle -> Item -> Creature -> World -> World
walkNozzle mz itm cr w = fromMaybe w $ do
@@ -936,8 +933,8 @@ shootPulseBall p dir w =
& cWorld . lWorld . pulseBalls . at i ?~
PulseBall
{ _pbPos = p
, _pbVel = 5 * unitVectorAtAngle dir
, _pbTimer = 50
, _pbVel = 3.5 * unitVectorAtAngle dir
, _pbTimer = 100
, _pbID = i
}
& soundStart (PBSound i) p energyReleaseS Nothing