Files
loop/src/Dodge/Item/Weapon/Grenade.hs
T
2021-09-26 12:09:44 +01:00

102 lines
3.4 KiB
Haskell

module Dodge.Item.Weapon.Grenade
where
import Dodge.Data
import Dodge.Data.SoundOrigin
import Dodge.Item.Data
import Dodge.Base
import Dodge.Zone
import Dodge.SoundLogic
import Dodge.SoundLogic.LoadSound
import Dodge.Item.Attachment.Data
import Dodge.Item.Draw
import Picture
import Geometry
import ShapePicture
import Shape
import Control.Lens
import qualified Data.IntMap.Strict as IM
moveGrenade :: Prop -> World -> World
moveGrenade pj w
| _pjTimer pj <= 0 = w
& props %~ IM.delete pID
& _pjPayload pj (_pjPos (_props w IM.! pID))
| otherwise = case collideCircWalls oldPos newPos 4 $ wallsNearPoint newPos w of
Nothing -> w & props . ix pID %~ normalUpdate
Just (p,v) -> w
& soundStart (Tap 0) p tapQuietS Nothing
& props . ix pID %~ ( ( pjPos .~ p ) . ( pjTimer -~ 1 ) . (pjVel .~ v) )
where
pID = _pjID pj
normalUpdate = (pjTimer -~ 1)
. (pjZ %~ (max 0 . (+ _pjVelZ pj)))
. (pjVelZ -~ 0.1)
. ( pjPos .~ newPos )
oldPos = _pjPos pj
newPos = _pjVel pj +.+ oldPos
grenadePic :: Int -> SPic
grenadePic time =
( colorSH (dark $ dark green) $ upperPrismPolyHalf 5 $ polyCirc 3 5
, pictures
[ color green $ arc (degToRad $ (179 * fromIntegral time / 50) - 180 )
(degToRad $ 180 - (179 * fromIntegral time / 50) )
5
-- , translate (-2) 2 $ rotate (pi*0.5)
-- $ scale 0.05 0.05 $ color green $ text $ show $ 1 + quot time 20
]
)
grenadeDraw :: Float -> Prop -> SPic
grenadeDraw dir prop = translateSPz z $ uncurryV translateSPf p $ rotateSP dir $ grenadePic time
where
p = _pjPos prop
time = _pjTimer prop
z = _pjZ prop
throwGrenade
:: (Point2 -> World -> World) -- ^ Payload
-> Creature
-> World
-> World
throwGrenade thePayload cr w = setWp $ removePict $ over props addG w
where
n = _crID cr
addG = IM.insert i $ Bomb
{ _pjPos = p
, _pjZ = 10
, _pjVelZ = 2
, _pjVel = v
, _prDraw = grenadeDraw dir
, _pjID = i
, _pjUpdate = moveGrenade
, _pjPayload = thePayload
, _pjTimer = fuseTime
}
j = _crInvSel cr
removePict = set (creatures . ix n . crInv . ix j . itEquipPict) $ \ _ _ -> (,) emptySH blank
i = newProjectileKey w
--(_, g) = randomR (-grenadeAccA,grenadeAccA::Float) (_randGen w)
--(_, _) = randomR (1 - 2*grenadeAccL,1+grenadeAccL::Float) g
v' = 1 / (fromIntegral fuseTime * _cameraZoom w) *.* rotateV (_cameraRot w) ( _mousePos w)
v | magV v' > 6 = 6 *.* normalizeV v'
| otherwise = v'
p' = _crPos cr +.+ rotateV (_crDir cr) (V2 (_crRad cr) 0)
p | circOnSomeWall p' 4 w = _crPos cr +.+ rotateV (_crDir cr) (V2 (_crRad cr-4) 0)
| otherwise = p'
dir = argV v
setWp :: World -> World
setWp w' = w' & creatures . ix n . crInv . ix j . itEffect .~ throwArmReset 20
fuseTime = _itFuseTime $ _itAttachment $ _crInv cr IM.! j
throwArmReset :: Int -> ItEffect
throwArmReset x = ItInvEffect {_itInvEffect = f ,_itEffectCounter = x }
where
f _ cr i = creatures . ix (_crID cr) . crInv %~ IM.adjust counterDown i
counterDown it
| _itEffectCounter (_itEffect it) == 0 = it
& itHammer .~ HammerUp
& itEquipPict .~ pictureWeaponOnAim (grenadePic 50)
| otherwise = it & itEffect . itEffectCounter -~ 1