{-# LANGUAGE ExistentialQuantification #-} module Unit ( SimpleUnit (..) , SmartUnit (..) ) where import Animation import Moving import Combat import Updating -- 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')