edge-0.9.1.0: Unit/Simple/Turret.hs
{-|
Module : Unit.Simple.Turret
Description : Fixed gun turret which rotates while firing
Copyright : (c) Christopher Howard, 2016
License : GPL-3
Maintainer : ch.howard@zoho.com
-}
module Unit.Simple.Turret ( Turret(..)
, new
) where
import Prelude ((+), (>), Maybe(..), max, (-), (/), pi, (*), sin, cos, Bool(..), (.), Double, map)
import Data.WrapAround (WP, WM)
import Sound.ALUT (Source(..))
import Animation
import Math
import ResourceTracker
import Updating
import qualified Moving as M (Locatable(..), Moving(..), Colliding(..), newLocation')
import Combat
import qualified Projectile.BulletSI as P.BulletSI (prj)
import AfterEffect
import qualified AfterEffect.SimpleExplosion as SimpleExplosion (new)
import Common
import Unit
radVelocity = pi/6 -- radians per second
velMagnitude = 40
kamikazeDmg = 6.0
maxInteg = 2.0
cRadius = 16
data Turret = Turret { tAngle :: Angle
, velocity :: Velocity
, center :: WP
, wmap :: WM
, launchTube :: [Projectile]
, sinceLastShot :: Time
, integrity :: Double
, rt :: RT
, queueShotSnd :: Bool
, shotSndSrc :: Maybe Source
}
instance Audible Turret where
processAudio s a = handSndSrc s
queueShotSnd
shotSndSrc
(\a -> a { queueShotSnd = False })
rt
"energy-shot-02.wav"
(\a b -> a { shotSndSrc = Just b })
a (wmap s) (M.center)
terminateAudio s = termSndSrc s shotSndSrc
new a b c d e = Turret { center = c
, tAngle = d
, velocity = appPair (* velMagnitude) (sin e, cos e)
, wmap = b
, launchTube = []
, sinceLastShot = 0
, integrity = maxInteg
, rt = a
, queueShotSnd = False
, shotSndSrc = Nothing
}
updateAngle t s = s { tAngle = tAngle s - radVelocity * t}
instance Animation Turret where
image s _ = reorient (tAngle s) (protectedGetImage (rt s) "turret.bmp")
instance M.Locatable Turret where
center = center
instance M.Moving Turret where
velocity = velocity
instance M.Colliding Turret where
collisionRadius _ = cRadius
instance InternallyUpdating Turret where
preUpdate s t = (updateFiringInformation t . updateAngle t) s
postUpdate s t = s { center = M.newLocation' s (wmap s) t }
updateFiringInformation t s = firing s sinceLastShot 1.5
(\x y -> x { sinceLastShot = y })
(\x y -> x { launchTube = y })
(\x y -> x { queueShotSnd = y })
p t launchTube
where p = map f [ 0.0, pi / 2, pi, 3 * pi / 2 ]
f x = P.BulletSI.prj s wmap (tAngle s + x)
instance Launcher Turret where
deployProjectiles s = (launchTube s, s { launchTube = [] })
instance Transient Turret where
expired' s = if integrity s > 0 then Nothing else Just [a]
where a = AfterEffect (SimpleExplosion.new (rt s)
(wmap s)
(center s)
(velocity s))
instance Damageable Turret where
inflictDamage s d = s { integrity = max 0 (integrity s - d) }
instance Damaging Turret where
damageEnergy s = kamikazeDmg