packages feed

edge-0.8.18: Projectile/Mine.hs

module Projectile.Mine ( Mine(..)
                       , new
                       ) where

import Combat ( Damageable(..), Damaging(..) )
import Animation ( Animation(..) )
import Updating
    ( SimpleTransient(..), Transient(..), InternallyUpdating(..) )
import Graphics.Gloss.Data.Picture ()
import Graphics.Gloss.Data.Color ()
import Data.WrapAround ( WP, WM )
import qualified Moving as M
    ( Colliding(..), Moving(..), Locatable(..) )
import ResourceTracker ( RT, ResourceTracker, protectedGetImage )
import Data.Maybe ()
import qualified AfterEffect.MineExplosion as MineExplosion ( new )
import AfterEffect ( AfterEffect(AfterEffect) )
import Common ( Time )
import Math ( remF, appPair, moreThanZero )

detRadius = 100
punch = 1

data Mine = Mine { center :: WP
                 , impacted :: Bool
                 , clock :: Time
                 , rt :: RT
                 , wmap :: WM
                 }

-- angle is radians
new :: ResourceTracker -> WM -> WP -> Mine
new a b c = Mine { center = c
                 , impacted = False
                 , clock = 0.0
                 , rt = a
                 , wmap = b
                 }

instance Animation Mine where

  image s _ = if m <= 0.1 || (m > 5 && m <= 5.1) then q else p
    where (p, q) = appPair (protectedGetImage (rt s)) ("mine.bmp", "mine-lit.bmp")
          m = remF (clock s) 10

instance M.Colliding Mine where

  collisionRadius _ = detRadius

instance M.Moving Mine where

  velocity _ = (0, 0)

instance M.Locatable Mine where

  center = center

instance SimpleTransient Mine where

  expired = impacted

instance InternallyUpdating Mine where

  preUpdate s t = s { clock = clock s + t }

  postUpdate s _ = s

instance Damaging Mine where

  damageEnergy _ = punch

instance Transient Mine where

  expired' s = if impacted s then Just [mE] else Nothing
    where mE = AfterEffect $ MineExplosion.new (rt s) (wmap s) (center s)

instance Damageable Mine where

  inflictDamage s d = s { impacted = moreThanZero d }