From ec9552b1d6ab303d54a8bbb8c93418f32fa29654 Mon Sep 17 00:00:00 2001 From: stuebinm Date: Wed, 8 Dec 2021 00:56:31 +0100 Subject: rudimentary linting for overlapping layers --- lib/LayerData.hs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 lib/LayerData.hs (limited to 'lib/LayerData.hs') diff --git a/lib/LayerData.hs b/lib/LayerData.hs new file mode 100644 index 0000000..1a07982 --- /dev/null +++ b/lib/LayerData.hs @@ -0,0 +1,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 -- cgit v1.2.3