edge-0.8.18: Unit.hs
{-# LANGUAGE ExistentialQuantification #-}
module Unit ( SimpleUnit (..)
, SmartUnit (..)
, firing
) where
import Animation ( Audible (..)
, Animation (..)
)
import Moving ( Locatable (..)
, Colliding (..)
, Moving (..)
)
import Combat ( Damaging (..)
, Damageable (..)
, Launcher (..)
, Projectile
)
import Updating ( Transient (..)
, InternallyUpdating (..)
, Observant (..)
)
import Common (Time, Angle)
import Data.Maybe (isNothing, fromJust)
-- Simple, i.e., no sensory awareness and related A.I.
data SimpleUnit = forall a. ( Animation a
, Colliding a
, Transient a
, Damageable a
, Damaging a
, Launcher a
, Audible a
) => SimpleUnit a
instance Colliding SimpleUnit where
collisionRadius (SimpleUnit a) = collisionRadius a
instance Moving SimpleUnit where
velocity (SimpleUnit a) = velocity a
instance Locatable SimpleUnit where
center (SimpleUnit a) = center a
instance Damaging SimpleUnit where
damageEnergy (SimpleUnit a) = damageEnergy a
instance Damageable SimpleUnit where
inflictDamage (SimpleUnit a) et = SimpleUnit (inflictDamage a et)
instance Transient SimpleUnit where
expired' (SimpleUnit a) = expired' a
instance InternallyUpdating SimpleUnit where
preUpdate (SimpleUnit a) et = SimpleUnit (preUpdate a et)
postUpdate (SimpleUnit a) et = SimpleUnit (postUpdate a et)
data SmartUnit = forall a. ( Animation a
, Colliding a
, Transient a
, Damageable a
, Damaging a
, Launcher a
, Audible a
, Observant a
) => SmartUnit a
instance Colliding SmartUnit where
collisionRadius (SmartUnit a) = collisionRadius a
instance Moving SmartUnit where
velocity (SmartUnit a) = velocity a
instance Locatable SmartUnit where
center (SmartUnit a) = center a
instance Damaging SmartUnit where
damageEnergy (SmartUnit a) = damageEnergy a
instance Damageable SmartUnit where
inflictDamage (SmartUnit a) et = SmartUnit (inflictDamage a et)
instance Transient SmartUnit where
expired' (SmartUnit a) = expired' a
instance InternallyUpdating SmartUnit where
preUpdate (SmartUnit a) et = SmartUnit (preUpdate a et)
postUpdate (SmartUnit a) et = SmartUnit (postUpdate a et)
instance Observant SmartUnit where
updateVision (SmartUnit a) arena = SmartUnit (updateVision a arena)
instance Launcher SimpleUnit where
deployProjectiles (SimpleUnit a) = let (ps, a') = deployProjectiles a in
(ps, SimpleUnit a')
instance Launcher SmartUnit where
deployProjectiles (SmartUnit a) = let (ps, a') = deployProjectiles a in
(ps, SmartUnit a')
instance Audible SimpleUnit where
processAudio (SimpleUnit a) wp = do a' <- processAudio a wp
return (SimpleUnit a')
terminateAudio (SimpleUnit a) = do a' <- terminateAudio a
return (SimpleUnit a')
instance Audible SmartUnit where
processAudio (SmartUnit a) wp = do a' <- processAudio a wp
return (SmartUnit a')
terminateAudio (SmartUnit a) = do a' <- terminateAudio a
return (SmartUnit a')
-- | Func abstracting the firing of projectiles
firing :: a -- ^ the object
-> (a -> Time) -- ^ func that retrieves time since last shot
-> Time -- ^ desired shot delay
-> (a -> Time -> a) -- ^ func which sets time since last shot in object
-> (a -> [Projectile] -> a) -- ^ func which sets projectiles in object
-> (a -> Bool -> a) -- ^ func which sets shot sound queued status
-> [Projectile] -- ^ new projectiles
-> Time -- ^ elapsed time
-> (a -> [Projectile]) -- ^ func which retrieves projectiles in object
-> a
firing a f b g h i c d j =
if m >= b then i (h (g a 0) (c ++ j a)) True else g a m
where m = f a + d