Refactor, add bullet modules and weapon effect modifiers

This commit is contained in:
2021-05-27 02:50:33 +02:00
parent 0187ae6001
commit 346c426b43
13 changed files with 395 additions and 144 deletions
+69 -37
View File
@@ -1,21 +1,22 @@
module Dodge.Item.Weapon.Launcher
where
import Dodge.Data
import Dodge.Item.Weapon.TriggerType
import Dodge.Default.Weapon
import Dodge.Default.Shell
import Dodge.SoundLogic.Synonyms
import Picture
import qualified IntMapHelp as IM
import Dodge.WorldEvent.Explosion
import Dodge.Picture.Layer
import Dodge.Item.Draw
import Geometry
import Dodge.Default.Shell
import Dodge.Item.Weapon.Shell
import Dodge.Item.Weapon.TriggerType
import Dodge.Base
import Dodge.SoundLogic
import Dodge.WorldEvent.SpawnParticle
import Dodge.WorldEvent.Cloud
import Dodge.RandomHelp
import Geometry
import Picture
import qualified IntMapHelp as IM
import Data.Maybe
import Control.Lens
@@ -45,7 +46,7 @@ launcher = defaultGun
, _wpAmmo = defaultShellAmmo
{ _amPayload = makeExplosionAt
, _amString = ""
, _amPjMove = basicAmPjMoves
, _amPjParams = basicAmPjMoves
, _amPjDraw = shellPic
}
}
@@ -54,19 +55,58 @@ basicAmPjMoves :: [PjParam]
basicAmPjMoves =
[spinDrag
,spinStart
,thrustParam
]
spinDrag :: PjParam
spinDrag = PjParam
{ _pjMoveParam = \_ _ _ -> reduceSpinBy 0.995
, _pjIntParam = 0
, _pjDisplayParam = ("SPIN DRAG:" ++ ) . show
{ _pjMoveParam = \i _ _ -> reduceSpinBy (1 - (fromIntegral i)*2 / 200)
, _pjIntParam = 1
, _pjDisplayParam = pjPadText "SPIN SLOWDOWN" . show
, _pjMaxParam = 5
}
pjPadText :: String -> String -> String
pjPadText s = (rightPad 12 ' ' s ++ ) . (' ':)
spinStart :: PjParam
spinStart = PjParam
{ _pjMoveParam = \_ _ cr -> pjEffAtTime 35 $ trySpinByCID (_crID cr)
, _pjIntParam = 0
, _pjDisplayParam = ("SPIN START:" ++ ) . show
{ _pjMoveParam = \i _ cr -> pjEffAtTime 35 $ trySpinByCID (_crID cr) i
, _pjIntParam = 2
, _pjDisplayParam = pjPadText "SPIN AMOUNT" . show
, _pjMaxParam = 5
}
thrustParam :: PjParam
thrustParam = PjParam
{ _pjMoveParam = \i _ _ -> pjThrust i
, _pjIntParam = 1
, _pjDisplayParam = pjPadText "THRUST DELAY" . show
, _pjMaxParam = 5
}
pjThrust :: Int -> Projectile -> World -> World
pjThrust i = pjEffTimeRange (st,et) $ doThrust
where
et | i == 0 = 36
| otherwise = 40 - (fromIntegral i * 20)
st = et - 100
doThrust :: Projectile -> World -> World
doThrust pj w = w
& randGen .~ g
& projectiles . ix i . pjVel %~ (\v -> accel +.+ frict *.* v)
& soundFromPos (ShellSound i) newPos (fromIntegral smokeTrailSound) 1 250
& makeFlameletTimed (oldPos -.- vel) (vel +.+ rotateV (pi+sparkD) accel) Nothing 3 10
& smokeGen
where
accel = _pjAcc pj
i = _pjID pj
oldPos = _pjPos pj
vel = _pjVel pj
newPos = oldPos +.+ vel
(frict,g) = randomR (0.6,0.9) $ _randGen w
(sparkD,_) = randomR (-0.2,0.2) $ _randGen w
r1 = randInCirc 10 & evalState $ _randGen w
smokeGen = makeSmokeCloudAt (oldPos +.+ r1 +.+ 30 *.* normalizeV (oldPos -.- newPos))
flameLauncher :: Item
flameLauncher = launcher & wpAmmo . amPayload .~ makeFlameExplosionAt
@@ -86,7 +126,7 @@ aRocketWithItemParams it cr w = over projectiles (IM.insert i theShell) w
i = IM.newKey $ _projectiles 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' (_amPjMove am)
ammoMvs pj w' = foldr (\pjP -> (_pjMoveParam pjP) (_pjIntParam pjP) it cr pj) w' (_amPjParams am)
theShell = defaultShell
{ _pjPos = pos
, _pjStartPos = pos
@@ -108,18 +148,10 @@ moveShell pj w
then doExplode
else w
| isJust thingHit = doExplode
| time >= 20 = w
| time > -99 = w
& randGen .~ g
& projectiles . ix i . pjVel %~ (\v -> accel +.+ frict *.* v)
& soundFromPos (ShellSound i) newPos (fromIntegral smokeTrailSound) 1 250
& makeFlameletTimed (oldPos -.- vel) (vel +.+ rotateV (pi+sparkD) accel) Nothing 3 10
& smokeGen
| time > -200 = w
| time > -300 = w
| otherwise = doExplode
where
time = _pjTimer pj
accel = _pjAcc pj
doExplode = w
& projectileExplosion oldPos
& stopSoundFrom (ShellSound i)
@@ -129,13 +161,9 @@ moveShell pj w
vel = _pjVel pj
projectileExplosion = _pjPayload pj
newPos = oldPos +.+ vel
(frict,g) = randomR (0.6,0.9) $ _randGen w
(sparkD,_) = randomR (-0.2,0.2) $ _randGen w
hitCr = fst <$> collideCircCrsPoint oldPos newPos 4 w
hitWl = fst <$> collideCircWalls' oldPos newPos 2 (wallsNearPoint newPos w)
thingHit = hitCr <|> hitWl
r1 = randInCirc 10 & evalState $ _randGen w
smokeGen = makeSmokeCloudAt (oldPos +.+ r1 +.+ 30 *.* normalizeV (oldPos -.- newPos))
reduceSpinBy :: Float -> Projectile -> World -> World
reduceSpinBy x pj = projectiles . ix (_pjID pj) . pjSpin *~ x
@@ -151,16 +179,18 @@ shellPic pj
pos = _pjPos pj
t = _pjTimer pj
decTimMvVel :: Projectile -> World -> World
decTimMvVel pj = projectiles . ix pjid %~
( (pjTimer -~ 1)
. (pjPos %~ (+.+ vel) )
. (pjAcc %~ rotateV rot )
)
pjEffTimeRange
:: (Int,Int)
-> (Projectile -> World -> World)
-> Projectile
-> World
-> World
pjEffTimeRange (st,et) f pj
| t <= et && t >= st = f pj
| otherwise = id
where
rot = _pjSpin pj
vel = _pjVel pj
pjid = _pjID pj
t = _pjTimer pj
pjEffAtTime
:: Int
@@ -174,13 +204,15 @@ pjEffAtTime t f pj
trySpinByCID
:: Int -- ^ creature id
-> Int -- ^ Spin amount
-> Projectile
-> World
-> World
trySpinByCID cid pj w = w & projectiles . ix pjid . pjSpin .~ newSpin
trySpinByCID cid i pj w = w & projectiles . ix pjid . pjSpin .~ newSpin
where
pjid = _pjID pj
dir = argV $ _pjVel pj
newSpin = case w ^? creatures . ix cid of
Just cr -> negate $ min 0.2 $ max (-0.2) $ normalizeAnglePi (dir - _crDir cr) / 20
Just cr -> negate $ min 0.2 $ max (-0.2) $ normalizeAnglePi (dir - _crDir cr) / spinFactor
_ -> 0
spinFactor = 5 * (6 - fromIntegral i)