Make thingsHit use streaming
This commit is contained in:
@@ -81,9 +81,9 @@ moveFlame :: Point2 -- ^ Rotation direction
|
||||
-> (World, Maybe Particle)
|
||||
moveFlame rotd w pt
|
||||
| time <= 0 = (makeFlamerSmokeAt (addZ 20 ep) w, Nothing)
|
||||
| otherwise = case thingsHitExceptCr (_ptCrIgnore pt) sp ep w of
|
||||
((_,Left _):_) -> (doSound $ dodamage w , mvPt' 0.7)
|
||||
((p,Right wl):_) -> (doSound $ dodamage w , rfl wl p)
|
||||
| otherwise = case runIdentity . S.head_ $ thingsHitExceptCr (_ptCrIgnore pt) sp ep w of
|
||||
Just (_,Left _) -> (doSound $ dodamage w , mvPt' 0.7)
|
||||
Just (p,Right wl) -> (doSound $ dodamage w , rfl wl p)
|
||||
_ -> (ptFlicker pt $ doSound $ dodamage w , mvPt' 0.98)
|
||||
where
|
||||
time = _ptTimer pt
|
||||
@@ -206,10 +206,10 @@ damageInArea :: (Creature -> Bool) -> (Wall -> Bool) -> Particle -> World -> Wor
|
||||
damageInArea crt wlt pt w = damwls damcrs
|
||||
where
|
||||
p = _ptPos pt
|
||||
damcrs = foldl' (flip $ \cr -> fst . hiteff [(p,Left cr)]) w $ IM.filter crt $ _creatures w
|
||||
damcrs = foldl' (flip $ \cr -> fst . hiteff (S.yield (p,Left cr))) w $ IM.filter crt $ _creatures w
|
||||
damwls w' = runIdentity
|
||||
. S.fold_
|
||||
(flip $ \wl -> fst . hiteff [(p,Right wl)])
|
||||
(flip $ \wl -> fst . hiteff (S.yield (p,Right wl)))
|
||||
w'
|
||||
id
|
||||
. S.filter wlt
|
||||
|
||||
@@ -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