Add trajectory to grenades, various refactoring

This commit is contained in:
2021-09-25 18:39:53 +01:00
parent a0340eb024
commit 32367b5b2d
32 changed files with 339 additions and 253 deletions
+4 -1
View File
@@ -15,6 +15,7 @@ import Dodge.Item.Weapon.TriggerType
import Dodge.SoundLogic.LoadSound
import Picture
import Geometry
import Geometry.Vector3D
import ShapePicture
import Shape
@@ -64,7 +65,9 @@ autoGun = defaultAutoGun
}
autoGunPic :: SPic
autoGunPic =
( colorSH red $ upperPrismPoly 5 $ rectNESW 4 12 (-4) (-12)
( colorSH red $ prismPoly
(map (addZ 5) $ rectNESW 2 12 (-2) (-12))
(map (addZ 0) $ rectNESW 4 12 (-4) (-12))
, mempty
)
+9 -8
View File
@@ -9,6 +9,7 @@ import qualified IntMapHelp as IM
import Dodge.Picture.Layer
import Picture
import Dodge.Item.Attachment.Data
import ShapePicture
import Data.Maybe
import Control.Lens
@@ -40,7 +41,7 @@ boostSelfL x cr invid w = case boostPoint x cr w of
cid = _crID cr
cpos = _crPos cr
r = _crRad cr
pid = fromMaybe (IM.newKey $ _projectiles w)
pid = fromMaybe (IM.newKey $ _props w)
(cr ^? crInv . ix invid . itAttachment . itInt)
crEff p ammoEff = addBoostShockwave pid p (r *.* normalizeV (p -.- cpos)) w
& creatures . ix cid %~
@@ -64,11 +65,11 @@ addBoostShockwave
-> Point2
-> World
-> World
addBoostShockwave pjid p v w = w & projectiles %~
addBoostShockwave pjid p v w = w & props %~
IM.insertWith f pjid thePJ
where
thePJ = LinearShockwave
{ _pjDraw = drawBoostShockwave
{ _prDraw = drawBoostShockwave
, _pjID = pjid
, _pjUpdate = updateLinearShockwave
, _pjPoints = [(p,v)]
@@ -76,16 +77,16 @@ addBoostShockwave pjid p v w = w & projectiles %~
}
f newVal oldVal = newVal & pjPoints %~ (++ _pjPoints oldVal)
updateLinearShockwave :: Projectile -> World -> World
updateLinearShockwave :: Prop -> World -> World
updateLinearShockwave pj w
| t < 1 = w & projectiles %~ IM.delete pjid
| otherwise = w & projectiles . ix (_pjID pj) . pjTimer -~ 1
| t < 1 = w & props %~ IM.delete pjid
| otherwise = w & props . ix (_pjID pj) . pjTimer -~ 1
where
pjid = _pjID pj
t = _pjTimer pj
drawBoostShockwave :: Projectile -> Picture
drawBoostShockwave pj = setLayer 1 $ onLayer UPtLayer $ pictures $
drawBoostShockwave :: Prop -> SPic
drawBoostShockwave pj = (,) mempty $ setLayer 1 $ onLayer UPtLayer $ pictures $
theArc ++
[ lineCol $ zip (reverse lps) $ map (`withAlpha` white) [0,0.05..]
, lineCol $ zip (reverse rps) $ map (`withAlpha` white) [0,0.05..]
+1 -1
View File
@@ -32,7 +32,7 @@ wpRecock = ItInvEffect
}
where
f _ cr i = creatures . ix (_crID cr) . crInv %~ IM.adjust fOnIt i
moveHammerUp HammerDown = HammerReleased
moveHammerUp HammerDown = HammerReleased
moveHammerUp HammerReleased = HammerUp
moveHammerUp HammerUp = HammerUp
moveHammerUp NoHammer = NoHammer
+40 -43
View File
@@ -5,12 +5,10 @@ import Dodge.Data.SoundOrigin
import Dodge.Item.Data
import Dodge.Base
import Dodge.Zone
import Dodge.Picture.Layer
import Dodge.SoundLogic
import Dodge.SoundLogic.LoadSound
import Dodge.Item.Attachment.Data
import Dodge.Item.Draw
import Dodge.Default.Shell
--import Dodge.Default
import Picture
import Geometry
@@ -19,64 +17,63 @@ import Shape
import Control.Lens
import qualified Data.IntMap.Strict as IM
--import System.Random
moveGrenade
:: Int -- ^ Timer
-> Float -- ^ Direction
-> Int -- ^ Projectile id
-> World
-> World
moveGrenade 0 _ pID w = over projectiles (IM.delete pID)
$ explosion (_pjPos (_projectiles w IM.! pID))
w
where
pj = _projectiles w IM.! pID
explosion = _pjPayload pj
moveGrenade time dir pID w = case hitWl of
Just (p,_) -> soundStart (Tap 0) p tapQuietS Nothing updatedWorld
_ -> updatedWorld
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
updatedWorld = updateV $ set (projectiles . ix pID . pjPos) finalPos
$ set (projectiles .ix pID. pjDraw)
(\ _ -> onLayer PtLayer $ uncurryV translate newPos
$ rotate dir $ _spPicture $ grenadePic time)
$ set (projectiles .ix pID.pjUpdate) (\_ -> moveGrenade (time-1) dir pID) w
pj = _projectiles w IM.! pID
pID = _pjID pj
normalUpdate = (pjTimer -~ 1)
. (pjZ %~ (max 0 . (+ _pjVelZ pj)))
. (pjVelZ -~ 0.1)
. ( pjPos .~ newPos )
oldPos = _pjPos pj
newPos = _pjVel pj +.+ oldPos
hitWl = collideCircWalls'' oldPos newPos 4 $ wallsNearPoint newPos w
finalPos = maybe newPos fst hitWl
setV v = set (projectiles .ix pID.pjVel) v
updateV = maybe id (setV . snd) hitWl
grenadePic :: Int -> SPic
grenadePic x = (,) emptySH $ pictures
[ color (dark $ dark green) $ circleSolid 5
, color green $ arc (degToRad $ (179 * fromIntegral x / 50) - 180 )
(degToRad $ 180 - (179 * fromIntegral x / 50) )
5
, translate (-2) 2 $ rotate (pi*0.5)
$ scale 0.05 0.05 $ color green $ text $ show $ 1 + quot x 20
]
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 explosion cr w = setWp $ removePict $ over projectiles addG w
throwGrenade thePayload cr w = setWp $ removePict $ over props addG w
where
n = _crID cr
addG = IM.insert i $ defaultShell
addG = IM.insert i $ Bomb
{ _pjPos = p
, _pjStartPos = p
, _pjZ = 10
, _pjVelZ = 2
, _pjVel = v
, _pjDraw = \_ -> onLayer PtLayer $ uncurryV translate p $ _spPicture $ grenadePic 0
, _prDraw = grenadeDraw dir
, _pjID = i
, _pjUpdate = \_ -> moveGrenade fuseTime dir i
, _pjPayload = explosion
, _pjUpdate = moveGrenade
, _pjPayload = thePayload
, _pjTimer = fuseTime
}
j = _crInvSel cr
removePict = set (creatures . ix n . crInv . ix j . itEquipPict) $ \ _ _ -> (,) emptySH blank
+19 -19
View File
@@ -100,17 +100,17 @@ thrustParam = PjParam
, _pjMaxParam = 5
}
pjThrust :: Int -> Projectile -> World -> World
pjThrust :: Int -> Prop -> World -> World
pjThrust i = pjEffTimeRange (st,et) doThrust
where
et | i == 0 = 36
| otherwise = 40 - (i * 20)
st = et - 100
doThrust :: Projectile -> World -> World
doThrust :: Prop -> World -> World
doThrust pj w = w
& randGen .~ g
& projectiles . ix i . pjVel %~ (\v -> accel +.+ frict *.* v)
& props . ix i . pjVel %~ (\v -> accel +.+ frict *.* v)
& soundContinue (ShellSound i) newPos missileLaunchS (Just 1)
& makeFlameletTimed (oldPos -.- vel) 0 (vel +.+ rotateV (pi+sparkD) accel) Nothing 3 10
& smokeGen
@@ -137,10 +137,10 @@ aRocketWithItemParams
-> Creature
-> World
-> World
aRocketWithItemParams it cr w = over projectiles (IM.insert i theShell) w
aRocketWithItemParams it cr w = over props (IM.insert i theShell) w
where
am = _wpAmmo it
i = IM.newKey $ _projectiles w
i = IM.newKey $ _props w
pos = _crPos cr +.+ ((_crRad cr +1) *.* unitVectorAtAngle dir)
dir = _crDir cr
ammoMvs pj w' = foldr (\pjP -> _pjMoveParam pjP (_pjIntParam pjP) it cr pj) w' (_amPjParams am)
@@ -149,7 +149,7 @@ aRocketWithItemParams it cr w = over projectiles (IM.insert i theShell) w
, _pjStartPos = pos
, _pjVel = rotateV dir (V2 1 0)
, _pjAcc = rotateV dir (V2 3 0)
, _pjDraw = _amPjDraw am
, _prDraw = _amPjDraw am
, _pjID = i
, _pjUpdate = \pj -> ammoMvs pj . decTimMvVel pj . moveShell pj
, _pjPayload = _amPayload am
@@ -157,7 +157,7 @@ aRocketWithItemParams it cr w = over projectiles (IM.insert i theShell) w
}
moveShell
:: Projectile -- ^ Projectile id
:: Prop -- ^ Projectile id
-> World
-> World
moveShell pj w
@@ -172,21 +172,21 @@ moveShell pj w
doExplode = w
& projectileExplosion oldPos
& stopSoundFrom (ShellSound i)
& projectiles %~ IM.delete i
& props %~ IM.delete i
i = _pjID pj
oldPos = _pjPos pj
vel = _pjVel pj
projectileExplosion = _pjPayload pj
newPos = oldPos +.+ vel
hitCr = fst <$> collideCircCrsPoint oldPos newPos 4 w
hitWl = fst <$> collideCircWalls'' oldPos newPos 2 (wallsNearPoint newPos w)
hitWl = fst <$> collideCircWalls oldPos newPos 2 (wallsNearPoint newPos w)
thingHit = hitCr <|> hitWl
reduceSpinBy :: Float -> Projectile -> World -> World
reduceSpinBy x pj = projectiles . ix (_pjID pj) . pjSpin *~ x
reduceSpinBy :: Float -> Prop -> World -> World
reduceSpinBy x pj = props . ix (_pjID pj) . pjSpin *~ x
shellPic :: Projectile -> Picture
shellPic pj = setDepth 20 . uncurryV translate pos $ rotate (argV accel) basePic
shellPic :: Prop -> SPic
shellPic pj = (,) mempty $ setDepth 20 . uncurryV translate pos $ rotate (argV accel) basePic
where
basePic = color black $ polygon $ map toV2 [(-6,4),(-6,-4),(6,-4),(8,0),(6,4)]
accel = _pjAcc pj
@@ -194,8 +194,8 @@ shellPic pj = setDepth 20 . uncurryV translate pos $ rotate (argV accel) basePic
pjEffTimeRange
:: (Int,Int)
-> (Projectile -> World -> World)
-> Projectile
-> (Prop -> World -> World)
-> Prop
-> World
-> World
pjEffTimeRange (st,et) f pj
@@ -206,8 +206,8 @@ pjEffTimeRange (st,et) f pj
pjEffAtTime
:: Int
-> (Projectile -> World -> World)
-> Projectile
-> (Prop -> World -> World)
-> Prop
-> World
-> World
pjEffAtTime t f pj
@@ -217,10 +217,10 @@ pjEffAtTime t f pj
trySpinByCID
:: Int -- ^ creature id
-> Int -- ^ Spin amount
-> Projectile
-> Prop
-> World
-> World
trySpinByCID cid i pj w = w & projectiles . ix pjid . pjSpin .~ newSpin
trySpinByCID cid i pj w = w & props . ix pjid . pjSpin .~ newSpin
where
pjid = _pjID pj
dir = argV $ _pjVel pj
+2 -2
View File
@@ -4,8 +4,8 @@ import Dodge.Data
import Geometry.Vector
import Control.Lens
decTimMvVel :: Projectile -> World -> World
decTimMvVel pj = projectiles . ix pjid %~
decTimMvVel :: Prop -> World -> World
decTimMvVel pj = props . ix pjid %~
( (pjTimer -~ 1)
. (pjPos %~ (+.+ vel) )
. (pjAcc %~ rotateV rot )
+7 -7
View File
@@ -113,19 +113,19 @@ aTractorBeam
aTractorBeam col cr w
= set (creatures . ix cid . crInv . ix itRef . itUse)
(\_ -> aTractorBeam ((col + 1) `mod` 10))
$ over projectiles (IM.insert i (tractorBeamAt col i pos dir)) w
$ over props (IM.insert i (tractorBeamAt col i pos dir)) w
where
i = newProjectileKey w
cid = _crID cr
pos = _crPos cr +.+ ((_crRad cr + 10) *.* unitVectorAtAngle dir)
dir = _crDir cr
itRef = _crInvSel cr
tractorBeamAt :: Int -> Int -> Point2 -> Float -> Projectile
tractorBeamAt :: Int -> Int -> Point2 -> Float -> Prop
tractorBeamAt colID i pos dir = Projectile
{ _pjPos = pos
, _pjStartPos = p'
, _pjVel = d
, _pjDraw = const blank
, _prDraw = const (mempty,blank)
, _pjID = i
, _pjUpdate = \_ -> updateTractor colID 10 i
}
@@ -137,12 +137,12 @@ tractorBeamAt colID i pos dir = Projectile
The interaction of this with objects, walls etc needs more thought. -}
updateTractor :: Int -> Int -> Int -> World -> World
updateTractor colID time i w
| time > 0 = set (projectiles . ix i . pjUpdate) (\_ -> updateTractor colID (time-1) i)
$ set (projectiles . ix i . pjDraw) (const pic)
| time > 0 = set (props . ix i . pjUpdate) (\_ -> updateTractor colID (time-1) i)
$ set (props . ix i . prDraw) (const (mempty,mempty))
$ over creatures (IM.map tractCr)
$ over floorItems (IM.map tractFlIt)
w
| otherwise = over projectiles (IM.delete i) w
| otherwise = over props (IM.delete i) w
where
tractCr cr
| circOnSeg p1 p2 cP 10
@@ -166,7 +166,7 @@ updateTractor colID time i w
iP = _flItPos it
m | dist iP p1 < 350 = 1
| otherwise = (410 - dist iP p1) / 60
pj = _projectiles w IM.! i
pj = _props w IM.! i
q = _pjVel pj
p1 = _pjPos pj
p' = _pjStartPos pj