Cleanup: broken pathfinding

This commit is contained in:
2021-11-16 18:05:47 +00:00
parent cb8cbe03a4
commit ebe9ad6b90
42 changed files with 491 additions and 301 deletions
+2 -2
View File
@@ -3,7 +3,7 @@ module Main
) where ) where
import Loop import Loop
import Dodge.Data import Dodge.Data
import Dodge.Initialisation import Dodge.LevelGen
import Dodge.Update import Dodge.Update
import Dodge.Event import Dodge.Event
import Dodge.Render import Dodge.Render
@@ -56,7 +56,7 @@ firstWorldLoad theConfig = do
SDL.cursorVisible $= False SDL.cursorVisible $= False
theKeyConfig <- loadKeyConfig theKeyConfig <- loadKeyConfig
pdata <- doPreload >>= applyWorldConfig theConfig pdata <- doPreload >>= applyWorldConfig theConfig
w <- worldFromSeed 0 w <- generateWorldFromSeed 0
return $ w & preloadData .~ pdata return $ w & preloadData .~ pdata
& keyConfig .~ theKeyConfig & keyConfig .~ theKeyConfig
& config .~ theConfig & config .~ theConfig
+69
View File
@@ -0,0 +1,69 @@
{- | Annotating tree structures with desired properties for rooms. -}
module Dodge.Annotation
( module Dodge.Annotation.Data
, module Dodge.Annotation
) where
import Dodge.RandomHelp
import Dodge.Layout.Tree.Polymorphic
import Dodge.Layout.Tree.Either
import Dodge.Room
import Dodge.Annotation.Data
import Data.Tree
import Control.Monad.State
import System.Random
import Control.Lens
addLock :: RandomGen g => Int -> Tree [Annotation g] -> State g (Tree [Annotation g])
addLock i t = do
(beforeLock, afterLock) <- splitTrunk t
newBefore <- applyToRandomNode (Key i :) beforeLock
return $ addToTrunk newBefore [Node [Lock i] afterLock]
{- | Add one corridor between each parent-child link of a tree of annotations. -}
padWithCorridors :: Tree [Annotation g] -> Tree [Annotation g]
padWithCorridors (Node x xs) = Node [Corridor] [Node x (map padWithCorridors xs)]
padSucWithCorridors :: Tree [Annotation g] -> Tree [Annotation g]
padSucWithCorridors (Node x xs) = Node x (map padWithCorridors xs)
{- Add one to three corridors between each parent-child link of a tree of annotations. -}
randomPadCorridors :: RandomGen g => Tree [Annotation g] -> State g (Tree [Annotation g])
randomPadCorridors (Node x xs) = do
n <- state $ randomR (1, 3)
xs' <- mapM randomPadCorridors xs
return $ treeFromTrunk (replicate n [Corridor]) (Node x xs')
{- | Add a corridor to a random out-link of a room. -}
roomThenCorridor :: RandomGen g => Room -> State g (Tree (Either Room Room))
roomThenCorridor theRoom = fmap (\r -> Node (Left theRoom) [(pure . Right) r])
(randomiseOutLinks corridor)
{- | Create a random room tree structure from a list of annotations. -}
anoToRoomTree :: RandomGen g => [Annotation g] -> State g (Tree (Either Room Room))
anoToRoomTree anos = case anos of
[SetLabel i randrm] -> do
rm <- randrm
return . connectRoom $ rm & rmLabel ?~ i
[UseLabel i randrm] -> do
rm <- randrm
return $ connectRoom $ rm & rmTakeFrom ?~ i
[ChainAnos ass] -> do
rms <- mapM anoToRoomTree ass
return $ linkEitherTrees rms
[OrAno as] -> do
a <- takeOne as
anoToRoomTree a
[Corridor] -> pure . Right <$> randomiseOutLinks corridor
[AirlockAno] -> airlock >>= roomThenCorridor
[FirstWeapon] -> do
branchWP <- branchRectWith weaponRoom
blockedC <- longBlockedCorridor
join $ takeOne $ return (appendEitherTree branchWP [blockedC]) : replicate 5 weaponRoom
[EndRoom] -> fmap (pure . Right) (telRoomLev 1)
[StartRoom] -> startRoom
(SpecificRoom rt:_) -> rt
(BossAno cr : _) -> do
br <- bossRoom cr
branchRectWith . pure . fmap Left $ treeFromPost [corridor,corridor] br
(TreasureAno crs loot : _) -> branchRectWith . fmap (pure . Left) $ lootRoom crs loot
_ -> do
w <- state $ randomR (100,400)
h <- state $ randomR (200,400)
fmap (pure . Right) . randomiseOutLinks $ roomRectAutoLinks w h
+26
View File
@@ -0,0 +1,26 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE StrictData #-}
module Dodge.Annotation.Data where
import Dodge.Data
import Dodge.Room
import Data.Tree
import Control.Monad.State
import Control.Lens
data Annotation g
= Lock Int
| Key Int
| Corridor
| AirlockAno
| FirstWeapon
| StartRoom
| EndRoom
| OrAno [[Annotation g]]
| SpecificRoom (State g (Tree (Either Room Room)))
| BossAno Creature
| TreasureAno [Creature] [Item]
| SetLabel Int (State g Room)
| UseLabel Int (State g Room)
| ChainAnos [[Annotation g]]
makeLenses ''Annotation
+3 -1
View File
@@ -163,7 +163,9 @@ startCr = defaultCreature
} }
{- | Items you start with. -} {- | Items you start with. -}
startInventory :: IM.IntMap Item startInventory :: IM.IntMap Item
startInventory = IM.fromList (zip [0..20] startInventory = IM.fromList $ zip [0..20] $ repeat NoItem
stackedInventory :: IM.IntMap Item
stackedInventory = IM.fromList (zip [0..20]
( (
[spreadGun [spreadGun
,tractorGun ,tractorGun
+3
View File
@@ -2,9 +2,12 @@ module Dodge.Debug.Terminal
where where
import Dodge.Data import Dodge.Data
import Dodge.Config.Data import Dodge.Config.Data
import Dodge.Creature
import Control.Lens import Control.Lens
applyTerminalString :: String -> World -> World applyTerminalString :: String -> World -> World
applyTerminalString "NOCLIP" w = w & config . debug_noclip %~ not applyTerminalString "NOCLIP" w = w & config . debug_noclip %~ not
applyTerminalString "LOADME" w = w & creatures . ix 0 . crInv .~ stackedInventory
applyTerminalString _ w = w applyTerminalString _ w = w
+1 -1
View File
@@ -7,7 +7,7 @@ import Geometry.Data
import Dodge.Data import Dodge.Data
import Dodge.Creature.State.Data import Dodge.Creature.State.Data
import Dodge.Room import Dodge.Room
import Dodge.Placements.Button import Dodge.Placement.Instance.Button
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
import Dodge.Layout.Tree.Either import Dodge.Layout.Tree.Either
import Dodge.Annotation import Dodge.Annotation
-8
View File
@@ -4,8 +4,6 @@ import Dodge.Save
import Dodge.Data import Dodge.Data
import Dodge.Data.SoundOrigin import Dodge.Data.SoundOrigin
import Dodge.Creature import Dodge.Creature
import Dodge.Floor
import Dodge.Layout
import Dodge.Story import Dodge.Story
import Dodge.WorldEvent.Cloud import Dodge.WorldEvent.Cloud
import Dodge.SoundLogic import Dodge.SoundLogic
@@ -17,12 +15,6 @@ import qualified Data.Set as S
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
import qualified Data.Map as M import qualified Data.Map as M
worldFromSeed :: Int -> IO World
worldFromSeed i = do
roomList <- layoutLevelFromSeed 0 i
return $ generateLevelFromRoomList roomList
initialWorld -- note this uses a random generator defined elsewhere
initialWorld :: World initialWorld :: World
initialWorld = defaultWorld initialWorld = defaultWorld
{ _keys = S.empty { _keys = S.empty
+10
View File
@@ -0,0 +1,10 @@
module Dodge.Item.Random where
import Dodge.Data
import Dodge.RandomHelp
import Dodge.Item.Weapon.BulletGuns
import Control.Monad.State
import System.Random
randBlockBreakWeapon :: RandomGen g => State g Item
randBlockBreakWeapon = takeOne [pistol,ltAutoGun,spreadGun,autoGun]
+1 -2
View File
@@ -1,7 +1,6 @@
{- | Definitions of weapons. {- | Definitions of weapons.
In progress: move out effects into other modules. -} In progress: move out effects into other modules. -}
module Dodge.Item.Weapon module Dodge.Item.Weapon where
where
import Dodge.Data import Dodge.Data
import Dodge.Data.SoundOrigin import Dodge.Data.SoundOrigin
import Dodge.Base import Dodge.Base
+3 -2
View File
@@ -3,10 +3,11 @@ module Dodge.Layout
( generateLevelFromRoomList ( generateLevelFromRoomList
) where ) where
import Dodge.Data import Dodge.Data
import Dodge.LevelGen import Dodge.Path
import Dodge.ShiftPoint
import Dodge.Placement.PlaceSpot
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.LevelGen.StaticWalls import Dodge.LevelGen.StaticWalls
import Dodge.LevelGen.Pathing
import Dodge.Room.Foreground import Dodge.Room.Foreground
import Dodge.Wall.Zone import Dodge.Wall.Zone
import Dodge.GameRoom import Dodge.GameRoom
+11 -199
View File
@@ -2,205 +2,17 @@
{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RankNTypes #-}
-- | deals with placement of objects within the world -- | deals with placement of objects within the world
-- after they have had their coordinates set by the layout -- after they have had their coordinates set by the layout
module Dodge.LevelGen module Dodge.LevelGen where
( shiftPlacement
, shiftPointBy
, invShiftPointBy
, placeSpot
) where
import Dodge.Data import Dodge.Data
import Dodge.LevelGen.Block import Dodge.Floor
import Dodge.LevelGen.Pathing import Dodge.Layout
import Dodge.LevelGen.TriggerDoor import Dodge.Initialisation
import Dodge.LevelGen.Data --import qualified IntMapHelp as IM
import Dodge.Default.Wall
--import Dodge.RandomHelp
--import Dodge.Placements.Spot
import Geometry
import Geometry.Vector3D
import Shape
import qualified IntMapHelp as IM
import Color
import System.Random --import Control.Lens
import Control.Monad.State
import Control.Lens
import qualified Data.IntSet as IS
import Data.Bifunctor
-- when placing a placement, we update the world and the room and assign an id generateWorldFromSeed :: Int -> IO World
-- to the placement generateWorldFromSeed i = do
placeSpot :: (World,Room) -> Placement -> ( (World,Room), [Placement] ) roomList <- layoutLevelFromSeed 0 i
placeSpot (w,rm) plmnt = case plmnt of return $ generateLevelFromRoomList roomList
Placement{_plSpot = PSRoomRand i} -> placeSpotRoomRand rm i plmnt w initialWorld -- note this uses a random generator defined elsewhere
Placement{_plSpot = PSLnk extract eff fallback} -> placeSpotUsingLink w rm plmnt extract eff fallback
Placement{} ->
let (i,w') = placeSpotID (shiftPSBy shift (_plSpot plmnt)) (_plType plmnt) w
newplmnt = plmnt & plMID ?~ i
in maybe ((w',rm),[newplmnt]) (recrPlace newplmnt w') (_plIDCont plmnt newplmnt)
where
recrPlace newplmnt w' pl = let (wr,newplmnts) = placeSpot (w',rm) pl
in (wr,newplmnt:newplmnts)
-- (placeSpot (w',rm)) (_plIDCont plmnt i)
PlacementUsingPos p subpl -> placeSpot (w,rm) (subpl (shiftPoint3By shift p))
RandomPlacement rplmnt -> placeSpot (w & randGen .~ g,rm) plmnt'
where
(plmnt', g) = runState rplmnt (_randGen w)
where
shift = _rmShift rm
-- this should be tidied up
placeSpotUsingLink :: World -> Room -> Placement
-> (RoomPos -> Maybe PlacementSpot)
-> (RoomPos -> Room -> Room)
-> Maybe Placement
-> ((World, Room), [Placement])
placeSpotUsingLink w rm plmnt extract eff fallback = case searchedPoss (_rmPos rm) of
Just (ps,pos,newrmpos) -> placeSpot (w, eff pos $ rm & rmPos .~ newrmpos) (plmnt & plSpot .~ ps)
Nothing -> case fallback of
Nothing -> ((w,rm),[plmnt])
Just plmnt' -> placeSpot (w,rm) plmnt'
where
searchedPoss [] = error "no correct pos type for lnk placement"
searchedPoss (pos:poss) = case extract pos of
Nothing -> second (pos:) <$> searchedPoss poss
Just ps -> Just ( ps,pos, poss)
placeSpotRoomRand :: Room -> Int -> Placement -> World -> ((World,Room),[Placement])
placeSpotRoomRand rm i plmnt w =
let (ps,g) = runState (_rmRandPSs rm !! i) $_randGen w
in placeSpot (w & randGen .~ g,rm) (plmnt & plSpot .~ uncurry PS ps)
shiftPlacement :: (Point2,Float) -> Placement -> Placement
shiftPlacement shift plmnt = case plmnt of
Placement {} -> plmnt & plSpot %~ shiftPSBy shift
& plIDCont %~ fmap (fmap $ shiftPlacement shift)
PlacementUsingPos p f -> PlacementUsingPos (shiftPoint3By shift p)
(fmap (shiftPlacement shift) f)
RandomPlacement rpl -> RandomPlacement $ fmap (shiftPlacement shift) rpl
shiftPSBy :: (Point2,Float) -> PlacementSpot -> PlacementSpot
shiftPSBy (pos,rot) ps = ps
& psPos %~ shiftPointBy (pos,rot)
& psRot %~ (+ rot)
-- the Int here allows for passing parameters down to other placements:
-- button ids, etc
placeSpotID :: PlacementSpot -> PSType -> World -> (Int, World)
placeSpotID ps pt w = case pt of
PutTrigger cond -> placeNewInto triggers cond w
PutProp prop -> plNewUpID props pjID (mvProp p rot prop) w
PutButton bt -> plNewUpID buttons btID (mvButton p rot bt) w
PutFlIt itm -> plNewUpID floorItems flItID (createFlIt p rot itm) w
PutCrit cr -> plNewUpID creatures crID (mvCr p rot cr) w
PutMachine col wallpoly mc -> placeMachine col (map doShift wallpoly) mc p rot w
PutLS ls -> plNewUpID lightSources lsID (mvLS p' rot ls) w
PutPressPlate pp -> plNewUpID pressPlates ppID (mvPP p rot pp) w
RandPS rgen -> evaluateRandPS rgen ps w
PutDoor col f pss -> placeDoor col f (map (bimap doShift doShift) pss) w
PutCoordinate coordp -> placeNewInto coordinates (doShift coordp) w
PutSlideDoor pathing col f a b spd -> placeSlideDoor pathing col f (doShift a) (doShift b) spd w
PutBlock (hp:hps) col ps' -> placeBlock (map doShift ps') hp col Opaque hps w
PutBlock{} -> error "messed up block placement somehow"
PutLineBlock wl wdth dpth a b -> placeLineBlock wl wdth dpth (doShift a) (doShift b) w
PutWall { _pwPoly = ps', _pwWall = wl } -> (0,placeWallPoly (map doShift ps') wl w)
PutForeground sh -> (0,w & foregroundShape %~ ((uncurryV translateSHf p . rotateSH rot) sh <>))
PutNothing -> (0,w)
PutID i -> (i, w)
PutWorldUpdate f -> (0,f ps w)
where
p@(V2 px py) = _psPos ps
p' = V3 px py 0
rot = _psRot ps
doShift = shiftPointBy (p,rot)
evaluateRandPS :: State StdGen PSType -> PlacementSpot -> World -> (Int,World)
evaluateRandPS rgen ps w = placeSpotID ps evaluatedType (set randGen g w)
where
(evaluatedType, g) = runState rgen (_randGen w)
placeWallPoly :: [Point2] -> Wall -> World -> World
placeWallPoly ps wl = rmCrossPaths . over walls (addWalls ps wl)
where
rmCrossPaths w = foldr (uncurry removePathsCrossing) w $ loopPairs ps
shiftPointBy :: (Point2,Float) -> Point2 -> Point2
shiftPointBy (pos,rot) p = pos +.+ rotateV rot p
invShiftPointBy :: (Point2,Float) -> Point2 -> Point2
invShiftPointBy (p1,r) p2 = rotateV (-r) $ p2 -.- p1
shiftPoint3By :: (Point2,Float) -> Point3 -> Point3
shiftPoint3By (pos,rot) (V3 x y z) = addZ z $ pos +.+ rotateV rot (V2 x y)
addWalls :: [Point2] -> Wall -> IM.IntMap Wall -> IM.IntMap Wall
addWalls qs wl wls = foldr (addPane wl) wls pairs
where
(p:ps) = orderPolygon qs
pairs = zip (ps ++ [p]) (p:ps)
addPane :: Wall -> (Point2,Point2) -> IM.IntMap Wall -> IM.IntMap Wall
addPane wl l wls = IM.insert wlid (wl { _wlLine = l, _wlID = wlid }) wls
where
wlid = IM.newKey wls
-- | generalised way of putting a new item into a lensed intmap, returning the
-- new index as well
placeNewInto :: ALens' World (IM.IntMap a)
-> a
-> World
-> (Int,World)
placeNewInto l x w = (i,w & l #%~ IM.insert i x)
where
i = IM.newKey $ w ^# l
-- | place an new object into an intmap and update its id
plNewUpID :: ALens' World (IM.IntMap a)
-> ALens' a Int
-> a
-> World
-> (Int,World)
plNewUpID l li x w = (i,w & l #%~ IM.insert i (x & li #~ i))
where
i = IM.newKey $ w ^# l
mvProp :: Point2 -> Float -> Prop -> Prop
mvProp p a = (pjRot +~ a) . (pjPos %~ ( (p +.+) . rotateV a ))
mvButton :: Point2 -> Float -> Button -> Button
mvButton p a = (btRot +~ a) . (btPos %~ ( (p +.+) . rotateV a ))
{- Creates a floor item at a given point.-}
createFlIt :: Point2 -> Float -> Item -> FloorItem
createFlIt p rot itm = FlIt { _flItPos = p , _flItRot = rot , _flItID = 0 , _flIt = itm }
mvPP :: Point2 -> Float -> PressPlate -> PressPlate
mvPP p rot pp = pp {_ppPos = p,_ppRot = rot}
mvCr :: Point2 -> Float -> Creature -> Creature
mvCr p rot cr = cr {_crPos = p,_crOldPos = p,_crDir = rot}
placeMachine :: Color -> [Point2] -> Machine -> Point2 -> Float -> World -> (Int,World)
placeMachine color wallpoly mc p rot w = (mcid
, w & machines %~ addMc
& walls %~ placeMachineWalls color wallpoly mcid wlid
)
where
mcid = IM.newKey $ _machines w
wlid = IM.newKey $ _walls w
wlids = IS.fromList [wlid .. wlid + length wallpoly - 1]
addMc mcs = IM.insert mcid (mc {_mcPos = p,_mcDir = rot,_mcID = mcid, _mcWallIDs = wlids}) mcs
-- TODO correctly remove/shift pathfinding lines (removePathsCrossing)
placeMachineWalls :: Color -> [Point2] -> Int -> Int -> IM.IntMap Wall -> IM.IntMap Wall
placeMachineWalls col poly mcid wlid = flip (foldr f) $ zip [wlid..] $ loopPairs poly
where
f (wid,l) = IM.insert wid baseWall{_wlID = wid, _wlLine = l}
baseWall = defaultMachineWall
& wlColor .~ col
& wlStructure . wlStMachine .~ mcid
mvLS :: Point3 -> Float -> LightSource -> LightSource
mvLS (V3 x y z) rot ls = ls {_lsPos = V3 x y z +.+.+ startPos,_lsDir = rot}
where
startPos = onXY (rotateV rot) $ _lsPos ls
-32
View File
@@ -1,32 +0,0 @@
module Dodge.LevelGen.Pathing
( removePathsCrossing
, pairsToGraph
)
where
import Dodge.Data
import Dodge.Base
import Dodge.Zone
import Geometry
import Control.Lens
import Data.Maybe
import Data.List
import qualified Data.IntMap.Strict as IM
import Data.Graph.Inductive hiding ((&))
--import Data.Graph.Inductive.NodeMap
pairsToGraph :: (Ord a, Eq b) => (a -> a -> b) -> [(a,a)] -> Gr a b
pairsToGraph f pairs =
let nodes' = nub (map fst pairs ++ map snd pairs)
pairs' = map (\(x,y)->(x,y,f x y)) pairs
in undir $ run_ Data.Graph.Inductive.empty $ insMapNodesM nodes' >> insMapEdgesM pairs'
removePathsCrossing :: Point2 -> Point2 -> World -> World
removePathsCrossing a b w = w
& pathGraph .~ newGraph
& pathGraphP .~ pg'
& pathPoints .~ foldr insertPoint IM.empty (labNodes newGraph)
where
pg' = filter (isNothing . uncurry (intersectSegSeg a b)) $ _pathGraphP w
insertPoint pp@(_,V2 x y) = insertInZoneWith (floorHun x) (floorHun y) (++) [pp]
newGraph = pairsToGraph dist pg'
+2 -2
View File
@@ -12,10 +12,10 @@ import Dodge.Config.Data
import Dodge.Config.Update import Dodge.Config.Update
import SDL import SDL
import SDL.Internal.Numbered import SDL.Internal.Numbered
import Dodge.Initialisation
import Preload.Update import Preload.Update
import Dodge.Base.Window import Dodge.Base.Window
import Dodge.SoundLogic import Dodge.SoundLogic
import Dodge.LevelGen
import Control.Lens import Control.Lens
import System.Random import System.Random
@@ -160,7 +160,7 @@ pauseMenuOptions =
startNewGame :: World -> Maybe World startNewGame :: World -> Maybe World
startNewGame w = Just $ w startNewGame w = Just $ w
& menuLayers .~ [WaitScreen (const "GENERATING...") 1] & menuLayers .~ [WaitScreen (const "GENERATING...") 1]
& sideEffects .~ const (worldFromSeed i <&> keyConfig .~ _keyConfig w <&> config .~ _config w & sideEffects .~ const (generateWorldFromSeed i <&> keyConfig .~ _keyConfig w <&> config .~ _config w
<&> preloadData .~ _preloadData w) -- this kills save games etc... <&> preloadData .~ _preloadData w) -- this kills save games etc...
where where
i = fst $ random (_randGen w) i = fst $ random (_randGen w)
+25 -3
View File
@@ -3,18 +3,24 @@ module Dodge.Path
--, pointTowardsImpulse' --, pointTowardsImpulse'
, makePathBetween , makePathBetween
, makePathBetweenPs , makePathBetweenPs
, removePathsCrossing
, pairsToGraph
) )
where where
import Dodge.Data import Dodge.Data
import Dodge.Base.Collide import Dodge.Base.Collide
import Dodge.Zone import Dodge.Zone
import Geometry.Data import Geometry.Data
import Dodge.Base
import Geometry
import Data.List import Control.Lens
import Data.Maybe import Data.Maybe
import Data.List
import qualified Data.IntMap.Strict as IM
import Data.Graph.Inductive hiding ((&))
--import Data.Graph.Inductive.PatriciaTree --import Data.Graph.Inductive.PatriciaTree
import Data.Graph.Inductive.Query.SP --import Data.Graph.Inductive.Graph hiding ((&))
import Data.Graph.Inductive.Graph hiding ((&))
makePathBetween :: Point2 -> Point2 -> World -> Maybe [Int] makePathBetween :: Point2 -> Point2 -> World -> Maybe [Int]
makePathBetween a b w = do -- join $ sp <$> a' <*> b' <*> return (_pathGraph w) makePathBetween a b w = do -- join $ sp <$> a' <*> b' <*> return (_pathGraph w)
@@ -73,3 +79,19 @@ pointTowardsImpulse a b w = find (flip (isWalkable a) w) =<< makePathBetweenPs a
-- case ns of -- case ns of
-- [] -> return Nothing -- [] -> return Nothing
-- _ -> return $ Just $ ns !! i -- _ -> return $ Just $ ns !! i
--
pairsToGraph :: (Ord a, Eq b) => (a -> a -> b) -> [(a,a)] -> Gr a b
pairsToGraph f pairs =
let nodes' = nub (map fst pairs ++ map snd pairs)
pairs' = map (\(x,y)->(x,y,f x y)) pairs
in undir $ run_ Data.Graph.Inductive.empty $ insMapNodesM nodes' >> insMapEdgesM pairs'
removePathsCrossing :: Point2 -> Point2 -> World -> World
removePathsCrossing a b w = w
& pathGraph .~ newGraph
& pathGraphP .~ pg'
& pathPoints .~ foldr insertPoint IM.empty (labNodes newGraph)
where
pg' = filter (isNothing . uncurry (intersectSegSeg a b)) $ _pathGraphP w
insertPoint pp@(_,V2 x y) = insertInZoneWith (floorHun x) (floorHun y) (++) [pp]
newGraph = pairsToGraph dist pg'
+1
View File
@@ -0,0 +1 @@
module Dodge.Placement where
+17
View File
@@ -0,0 +1,17 @@
module Dodge.Placement.Instance
( module Dodge.Placement.Instance.Door
, module Dodge.Placement.Instance.LightSource
, module Dodge.Placement.Instance.Wall
, module Dodge.Placement.Instance.Button
, module Dodge.Placement.Instance.Turret
, module Dodge.Placement.Instance.Sensor
, module Dodge.Placement.Instance.Creature
)
where
import Dodge.Placement.Instance.Door
import Dodge.Placement.Instance.LightSource
import Dodge.Placement.Instance.Wall
import Dodge.Placement.Instance.Button
import Dodge.Placement.Instance.Turret
import Dodge.Placement.Instance.Sensor
import Dodge.Placement.Instance.Creature
@@ -1,4 +1,4 @@
module Dodge.Placements.Button where module Dodge.Placement.Instance.Button where
import Dodge.Data import Dodge.Data
import Color import Color
import Geometry import Geometry
@@ -6,7 +6,7 @@ import Geometry.Vector3D
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Default import Dodge.Default
import Dodge.LevelGen.Switch import Dodge.LevelGen.Switch
import Dodge.Placements.LightSource import Dodge.Placement.Instance.LightSource
import Dodge.PlacementSpot import Dodge.PlacementSpot
import ShapePicture import ShapePicture
+8
View File
@@ -0,0 +1,8 @@
module Dodge.Placement.Instance.Creature where
import Dodge.LevelGen.Data
import Dodge.RandomHelp
import Dodge.Creature.ArmourChase
import Dodge.Creature.ChaseCrit
randC1 :: PSType
randC1 = RandPS $ takeOne $ map PutCrit $ armourChaseCrit : replicate 50 chaseCrit
@@ -1,5 +1,4 @@
module Dodge.Placements.Door module Dodge.Placement.Instance.Door where
where
import Dodge.Data import Dodge.Data
import Dodge.Base import Dodge.Base
import Color import Color
@@ -1,4 +1,4 @@
module Dodge.Placements.LightSource where module Dodge.Placement.Instance.LightSource where
import Dodge.Data import Dodge.Data
import Dodge.LightSources.Lamp import Dodge.LightSources.Lamp
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
@@ -1,4 +1,4 @@
module Dodge.Placements.Sensor module Dodge.Placement.Instance.Sensor
( lightSensor ( lightSensor
) where ) where
import Color import Color
@@ -1,4 +1,4 @@
module Dodge.Placements.Turret where module Dodge.Placement.Instance.Turret where
import Color import Color
import Dodge.Data import Dodge.Data
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
@@ -1,4 +1,4 @@
module Dodge.Placements.Wall module Dodge.Placement.Instance.Wall
where where
import Dodge.Data import Dodge.Data
import Color import Color
+199
View File
@@ -0,0 +1,199 @@
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes #-}
-- | deals with placement of objects within the world
-- after they have had their coordinates set by the layout
module Dodge.Placement.PlaceSpot
( shiftPlacement
, shiftPointBy
, invShiftPointBy
, placeSpot
) where
import Dodge.Data
import Dodge.Path
import Dodge.Placement.PlaceSpot.Block
import Dodge.Placement.PlaceSpot.TriggerDoor
import Dodge.LevelGen.Data
import Dodge.Default.Wall
import Dodge.ShiftPoint
--import Dodge.RandomHelp
--import Dodge.Placements.Spot
import Geometry
import Geometry.Vector3D
import Shape
import qualified IntMapHelp as IM
import Color
import System.Random
import Control.Monad.State
import Control.Lens
import qualified Data.IntSet as IS
import Data.Bifunctor
-- when placing a placement, we update the world and the room and assign an id
-- to the placement
placeSpot :: (World,Room) -> Placement -> ( (World,Room), [Placement] )
placeSpot (w,rm) plmnt = case plmnt of
Placement{_plSpot = PSRoomRand i} -> placeSpotRoomRand rm i plmnt w
Placement{_plSpot = PSLnk extract eff fallback} -> placeSpotUsingLink w rm plmnt extract eff fallback
Placement{} ->
let (i,w') = placeSpotID (shiftPSBy shift (_plSpot plmnt)) (_plType plmnt) w
newplmnt = plmnt & plMID ?~ i
in maybe ((w',rm),[newplmnt]) (recrPlace newplmnt w') (_plIDCont plmnt newplmnt)
where
recrPlace newplmnt w' pl = let (wr,newplmnts) = placeSpot (w',rm) pl
in (wr,newplmnt:newplmnts)
-- (placeSpot (w',rm)) (_plIDCont plmnt i)
PlacementUsingPos p subpl -> placeSpot (w,rm) (subpl (shiftPoint3By shift p))
RandomPlacement rplmnt -> placeSpot (w & randGen .~ g,rm) plmnt'
where
(plmnt', g) = runState rplmnt (_randGen w)
where
shift = _rmShift rm
-- this should be tidied up
placeSpotUsingLink :: World -> Room -> Placement
-> (RoomPos -> Maybe PlacementSpot)
-> (RoomPos -> Room -> Room)
-> Maybe Placement
-> ((World, Room), [Placement])
placeSpotUsingLink w rm plmnt extract eff fallback = case searchedPoss (_rmPos rm) of
Just (ps,pos,newrmpos) -> placeSpot (w, eff pos $ rm & rmPos .~ newrmpos) (plmnt & plSpot .~ ps)
Nothing -> case fallback of
Nothing -> ((w,rm),[plmnt])
Just plmnt' -> placeSpot (w,rm) plmnt'
where
searchedPoss [] = error "no correct pos type for lnk placement"
searchedPoss (pos:poss) = case extract pos of
Nothing -> second (pos:) <$> searchedPoss poss
Just ps -> Just ( ps,pos, poss)
placeSpotRoomRand :: Room -> Int -> Placement -> World -> ((World,Room),[Placement])
placeSpotRoomRand rm i plmnt w =
let (ps,g) = runState (_rmRandPSs rm !! i) $_randGen w
in placeSpot (w & randGen .~ g,rm) (plmnt & plSpot .~ uncurry PS ps)
shiftPlacement :: (Point2,Float) -> Placement -> Placement
shiftPlacement shift plmnt = case plmnt of
Placement {} -> plmnt & plSpot %~ shiftPSBy shift
& plIDCont %~ fmap (fmap $ shiftPlacement shift)
PlacementUsingPos p f -> PlacementUsingPos (shiftPoint3By shift p)
(fmap (shiftPlacement shift) f)
RandomPlacement rpl -> RandomPlacement $ fmap (shiftPlacement shift) rpl
shiftPSBy :: (Point2,Float) -> PlacementSpot -> PlacementSpot
shiftPSBy (pos,rot) ps = ps
& psPos %~ shiftPointBy (pos,rot)
& psRot %~ (+ rot)
-- the Int here allows for passing parameters down to other placements:
-- button ids, etc
placeSpotID :: PlacementSpot -> PSType -> World -> (Int, World)
placeSpotID ps pt w = case pt of
PutTrigger cond -> placeNewInto triggers cond w
PutProp prop -> plNewUpID props pjID (mvProp p rot prop) w
PutButton bt -> plNewUpID buttons btID (mvButton p rot bt) w
PutFlIt itm -> plNewUpID floorItems flItID (createFlIt p rot itm) w
PutCrit cr -> plNewUpID creatures crID (mvCr p rot cr) w
PutMachine col wallpoly mc -> placeMachine col (map doShift wallpoly) mc p rot w
PutLS ls -> plNewUpID lightSources lsID (mvLS p' rot ls) w
PutPressPlate pp -> plNewUpID pressPlates ppID (mvPP p rot pp) w
RandPS rgen -> evaluateRandPS rgen ps w
PutDoor col f pss -> placeDoor col f (map (bimap doShift doShift) pss) w
PutCoordinate coordp -> placeNewInto coordinates (doShift coordp) w
PutSlideDoor pathing col f a b spd -> placeSlideDoor pathing col f (doShift a) (doShift b) spd w
PutBlock (hp:hps) col ps' -> placeBlock (map doShift ps') hp col Opaque hps w
PutBlock{} -> error "messed up block placement somehow"
PutLineBlock wl wdth dpth a b -> placeLineBlock wl wdth dpth (doShift a) (doShift b) w
PutWall { _pwPoly = ps', _pwWall = wl } -> (0,placeWallPoly (map doShift ps') wl w)
PutForeground sh -> (0,w & foregroundShape %~ ((uncurryV translateSHf p . rotateSH rot) sh <>))
PutNothing -> (0,w)
PutID i -> (i, w)
PutWorldUpdate f -> (0,f ps w)
where
p@(V2 px py) = _psPos ps
p' = V3 px py 0
rot = _psRot ps
doShift = shiftPointBy (p,rot)
evaluateRandPS :: State StdGen PSType -> PlacementSpot -> World -> (Int,World)
evaluateRandPS rgen ps w = placeSpotID ps evaluatedType (set randGen g w)
where
(evaluatedType, g) = runState rgen (_randGen w)
placeWallPoly :: [Point2] -> Wall -> World -> World
placeWallPoly ps wl = rmCrossPaths . over walls (addWalls ps wl)
where
rmCrossPaths w = foldr (uncurry removePathsCrossing) w $ loopPairs ps
addWalls :: [Point2] -> Wall -> IM.IntMap Wall -> IM.IntMap Wall
addWalls qs wl wls = foldr (addPane wl) wls pairs
where
(p:ps) = orderPolygon qs
pairs = zip (ps ++ [p]) (p:ps)
addPane :: Wall -> (Point2,Point2) -> IM.IntMap Wall -> IM.IntMap Wall
addPane wl l wls = IM.insert wlid (wl { _wlLine = l, _wlID = wlid }) wls
where
wlid = IM.newKey wls
-- | generalised way of putting a new item into a lensed intmap, returning the
-- new index as well
placeNewInto :: ALens' World (IM.IntMap a)
-> a
-> World
-> (Int,World)
placeNewInto l x w = (i,w & l #%~ IM.insert i x)
where
i = IM.newKey $ w ^# l
-- | place an new object into an intmap and update its id
plNewUpID :: ALens' World (IM.IntMap a)
-> ALens' a Int
-> a
-> World
-> (Int,World)
plNewUpID l li x w = (i,w & l #%~ IM.insert i (x & li #~ i))
where
i = IM.newKey $ w ^# l
mvProp :: Point2 -> Float -> Prop -> Prop
mvProp p a = (pjRot +~ a) . (pjPos %~ ( (p +.+) . rotateV a ))
mvButton :: Point2 -> Float -> Button -> Button
mvButton p a = (btRot +~ a) . (btPos %~ ( (p +.+) . rotateV a ))
{- Creates a floor item at a given point.-}
createFlIt :: Point2 -> Float -> Item -> FloorItem
createFlIt p rot itm = FlIt { _flItPos = p , _flItRot = rot , _flItID = 0 , _flIt = itm }
mvPP :: Point2 -> Float -> PressPlate -> PressPlate
mvPP p rot pp = pp {_ppPos = p,_ppRot = rot}
mvCr :: Point2 -> Float -> Creature -> Creature
mvCr p rot cr = cr {_crPos = p,_crOldPos = p,_crDir = rot}
placeMachine :: Color -> [Point2] -> Machine -> Point2 -> Float -> World -> (Int,World)
placeMachine color wallpoly mc p rot w = (mcid
, w & machines %~ addMc
& walls %~ placeMachineWalls color wallpoly mcid wlid
)
where
mcid = IM.newKey $ _machines w
wlid = IM.newKey $ _walls w
wlids = IS.fromList [wlid .. wlid + length wallpoly - 1]
addMc mcs = IM.insert mcid (mc {_mcPos = p,_mcDir = rot,_mcID = mcid, _mcWallIDs = wlids}) mcs
-- TODO correctly remove/shift pathfinding lines (removePathsCrossing)
placeMachineWalls :: Color -> [Point2] -> Int -> Int -> IM.IntMap Wall -> IM.IntMap Wall
placeMachineWalls col poly mcid wlid = flip (foldr f) $ zip [wlid..] $ loopPairs poly
where
f (wid,l) = IM.insert wid baseWall{_wlID = wid, _wlLine = l}
baseWall = defaultMachineWall
& wlColor .~ col
& wlStructure . wlStMachine .~ mcid
mvLS :: Point3 -> Float -> LightSource -> LightSource
mvLS (V3 x y z) rot ls = ls {_lsPos = V3 x y z +.+.+ startPos,_lsDir = rot}
where
startPos = onXY (rotateV rot) $ _lsPos ls
@@ -1,13 +1,13 @@
{- | Creation, update and destruction of destructible walls. -} {- | Creation, update and destruction of destructible walls. -}
module Dodge.LevelGen.Block module Dodge.Placement.PlaceSpot.Block
( placeBlock ( placeBlock
, placeLineBlock , placeLineBlock
) )
where where
import Dodge.Data import Dodge.Data
import Dodge.Path
import Dodge.Base import Dodge.Base
import Dodge.Zone import Dodge.Zone
import Dodge.LevelGen.Pathing
import Dodge.Default.Wall import Dodge.Default.Wall
import Geometry import Geometry
import qualified IntMapHelp as IM import qualified IntMapHelp as IM
@@ -1,5 +1,5 @@
--{-# LANGUAGE BangPatterns #-} --{-# LANGUAGE BangPatterns #-}
module Dodge.LevelGen.TriggerDoor module Dodge.Placement.PlaceSpot.TriggerDoor
( placeDoor ( placeDoor
, placeSlideDoor , placeSlideDoor
) where ) where
-15
View File
@@ -1,15 +0,0 @@
module Dodge.Placements
( module Dodge.Placements.Door
, module Dodge.Placements.LightSource
, module Dodge.Placements.Wall
, module Dodge.Placements.Button
, module Dodge.Placements.Turret
, module Dodge.Placements.Sensor
)
where
import Dodge.Placements.Door
import Dodge.Placements.LightSource
import Dodge.Placements.Wall
import Dodge.Placements.Button
import Dodge.Placements.Turret
import Dodge.Placements.Sensor
+1 -1
View File
@@ -1,7 +1,7 @@
{-# LANGUAGE TupleSections #-} {-# LANGUAGE TupleSections #-}
{- Rooms that contain two doors and a switch alternating both. -} {- Rooms that contain two doors and a switch alternating both. -}
module Dodge.Room.Airlock where module Dodge.Room.Airlock where
import Dodge.Placements import Dodge.Placement.Instance
import Dodge.Room.Foreground import Dodge.Room.Foreground
import Dodge.Default.Room import Dodge.Default.Room
import Dodge.Default.Wall import Dodge.Default.Wall
+1 -1
View File
@@ -3,7 +3,7 @@ module Dodge.Room.Boss
where where
import Dodge.Data import Dodge.Data
import Dodge.Default.Room import Dodge.Default.Room
import Dodge.Placements import Dodge.Placement.Instance
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Room.Link import Dodge.Room.Link
+1 -1
View File
@@ -5,7 +5,7 @@ import Dodge.LevelGen.Data
import Dodge.Default.Room import Dodge.Default.Room
--import Dodge.LevelGen.Data --import Dodge.LevelGen.Data
--import Dodge.LightSources.Lamp --import Dodge.LightSources.Lamp
import Dodge.Placements import Dodge.Placement.Instance
import Geometry import Geometry
import Tile import Tile
+1 -1
View File
@@ -4,7 +4,7 @@ module Dodge.Room.Door
import Geometry import Geometry
import Dodge.Data import Dodge.Data
import Dodge.Default.Room import Dodge.Default.Room
import Dodge.Placements import Dodge.Placement.Instance
import Color import Color
import Data.Maybe import Data.Maybe
+1 -1
View File
@@ -1,7 +1,7 @@
module Dodge.Room.Furniture module Dodge.Room.Furniture
where where
import Dodge.Data import Dodge.Data
import Dodge.LevelGen import Dodge.Placement.PlaceSpot
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Room.Foreground import Dodge.Room.Foreground
import Dodge.Default.Wall import Dodge.Default.Wall
+16 -1
View File
@@ -9,6 +9,8 @@ module Dodge.Room.Link
, shiftRoomBy , shiftRoomBy
, shiftLinkBy , shiftLinkBy
, doRoomShift , doRoomShift
, sortOutLinksOn
, filterSortOutLinksOn
, randomiseAllLinks , randomiseAllLinks
, filterLinks , filterLinks
, changeLinkTo , changeLinkTo
@@ -18,7 +20,7 @@ module Dodge.Room.Link
, invShiftLinkBy , invShiftLinkBy
, finalLinksUpdate , finalLinksUpdate
) where ) where
import Dodge.LevelGen import Dodge.Placement.PlaceSpot
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.RandomHelp import Dodge.RandomHelp
import Geometry import Geometry
@@ -34,6 +36,19 @@ randomiseOutLinks r = do
newLinks <- shuffle $ init $ _rmLinks r newLinks <- shuffle $ init $ _rmLinks r
return $ r {_rmLinks = newLinks ++ [last $ _rmLinks r]} return $ r {_rmLinks = newLinks ++ [last $ _rmLinks r]}
sortOutLinksOn :: Ord b => ((Point2,Float) -> b) -> Room -> Room
sortOutLinksOn f = rmLinks %~ dosort
where
dosort [] = []
dosort xs = sortOn f (init xs) ++ [last xs]
filterSortOutLinksOn :: Ord b => ((Point2,Float) -> Bool) -> ((Point2,Float) -> b) -> Room -> Room
filterSortOutLinksOn test f = rmLinks %~ dosort
where
dosort [] = []
dosort xs = let (ys,zs) = partition test (init xs)
in sortOn f ys ++ zs ++ [last xs]
{- Shuffle all links of a room randomly. -} {- Shuffle all links of a room randomly. -}
randomiseAllLinks :: RandomGen g => Room -> State g Room randomiseAllLinks :: RandomGen g => Room -> State g Room
randomiseAllLinks r = do randomiseAllLinks r = do
+1 -3
View File
@@ -6,7 +6,7 @@ module Dodge.Room.LongDoor
import Dodge.Data import Dodge.Data
import Dodge.Default.Room import Dodge.Default.Room
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Placements import Dodge.Placement.Instance
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Room.Procedural import Dodge.Room.Procedural
--import Dodge.Layout.Tree.Either --import Dodge.Layout.Tree.Either
@@ -140,5 +140,3 @@ slowDoorRoom = do
proom <- southPillarsRoom x y h proom <- southPillarsRoom x y h
addButtonSlowDoor x h (proom & rmPmnts %~ (++ (crits ++ barrels ++ lsources))) addButtonSlowDoor x h (proom & rmPmnts %~ (++ (crits ++ barrels ++ lsources)))
randC1 :: PSType
randC1 = RandPS $ takeOne $ map PutCrit $ armourChaseCrit : replicate 50 chaseCrit
+2 -2
View File
@@ -11,7 +11,7 @@ module Dodge.Room.Procedural
) where ) where
import Dodge.Data import Dodge.Data
import Dodge.Default.Wall import Dodge.Default.Wall
import Dodge.Placements import Dodge.Placement.Instance
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Room.Path import Dodge.Room.Path
import Dodge.Default.Room import Dodge.Default.Room
@@ -21,7 +21,7 @@ import Dodge.Room.Foreground
import Dodge.Item.Weapon import Dodge.Item.Weapon
import Dodge.Item.Weapon.Launcher import Dodge.Item.Weapon.Launcher
import Dodge.RandomHelp import Dodge.RandomHelp
import Dodge.LevelGen import Dodge.Placement.PlaceSpot
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.LevelGen.Switch import Dodge.LevelGen.Switch
import Dodge.Creature import Dodge.Creature
+15 -2
View File
@@ -5,12 +5,12 @@ import Geometry
import Dodge.Default.Room import Dodge.Default.Room
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Placements import Dodge.Placement.Instance
import Dodge.Room.Corridor import Dodge.Room.Corridor
import Dodge.Room.Furniture import Dodge.Room.Furniture
--import Dodge.LevelGen.Data --import Dodge.LevelGen.Data
--import Dodge.Default.Wall --import Dodge.Default.Wall
--import Dodge.RandomHelp import Dodge.RandomHelp
import Dodge.Creature import Dodge.Creature
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
@@ -75,6 +75,19 @@ blockedCorridor = do
] ]
sequence $ treeFromPost [] $ return $ Right $ set rmPmnts plmnts corridor sequence $ treeFromPost [] $ return $ Right $ set rmPmnts plmnts corridor
-- | A single corridor with a destructible block blocking it.
blockedCorridor' :: RandomGen g => State g Room
blockedCorridor' = do
r <- state $ randomR (0,pi)
theblocks <- takeOne [ [sPS (V2 20 40) r $ PutBlock [1] thecol $ reverse $ square 10]
, [ sPS (V2 5 40) r $ PutBlock [1] thecol $ reverse $ square 10
, sPS (V2 35 40) (r+0.5) $ PutBlock [1] thecol $ reverse $ square 10
]
]
return $ corridor & rmPmnts .~ theblocks
where
thecol = V4 (150/256) ( 75/256) 0 ( 250/256)
lasTunnel :: Room lasTunnel :: Room
lasTunnel = defaultRoom lasTunnel = defaultRoom
{ _rmPolys = polys { _rmPolys = polys
+1 -2
View File
@@ -9,14 +9,13 @@ import Dodge.RandomHelp
import Dodge.Default.Wall import Dodge.Default.Wall
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
import Dodge.Layout.Tree.Either import Dodge.Layout.Tree.Either
import Dodge.Placements import Dodge.Placement.Instance
--import Dodge.LevelGen.Data --import Dodge.LevelGen.Data
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Room.Corridor import Dodge.Room.Corridor
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Room.Door import Dodge.Room.Door
import Dodge.Room.Airlock import Dodge.Room.Airlock
import Dodge.Room.LongDoor
import Geometry import Geometry
import Picture import Picture
import Tile import Tile
+42 -6
View File
@@ -1,14 +1,18 @@
module Dodge.Room.Start where module Dodge.Room.Start where
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Data
import Dodge.Room.Door import Dodge.Room.Door
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Room.Foreground import Dodge.Room.Foreground
import Dodge.Room.Furniture import Dodge.Room.Furniture
import Dodge.Placements import Dodge.Room.RoadBlock
import Dodge.Placement.Instance
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
import Dodge.Item.Random
--import Dodge.LevelGen.Data --import Dodge.LevelGen.Data
import Geometry.Data import Geometry.Data
import Padding
import Color import Color
import Shape import Shape
@@ -20,17 +24,49 @@ import System.Random
rezBox :: Room rezBox :: Room
--rezBox = shiftRoomBy (V2 (-20) (-10),0) $ roomRect 40 20 1 1 --rezBox = shiftRoomBy (V2 (-20) (-10),0) $ roomRect 40 20 1 1
rezBox = roomRect 40 40 1 1 rezBox = roomRect 40 60 1 1
& rmPmnts .~ [ spanColLightI (V3 0 0.5 0) 95 (V2 0 1) (V2 40 1) ] & rmPmnts .~ [ spanColLightI (V3 0 0 0.5) 95 (V2 0 1) (V2 40 1) ]
rezInvBox :: Room rezInvBox :: Room
rezInvBox = roomRect 40 40 1 1 rezInvBox = roomRect 40 60 1 1
& rmPmnts .~ [ spanColLightI (V3 0 0.5 0) 95 (V2 0 39) (V2 40 39) ] & rmPmnts .~ [ spanColLightI (V3 0 0 0.5) 95 (V2 0 59) (V2 40 59) ]
crRezBox :: Room
crRezBox = rezInvBox -- & rmPmnts %~ (sPS (V2 20 0) pi randC1 :)
wpRezBox :: Item -> Room
wpRezBox wp = rezInvBox & rmPmnts %~ (sPS (V2 15 30) 1 (PutFlIt wp) :)
startRoom :: RandomGen g => State g (Tree (Either Room Room)) startRoom :: RandomGen g => State g (Tree (Either Room Room))
startRoom = do startRoom = do
w <- state $ randomR (100,400) w <- state $ randomR (100,400)
h <- state $ randomR (100,200) h <- state $ randomR (40,40)
theweapon <- randBlockBreakWeapon
let bottomEdgeTest (V2 _ y,_) = y < 1
bottomLeftTest (V2 x y,_) = y < 1 && x < 21
centralRoom <- filterSortOutLinksOn bottomEdgeTest ((\(V2 a b) -> (b,a)) . fst) <$>
(randomiseOutLinks =<< changeLinkTo bottomLeftTest
((roomRectAutoLinks w h) {_rmPmnts = []}))
let n = length $ filter bottomEdgeTest $ _rmLinks centralRoom
i <- state $ randomR (0,n-3)
j <- state $ randomR (i,n-2)
blcor <- blockedCorridor'
let rezrooms = map adddoor
$ insertAt i (wpRezBox theweapon)
$ insertAt j crRezBox
$ replicate (n-3) rezInvBox
return $ treeFromTrunk [Left rezBox
, Left door
]
(Node (Left centralRoom) (rezrooms ++ [onwardtree blcor]))
where
adddoor rm = treeFromPost [Left door] (Left rm)
onwardtree blcor = treeFromPost [Left door] (Right blcor)
randomRezBoxes :: RandomGen g => State g (Tree (Either Room Room))
randomRezBoxes = do
w <- state $ randomR (100,400)
h <- state $ randomR (40,40)
let bottomEdgeTest (V2 _ y,_) = y < 1 let bottomEdgeTest (V2 _ y,_) = y < 1
centralRoom <- randomiseOutLinks =<< changeLinkTo bottomEdgeTest centralRoom <- randomiseOutLinks =<< changeLinkTo bottomEdgeTest
((roomRectAutoLinks w h) {_rmPmnts = []}) ((roomRectAutoLinks w h) {_rmPmnts = []})
+1 -1
View File
@@ -5,7 +5,7 @@ import Dodge.Data
import Dodge.Base import Dodge.Base
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Dodge.Room.Procedural import Dodge.Room.Procedural
import Dodge.Placements import Dodge.Placement.Instance
--import Dodge.LevelGen.Data --import Dodge.LevelGen.Data
import Geometry import Geometry
import Picture import Picture
+1 -1
View File
@@ -5,7 +5,7 @@ Typically dead ends.
module Dodge.Room.Treasure module Dodge.Room.Treasure
where where
import Dodge.Data import Dodge.Data
import Dodge.Placements import Dodge.Placement.Instance
import Dodge.Default.Room import Dodge.Default.Room
import Dodge.LevelGen.Data import Dodge.LevelGen.Data
import Geometry import Geometry
+12
View File
@@ -0,0 +1,12 @@
module Dodge.ShiftPoint where
import Geometry
import Geometry.Vector3D
shiftPointBy :: (Point2,Float) -> Point2 -> Point2
shiftPointBy (pos,rot) p = pos +.+ rotateV rot p
invShiftPointBy :: (Point2,Float) -> Point2 -> Point2
invShiftPointBy (p1,r) p2 = rotateV (-r) $ p2 -.- p1
shiftPoint3By :: (Point2,Float) -> Point3 -> Point3
shiftPoint3By (pos,rot) (V3 x y z) = addZ z $ pos +.+ rotateV rot (V2 x y)
+4
View File
@@ -7,6 +7,7 @@ module Padding
, rotU , rotU
, rotD , rotD
, rotListAt , rotListAt
, insertAt
) )
where where
leftPad :: Int -> a -> [a] -> [a] leftPad :: Int -> a -> [a] -> [a]
@@ -46,3 +47,6 @@ rotListAt x' xs = f x' xs []
| y == x = y:ys ++ zs | y == x = y:ys ++ zs
| otherwise = f x ys (y:zs) | otherwise = f x ys (y:zs)
f _ [] zs = zs f _ [] zs = zs
insertAt :: Int -> a -> [a] -> [a]
insertAt i x xs = let (ys,zs) = splitAt i xs in ys ++ [x] ++ zs