module Projectile.SWForward ( SWForward(..) , 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 GHC.Float import Common velocityC = 700.0 rangeC = 1000.0 integrityMax = 60.0 punch = 6.0 radiusGrowth = 50.0 data SWForward = SWForward { velocity :: Velocity , center :: WrapPoint , rangeLeft :: Double , wrapMap :: WrapMap , idealNewCenter :: Maybe WrapPoint , integrity :: Double , clock :: Time , radius :: Double } -- angle is radians new :: WrapMap -> Angle -> WrapPoint -> Velocity -> SWForward new wmap angle center' (vpx, vpy) = let x = cos angle * velocityC in let y = sin angle * velocityC in SWForward { velocity = (x + vpx, y + vpy) , center = center' , rangeLeft = rangeC , wrapMap = wmap , idealNewCenter = Nothing , clock = 0.0 , integrity = integrityMax , radius = 2.0 } instance Animation SWForward where image self t = Color violet (Circle (double2Float (radius self))) instance M.Colliding SWForward where collisionRadius self = radius self instance M.Moving SWForward where velocity self = Projectile.SWForward.velocity self instance M.Locatable SWForward where center self = Projectile.SWForward.center self instance SimpleTransient SWForward where expired self = rangeLeft self <= 0.0 || integrity self <= 0.0 instance InternallyUpdating SWForward 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 , radius = min 128.0 ((radius self) + radiusGrowth * t) } updateIdealTargetCenter :: Time -> SWForward -> SWForward 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 SWForward where damageEnergy self = punch instance Transient SWForward where expired' self = if rangeLeft self <= 0.0 || integrity self <= 0.0 then Just [] else Nothing instance Damageable SWForward where inflictDamage self d = self { integrity = integrity self - d }