module Dodge.Projectile.Create ( createShell, PJStabiliser (..), ) where import qualified Quaternion as Q import Dodge.Data.Muzzle import Data.Maybe import Dodge.Data.World import Dodge.Item.Location import Geometry import qualified IntMapHelp as IM import LensHelp import NewInt data PJStabiliser = StabOrthReduce | StabSpinIncrease -- assumes the mscreen is in your inventory -- TODO take into account creature aimstance positioning createShell :: (Point3, Q.Quaternion Float) -> Maybe (NewInt ItmInt) -> Maybe (NewInt ItmInt) -> Maybe PJStabiliser -> ProjectileType -> Payload -> Muzzle -> Creature -> World -> World createShell (p,q) mdetonator mscreen stab pjtype payload muz cr w = w & updatescreen & updatedetonator & cWorld . lWorld . projectiles . at i ?~ Shell { _pjPos = pos , _pjZ = 20 , _pjZVel = 5 , _pjVel = rotateV dir' (V2 speed 0) + crvelcomponent , _pjID = i , _pjDir = dir' , _pjSpin = 0 , _pjPayload = payload , _pjTimer = lifespan , _pjBarrelSpin = bs -- , _pjUpdates = -- anyspin , _pjType = pjtype , _pjDetonatorID = mdetonator , _pjScreenID = mscreen } where crvelcomponent = case stab of Just StabOrthReduce -> projV (cr ^. crPos - cr ^. crOldPos) (unitVectorAtAngle dir) _ -> cr ^. crPos - cr ^. crOldPos bs = case stab of Just StabOrthReduce -> Nothing Just StabSpinIncrease -> Just (_crID cr, 5) _ -> Just (_crID cr, 2) speed = case pjtype of Grenade{} -> 4 Rocket{} -> 1 RetiredProjectile -> 0 lifespan = 350 updatedetonator = fromMaybe id $ do screenid <- mdetonator return $ pointerToItemID screenid . itUse . uaParams . apProjectiles .:~ i updatescreen = fromMaybe id $ do screenid <- mscreen return $ pointerToItemID screenid . itUse . uaParams . apProjectiles .:~ i i = IM.newKey $ w ^. cWorld . lWorld . projectiles dir = _crDir cr + _mzRot muz pos = _crPos cr + rotateV dir (xyV3 p + rotateV (argV (Q.qToV2 q)) (_mzPos muz)) dir' = dir + argV (Q.qToV2 q)