Refactor ai
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
{- |
|
||||
Deals with moving creature wall collisions.
|
||||
-}
|
||||
module Dodge.WallCreatureCollisions where
|
||||
-- imports {{{
|
||||
import Dodge.Data
|
||||
import Dodge.Creature.State.Data
|
||||
import Dodge.Base
|
||||
@@ -43,12 +45,11 @@ wallBuffer = 3
|
||||
-- out from the wall
|
||||
-- this is then repeated if the point ends up on a new wall
|
||||
collideWalls :: Float -> Point2 -> [(Point2,Point2)] -> Point2 -> Point2
|
||||
collideWalls rad cp1 walls cp2
|
||||
= case (listToMaybe.mapMaybe (pushOutFromWall rad cp2)) walls of
|
||||
Nothing -> cp2
|
||||
Just cp3 -> case (listToMaybe.reverse.mapMaybe (pushOutFromWall rad cp3)) walls of
|
||||
Nothing -> cp3
|
||||
Just cp4 -> cp4
|
||||
collideWalls rad cp1 walls cp2 = case (listToMaybe.mapMaybe (pushOutFromWall rad cp2)) walls of
|
||||
Nothing -> cp2
|
||||
Just cp3 -> case (listToMaybe.reverse.mapMaybe (pushOutFromWall rad cp3)) walls of
|
||||
Nothing -> cp3
|
||||
Just cp4 -> cp1
|
||||
|
||||
-- pushes a point out from a list of walls
|
||||
-- if multiple new points occur, chooses the one closest to the orignal point
|
||||
@@ -72,15 +73,16 @@ pushOrCrush wls cr = case mapMaybe (pushOutFromWall (_crRad cr) cpos) wls of
|
||||
-- assumes wall points are different
|
||||
pushOutFromWall :: Float -> Point2 -> (Point2,Point2) -> Maybe (Point2)
|
||||
pushOutFromWall rad cp2 (wp1,wp2)
|
||||
| isOnWall = Just newP -- +.+ (1 *.* norm))
|
||||
| otherwise = Nothing
|
||||
where norm = errorNormalizeV 61 $ vNormal (wp1 -.- wp2)
|
||||
wp1' = (rad *.* norm) +.+ wp1
|
||||
wp2' = (rad *.* norm) +.+ wp2
|
||||
newP = errorClosestPointOnLine 5 wp1' wp2' cp2
|
||||
isOnWall = circOnSegNoEndpoints wp1 wp2 cp2 rad
|
||||
isJust Nothing = False
|
||||
isJust _ = True
|
||||
| isOnWall = Just newP -- +.+ (1 *.* norm))
|
||||
| otherwise = Nothing
|
||||
where
|
||||
norm = errorNormalizeV 61 $ vNormal (wp1 -.- wp2)
|
||||
wp1' = (rad *.* norm) +.+ wp1
|
||||
wp2' = (rad *.* norm) +.+ wp2
|
||||
newP = errorClosestPointOnLine 5 wp1' wp2' cp2
|
||||
isOnWall = circOnSegNoEndpoints wp1 wp2 cp2 rad
|
||||
isJust Nothing = False
|
||||
isJust _ = True
|
||||
|
||||
pushOutFromCorners :: World -> Creature -> Creature
|
||||
pushOutFromCorners w cr = cr & crPos .~ newPos
|
||||
@@ -93,8 +95,9 @@ collideCorners rad p1 ps p2 = foldr (intersectCirclePoint rad) p2 ps
|
||||
|
||||
-- collide circles with points (outer corners)
|
||||
intersectCirclePoint :: Float -> Point2 -> Point2 -> Point2
|
||||
intersectCirclePoint rad p cCen | dist cCen p > rad = cCen
|
||||
| otherwise = p +.+ (rad *.* errorNormalizeV 65 (cCen -.- p))
|
||||
intersectCirclePoint rad p cCen
|
||||
| dist cCen p > rad = cCen
|
||||
| otherwise = p +.+ (rad *.* errorNormalizeV 65 (cCen -.- p))
|
||||
|
||||
checkPushThroughs :: Float -> Point2 -> [(Point2,Point2)] -> Point2 -> Point2
|
||||
checkPushThroughs rad cp1 walls cp2
|
||||
@@ -102,12 +105,13 @@ checkPushThroughs rad cp1 walls cp2
|
||||
|
||||
checkPushThrough :: Float -> Point2 -> Point2 -> (Point2,Point2) -> Maybe (Point2)
|
||||
checkPushThrough rad cp1 cp2 (wp1,wp2)
|
||||
| isPushedThrough = intersectSegSeg' cp1 cp2 wp1 wp2
|
||||
| otherwise = Nothing
|
||||
where norm = errorNormalizeV 61 $ vNormal (wp1 -.- wp2)
|
||||
wp1' = (rad *.* norm) +.+ wp1
|
||||
wp2' = (rad *.* norm) +.+ wp2
|
||||
newP = errorClosestPointOnLine 5 wp1' wp2' cp2
|
||||
isPushedThrough = isRHS wp1 wp2 cp2 && isJust (intersectSegSeg' cp1 cp2 wp1 wp2)
|
||||
isJust Nothing = False
|
||||
isJust _ = True
|
||||
| isPushedThrough = intersectSegSeg' cp1 cp2 wp1 wp2
|
||||
| otherwise = Nothing
|
||||
where
|
||||
norm = errorNormalizeV 61 $ vNormal (wp1 -.- wp2)
|
||||
wp1' = (rad *.* norm) +.+ wp1
|
||||
wp2' = (rad *.* norm) +.+ wp2
|
||||
newP = errorClosestPointOnLine 5 wp1' wp2' cp2
|
||||
isPushedThrough = isRHS wp1 wp2 cp2 && isJust (intersectSegSeg' cp1 cp2 wp1 wp2)
|
||||
isJust Nothing = False
|
||||
isJust _ = True
|
||||
|
||||
Reference in New Issue
Block a user