module Dodge.Projectile.Create where import Dodge.SoundLogic import Dodge.Reloading import Control.Monad import Data.Maybe import Dodge.Data.World import Geometry import qualified IntMapHelp as IM import LensHelp import qualified SDL createProjectile :: Item -> Muzzle -> Item -> Creature -> World -> World createProjectile ammoitem muz itm cr = fromMaybe failsound $ do x <- ammoitem ^? itUse . amagLoadStatus . iaLoaded guard $ x > 0 matype <- ammoitem ^? itUse . amagType guard $ matype == ProjectileAmmo j <- ammoitem ^? itLocation . ipInvID pt <- ammoitem ^? itUse . amagParams . ampPjCreation return $ case pt of CreateShell -> fireShell ammoitem muz itm cr . extrafuncs j CreateTrackingShell -> fireTrackingShell ammoitem muz itm cr . extrafuncs j where --extrafuncs j = cancelanyreloading . startthesound . useammo j extrafuncs j = startthesound . useammo j useammo j = cWorld . lWorld . creatures . ix (_crID cr) . crInv . ix j . itUse . amagLoadStatus . iaLoaded -~ 1 --cancelanyreloading = cWorld . lWorld . creatures . ix (_crID cr) %~ crCancelReloading -- the sound should be moved to the projectile firing startthesound = soundMultiFrom [CrWeaponSound (_crID cr) j | j <- [0..3]] (_crPos cr) tap4S Nothing failsound w' = case w' ^? input . mouseButtons . ix SDL.ButtonLeft of Just 0 -> soundStart (CrReloadSound (_crID cr)) (_crPos cr) click1S Nothing w' _ -> soundContinue (CrReloadSound (_crID cr)) (_crPos cr) click1S Nothing w' fireShell :: Item -> Muzzle -> Item -> Creature -> World -> World fireShell ammoitem muz it cr = makeShell ammoitem muz it cr [ PJShellCollisionCheck , PJDecTimMvVel , 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 makeShell :: Item -> Muzzle -> Item -> Creature -> [ProjectileUpdate] -> World -> World makeShell ammoitem muz it cr theupdate w = fromMaybe w $ do aparams <- ammoitem ^? itUse . amagParams return $ w & cWorld . lWorld . projectiles . at i ?~ Shell { _prjPos = pos , _prjZ = 20 , _prjStartPos = pos , _prjVel = rotateV dir (V2 1 0) , _prjDraw = DrawShell , _prjID = i , _prjAcc = rotateV dir (V2 3 0) , _prjDir = dir , _prjSpin = 0 , _prjPayload = _ampPayload aparams , _prjTimer = 350 , _prjUpdates = theupdate , _prjMITID = Just $ _itID it } where i = IM.newKey $ w ^. cWorld . lWorld . projectiles -- _props (_cWorld w) dir = _crDir cr + _mzRot muz pos = _crPos cr +.+ rotateV dir (_mzPos muz) --am = _heldConsumption $ _itUse it fireTrackingShell :: Item -> Muzzle -> Item -> Creature -> World -> World fireTrackingShell ammoitem muz it cr = fromMaybe id $ do return $ makeShell ammoitem muz it cr [ PJRemoteShellCollisionCheck , PJDecTimMvVel , PJSpin 335 (_crID cr) spinamount , PJTrack (350 - thrustdelay) 0 (_itID it) , PJThrust (350 - thrustdelay) 0 , PJReduceSpin (1 - fromIntegral spindrag * 2 / 200) ] where spinamount = _shellSpinAmount params thrustdelay = _shellThrustDelay params spindrag = _shellSpinDrag params params = _itParams it