Cleanup and various bugfixes

This commit is contained in:
2021-11-16 21:31:53 +00:00
parent ebe9ad6b90
commit 5d0b48829c
12 changed files with 103 additions and 39 deletions
+1
View File
@@ -17,6 +17,7 @@ import Dodge.LevelGen.Data
import Dodge.LevelGen.Switch import Dodge.LevelGen.Switch
import Dodge.Item.Weapon.Launcher import Dodge.Item.Weapon.Launcher
import Dodge.PlacementSpot import Dodge.PlacementSpot
import Dodge.RoomPos
import MonadHelp import MonadHelp
import Data.Tree import Data.Tree
import Color import Color
+1
View File
@@ -10,5 +10,6 @@ data GameRoom = GameRoom
, _grViewpointsEx :: [Point2] , _grViewpointsEx :: [Point2]
, _grBound :: [Point2] , _grBound :: [Point2]
, _grDir :: Float -- ^ gives direction of room , _grDir :: Float -- ^ gives direction of room
, _grLinkDirs :: [Float]
, _grName :: String , _grName :: String
} }
+22 -14
View File
@@ -149,23 +149,31 @@ wallsFromRooms =
where where
f i (x,y) = (i, defaultWall {_wlLine = (x,y) , _wlID = i}) f i (x,y) = (i, defaultWall {_wlLine = (x,y) , _wlID = i})
-- TODO sort out shifting before or after etc
gameRoomsFromRooms :: [Room] -> [GameRoom] gameRoomsFromRooms :: [Room] -> [GameRoom]
gameRoomsFromRooms = map f gameRoomsFromRooms = map gameRoomFromRoom
gameRoomFromRoom :: Room -> GameRoom
gameRoomFromRoom rm = GameRoom
{ _grViewpoints = _rmViewpoints rm ++ (map fst . foldl' (flip cutWalls) [] $ _rmPolys rm)
-- ++ map fst (_rmLinks rm)
, _grViewpointsEx = mapMaybe unpos (_rmPos rm)
, _grBound = expandPolyCorners 50 . convexHullSafe . nubBy closePoints
. concat $ _rmBound rm ++ _rmPolys rm
, _grDir = getDir $ _rmPos rm
, _grLinkDirs = mapMaybe undir $ _rmPos rm
, _grName = _rmName rm
}
where where
f rm = GameRoom doshift = shiftPointBy (_rmShift rm)
{ _grViewpoints = _rmViewpoints rm ++ (map fst . foldl' (flip cutWalls) [] $ _rmPolys rm) unpos (OutLink _ p _) = Just $ doshift p
++ map fst (_rmLinks rm) unpos (InLink p _) = Just $ doshift p
, _grViewpointsEx = mapMaybe unpos (_rmPos rm)
, _grBound = expandPolyByFixed 100 . convexHullSafe . nubBy closePoints
. concat $ _rmBound rm ++ _rmPolys rm
, _grDir = getDir $ _rmPos rm
, _grName = _rmName rm
}
closePoints x y = roundPoint2 x == roundPoint2 y
unpos (OutLink _ p _) = Just p
unpos (InLink p _) = Just p
unpos _ = Nothing unpos _ = Nothing
getDir (InLink _ a:_) = a undir (OutLink _ _ a) = Just $ 0.5*pi + a + snd (_rmShift rm)
undir (InLink _ a) = Just $ 0.5*pi + a + snd (_rmShift rm)
undir _ = Nothing
closePoints x y = roundPoint2 x == roundPoint2 y
getDir (InLink _ a:_) = a -- + snd (_rmShift rm)
getDir (_:xs) = getDir xs getDir (_:xs) = getDir xs
getDir _ = 0 -- fallback getDir _ = 0 -- fallback
-8
View File
@@ -92,14 +92,6 @@ data RoomPos
| LabPos Int RoomPos | LabPos Int RoomPos
deriving (Eq,Ord,Show) deriving (Eq,Ord,Show)
extractRoomPos :: RoomPos -> (Point2,Float)
extractRoomPos rp = case rp of
OutLink _ p a -> (p,a)
InLink p a -> (p,a)
UnusedLink p a -> (p,a)
PosPl p a -> (p,a)
LabPos _ rp' -> extractRoomPos rp'
makeLenses ''Room makeLenses ''Room
makeLenses ''PSType makeLenses ''PSType
makeLenses ''PlacementSpot makeLenses ''PlacementSpot
+8
View File
@@ -7,6 +7,7 @@ module Dodge.LevelGen.StaticWalls
, removeInverseWalls , removeInverseWalls
, expandPolyByFixed , expandPolyByFixed
, cutPoly , cutPoly
, expandPolyCorners
) )
where where
import Geometry import Geometry
@@ -96,6 +97,13 @@ expandPolyByFixed :: Float -> [Point2] -> [Point2]
expandPolyByFixed x ps = map f ps expandPolyByFixed x ps = map f ps
where where
f p = p +.+ x *.* safeNormalizeV (p -.- centroid ps) f p = p +.+ x *.* safeNormalizeV (p -.- centroid ps)
-- | Given a value and a poly, pushes points out by a fixed amount along an
-- angle determined by the corner, i.e. by the two other neighbour points
expandPolyCorners :: Float -> [Point2] -> [Point2]
expandPolyCorners d (x:y:z:xs) = zipWith3 f (x:y:z:xs) (y:z:xs++[x]) (z:xs ++ [x,y])
where
f l c r = c +.+ d *.* normalizeV (normalizeV (c -.- r) +.+ normalizeV (c -.- l))
expandPolyCorners _ _ = error "trying to expand poly corners of 2 or fewer points"
-- | Given a polygon expressed as a list of points and a collection of walls, -- | Given a polygon expressed as a list of points and a collection of walls,
-- returns: -- returns:
-- fst: points of the polygon's intersection with walls -- fst: points of the polygon's intersection with walls
-1
View File
@@ -1,6 +1,5 @@
module Dodge.Path module Dodge.Path
( pointTowardsImpulse ( pointTowardsImpulse
--, pointTowardsImpulse'
, makePathBetween , makePathBetween
, makePathBetweenPs , makePathBetweenPs
, removePathsCrossing , removePathsCrossing
+6 -5
View File
@@ -66,14 +66,15 @@ roomRect x y xn yn = defaultRoom
lnks = nlnks ++ elnks ++ wlnks ++ slnks lnks = nlnks ++ elnks ++ wlnks ++ slnks
pth = linksAndPath lnks $ map (bimap (+.+ V2 20 20) (+.+ V2 20 20)) (makeGrid xd xn yd yn) pth = linksAndPath lnks $ map (bimap (+.+ V2 20 20) (+.+ V2 20 20)) (makeGrid xd xn yd yn)
{- Creates a rectangular room, automatically creates links and pathfinding graph at a sensible size. -} {- Creates a rectangular room, automatically creates links and pathfinding graph at a sensible size. -}
-- it is not clear to me that this works for very small rooms (but it does seem
-- to do so)
roomRectAutoLinks :: Float -> Float -> Room roomRectAutoLinks :: Float -> Float -> Room
roomRectAutoLinks x y = (roomRect x y ((ceiling x - 40) `div` 60) ((ceiling y - 40) `div` 60)) roomRectAutoLinks x y = (roomRect x y xn yn)
{_rmPmnts = plmnts} {_rmPmnts = plmnts}
where where
plmnts = xn = max 1 $ (ceiling x - 40) `div` 60
[mntLightLnkCond unusedLnkToPS yn = max 1 $ (ceiling y - 40) `div` 60
-- ,sps0 $ PutForeground $ thinHighBarChain 50 $ rectNSWE y 0 0 x plmnts = [mntLightLnkCond unusedLnkToPS ]
]
{- Combines two rooms into one room. {- Combines two rooms into one room.
Mostly involves concatenation. -} Mostly involves concatenation. -}
combineRooms :: Room -> Room -> Room combineRooms :: Room -> Room -> Room
+48 -8
View File
@@ -1,7 +1,10 @@
module Dodge.Room.Start where module Dodge.Room.Start where
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Data import Dodge.Data
import Dodge.Layout.Tree.Either
import Dodge.RandomHelp
import Dodge.Room.Door import Dodge.Room.Door
import Dodge.Room.Room
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Room.Foreground import Dodge.Room.Foreground
@@ -23,23 +26,38 @@ import System.Random
--import qualified Data.IntMap.Strict as IM --import qualified Data.IntMap.Strict as IM
rezBox :: Room rezBox :: Room
--rezBox = shiftRoomBy (V2 (-20) (-10),0) $ roomRect 40 20 1 1
rezBox = roomRect 40 60 1 1 rezBox = roomRect 40 60 1 1
& rmPmnts .~ [ spanColLightI (V3 0 0 0.5) 95 (V2 0 1) (V2 40 1) ] & rmPmnts .~ [ spanColLightI rezcol 95 (V2 0 1) (V2 40 1) ]
rezcol :: Point3
rezcol = V3 0.0 0.1 0.5
rezInvBox :: Room rezInvBox :: Room
rezInvBox = roomRect 40 60 1 1 rezInvBox = roomRect 40 60 1 1
& rmPmnts .~ [ spanColLightI (V3 0 0 0.5) 95 (V2 0 59) (V2 40 59) ] & rmPmnts .~ [ spanColLightI rezcol 95 (V2 0 59) (V2 40 59) ]
crRezBox :: Room crRezBox :: Room
crRezBox = rezInvBox -- & rmPmnts %~ (sPS (V2 20 0) pi randC1 :) crRezBox = rezInvBox & rmPmnts %~ (sPS (V2 20 50) (1.5*pi) randC1 :)
wpRezBox :: Item -> Room wpRezBox :: Item -> Room
wpRezBox wp = rezInvBox & rmPmnts %~ (sPS (V2 15 30) 1 (PutFlIt wp) :) wpRezBox wp = rezInvBox & rmPmnts %~ (sPS (V2 15 30) 1 (PutFlIt wp) :)
rezBoxesThenWeaponRoom :: RandomGen g => State g (Tree (Either Room Room))
rezBoxesThenWeaponRoom = do
rboxes <- rezBoxes
wroom <- weaponRoom
return $ rboxes `appendEitherTree` [wroom]
startRoom :: RandomGen g => State g (Tree (Either Room Room)) startRoom :: RandomGen g => State g (Tree (Either Room Room))
startRoom = do startRoom = join $ takeOne
w <- state $ randomR (100,400) [-- rezBoxesWp
rezBoxesThenWeaponRoom
--, rezBoxesWpCrit
]
rezBoxesWpCrit :: RandomGen g => State g (Tree (Either Room Room))
rezBoxesWpCrit = do
w <- state $ randomR (200,400)
h <- state $ randomR (40,40) h <- state $ randomR (40,40)
theweapon <- randBlockBreakWeapon theweapon <- randBlockBreakWeapon
let bottomEdgeTest (V2 _ y,_) = y < 1 let bottomEdgeTest (V2 _ y,_) = y < 1
@@ -63,8 +81,30 @@ startRoom = do
adddoor rm = treeFromPost [Left door] (Left rm) adddoor rm = treeFromPost [Left door] (Left rm)
onwardtree blcor = treeFromPost [Left door] (Right blcor) onwardtree blcor = treeFromPost [Left door] (Right blcor)
randomRezBoxes :: RandomGen g => State g (Tree (Either Room Room)) rezBoxesWp :: RandomGen g => State g (Tree (Either Room Room))
randomRezBoxes = do rezBoxesWp = do
w <- state $ randomR (100,400)
h <- state $ randomR (40,40)
theweapon <- randBlockBreakWeapon
let bottomEdgeTest (V2 _ y,_) = y < 1
centralRoom <- randomiseOutLinks =<< changeLinkTo bottomEdgeTest
((roomRectAutoLinks w h) {_rmPmnts = []})
blcor <- blockedCorridor'
let n = length $ filter bottomEdgeTest $ _rmLinks centralRoom
let rezrooms = map adddoor
$ wpRezBox theweapon : replicate (n-2) rezInvBox
centralRoom' <- changeLinkFrom bottomEdgeTest centralRoom
return $ treeFromTrunk [Left rezBox
, Left door
]
(Node (Left centralRoom') (rezrooms ++ [onwardtree blcor]))
where
--dbox = treeFromPost [Left door] (Left rezInvBox)
adddoor rm = treeFromPost [Left door] (Left rm)
onwardtree blcor = treeFromPost [Left door] (Right blcor)
rezBoxes :: RandomGen g => State g (Tree (Either Room Room))
rezBoxes = do
w <- state $ randomR (100,400) w <- state $ randomR (100,400)
h <- state $ randomR (40,40) h <- state $ randomR (40,40)
let bottomEdgeTest (V2 _ y,_) = y < 1 let bottomEdgeTest (V2 _ y,_) = y < 1
+11
View File
@@ -0,0 +1,11 @@
module Dodge.RoomPos where
import Dodge.LevelGen.Data
import Geometry
extractRoomPos :: RoomPos -> (Point2,Float)
extractRoomPos rp = case rp of
OutLink _ p a -> (p,a)
InLink p a -> (p,a)
UnusedLink p a -> (p,a)
PosPl p a -> (p,a)
LabPos _ rp' -> extractRoomPos rp'
+4 -1
View File
@@ -176,9 +176,12 @@ farWallPoints :: Point2 -> World -> [Point2]
farWallPoints p w = concatMap _grViewpoints grs ++ linkvps farWallPoints p w = concatMap _grViewpoints grs ++ linkvps
where where
grs = filter (pointInOrOnPolygon p . _grBound) (_gameRooms w) grs = filter (pointInOrOnPolygon p . _grBound) (_gameRooms w)
linkvps = map extend (concatMap _grViewpointsEx grs) linkvps = map extend (concatMap _grViewpointsEx grs
++ map addDir (concatMap _grLinkDirs grs)
)
extend :: Point2 -> Point2 extend :: Point2 -> Point2
extend outp = p +.+ maxViewDistance *.* safeNormalizeV (outp -.- p) extend outp = p +.+ maxViewDistance *.* safeNormalizeV (outp -.- p)
addDir a = p +.+ unitVectorAtAngle a
maxViewDistance :: Float maxViewDistance :: Float
maxViewDistance = 800 maxViewDistance = 800
+1 -1
View File
@@ -163,7 +163,7 @@ grahamScan = foldr push []
-- https://codereview.stackexchange.com/questions/206019/graham-scan-algorithm-in-haskell -- https://codereview.stackexchange.com/questions/206019/graham-scan-algorithm-in-haskell
grahamEliminate :: [Point2] -> [Point2] grahamEliminate :: [Point2] -> [Point2]
grahamEliminate (x:y:z:xs) grahamEliminate (x:y:z:xs)
| isRHS x y z = grahamEliminate (x:z:xs) | not $ isLHS x y z = grahamEliminate (x:z:xs)
grahamEliminate xs = xs grahamEliminate xs = xs
-- | Return midpoint between two points. -- | Return midpoint between two points.
+1 -1
View File
@@ -22,7 +22,7 @@ isLHS
a2 = y' - y a2 = y' - y
b1 = x'' - x b1 = x'' - x
b2 = y'' - y b2 = y'' - y
-- | Test whether a point is on the LHS of a line. -- | Test whether a point is on the RHS of a line.
-- Returns False if the line is of zero length. -- Returns False if the line is of zero length.
isRHS isRHS
:: Point2 -- ^ First line point. :: Point2 -- ^ First line point.