Make thingsHit use streaming
This commit is contained in:
@@ -6,9 +6,7 @@ module Dodge.WorldEvent.ThingsHit
|
||||
( thingsHit
|
||||
, wallsHit
|
||||
, thingHit
|
||||
, thingsHitLongLine
|
||||
, thingsHitExceptCr
|
||||
, thingsHitExceptCrLongLine
|
||||
)
|
||||
where
|
||||
import Dodge.Data
|
||||
@@ -20,27 +18,31 @@ import qualified Data.IntMap.Strict as IM
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import Data.Bifunctor
|
||||
import Streaming
|
||||
import qualified Streaming.Prelude as S
|
||||
|
||||
{- List those objects that appear on a line. -}
|
||||
thingsHit
|
||||
:: Point2 -- ^ Line start point
|
||||
-> Point2 -- ^ Line end point
|
||||
-> World
|
||||
-> [(Point2, Either Creature Wall)]
|
||||
-> Stream (Of (Point2, Either Creature Wall)) Identity ()
|
||||
thingsHit sp ep w
|
||||
| sp == ep = []
|
||||
| otherwise = sortOn (dist sp . fst) (crs ++ wls)
|
||||
| sp == ep = S.each []
|
||||
| otherwise = fmap (const ()) $ S.mergeOn (dist sp . fst) crs wls
|
||||
where
|
||||
crs = mapMaybe
|
||||
(\cr -> (,Left cr) <$> listToMaybe (intersectCircSeg (_crPos cr) (_crRad cr) sp ep))
|
||||
. IM.elems
|
||||
crs :: Stream (Of (Point2, Either Creature Wall)) Identity ()
|
||||
crs = sortStreamOn (dist sp . fst)
|
||||
. S.mapMaybe
|
||||
(\cr -> (,Left cr) <$> listToMaybe (intersectCircSeg (_crPos cr) (_crRad cr) sp ep))
|
||||
. S.each
|
||||
$ _creatures w
|
||||
wls = map (second Right) . IM.elems $ wallsOnLineHit sp ep
|
||||
$ IM.unions [f b $ f a $ _znObjects $ _wallsZone w
|
||||
| a<-[x-1,x,x+1] , b<-[y-1,y,y+1]]
|
||||
(x,y) = zoneOfPoint (0.5 *.* (sp +.+ ep))
|
||||
f i = fromMaybe IM.empty . IM.lookup i
|
||||
wls :: Stream (Of (Point2, Either Creature Wall)) Identity ()
|
||||
wls = S.map (second Right)
|
||||
. sortStreamOn (dist sp . fst)
|
||||
. overlapSegWalls sp ep $ wallsAlongLine sp ep w
|
||||
thingHit :: Point2 -> Point2 -> World -> Maybe (Point2, Either Creature Wall)
|
||||
thingHit sp ep = listToMaybe . thingsHit sp ep
|
||||
thingHit sp ep = runIdentity . S.head_ . thingsHit sp ep
|
||||
{- List objects that appear on a line.
|
||||
Can filter out a creature. -}
|
||||
thingsHitExceptCr
|
||||
@@ -48,9 +50,9 @@ thingsHitExceptCr
|
||||
-> Point2 -- ^ Line start point
|
||||
-> Point2 -- ^ Line end point
|
||||
-> World
|
||||
-> [(Point2, Either Creature Wall)]
|
||||
-> Stream (Of (Point2, Either Creature Wall)) Identity ()
|
||||
thingsHitExceptCr Nothing sp ep = thingsHit sp ep
|
||||
thingsHitExceptCr (Just cid) sp ep = filter crNotCid . thingsHit sp ep
|
||||
thingsHitExceptCr (Just cid) sp ep = S.filter crNotCid . thingsHit sp ep
|
||||
where
|
||||
crNotCid (_,Left cr) = _crID cr /= cid
|
||||
crNotCid _ = True
|
||||
@@ -70,27 +72,3 @@ wallsHit sp ep w
|
||||
-- $ _walls w
|
||||
(x,y) = zoneOfPoint (0.5 *.* (sp +.+ ep))
|
||||
f i = fromMaybe IM.empty . IM.lookup i
|
||||
|
||||
thingsHitExceptCrLongLine
|
||||
:: Maybe Int
|
||||
-> Point2
|
||||
-> Point2
|
||||
-> World
|
||||
-> [(Point2, Either Creature Wall)]
|
||||
thingsHitExceptCrLongLine Nothing sp ep = thingsHitLongLine sp ep
|
||||
thingsHitExceptCrLongLine (Just cid) sp ep = filter crNotCid . thingsHitLongLine sp ep
|
||||
where
|
||||
crNotCid (_,Left cr) = _crID cr /= cid
|
||||
crNotCid _ = True
|
||||
|
||||
thingsHitLongLine :: Point2 -> Point2 -> World -> [(Point2, Either Creature Wall)]
|
||||
thingsHitLongLine sp ep w
|
||||
| sp == ep = []
|
||||
| otherwise = sortOn (dist sp . fst) (crs ++ wls)
|
||||
where
|
||||
crs = mapMaybe
|
||||
(\cr -> (,Left cr) <$> listToMaybe (intersectCircSeg (_crPos cr) (_crRad cr) sp ep))
|
||||
. IM.elems
|
||||
$ _creatures w
|
||||
-- $ creaturesAlongLine sp ep w
|
||||
wls = map (second Right) . IM.elems $ wallsOnLineHit sp ep $ _walls w
|
||||
|
||||
Reference in New Issue
Block a user