This commit is contained in:
2022-07-20 12:34:52 +01:00
parent 577cf0c44e
commit 8142899be1
3 changed files with 24 additions and 168 deletions
-1
View File
@@ -11,4 +11,3 @@ data ProjectileUpdate
| PJReduceSpin {_pjuReduceSpin :: Float}
| PJRemoteDirection {_pjuStart :: Int, _pjuEnd :: Int, _pjuCID :: Int, _pjuITID :: Int}
| PJSetScope {_pjuITID :: Int}
+22 -165
View File
@@ -6,30 +6,15 @@ module Dodge.Item.Weapon.Launcher
) where
import Dodge.Data
import Dodge.Payload
import Dodge.Base.Collide
import Dodge.Reloading.Action
import Dodge.EnergyBall
import Dodge.Default.Weapon
import Dodge.Item.Location
import Dodge.SoundLogic.LoadSound
import Dodge.Item.Weapon.Shell
import Dodge.Item.Weapon.Remote
import Dodge.Item.Weapon.TriggerType
import Dodge.Movement.Turn
import Dodge.Base
import Dodge.Base.Collide
import Dodge.Zone
import Dodge.SoundLogic
import Dodge.WorldEvent.Cloud
import RandomHelp
import Geometry
import qualified IntMapHelp as IM
import qualified Streaming.Prelude as S
--import qualified Data.Set as S
import qualified Data.Map.Strict as M
import qualified SDL
import Data.Maybe
import Control.Lens
launcher :: Item
@@ -47,7 +32,7 @@ launcher = defaultWeapon
, _itParams = ShellLauncher
{ _shellSpinDrag = 1
, _shellSpinAmount = 2
, _shellThrustDelay = 1
, _shellThrustDelay = 20
}
, _itTweaks = Tweakable
{ _tweakSel = 0
@@ -86,6 +71,7 @@ launcherX i = launcher
, useTimeCheck
, withSoundStart tap4S
, useAmmoAmount i
]
usePjCreation :: Item -> Creature -> World -> World
usePjCreation it = _amPjCreation (_laAmmoType (_itConsumption it)) it
@@ -128,115 +114,18 @@ thrustParam = TweakParam
, _nameTweak = "THRUST DELAY"
}
pjThrust :: Int -> Proj -> World -> World
pjThrust i = pjEffTimeRange (st,et) doThrust
where
et | i == 0 = 36
| otherwise = 40 - (i * 20)
st = et - 100
pjTrack :: Int -> Int -> Proj -> World -> World
pjTrack itid i pj w = pjEffTimeRange (st,et) rotateToTarget pj w
where
et | i == 0 = 36
| otherwise = 40 - (i * 20)
st = et - 100
rotateToTarget _ = fromMaybe id $ do
tpos <- w ^? itPoint . itTargeting . tgPos . _Just
return $ projectiles . ix (_prjID pj) . prjSpin .~ turnToAmount 0.15 (_prjPos pj) tpos
(argV $ _prjAcc pj)
itPoint = pointToItem $ _itemPositions w IM.! itid
doThrust :: Proj -> World -> World
doThrust pj w = w
& randGen .~ g
& projectiles . ix i . prjVel %~ (\v -> accel +.+ frict *.* v)
& soundContinue (ShellSound i) newPos missileLaunchS (Just 1)
& makeFlamelet (oldPos -.- vel) 0 (vel +.+ rotateV (pi+sparkD) accel) 3 10
& shellTrailCloud (addZ 20 (oldPos +.+ r1 +.+ 30 *.* normalizeV (oldPos -.- newPos)))
where
accel = _prjAcc pj
i = _prjID pj
oldPos = _prjPos pj
vel = _prjVel 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
fireShell :: Item -> Creature -> World -> World
fireShell it cr = makeShell it cr $ \pj -> pjEffAtTime 35 (trySpinByCID (_crID cr) spinamount) pj
. pjThrust thrustdelay pj
. reduceSpinBy (1-fromIntegral spindrag*2 / 200) pj
. decTimMvVel pj
. moveShell pj
fireShell it cr = makeShell it cr
[ PJSpin 335 (_crID cr) spinamount
, PJThrust (350 - thrustdelay) 0
, PJReduceSpin (1-fromIntegral spindrag*2 / 200)
]
where
params = _itParams it
spindrag = _shellSpinDrag params
spinamount = _shellSpinAmount params
thrustdelay = _shellThrustDelay params
moveShell :: Proj -- ^ Projectile id
-> World
-> World
moveShell pj w
| time > 40 = if circOnSomeWall oldPos 4 w
then doExplode
else w
| anythingHitCirc 2 oldPos newPos w = doExplode
| time > -300 = w
| otherwise = doExplode
where
time = _prjTimer pj
doExplode = w
& usePayload (_prjPayload pj) oldPos
& stopSoundFrom (ShellSound i)
& projectiles %~ IM.delete i
i = _prjID pj
oldPos = _prjPos pj
vel = _prjVel pj
newPos = oldPos +.+ vel
reduceSpinBy :: Float -> Proj -> World -> World
reduceSpinBy x pj = projectiles . ix (_prjID pj) . prjSpin *~ x
pjEffTimeRange
:: (Int,Int)
-> (Proj -> World -> World)
-> Proj
-> World
-> World
pjEffTimeRange (st,et) f pj
| t <= et && t >= st = f pj
| otherwise = id
where
t = _prjTimer pj
pjEffAtTime
:: Int
-> (Proj -> World -> World)
-> Proj
-> World
-> World
pjEffAtTime t f pj
| _prjTimer pj == t = f pj
| otherwise = id
trySpinByCID
:: Int -- ^ creature id
-> Int -- ^ Spin amount
-> Proj
-> World
-> World
trySpinByCID cid i pj w = w & projectiles . ix pjid . prjSpin .~ newSpin
where
pjid = _prjID pj
dir = argV $ _prjVel pj
newSpin = case w ^? creatures . ix cid of
Just cr -> negate $ min 0.2 $ max (-0.2) $ normalizeAnglePi (dir - _crDir cr) / spinFactor
_ -> 0
spinFactor = 5 * (6 - fromIntegral i)
remoteLauncher :: Item
remoteLauncher = launcher
& itType . iyBase .~ HELD REMOTELAUNCHER
@@ -253,45 +142,13 @@ fireRemoteShell it cr w = set (creatures . ix cid . crInv . ix j . itUse . rUse)
(w',itid) = getHeldItemLoc cr w
i = IM.newKey $ _props w
cid = _crID cr
addRemRocket = makeShell it cr $ \pj ->
decTimMvVel pj . setRemoteScope itid (_prjPos pj) . moveRemoteShell cid itid pj
addRemRocket = makeShell it cr
[ PJSetScope itid
, PJThrust 330 0
, PJRemoteDirection 340 0 cid itid
]
j = crSel cr
moveRemoteShell :: Int -> Int -> Proj -> World -> World
moveRemoteShell cid itid pj w
| time > 40 = if circOnSomeWall oldPos 4 w
then doExplosion
else w
| anythingHitCirc 2 oldPos newPos w = doExplosion
| time >= 20 = w & projectiles . ix i . prjDir .~ newdir
| time > -99 = w & set randGen g
& projectiles . ix i %~
( ( prjVel %~ ( (accel +.+) . (frict *.*) ) )
. ( prjDir .~ newdir )
)
& soundContinue (ShellSound i) newPos missileLaunchS (Just 1)
& smokeGen
& makeFlamelet oldPos 20 (0.5 *.* rotateV (pi+sparkD) accel) 3 10
| time > -200 = w
| otherwise = doExplosion
where
time = _prjTimer pj
i = _prjID pj
oldPos = _prjPos pj
vel = _prjVel pj
newPos = oldPos +.+ vel
newdir
| SDL.ButtonRight `M.member` _mouseButtons w
&& w ^? creatures . ix cid . crInvSel . iselPos == w ^? itemPositions . ix itid . ipInvID
= _cameraRot w + argV (_mousePos w)
| otherwise = _prjDir pj
accel = rotateV newdir (V2 2 0)
(frict,g) = randomR (0.6,0.9) $ _randGen w
(sparkD,_) = randomR (-0.5,0.5) $ _randGen w
r1 = _randGen w & evalState (randInCirc 10)
smokeGen = shellTrailCloud $ addZ 20 $ oldPos +.+ r1 +.+ 30 *.* normalizeV (oldPos -.- newPos)
doExplosion = explodeRemoteRocket itid i $ stopSoundFrom (ShellSound i) w
explodeRemoteRocket
:: Int -- ^ Item id
-> Int -- ^ Projectile id
@@ -311,18 +168,18 @@ fireTrackingShell :: Item -> Creature -> World -> World
fireTrackingShell it cr w = addTrackRocket w'
where
(w',itid) = getHeldItemLoc cr w
addTrackRocket = makeShell it cr $ \pj -> pjEffAtTime 35 (trySpinByCID (_crID cr) spinamount) pj
. pjThrust thrustdelay pj
. reduceSpinBy (1-fromIntegral spindrag*2 / 200) pj
. decTimMvVel pj
. pjTrack itid thrustdelay pj
. moveShell pj
addTrackRocket = makeShell it cr
[ PJSpin 335 (_crID cr) spinamount
, PJTrack (350 - thrustdelay) 0 itid
, PJThrust (350 - thrustdelay) 0
, PJReduceSpin (1-fromIntegral spindrag*2 / 200)
]
spinamount = _shellSpinAmount params
thrustdelay = _shellThrustDelay params
spindrag = _shellSpinDrag params
params = _itParams it
makeShell :: Item -> Creature -> (Proj -> World -> World) -> World -> World
makeShell :: Item -> Creature -> [ProjectileUpdate] -> World -> World
makeShell it cr theupdate w = w & projectiles %~ IM.insert i Shell
{ _prjPos = pos
, _prjZ = 20
@@ -330,13 +187,13 @@ makeShell it cr theupdate w = w & projectiles %~ IM.insert i Shell
, _prjVel = rotateV dir (V2 1 0)
, _prjDraw = DrawShell
, _prjID = i
, _prjUpdate = theupdate
, _prjUpdate = const id
, _prjAcc = rotateV dir (V2 3 0)
, _prjDir = dir
, _prjSpin = 0
, _prjPayload = _amPayload $ _laAmmoType am
, _prjTimer = 50
, _prjUpdates = []
, _prjTimer = 350
, _prjUpdates = theupdate
}
where
i = IM.newKey $ _props w
+2 -2
View File
@@ -30,7 +30,7 @@ import Control.Lens
updateProjectile :: Proj -> World -> World
updateProjectile pj = case pj of
Shell{} -> updateShell pj . decTimMvVel pj . upsProjectile pj
RemoteShell{} -> _prjUpdate pj pj
RemoteShell{} -> updateShell pj . decTimMvVel pj . upsProjectile pj
updateShell :: Proj -> World -> World
updateShell pj w
@@ -72,7 +72,7 @@ upProjectile pu pj = case pu of
PJSetScope itid -> setRemoteScope itid (_prjPos pj)
where
time = _prjTimer pj
act st et = time >= st && time <= et
act st et = time <= st && time >= et
ain t = time == t
setRemoteDir :: Int -> Int -> Proj -> World -> World