Implement targeting launcher shells using separate item

This commit is contained in:
2024-09-29 16:24:26 +01:00
parent 7d72fa3c5d
commit 88c3e02459
36 changed files with 747 additions and 610 deletions
+14 -9
View File
@@ -2,15 +2,22 @@ module Dodge.Projectile.Create (
createShell,
) where
import Dodge.Item.Location
import Data.Maybe
import Dodge.Data.World
import Geometry
import qualified IntMapHelp as IM
import LensHelp
homingDrawType :: ProjectileHoming -> ProjectileDraw
homingDrawType ht = case ht of
NoHoming -> DrawShell
HomeUsingRemoteScreen {} -> DrawRemoteShell
HomeUsingTargeting {} -> DrawRemoteShell
-- assumes the mscreen is in your inventory
createShell :: Maybe Item -> AmmoParams -> Muzzle -> Item -> Creature -> World -> World
createShell mscreen aparams muz it cr w = w
createShell :: ProjectileHoming -> AmmoParams -> Muzzle -> Item -> Creature -> World -> World
createShell homing aparams muz it cr w = w
& updatescreen
& cWorld . lWorld . projectiles . at i
?~ Shell
@@ -18,7 +25,7 @@ createShell mscreen aparams muz it cr w = w
, _prjZ = 20
, _prjStartPos = pos
, _prjVel = rotateV dir (V2 1 0)
, _prjDraw = maybe DrawShell (const DrawRemoteShell) mscreen
, _prjDraw = homingDrawType homing
, _prjID = i
, _prjAcc = rotateV dir (V2 3 0)
, _prjDir = dir
@@ -26,10 +33,10 @@ createShell mscreen aparams muz it cr w = w
, _prjPayload = _ampPayload aparams
, _prjTimer = 350
, _prjUpdates =
[ CollisionEffectPU (mscreen ^? _Just . itID) --Just screenid)
[ CollisionEffectPU (homing ^? phRemoteID) --Just screenid)
, TimePU
, StartSpinPU 335 (_crID cr) (_shellSpinAmount params)
, RemoteDirectionPU (350 - thrustdelay) 0 (mscreen ^? _Just . itID)
, RemoteDirectionPU (350 - thrustdelay) 0 homing
, ThrustPU (350 - thrustdelay) 0
, ReduceSpinPU (1 - fromIntegral (_shellSpinDrag params) * 2 / 200)
]
@@ -38,10 +45,8 @@ createShell mscreen aparams muz it cr w = w
thrustdelay = _shellThrustDelay params
params = _itParams it
updatescreen = fromMaybe id $ do
screeninvid <- mscreen ^? _Just . itLocation . ilInvID
return $
cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix screeninvid
. itUse
screenid <- homing ^? phRemoteID
return $ pointerToItemID screenid . itUse
. atLinkedProjectile
?~ i
i = IM.newKey $ w ^. cWorld . lWorld . projectiles
+26 -10
View File
@@ -3,6 +3,7 @@ module Dodge.Projectile.Update
( updateProjectile
) where
import Dodge.Movement.Turn
import NewInt
import Dodge.Payload
import Control.Lens
@@ -108,16 +109,31 @@ trySpinByCID cid i pj w = w & cWorld . lWorld . projectiles . ix pjid . prjSpin
spinFactor = 5 * (6 - fromIntegral i)
-- note this only allows YOU to remotely track projectiles
pjRemoteSetDirection :: Maybe (NewInt ItmInt) -> Projectile -> World -> World
pjRemoteSetDirection mscreenid pj w = fromMaybe w $ do
screenid <- fmap _unNInt mscreenid
let newdir
| w ^? cWorld . lWorld . creatures . ix 0 . crManipulation . manObject . imSelectedItem
== w ^? cWorld . lWorld . itemLocations . ix screenid . ilInvID
= (w ^. wCam . camRot) + argV (_mousePos (_input w))
| otherwise = _prjDir pj
turntonewdir = magV (_prjAcc pj) *.* unitVectorAtAngle newdir
return $ w & cWorld . lWorld . projectiles . ix (_prjID pj) . prjAcc .~ turntonewdir
pjRemoteSetDirection :: ProjectileHoming -> Projectile -> World -> World
pjRemoteSetDirection ph pj w = case ph of
NoHoming -> w
HomeUsingRemoteScreen screenid ->
let newdir
| w ^? cWorld . lWorld . creatures . ix 0 . crManipulation . manObject . imSelectedItem
== w ^? cWorld . lWorld . itemLocations . ix (_unNInt screenid) . ilInvID
= (w ^. wCam . camRot) + argV (_mousePos (_input w))
| otherwise = _prjDir pj
in w & cWorld . lWorld . projectiles . ix (_prjID pj) . prjAcc
.~ magV (_prjAcc pj) *.* unitVectorAtAngle newdir
HomeUsingTargeting itid -> fromMaybe w $ do
tp <- w ^? pointerToItemID itid . itUse . tgPos . _Just
return $ w & cWorld . lWorld . projectiles . ix (_prjID pj) . prjAcc
%~ vecTurnTo 0.2 (_prjPos pj) tp
--pjRemoteSetDirection mscreenid pj w = fromMaybe w $ do
-- screenid <- fmap _unNInt mscreenid
-- let newdir
-- | w ^? cWorld . lWorld . creatures . ix 0 . crManipulation . manObject . imSelectedItem
-- == w ^? cWorld . lWorld . itemLocations . ix screenid . ilInvID
-- = (w ^. wCam . camRot) + argV (_mousePos (_input w))
-- | otherwise = _prjDir pj
-- turntonewdir = magV (_prjAcc pj) *.* unitVectorAtAngle newdir
-- return $ w & cWorld . lWorld . projectiles . ix (_prjID pj) . prjAcc .~ turntonewdir
reduceSpinBy :: Float -> Int -> World -> World
reduceSpinBy x pjid = cWorld . lWorld . projectiles . ix pjid . prjSpin *~ x