Identify broken wall collisions

This commit is contained in:
2021-11-19 00:35:04 +00:00
parent 15f2c419d2
commit b1a49bbdc3
13 changed files with 112 additions and 24 deletions
+48 -1
View File
@@ -6,6 +6,7 @@ module Dodge.WorldEvent.ThingsHit
, thingHit
, thingsHitLongLine
, thingsHitExceptCr
, thingsHitExceptCr3D'
, thingsHitExceptCrLongLine
)
where
@@ -13,12 +14,14 @@ import Dodge.Data
import Dodge.Base
import Dodge.Zone
import Geometry
import Geometry.Vector3D
import qualified Data.IntMap.Strict as IM
import Data.List
import Data.Maybe
import Data.Bifunctor
{- List those objects that appear on a line. -}
thingsHit
thingsHit
:: Point2 -- ^ Line start point
-> Point2 -- ^ Line end point
-> World
@@ -41,8 +44,52 @@ thingsHit sp ep w
_ -> IM.empty
wls = zip (map (fromJust . hitPoint) hitWls) (map Right hitWls)
hitPoint w' = uncurry (intersectSegSeg sp ep) (_wlLine w')
{- List those objects that appear on a line. -}
thingsHit3D
:: Point3 -- ^ Line start point
-> Point3 -- ^ Line end point
-> World
-> [(Point3, Either Creature Wall)]
thingsHit3D sp ep w
| sp == ep = []
| otherwise = sortOn (dist3 sp . fst) (crs ++ wls)
where
hitCrs = IM.elems
$ IM.filter (\cr -> circOnSeg (stripZ sp) (stripZ ep) (_crPos cr) (_crRad cr))
$ _creatures w
crPs = map (\cr -> ssaTriPoint (stripZ ep) (_crPos cr) (stripZ sp) (_crRad cr)) hitCrs
crs = zip (map (addZ 20) crPs) (map Left hitCrs)
hitWls = wallsOnLine (stripZ sp) (stripZ 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 *.* (stripZ sp +.+ stripZ ep))
f i m = case IM.lookup i m of
Just val -> val
_ -> IM.empty
wls = zip (map (addZ 20 . fromJust . hitPoint) hitWls) (map Right hitWls)
hitPoint w' = uncurry (intersectSegSeg (stripZ sp) (stripZ ep)) (_wlLine w')
thingHit :: Point2 -> Point2 -> World -> Maybe (Point2, Either Creature Wall)
thingHit sp ep = listToMaybe . thingsHit sp ep
thingsHitExceptCr3D'
:: Maybe Int -- ^ A possible creature ID
-> Point3 -- ^ Line start point
-> Point3 -- ^ Line end point
-> World
-> [(Point2, Either Creature Wall)]
thingsHitExceptCr3D' mcid sp ep = fmap (first stripZ) . thingsHitExceptCr3D mcid sp ep
{- List objects that appear on a line.
Can filter out a creature. -}
thingsHitExceptCr3D
:: Maybe Int -- ^ A possible creature ID
-> Point3 -- ^ Line start point
-> Point3 -- ^ Line end point
-> World
-> [(Point3, Either Creature Wall)]
thingsHitExceptCr3D Nothing sp ep = thingsHit3D sp ep
thingsHitExceptCr3D (Just cid) sp ep = filter crNotCid . thingsHit3D sp ep
where
crNotCid (_,Left cr) = _crID cr /= cid
crNotCid _ = True
{- List objects that appear on a line.
Can filter out a creature. -}
thingsHitExceptCr