Improve bullet hit detection

This commit is contained in:
2026-04-13 20:26:34 +01:00
parent b8bec2c830
commit 431e64fbfb
8 changed files with 59 additions and 17 deletions
+11
View File
@@ -18,6 +18,7 @@ module Dodge.Base.Collide (
collideCircWalls, collideCircWalls,
overlapSegWalls, overlapSegWalls,
overlapSegCrs, overlapSegCrs,
overlapSegCrs',
bouncePoint, bouncePoint,
circOnSomeWall, circOnSomeWall,
circOnAnyCr, circOnAnyCr,
@@ -35,6 +36,7 @@ module Dodge.Base.Collide (
crHeight, crHeight,
) where ) where
import Control.Applicative
import Data.Foldable import Data.Foldable
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import Control.Lens import Control.Lens
@@ -66,6 +68,15 @@ overlapSegCrs sp ep = mapMaybe f
(,cr) (,cr)
<$> fst (intersectCircSeg (cr ^. crPos . _xy) (crRad $ cr ^. crType) sp ep) <$> fst (intersectCircSeg (cr ^. crPos . _xy) (crRad $ cr ^. crType) sp ep)
overlapSegCrs' :: Point2 -> Point2 -> [Creature] -> [(Point2, Creature)]
{-# INLINE overlapSegCrs' #-}
overlapSegCrs' sp ep = mapMaybe f
where
f cr =
(,cr)
<$> g (intersectCircSeg (cr ^. crPos . _xy) (crRad $ cr ^. crType) sp ep)
g (a,b) = a <|> b
doBounce :: Float -> Point2 -> Point2 -> (Point2, Maybe Wall) -> Maybe (Point2, Point2) doBounce :: Float -> Point2 -> Point2 -> (Point2, Maybe Wall) -> Maybe (Point2, Point2)
{-# INLINE doBounce #-} {-# INLINE doBounce #-}
doBounce x sp ep (p, mwl) = fmap f mwl doBounce x sp ep (p, mwl) = fmap f mwl
+1 -1
View File
@@ -168,7 +168,7 @@ hitEffFromBul w bu = case _buEffect bu of
DestroyBullet -> expireAndDamage bu hitstream w DestroyBullet -> expireAndDamage bu hitstream w
where where
sp = _buPos bu sp = _buPos bu
hitstream = thingsHitZ 20 sp (sp + _buVel bu) w hitstream = thingsHitZ' 20 sp (sp + _buVel bu) w
getBulHitDams :: Bullet -> Point2 -> [Damage] getBulHitDams :: Bullet -> Point2 -> [Damage]
getBulHitDams bu p = case _buPayload bu of getBulHitDams bu p = case _buPayload bu of
+1 -1
View File
@@ -66,7 +66,7 @@ slimeCrit :: Creature
slimeCrit = defaultCreature slimeCrit = defaultCreature
& crName .~ "slimeCrit" & crName .~ "slimeCrit"
& crHP .~ HP 1000 & crHP .~ HP 1000
& crType .~ SlimeCrit 40 0 (V2 50 0) False True & crType .~ SlimeCrit 40 0 0 (V2 50 0) False True
& crFaction .~ ColorFaction (light green) & crFaction .~ ColorFaction (light green)
& crPerception . cpVision . viFOV .~ FloatFOV pi & crPerception . cpVision . viFOV .~ FloatFOV pi
& crActionPlan .~ SlimeIntelligence & crActionPlan .~ SlimeIntelligence
+1 -2
View File
@@ -3,7 +3,6 @@
module Dodge.Creature.Update (updateCreature) where module Dodge.Creature.Update (updateCreature) where
import Dodge.WorldEvent.ThingsHit import Dodge.WorldEvent.ThingsHit
import Dodge.Creature.Radius
import Color import Color
import Control.Monad import Control.Monad
import qualified IntMapHelp as IM import qualified IntMapHelp as IM
@@ -112,7 +111,7 @@ slimeCritUpdate cid w
| otherwise = id | otherwise = id
v = (s * r) *^ unitVectorAtAngle (cr ^. crDir) v = (s * r) *^ unitVectorAtAngle (cr ^. crDir)
--r = crRad (cr ^. crType) --r = crRad (cr ^. crType)
r = (cr ^?! crType . slimeRad) r = cr ^?! crType . slimeRad
p = cr ^?! crType . slimeCompression p = cr ^?! crType . slimeCompression
(p',f') (p',f')
| dot p v > 0 && dot p v > dot p (vNormal v) && dot p v > dot p (-vNormal v) = (p, id) | dot p v > 0 && dot p v > dot p (vNormal v) && dot p v > dot p (-vNormal v) = (p, id)
+1
View File
@@ -73,6 +73,7 @@ data CreatureType
| SlimeCrit | SlimeCrit
{ _slimeRad :: Float { _slimeRad :: Float
, _slimeRadWobble :: Float , _slimeRadWobble :: Float
, _slimeSplitTimer :: Int
, _slimeCompression :: Point2 , _slimeCompression :: Point2
, _slimeIsCompressing :: Bool , _slimeIsCompressing :: Bool
, _slimeResetDir :: Bool , _slimeResetDir :: Bool
+8 -8
View File
@@ -29,15 +29,15 @@ chaseCritInternal w cr =
crabCritInternal :: Int -> World -> World crabCritInternal :: Int -> World -> World
crabCritInternal cid w = crabCritInternal cid w =
-- (crVocalization %~ updateVocTimer) -- (crVocalization %~ updateVocTimer)
(tocr %~ ((crType . meleeCooldownL %~ max 0 . subtract 1))) (tocr %~ (crType . meleeCooldownL %~ max 0 . subtract 1))
. (tocr %~ ((crType . meleeCooldownR %~ max 0 . subtract 1))) . (tocr %~ (crType . meleeCooldownR %~ max 0 . subtract 1))
. (tocr %~ ((crType . dodgeCooldown %~ max 0 . subtract 1))) . (tocr %~ (crType . dodgeCooldown %~ max 0 . subtract 1))
. (tocr %~ (searchIfDamaged)) . (tocr %~ searchIfDamaged)
. (tocr %~ (targetYouWhenCognizant w)) . (tocr %~ targetYouWhenCognizant w)
. (tocr %~ (perceptionUpdate [0] w)) . (tocr %~ perceptionUpdate [0] w)
. crabActionUpdate cid . crabActionUpdate cid
. (tocr %~ (setMvPosToTargetCr w)) . (tocr %~ setMvPosToTargetCr w)
. (tocr %~ (setViewPos w)) . (tocr %~ setViewPos w)
-- . overrideMeleeCloseTarget w -- . overrideMeleeCloseTarget w
$ (tocr %~ doStrategyActions) w $ (tocr %~ doStrategyActions) w
where where
+7 -5
View File
@@ -57,12 +57,14 @@ tutAnoTree = do
foldMTRS foldMTRS
[ tToBTree "TutStartRez" . return . cleatOnward <$> tutRezBox [ tToBTree "TutStartRez" . return . cleatOnward <$> tutRezBox
, corDoor , corDoor
, tToBTree "" . return . cleatOnward <$> (cChasm -- , tToBTree "" . return . cleatOnward <$> (cChasm
<&> rmPmnts .:~ (sps0 (PutCrit slimeCrit) & plSpot . psPos .~ V2 100 20)) -- <&> rmPmnts .:~ (sps0 (PutCrit slimeCrit) & plSpot . psPos .~ V2 100 20))
, corDoor -- , corDoor
, loadAmmoTut -- , loadAmmoTut
, corDoor -- , corDoor
, chasmSpitTerminal , chasmSpitTerminal
, corDoor
, tutHub
--b , corDoor --b , corDoor
--b , tToBTree "slowCrush" . return . cleatOnward <$> pushCaverns --b , tToBTree "slowCrush" . return . cleatOnward <$> pushCaverns
--b , corDoor --b , corDoor
+29
View File
@@ -6,6 +6,7 @@ Find which objects lie upon a line.
module Dodge.WorldEvent.ThingsHit ( module Dodge.WorldEvent.ThingsHit (
thingsHit, thingsHit,
thingsHitZ, thingsHitZ,
thingsHitZ',
thingHit, thingHit,
thingHitFilt, thingHitFilt,
thingsHitExceptCr, thingsHitExceptCr,
@@ -59,6 +60,14 @@ thingsHitZ z sp ep w =
(map (second Left) (crsHitZ z sp ep w)) (map (second Left) (crsHitZ z sp ep w))
(map (second Right) (wlsHit sp ep w)) (map (second Right) (wlsHit sp ep w))
-- includes cr exit wounds
thingsHitZ' :: Float -> Point2 -> Point2 -> World -> [(Point2, Either Creature Wall)]
thingsHitZ' z sp ep w =
List.mergeOn
(dist sp . fst)
(map (second Left) (crsHitZ' z sp ep w))
(map (second Right) (wlsHit sp ep w))
crWlPbHit :: Point2 -> Point2 -> World -> [(Point2, Object)] crWlPbHit :: Point2 -> Point2 -> World -> [(Point2, Object)]
crWlPbHit sp ep w = crWlPbHit sp ep w =
List.mergeOn List.mergeOn
@@ -104,6 +113,26 @@ crsHitZ z sp ep w
. IS.toList . IS.toList
. crixsNearSeg sp ep . crixsNearSeg sp ep
$ w $ w
where
f cr
-- | CrDestroyed{} <- cr ^. crHP = Nothing
-- | otherwise = Just cr
| HP{} <- cr ^. crHP = Just cr
| CrIsCorpse{} <- cr ^. crHP
, z < 5 = Just cr
| otherwise = Nothing
-- records exit wounds if there is no entry wound
crsHitZ' :: Float -> Point2 -> Point2 -> World -> [(Point2, Creature)]
crsHitZ' z sp ep w
| sp == ep = mempty
| otherwise =
sortOn (dist sp . fst)
. overlapSegCrs' sp ep
. mapMaybe (\cid -> f =<< w ^? cWorld . lWorld . creatures . ix cid)
. IS.toList
. crixsNearSeg sp ep
$ w
where where
f cr f cr
| HP{} <- cr ^. crHP = Just cr | HP{} <- cr ^. crHP = Just cr