module Projectile.BulletMI ( BulletMI(..) , new ) where import Combat import Animation import Updating import Graphics.Gloss.Data.Picture import Graphics.Gloss.Data.Color import Data.WrapAround import qualified Moving as M import Common velocityC = 400.0 rangeC = 500.0 data BulletMI = BulletMI { velocity :: Velocity , center :: WrapPoint , rangeLeft :: Double , wrapMap :: WrapMap , idealNewCenter :: Maybe WrapPoint , impacted :: Bool , clock :: Time } -- angle is radians new :: WrapMap -> Angle -> WrapPoint -> Velocity -> BulletMI new wmap angle center' (vpx, vpy) = let x = cos angle * velocityC in let y = sin angle * velocityC in BulletMI { velocity = (x + vpx, y + vpy) , center = center' , rangeLeft = rangeC , wrapMap = wmap , idealNewCenter = Nothing , impacted = False , clock = 0.0 } instance Animation BulletMI where image self t = let r = fromInteger (ceiling (clock self)) - clock self in Color (c r) (Rotate 45.0 (Circle 4.0)) where c x | x < 0.10 = red | x < 0.20 = yellow | x < 0.30 = red | x < 0.40 = yellow | x < 0.50 = red | x < 0.60 = yellow | x < 0.70 = red | x < 0.80 = yellow | x < 0.90 = red | otherwise = yellow instance M.Colliding BulletMI where collisionRadius b = 2.0 instance M.Moving BulletMI where velocity b = Projectile.BulletMI.velocity b instance M.Locatable BulletMI where center b = Projectile.BulletMI.center b instance SimpleTransient BulletMI where expired b = rangeLeft b <= 0.0 instance InternallyUpdating BulletMI where preUpdate self t = let s' = updateIdealTargetCenter t self in s' { clock = clock self + t } postUpdate self t = let center' = case idealNewCenter self of Nothing -> center self Just x -> x in self { center = center' , idealNewCenter = Nothing } updateIdealTargetCenter :: Time -> BulletMI -> BulletMI updateIdealTargetCenter t self = let newLoc = M.idealNewLocation (wrapMap self) (center self) (velocity self) t in self { idealNewCenter = Just (newLoc) , rangeLeft = max 0.0 $ rangeLeft self - distance (wrapMap self) (center self) (newLoc) } instance Damaging BulletMI where damageEnergy b = 2.0 instance Transient BulletMI where expired' self = if impacted self || rangeLeft self <= 0.0 then Just [] else Nothing instance Damageable BulletMI where inflictDamage self d = if d > 0 then self { impacted = True } else self