module Dodge.Update.WallDamage (updateWallDamages, updateEdgesWall) where import Control.Lens import Data.Foldable import Data.Maybe import Data.Monoid import qualified Data.Set as S import Dodge.Data.World import Dodge.Wall.Damage import Dodge.Wall.Pathing import Dodge.WorldEvent.ThingsHit import Dodge.Zoning.Base import Geometry.Data import qualified IntMapHelp as IM updateWallDamages :: World -> World updateWallDamages w = let (is, w') = IM.foldlWithKey' f (mempty, w) (w ^. cWorld . lWorld . wallDamages) in updateEdgesWall is w' & cWorld . lWorld . wallDamages .~ IM.empty where f isw k dams = fromMaybe isw $ do wl <- isw ^? _2 . cWorld . lWorld . walls . ix k return $ foldl' (flip (`damageWall` wl)) isw dams updateEdgesWall :: S.Set Int2 -> World -> World updateEdgesWall is w = hack $ updateEdgesWall' (zonesExtract (w ^. incEdgeZoning & each . each %~ S.fromList) is) w where hack w' | null is = w' | otherwise = (foldMap Sum $ w' ^.. cWorld . incGraph . each . each . seObstacles . to length) `seq` w' updateEdgesWall' :: S.Set (Int, Int) -> World -> World updateEdgesWall' = flip $ foldl' updateEdgeWallObs updateEdgeWallObs :: World -> (Int, Int) -> World updateEdgeWallObs w (i, j) = w & cWorld . incGraph . ix i . ix j . seObstacles %~ f wlflags where s = w ^?! cWorld . incNode . ix i e = w ^?! cWorld . incNode . ix j wlflags = foldMap (^. _2 . to getWallPathing) $ wlsHitUnsorted s e w f x = (`S.union` S.map WallObstacle x) . (S.\\ (S.fromList $ map WallObstacle [minBound .. maxBound]))