module Projectile.Blade ( Blade(..) , new , range , speed ) 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 Trigonometry import Data.Maybe import ResourceTracker import GHC.Float import Common velocityC = 250.0 rangeC = 1500.0 punch = 4.0 range = rangeC speed = velocityC data Blade = Blade { velocity :: Velocity , center :: WrapPoint , rangeLeft :: Double , wrapMap :: WrapMap , idealNewCenter :: Maybe WrapPoint , clock :: Time , resourceTracker :: ResourceTracker } -- angle is radians new :: WrapMap -> ResourceTracker -> Angle -> WrapPoint -> Velocity -> Blade new wmap rt angle center' (vpx, vpy) = let x = cos angle * velocityC in let y = sin angle * velocityC in Blade { velocity = (x + vpx, y + vpy) , center = center' , rangeLeft = rangeC , wrapMap = wmap , idealNewCenter = Nothing , clock = 0.0 , resourceTracker = rt } instance Animation Blade where image self t = Rotate (double2Float deg) p where deg = radToDeg ((clock self * 4 * pi) `doubleRem` (2 * pi)) p = fromMaybe (Color white (Line [(-40, 0), (40, 0)])) (getImage rt "blade.bmp") rt = resourceTracker self instance M.Colliding Blade where collisionRadius self = 20.0 instance M.Moving Blade where velocity self = Projectile.Blade.velocity self instance M.Locatable Blade where center self = Projectile.Blade.center self instance SimpleTransient Blade where expired self = rangeLeft self <= 0.0 instance InternallyUpdating Blade where preUpdate self t = updateIdealTargetCenter t self postUpdate self t = let center' = case idealNewCenter self of Nothing -> center self Just x -> x in self { center = center' , idealNewCenter = Nothing , clock = clock self + t } updateIdealTargetCenter :: Time -> Blade -> Blade 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 - Data.WrapAround.distance (wrapMap self) (center self) (newLoc) } instance Damaging Blade where damageEnergy b = punch instance Transient Blade where expired' self = if rangeLeft self <= 0.0 then Just [] else Nothing instance Damageable Blade where inflictDamage self d = self