{- | Controls a walls response to external damage.
 - Indestructible walls may still produce sparks, dust etc
 -}
module Dodge.Wall.Damage
    ( damageBlocksBy
    , damageWall
    ) where
import Dodge.Data
import Dodge.Block
import LensHelp
import Dodge.Wall.DamageEffect

damageWall :: Damage -> Wall -> World -> World
damageWall dt wl w = case _wlStructure wl of
    MachinePart mcid -> fst . defaultWallDamage dt wl $ w
        & machines . ix mcid . mcDamage .:~ dt
    BlockPart blid   -> let (w',x) = defaultWallDamage dt wl w
        in w' & blocks . ix blid . blHP -~ x & maybeDestroyBlock blid
    DoorPart drid   -> let (w',x) = defaultWallDamage dt wl w
        in w' & doors . ix drid . drHP -~ x & maybeDestroyDoor drid
    _   -> fst $ defaultWallDamage dt wl w

-- block destruction is convoluted...
maybeDestroyBlock :: Int -> World -> World
maybeDestroyBlock blid w = case w ^? blocks . ix blid of
    Just bl | _blHP bl < 1 -> destroyBlock bl w 
    _ -> w

maybeDestroyDoor :: Int -> World -> World
maybeDestroyDoor drid w = case w ^? doors . ix drid of
    Just dr | _drHP dr < 1 -> destroyDoor dr w 
    _ -> w

damageBlocksBy :: Int -> Wall -> World -> World
damageBlocksBy x wl = case wl ^? wlStructure . wsBlock of
    Just blid -> blocks . ix blid . blHP -~ x
    Nothing   -> id
