refactor: pass creature to weapon use function, as opposed to just id

This commit is contained in:
2021-05-23 22:07:46 +02:00
parent 3ae454acf4
commit cda035b1d1
11 changed files with 235 additions and 219 deletions
+2 -2
View File
@@ -84,7 +84,7 @@ autoRadarEffect :: ItEffect
autoRadarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 }
where
f :: Int -> Creature -> Int -> World -> World
f 0 cr i w = aRadarPulse (_crID cr) w
f 0 cr i w = aRadarPulse cr w
& creatures . ix (_crID cr) . crInv . ix i
. itEffect . itInvEffect .~ f 100
f t cr i w = w
@@ -96,7 +96,7 @@ autoSonarEffect :: ItEffect
autoSonarEffect = ItInvEffect {_itInvEffect = f 50 ,_itEffectCounter = 0 }
where
f :: Int -> Creature -> Int -> World -> World
f 0 cr i w = aSonarPulse (_crID cr)
f 0 cr i w = aSonarPulse cr
w & creatures . ix (_crID cr) . crInv . ix i
. itEffect . itInvEffect .~ f 140
f t cr i w = w & creatures . ix (_crID cr) . crInv . ix i
+3 -3
View File
@@ -57,11 +57,12 @@ grenadePic x = pictures
throwGrenade
:: (Point2 -> World -> World) -- ^ Payload
-> Int -- ^ Creature id
-> Creature
-> World
-> World
throwGrenade explosion n w = setWp $ removePict $ over projectiles addG w
throwGrenade explosion cr w = setWp $ removePict $ over projectiles addG w
where
n = _crID cr
addG = IM.insert i $ Shell
{ _pjPos = p
, _pjStartPos = p
@@ -71,7 +72,6 @@ throwGrenade explosion n w = setWp $ removePict $ over projectiles addG w
, _pjUpdate = moveGrenade fuseTime dir i
, _pjPayload = explosion
}
cr = _creatures w IM.! n
j = _crInvSel cr
removePict = set (creatures . ix n . crInv . ix j . itEquipPict) $ \ _ _ -> blank
i = newProjectileKey w
+3 -3
View File
@@ -23,13 +23,13 @@ import Data.Maybe (fromMaybe)
import qualified Data.Sequence as Seq
import qualified Data.IntMap.Strict as IM
aLaser :: Int -> World -> World
aLaser cid w = over particles (makeLaserAt phaseV pos dir (Just cid) : )
aLaser :: Creature -> World -> World
aLaser cr w = over particles (makeLaserAt phaseV pos dir (Just cid) : )
$ soundFrom LasSound 24 1 0
$ laserGunFlashAt (pos +.+ 5 *.* unitVectorAtAngle dir)
w
where
cr = _creatures w IM.! cid
cid = _crID cr
pos = _crPos cr +.+ ((_crRad cr +3) *.* unitVectorAtAngle dir)
dir = _crDir cr
phaseV = charToPhaseV
+111 -103
View File
@@ -19,25 +19,23 @@ import Data.Maybe
import qualified Data.IntMap.Strict as IM
withThinSmoke
:: (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
:: (Creature -> World -> World) -- ^ Underlying effect
-> Creature
-> World
-> World
withThinSmoke eff cid w = eff cid $ foldr (makeThinSmokeAt . (+.+ pos)) w ps
withThinSmoke eff cr w = eff cr $ foldr (makeThinSmokeAt . (+.+ pos)) w ps
where
cr = _creatures w IM.! cid
dir = _crDir cr
pos = _crPos cr +.+ (_crRad cr +0.5) *.* unitVectorAtAngle dir
ps = (replicateM 5 . randInCirc) 8 & evalState $ _randGen w
withThickSmoke
:: (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
:: (Creature -> World -> World) -- ^ Underlying effect
-> Creature
-> World
-> World
withThickSmoke eff cid w = eff cid $ foldr (makeThickSmokeAt . (+.+ pos)) w ps
withThickSmoke eff cr w = eff cr $ foldr (makeThickSmokeAt . (+.+ pos)) w ps
where
cr = _creatures w IM.! cid
dir = _crDir cr
pos = _crPos cr +.+ (_crRad cr + 15) *.* unitVectorAtAngle dir
ps = (replicateM 20 . randInCirc) 8 & evalState $ _randGen w
@@ -48,26 +46,26 @@ Applies ammo check and use cooldown check. -}
rateIncAB
:: Int -- ^ Start rate
-> Int -- ^ End rate
-> (Int -> World -> World) -- ^ Effect on first fire
-> (Int -> World -> World) -- ^ Effect on continued fire
-> Int -- ^ Creature id
-> (Creature -> World -> World) -- ^ Effect on first fire
-> (Creature -> World -> World) -- ^ Effect on continued fire
-> Creature -- ^ Creature id
-> World
-> World
rateIncAB startRate fastRate shooteff1 shooteff2 cid w
rateIncAB startRate fastRate shooteff1 shooteff2 cr w
| repeatFire = set (pointItem . itUseRate) (max fastRate (currentRate - 1))
$ over (pointItem . wpLoadedAmmo) (\ammo -> ammo-1)
$ set (pointItem . itUseTime) currentRate
$ shooteff2 cid
$ shooteff2 cr
w
| firstFire = set (pointItem . itUseRate) (startRate - 1)
$ over (pointItem . wpLoadedAmmo) (\ammo -> ammo-1)
$ set (pointItem . itUseTime) startRate
$ shooteff1 cid
$ shooteff1 cr
w
| reloadCondition = fromMaybe w $ startReloadingWeapon cid w
| reloadCondition = fromMaybe w $ startReloadingWeapon cr w
| otherwise = w
where
cr = _creatures w IM.! cid
cid = _crID cr
itRef = _crInvSel cr
item = _crInv cr IM.! itRef
pointItem = creatures . ix cid . crInv . ix itRef
@@ -84,32 +82,32 @@ Shoot a weapon rapidly after a warm up.
Applies ammo check as well. -}
withWarmUp
:: Int -- ^ Warm up time (in frames)
-> (Int -> World -> World)
-> (Creature -> World -> World)
-- ^ Shoot effect
-> Int -- ^ Creature id
-> Creature
-> World
-> World
withWarmUp t f cid w
| reloadCondition = fromMaybe w $ startReloadingWeapon cid w
withWarmUp t f cr w
| reloadCondition = fromMaybe w $ startReloadingWeapon cr w
| _wpReloadState item /= 0 = w
| fState == 0 = set (pointerToItem . wpFire) (withWarmUp 100 f)
| fState == 0 = set (pointerToItem . itUse) (withWarmUp 100 f)
$ set (pointerToItem . itUseTime) 2
w
| t > 2 = set (pointerToItem . wpFire) (withWarmUp (t-1) f)
| t > 2 = set (pointerToItem . itUse) (withWarmUp (t-1) f)
$ set (pointerToItem . itUseTime) 2
$ soundFrom (CrWeaponSound cid) 26 2 0
w
| t > 0 = set (pointerToItem . wpFire) (withWarmUp (t-1) f)
| t > 0 = set (pointerToItem . itUse) (withWarmUp (t-1) f)
$ set (pointerToItem . itUseTime) 2
w
| otherwise = set (pointerToItem . wpFire) (withWarmUp 1 f)
| otherwise = set (pointerToItem . itUse) (withWarmUp 1 f)
$ over (pointerToItem . wpLoadedAmmo) (\ammo -> ammo-1)
$ set (pointerToItem . itUseTime) 2
$ f cid
$ f cr
$ soundFrom (CrWeaponSound cid) 28 2 0
w
where
cr = _creatures w IM.! cid
cid = _crID cr
itRef = _crInvSel cr
item = _crInv cr IM.! itRef
pointerToItem = creatures . ix cid . crInv . ix itRef
@@ -120,33 +118,36 @@ Adds a sound to a creature based world effect.
The sound is emitted from the creature's position. -}
withSound
:: Int -- ^ Sound id
-> (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
-> (Creature -> World -> World) -- ^ Underlying effect
-> Creature
-> World -> World
withSound soundid f cid w = (soundOncePos soundid p . f cid) w
withSound soundid f cr w = (soundOncePos soundid p . f cr) w
where
cid = _crID cr
p = _crPos (_creatures w IM.! cid)
withRecoil
:: Float -- ^ Recoil amount
-> (Int -> World -> World)
-> (Creature -> World -> World)
-- ^ Underlying world effect, takes creature id as input
-> Int -- ^ Creature id
-> Creature
-> World -> World
withRecoil recoilAmount eff cid = eff cid . over (creatures . ix cid) pushback
withRecoil recoilAmount eff cr = eff cr . over (creatures . ix cid) pushback
where
cid = _crID cr
pushback cr = over crPos (+.+ rotateV (_crDir cr) ((-recoilAmount) / _crMass cr ,0)) cr
{- |
Pushes a creature sideways by a random amount.
Applied before the underlying effect. -}
withSidePush
:: Float -- ^ Maximal possible side push amount
-> (Int -> World -> World)
-> (Creature -> World -> World)
-- ^ Underlying world effect, takes creature id as input
-> Int -- ^ Creature id
-> Creature
-> World -> World
withSidePush maxSide eff cid w = eff cid . over (creatures . ix cid) push $ w
withSidePush maxSide eff cr w = eff cr . over (creatures . ix cid) push $ w
where
cid = _crID cr
push cr = over crPos (+.+ rotateV (_crDir cr) (0,pushAmount / _crMass cr)) cr
(pushAmount, _) = randomR (-maxSide,maxSide) $ _randGen w
{- |
@@ -154,31 +155,32 @@ Pushes a creature sideways by a random amount.
Applied after the underlying effect. -}
withSidePushAfter
:: Float -- ^ Maximal possible side push amount
-> (Int -> World -> World)
-> (Creature -> World -> World)
-- ^ Underlying world effect, takes creature id as input
-> Int -- ^ Creature id
-> Creature -- ^ Creature id
-> World -> World
withSidePushAfter maxSide eff cid w = over (creatures . ix cid) push . eff cid $ w
withSidePushAfter maxSide eff cr w = over (creatures . ix cid) push . eff cr $ w
where
cid = _crID cr
push cr = over crPos (+.+ rotateV (_crDir cr) (0,pushAmount / _crMass cr)) cr
(pushAmount, _) = randomR (-maxSide,maxSide) $ _randGen w
{- |
Applies a world effect and sound effect after an ammo check. -}
shootWithSound
:: Int -- ^ Sound identifier
-> (Int -> World -> World)
-> (Creature -> World -> World)
-- ^ Shoot effect, takes creature id as input
-> Int -- ^ Creature id
-> Creature
-> World -> World
shootWithSound soundid f cid w
shootWithSound soundid f cr w
| fireCondition = over (pointerToItem . wpLoadedAmmo) (\ammo -> ammo-1)
$ soundOncePos soundid (_crPos cr)
$ set (pointerToItem . itUseTime) (_itUseRate item)
$ f cid w
| reloadCondition = fromMaybe w $ startReloadingWeapon cid w
$ f cr w
| reloadCondition = fromMaybe w $ startReloadingWeapon cr w
| otherwise = w
where
cr = _creatures w IM.! cid
cid = _crID cr
itRef = _crInvSel cr
item = _crInv cr IM.! itRef
pointerToItem = creatures . ix cid . crInv . ix itRef
@@ -189,47 +191,47 @@ shootWithSound soundid f cid w
{- |
Applies a world effect after an item use cooldown check. -}
useTimeCheck
:: (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
:: (Creature -> World -> World) -- ^ Underlying effect
-> Creature
-> World
-> World
useTimeCheck f cid w = case theItem ^? itUseTime of
Just 0 -> f cid $ setUseTime w
useTimeCheck f cr w = case theItem ^? itUseTime of
Just 0 -> f cr $ setUseTime w
_ -> w
where
cr = _creatures w IM.! cid
cid = _crID cr
setUseTime = creatures . ix cid . crInv . ix (_crInvSel cr) . itUseTime +~ useRate
theItem = _crInv cr IM.! _crInvSel cr
useRate = fromMaybe 0 $ theItem ^? itUseRate
{- |
Applies a world effect after a hammer position check. -}
hammerCheck
:: (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
:: (Creature -> World -> World) -- ^ Underlying effect
-> Creature
-> World
-> World
hammerCheck f cid w = case (_crInv cr IM.! _crInvSel cr) ^? itHammer of
Just HammerUp -> f cid $ setHammerDown w
hammerCheck f cr w = case (_crInv cr IM.! _crInvSel cr) ^? itHammer of
Just HammerUp -> f cr $ setHammerDown w
_ -> setHammerDown w
where
cr = _creatures w IM.! cid
cid = _crID cr
setHammerDown = creatures . ix cid . crInv . ix (_crInvSel cr) . itHammer .~ HammerDown
{- |
Applies a world effect after an ammo check. -}
shoot
:: (Int -> World -> World)
-- ^ Underlying effect, takes creature id as input
-> Int -- ^ Creature id
:: (Creature -> World -> World)
-- ^ Underlying effect
-> Creature
-> World
-> World
shoot f cid w
shoot f cr w
| fireCondition = over (pointerToItem . wpLoadedAmmo) (\ammo -> ammo-1)
$ set (pointerToItem . itUseTime) (_itUseRate item)
$ f cid w
| reloadCondition = fromMaybe w $ startReloadingWeapon cid w
$ f cr w
| reloadCondition = fromMaybe w $ startReloadingWeapon cr w
| otherwise = w
where
cr = _creatures w IM.! cid
cid = _crID cr
itRef = _crInvSel cr
item = _crInv cr IM.! itRef
pointerToItem = creatures . ix cid . crInv . ix itRef
@@ -239,43 +241,45 @@ shoot f cid w
reloadCondition = _wpLoadedAmmo item == 0
withMuzFlare
:: (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
:: (Creature -> World -> World) -- ^ Underlying effect
-> Creature
-> World
-> World
withMuzFlare f cid w = tempLightForAt 3 pos . muzzleFlashAt pos2 $ f cid w
withMuzFlare f cr w = tempLightForAt 3 pos . muzzleFlashAt pos2 $ f cr w
where
cr = _creatures w IM.! cid
cid = _crID cr
pos = _crPos cr +.+ _crRad cr *.* unitVectorAtAngle (_crDir cr)
pos2 = _crPos cr +.+ (2 * _crRad cr) *.* unitVectorAtAngle (_crDir cr)
{- |
Rotates the creature randomly, applies the effect, rotates the creature back. -}
withRandomDir
:: Float -- ^ Max possible rotation
-> (Int -> World -> World)
-> (Creature -> World -> World)
-- ^ Underlying effect
-> Int -- ^ Creature id
-> Creature
-> World
-> World
withRandomDir acc f cid w = over (creatures . ix cid . crDir) (\d -> d - a)
. f cid
withRandomDir acc f cr w = over (creatures . ix cid . crDir) (\d -> d - a)
. f cr
. over (creatures . ix cid . crDir) (+ a)
$ set randGen g
w
where (a, g) = randomR (-acc,acc) $ _randGen w
where
cid = _crID cr
(a, g) = randomR (-acc,acc) $ _randGen w
{- |
Creates a bullet with a given velocity, width, and 'HitEffect' -}
withVelWthHiteff
:: Point2 -- ^ Velocity, x direction is forward with respect to the creature
-> Float -- ^ Bullet width
-> HitEffect -- ^ Bullet effect when hitting creature, wall etc
-> Int -- ^ Creature id
-> Creature -- ^ Creature id
-> World
-> World
withVelWthHiteff vel width hiteff cid w
withVelWthHiteff vel width hiteff cr w
= over particles (newbul : ) $ set randGen g w
where
cr = _creatures w IM.! cid
cid = _crID cr
newbul = aGenBulAt (Just cid) (numColor colid) pos (rotateV dir vel) hiteff width
(colid, g) = randomR (0,11) $ _randGen w
dir = _crDir cr
@@ -284,37 +288,38 @@ withVelWthHiteff vel width hiteff cid w
Translate the creature sideways a random amount, apply the effect, translate back. -}
withRandomOffset
:: Float -- ^ Max possible translate
-> (Int -> World -> World)
-> (Creature -> World -> World)
-- ^ Underlying effect
-> Int -- ^ Creature id
-> Creature -- ^ Creature id
-> World
-> World
withRandomOffset offsetAmount f cid w
withRandomOffset offsetAmount f cr w
= over (creatures . ix cid . crPos) (-.- offV)
. f cid
. f cr
. over (creatures . ix cid . crPos) (+.+ offV)
$ set randGen g
w
where
(offsetVal , g) = randomR (-offsetAmount,offsetAmount) $ _randGen w
cr = _creatures w IM.! cid
cid = _crID cr
offV = rotateV (_crDir cr) (0,offsetVal)
-- | Rotates a creature with minimum rotation at least 0.1.
-- Rotates the player creature before applying the effect, other creatures after.
torqueBeforeForced
:: Float -- ^ Max possible rotation (less the 0.1 forced rotation)
-> (Int -> World -> World)
-> (Creature -> World -> World)
-- ^ Underlying effect
-> Int -- ^ Creature id
-> Creature
-> World
-> World
torqueBeforeForced torque feff cid w
| cid == 0 = feff cid $ w
torqueBeforeForced torque feff cr w
| cid == 0 = feff cr $ w
& randGen .~ g
& creatures . ix cid . crDir +~ rot'
& cameraRot +~ rot'
| otherwise = feff cid $ set randGen g $ over (creatures . ix cid . crDir) (+rot') w
| otherwise = feff cr $ set randGen g $ over (creatures . ix cid . crDir) (+rot') w
where
cid = _crID cr
(rot, g) = randomR (-torque,torque) $ _randGen w
rot' | rot < 0 = rot - 0.1
| otherwise = rot + 0.1
@@ -322,29 +327,31 @@ torqueBeforeForced torque feff cid w
-- Note this currently (29/4/2021) rotates other creatures /after/ applying the effect.
torqueBefore
:: Float -- ^ Max possible rotation
-> (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
-> (Creature -> World -> World) -- ^ Underlying effect
-> Creature -- ^ Creature id
-> World
-> World
torqueBefore torque feff cid w
| cid == 0 = feff cid $ w
torqueBefore torque feff cr w
| cid == 0 = feff cr $ w
& randGen .~ g
& creatures . ix cid . crDir +~ rot
& cameraRot +~ rot
| otherwise = set randGen g $ over (creatures . ix cid . crDir) (+rot) $ feff cid w
| otherwise = set randGen g $ over (creatures . ix cid . crDir) (+rot) $ feff cr w
where
cid = _crID cr
(rot, g) = randomR (-torque,torque) $ _randGen w
-- | Rotate a randomly creature after applying an effect.
torqueAfter
:: Float -- ^ Max possible rotation
-> (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
-> (Creature -> World -> World) -- ^ Underlying effect
-> Creature -- ^ Creature id
-> World
-> World
torqueAfter torque feff cid w
| cid == 0 = rotateScope $ set randGen g $ over cameraRot (+rot) $ feff cid w
| otherwise = set randGen g $ over (creatures . ix cid . crDir) (+rot) $ feff cid w
torqueAfter torque feff cr w
| cid == 0 = rotateScope $ set randGen g $ over cameraRot (+rot) $ feff cr w
| otherwise = set randGen g $ over (creatures . ix cid . crDir) (+rot) $ feff cr w
where
cid = _crID cr
(rot, g) = randomR (-torque,torque) $ _randGen w
rotateScope = creatures . ix 0 . crInv . ix (_crInvSel (_creatures w IM.! 0))
. itAttachment . _Just . scopePos %~ rotateV rot
@@ -356,12 +363,12 @@ spreadNumVelWthHiteff
-> Point2 -- ^ Velocity, x is direction of creature
-> Float -- ^ Bullet width
-> HitEffect -- ^ Effect when hitting creature, wall etc
-> Int -- ^ Creature id
-> Creature -- ^ Creature id
-> World
-> World
spreadNumVelWthHiteff spread num vel wth eff cid w = over particles (newbuls ++) w
spreadNumVelWthHiteff spread num vel wth eff cr w = over particles (newbuls ++) w
where
cr = _creatures w IM.! cid
cid = _crID cr
newbuls = zipWith3
(\pos d colid -> aGenBulAt (Just cid) (numColor colid) pos (rotateV d vel) eff wth)
poss dirs colids
@@ -378,12 +385,12 @@ numVelWthHitEff
-> Point2 -- ^ Velocity, x axis is direction of creature
-> Float -- ^ Bullet width
-> HitEffect -- ^ Effect when hitting creature, wall etc
-> Int -- ^ Creature id
-> Creature -- ^ Creature id
-> World
-> World
numVelWthHitEff num vel wth eff cid w = over particles (newbuls ++) w
numVelWthHitEff num vel wth eff cr w = over particles (newbuls ++) w
where
cr = _creatures w IM.! cid
cid = _crID cr
newbuls = zipWith
(\p colid -> aGenBulAt (Just cid) (numColor colid) p (rotateV d vel) eff wth)
poss
@@ -400,16 +407,17 @@ Uses '_wpSpread' as a parameter for the current offset angle. -}
randWalkAngle
:: Float -- ^ Max offset angle
-> Float -- ^ Walk speed
-> (Int -> World -> World) -- ^ Underlying effect
-> Int -- ^ Creature id
-> (Creature -> World -> World) -- ^ Underlying effect
-> Creature -- ^ Creature id
-> World
-> World
randWalkAngle ma aspeed f cid w = w
randWalkAngle ma aspeed f cr w = w
& creatures . ix cid . crDir -~ a
& f cid
& f cr
& creatures . ix cid . crDir +~ a
& creatures . ix cid . crInv . ix i . wpSpread .~ newa
where
cid = _crID cr
a = _wpSpread $ _crInv (_creatures w IM.! cid) IM.! i
(walka, _) = randomR (-aspeed,aspeed) (_randGen w)
newa = min ma $ max (negate ma) (a + walka)
+10 -8
View File
@@ -18,13 +18,15 @@ import Control.Lens
import qualified Data.IntMap.Strict as IM
{- |
Creates an outwardly increasing circle that draws creatures, even those behind walls. -}
aSonarPulse :: Int -> World -> World
aSonarPulse cid w = over particles ((:) $ sonarPulseAt (_crPos (_creatures w IM.! cid))) w
aSonarPulse :: Creature -> World -> World
aSonarPulse cr w = over particles ((:) $ sonarPulseAt (_crPos cr)) w
{- |
Creates an outwardly increasing circle that displays walls, even those behind other walls. -}
aRadarPulse :: Int -> World -> World
aRadarPulse cid w = over particles ((:) $ radarPulseAt (_crPos (_creatures w IM.! cid))) w
aRadarPulse :: Creature -> World -> World
aRadarPulse cr w = over particles ((:) $ radarPulseAt (_crPos (_creatures w IM.! cid))) w
where
cid = _crID cr
{- |
Radar blip at a point.
@@ -113,16 +115,16 @@ mvRadar x p w pt =
aTractorBeam
:: Int -- ^ Color id
-> Int -- ^ Creature id
-> Creature -- ^ Creature id
-> World
-> World
aTractorBeam col cid w
= set (creatures . ix cid . crInv . ix itRef . wpFire)
aTractorBeam col cr w
= set (creatures . ix cid . crInv . ix itRef . itUse)
(shoot $ aTractorBeam ((col + 1) `mod` 10))
$ over projectiles (IM.insert i (tractorBeamAt col i pos dir)) w
where
i = newProjectileKey w
cr = _creatures w IM.! cid
cid = _crID cr
pos = _crPos cr +.+ ((_crRad cr + 10) *.* unitVectorAtAngle dir)
dir = _crDir cr
itRef = _crInvSel cr