summaryrefslogtreecommitdiff
path: root/lib/LayerData.hs
blob: 1a07982adfb6db81345b641b29ae10284860f500 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{-# LANGUAGE OverloadedStrings #-}

module LayerData where


import           Control.Monad.Zip (mzipWith)
import           Data.Set          (Set, insert)
import           Data.Text         (Text)
import qualified Data.Text         as T
import           Data.Vector       (Vector, uncons)
import           Tiled             (GlobalId (unGlobalId), Layer (..))
import           Util              (PrettyPrint (..))

-- | A collision between two layers of the given names.
-- Wrapped in a newtype so that Eq can ignore the order of the two
newtype Collision = Collision { fromCollision ::  (Text, Text) }
  deriving Ord

instance Eq Collision where
  (Collision (a,b)) == (Collision (a',b')) = ((a,b) == (a',b')) || ((a,b) == (b',a'))

instance PrettyPrint Collision where
  prettyprint (Collision (a,b)) = a <> " and " <> b

instance Show Collision where
  show c = T.unpack $ prettyprint c

-- | Finds pairwise tile collisions between the given layers.
layerOverlaps :: Vector Layer -> Set Collision
layerOverlaps layers = case uncons layers of
  Nothing -> mempty
  Just (l, ls) ->
   fst . foldr overlapBetween (mempty, l) $ ls
   where overlapBetween :: Layer -> (Set Collision, Layer) -> (Set Collision, Layer)
         overlapBetween layer (acc, oldlayer) =
          (if collides then insert collision acc else acc, layer)
          where
           collision = Collision (layerName layer, layerName oldlayer)
           collides = case (layerData layer, layerData oldlayer) of
             (Just d1, Just d2) ->
               0 /= maximum (mzipWith (\a b -> unGlobalId a * unGlobalId b) d1 d2)
             _ -> False