Start to implement lock and key system
This commit is contained in:
+1
-1
@@ -1515,7 +1515,7 @@ basicShooterAI w (f,g) cr =
|
|||||||
cid = _crID cr
|
cid = _crID cr
|
||||||
ypos = _crPos $ you w
|
ypos = _crPos $ you w
|
||||||
wp = _crInv cr IM.! _crInvSel cr
|
wp = _crInv cr IM.! _crInvSel cr
|
||||||
(aimtime,g1) = randomR (80,120) g
|
(aimtime,g1) = randomR (60,80) g
|
||||||
noAmmo = 0 == _wpLoadedAmmo wp
|
noAmmo = 0 == _wpLoadedAmmo wp
|
||||||
turnCloseSlow p | errorAngleVV 22 (p -.- cpos)
|
turnCloseSlow p | errorAngleVV 22 (p -.- cpos)
|
||||||
(unitVectorAtAngle (_crDir cr)) < 0.4
|
(unitVectorAtAngle (_crDir cr)) < 0.4
|
||||||
|
|||||||
@@ -74,7 +74,10 @@ armourChaseCrit = defaultCreature
|
|||||||
, _crHP = 300
|
, _crHP = 300
|
||||||
, _crPict = enemyPict green
|
, _crPict = enemyPict green
|
||||||
, _crState = defaultState {_goals = [[Wait]]}
|
, _crState = defaultState {_goals = [[Wait]]}
|
||||||
, _crInv = IM.fromList [(0,frontArmour)]
|
, _crInv = IM.fromList
|
||||||
|
[(0,frontArmour)
|
||||||
|
,(1,medkit 200)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
miniGunCrit :: Creature
|
miniGunCrit :: Creature
|
||||||
miniGunCrit = defaultCreature
|
miniGunCrit = defaultCreature
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
{-
|
||||||
|
Contains base datatypes that cannot be seperated into
|
||||||
|
different modules because they are interdependent;
|
||||||
|
circular imports are scary.
|
||||||
|
-}
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
{-# LANGUAGE StrictData #-}
|
{-# LANGUAGE StrictData #-}
|
||||||
|
|||||||
+14
-7
@@ -6,10 +6,12 @@ import Picture
|
|||||||
import Dodge.Data
|
import Dodge.Data
|
||||||
import Dodge.Room
|
import Dodge.Room
|
||||||
import Dodge.Room.Procedural
|
import Dodge.Room.Procedural
|
||||||
|
import Dodge.Room.RoadBlock
|
||||||
import Dodge.Room.Data
|
import Dodge.Room.Data
|
||||||
import Dodge.Room.Link
|
import Dodge.Room.Link
|
||||||
import Dodge.Room.Door
|
import Dodge.Room.Door
|
||||||
import Dodge.Room.Branch
|
import Dodge.Room.Branch
|
||||||
|
import Dodge.Room.Boss
|
||||||
import Dodge.Base
|
import Dodge.Base
|
||||||
import Dodge.Layout
|
import Dodge.Layout
|
||||||
import Dodge.Layout.Tree.Polymorphic
|
import Dodge.Layout.Tree.Polymorphic
|
||||||
@@ -22,6 +24,7 @@ import Dodge.SoundLogic
|
|||||||
import Dodge.RandomHelp
|
import Dodge.RandomHelp
|
||||||
import Dodge.LightSources
|
import Dodge.LightSources
|
||||||
import Dodge.LevelGen.Data
|
import Dodge.LevelGen.Data
|
||||||
|
import Dodge.Item.Weapon
|
||||||
|
|
||||||
import Data.Tree
|
import Data.Tree
|
||||||
import Data.Maybe (fromJust,isNothing)
|
import Data.Maybe (fromJust,isNothing)
|
||||||
@@ -33,15 +36,18 @@ import System.Random
|
|||||||
roomTreex :: RandomGen g => State g (Maybe [Room])
|
roomTreex :: RandomGen g => State g (Maybe [Room])
|
||||||
roomTreex = do
|
roomTreex = do
|
||||||
struct' <- aTreeStrut
|
struct' <- aTreeStrut
|
||||||
-- let struct = treePost [[SpecificRoom $ fmap (pure . Right) pistolerRoom]] [EndRoom]
|
-- let struct = treeFromPost [[SpecificRoom $ fmap (pure . Right) pistolerRoom]] [EndRoom]
|
||||||
let struct = treePost [[SpecificRoom $ fmap (pure . Right) testRoom]] [EndRoom]
|
let struct = treeFromPost [[SpecificRoom $ fmap (pure . Right) testRoom]] [EndRoom]
|
||||||
let t' = padCorridors struct
|
let t' = padCorridors struct
|
||||||
t = treeTrunk
|
t = treeFromTrunk
|
||||||
[[StartRoom]
|
[[StartRoom]
|
||||||
,[Corridor]
|
,[Corridor]
|
||||||
,[BossAno $ addArmour launcherCrit & crHP +~ 800
|
,[SpecificRoom $ fmap (pure . Right) armouredCorridor]
|
||||||
& crState . crDropsOnDeath .~ DropSpecific [0]
|
,[Corridor]
|
||||||
]
|
,[TreasureAno [addArmour autoCrit,addArmour autoCrit] [launcher]]
|
||||||
|
-- ,[BossAno $ addArmour launcherCrit & crHP +~ 800
|
||||||
|
-- & crState . crDropsOnDeath .~ DropSpecific [0]
|
||||||
|
-- ]
|
||||||
,[Corridor]
|
,[Corridor]
|
||||||
,[OrAno [[DoorAno]
|
,[OrAno [[DoorAno]
|
||||||
,[Corridor]
|
,[Corridor]
|
||||||
@@ -49,6 +55,7 @@ roomTreex = do
|
|||||||
]
|
]
|
||||||
,[FirstWeapon]
|
,[FirstWeapon]
|
||||||
,[Corridor]
|
,[Corridor]
|
||||||
|
,[SpecificRoom $ branchRectWith $ fmap (pure . Left) armouredChasers]
|
||||||
]
|
]
|
||||||
t'
|
t'
|
||||||
fmap (shiftExpandTree . expandTreeBy id) $ mapM annoToRoomTree t
|
fmap (shiftExpandTree . expandTreeBy id) $ mapM annoToRoomTree t
|
||||||
@@ -60,7 +67,7 @@ lev1' :: RandomGen g => State g (Tree Room)
|
|||||||
lev1' = do
|
lev1' = do
|
||||||
firstWeapon <- takeOne $ [[branchRectWith weaponRoom,blockedCorridor]] ++ replicate 5 [weaponRoom]
|
firstWeapon <- takeOne $ [[branchRectWith weaponRoom,blockedCorridor]] ++ replicate 5 [weaponRoom]
|
||||||
iterateWhile boundClip $ fmap (shiftRoomTree . expandTreeBy id)
|
iterateWhile boundClip $ fmap (shiftRoomTree . expandTreeBy id)
|
||||||
$ sequence $ treePost
|
$ sequence $ treeFromPost
|
||||||
(
|
(
|
||||||
[return $ return $ Right deadEndRoom
|
[return $ return $ Right deadEndRoom
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -124,15 +124,12 @@ autoGun = defaultGun
|
|||||||
, _itInvDisplay = displayAutoGun
|
, _itInvDisplay = displayAutoGun
|
||||||
}
|
}
|
||||||
autoFireMode = shootWithSound (fromIntegral autoGunSound)
|
autoFireMode = shootWithSound (fromIntegral autoGunSound)
|
||||||
. withRecoil 40
|
|
||||||
. torqueBefore 0.05
|
. torqueBefore 0.05
|
||||||
. withRandomDir (autogunSpread/2)
|
$ autoGunNonTwistEff
|
||||||
. withMuzFlare
|
|
||||||
. withVelWthHiteff (50,0) 3
|
|
||||||
$ destroyOnImpact bulIncCr' bulIncWall' bulHitFF'
|
|
||||||
singleFireMode = shootWithSound (fromIntegral autoGunSound)
|
singleFireMode = shootWithSound (fromIntegral autoGunSound)
|
||||||
. withRecoil 40
|
|
||||||
. torqueAfter 0.03
|
. torqueAfter 0.03
|
||||||
|
$ autoGunNonTwistEff
|
||||||
|
autoGunNonTwistEff = withRecoil 40
|
||||||
. withRandomDir (autogunSpread/2)
|
. withRandomDir (autogunSpread/2)
|
||||||
. withMuzFlare
|
. withMuzFlare
|
||||||
. withVelWthHiteff (50,0) 3
|
. withVelWthHiteff (50,0) 3
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import Dodge.Room.Procedural
|
|||||||
import Dodge.Room.Branch
|
import Dodge.Room.Branch
|
||||||
import Dodge.Room.Door
|
import Dodge.Room.Door
|
||||||
import Dodge.Room.Boss
|
import Dodge.Room.Boss
|
||||||
|
import Dodge.Room.Treasure
|
||||||
import Dodge.Room.Link
|
import Dodge.Room.Link
|
||||||
import Dodge.Room.Data
|
import Dodge.Room.Data
|
||||||
import Dodge.Room
|
import Dodge.Room
|
||||||
@@ -34,7 +35,7 @@ data Annotation g
|
|||||||
| OrAno [[Annotation g]]
|
| OrAno [[Annotation g]]
|
||||||
| SpecificRoom (State g (Tree (Either Room Room)))
|
| SpecificRoom (State g (Tree (Either Room Room)))
|
||||||
| BossAno Creature
|
| BossAno Creature
|
||||||
| TreasureAno [Creature] Item
|
| TreasureAno [Creature] [Item]
|
||||||
|
|
||||||
addLock :: RandomGen g => Int -> Tree [Annotation g] -> State g (Tree [Annotation g])
|
addLock :: RandomGen g => Int -> Tree [Annotation g] -> State g (Tree [Annotation g])
|
||||||
addLock i t = do
|
addLock i t = do
|
||||||
@@ -49,12 +50,13 @@ randomPadCorridors :: RandomGen g => Tree [Annotation g] -> State g (Tree [Annot
|
|||||||
randomPadCorridors (Node x xs) = do
|
randomPadCorridors (Node x xs) = do
|
||||||
n <- state $ randomR (1, 3)
|
n <- state $ randomR (1, 3)
|
||||||
xs' <- mapM randomPadCorridors xs
|
xs' <- mapM randomPadCorridors xs
|
||||||
return $ treeTrunk (replicate n [Corridor]) (Node x xs')
|
return $ treeFromTrunk (replicate n [Corridor]) (Node x xs')
|
||||||
|
|
||||||
roomThenCorridor :: RandomGen g => Room -> State g (Tree (Either Room Room))
|
roomThenCorridor :: RandomGen g => Room -> State g (Tree (Either Room Room))
|
||||||
roomThenCorridor theRoom = fmap (\r -> Node (Left theRoom) [(pure . Right) r])
|
roomThenCorridor theRoom = fmap (\r -> Node (Left theRoom) [(pure . Right) r])
|
||||||
(randomiseOutLinks corridor)
|
(randomiseOutLinks corridor)
|
||||||
|
|
||||||
|
|
||||||
annoToRoomTree :: RandomGen g => [Annotation g] -> State g (Tree (Either Room Room))
|
annoToRoomTree :: RandomGen g => [Annotation g] -> State g (Tree (Either Room Room))
|
||||||
annoToRoomTree [OrAno as] = do
|
annoToRoomTree [OrAno as] = do
|
||||||
a <- takeOne as
|
a <- takeOne as
|
||||||
@@ -74,6 +76,8 @@ annoToRoomTree [StartRoom] = do
|
|||||||
fmap (pure . Right) $ randomiseOutLinks (shiftRoomBy ((-20,-20),0) $ roomRectAutoLinks w h)
|
fmap (pure . Right) $ randomiseOutLinks (shiftRoomBy ((-20,-20),0) $ roomRectAutoLinks w h)
|
||||||
annoToRoomTree (SpecificRoom rt:_) = rt
|
annoToRoomTree (SpecificRoom rt:_) = rt
|
||||||
annoToRoomTree (BossAno cr : _) = branchRectWith . fmap (pure . Left) $ bossRoom cr
|
annoToRoomTree (BossAno cr : _) = branchRectWith . fmap (pure . Left) $ bossRoom cr
|
||||||
|
annoToRoomTree (TreasureAno crs loot : _) =
|
||||||
|
branchRectWith . fmap (pure . Left) $ lootRoom crs loot
|
||||||
annoToRoomTree _ = do
|
annoToRoomTree _ = do
|
||||||
w <- state $ randomR (100,400)
|
w <- state $ randomR (100,400)
|
||||||
h <- state $ randomR (200,400)
|
h <- state $ randomR (200,400)
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
{-
|
||||||
|
Helpers for the manipulation of rose trees.
|
||||||
|
Throughout, the _trunk_ refers to successive first children in the tree.
|
||||||
|
For example, in the tree
|
||||||
|
|
||||||
|
> Node a [ Node b [], Node c [Node d []] ]
|
||||||
|
|
||||||
|
the nodes in the trunk are [a,b] (note that d is not the first child of b).
|
||||||
|
-}
|
||||||
module Dodge.Layout.Tree.Polymorphic
|
module Dodge.Layout.Tree.Polymorphic
|
||||||
where
|
where
|
||||||
import Dodge.RandomHelp
|
import Dodge.RandomHelp
|
||||||
@@ -10,20 +19,20 @@ import System.Random
|
|||||||
Creates a linear tree.
|
Creates a linear tree.
|
||||||
Safe.
|
Safe.
|
||||||
-}
|
-}
|
||||||
treePost :: [a] -> a -> Tree a
|
treeFromPost :: [a] -> a -> Tree a
|
||||||
treePost [] y = Node y []
|
treeFromPost [] y = Node y []
|
||||||
treePost (x:xs) y = Node x [treePost xs y]
|
treeFromPost (x:xs) y = Node x [treeFromPost xs y]
|
||||||
|
|
||||||
{-
|
{-
|
||||||
Creates a tree with one trunk branch,
|
Creates a tree with one trunk branch,
|
||||||
input as a list, that ends in another tree.
|
input as a list, that ends in another tree.
|
||||||
-}
|
-}
|
||||||
treeTrunk
|
treeFromTrunk
|
||||||
:: [a] -- ^ The trunk
|
:: [a] -- ^ The trunk
|
||||||
-> Tree a -- ^ The end of the tree
|
-> Tree a -- ^ The end of the tree
|
||||||
-> Tree a
|
-> Tree a
|
||||||
treeTrunk [] t = t
|
treeFromTrunk [] t = t
|
||||||
treeTrunk (x:xs) t = Node x [treeTrunk xs t]
|
treeFromTrunk (x:xs) t = Node x [treeFromTrunk xs t]
|
||||||
|
|
||||||
{-
|
{-
|
||||||
Applies a function to the root of a tree.
|
Applies a function to the root of a tree.
|
||||||
@@ -43,6 +52,15 @@ applyToNode (i:is) f (Node x xs) = Node x (ys ++ [applyToNode is f z] ++ zs)
|
|||||||
where
|
where
|
||||||
(ys, z:zs) = splitAt i xs
|
(ys, z:zs) = splitAt i xs
|
||||||
|
|
||||||
|
{-
|
||||||
|
Applies a function to the first node along a trunk that satisfies a given property.
|
||||||
|
-}
|
||||||
|
applyToSubTrunkBy :: (a -> Bool) -> (Tree a -> Tree a) -> Tree a -> Tree a
|
||||||
|
applyToSubTrunkBy cond f (Node x (t:ts))
|
||||||
|
| cond x = f (Node x (t:ts))
|
||||||
|
| otherwise = Node x (applyToSubTrunkBy cond f t : ts)
|
||||||
|
applyToSubTrunkBy _ _ t = t
|
||||||
|
|
||||||
zipTree :: Tree a -> Tree b -> Tree (a,b)
|
zipTree :: Tree a -> Tree b -> Tree (a,b)
|
||||||
zipTree (Node x xs) (Node y ys) = Node (x,y) $ zipWith zipTree xs ys
|
zipTree (Node x xs) (Node y ys) = Node (x,y) $ zipWith zipTree xs ys
|
||||||
|
|
||||||
@@ -79,7 +97,7 @@ applyToRandomNode f t = do
|
|||||||
return $ applyToNode p f t
|
return $ applyToNode p f t
|
||||||
|
|
||||||
{-
|
{-
|
||||||
Add a forest to the end of a tree.
|
Add a forest to the end of a tree (along the trunk).
|
||||||
-}
|
-}
|
||||||
addToTrunk :: Tree a -> [Tree a] -> Tree a
|
addToTrunk :: Tree a -> [Tree a] -> Tree a
|
||||||
addToTrunk (Node x []) f = Node x f
|
addToTrunk (Node x []) f = Node x f
|
||||||
|
|||||||
+16
-7
@@ -106,10 +106,6 @@ instance (Shiftable a) => Shiftable [a] where
|
|||||||
translateS p x = map (translateS p) x
|
translateS p x = map (translateS p) x
|
||||||
rotateS r x = map (rotateS r) x
|
rotateS r x = map (rotateS r) x
|
||||||
|
|
||||||
instance Shiftable RoomLink where
|
|
||||||
translateS q (RL p r) = RL (p +.+ q) r
|
|
||||||
rotateS s (RL p r) = RL (rotateV s p) (r+s)
|
|
||||||
|
|
||||||
instance Shiftable PlacementSpot where
|
instance Shiftable PlacementSpot where
|
||||||
translateS p' (PS p r x) = PS (p +.+ p') r x
|
translateS p' (PS p r x) = PS (p +.+ p') r x
|
||||||
rotateS r' (PS p r x) = PS (rotateV r' p) (r + r') x
|
rotateS r' (PS p r x) = PS (rotateV r' p) (r + r') x
|
||||||
@@ -133,9 +129,21 @@ addPane c (p0,p1) wls = IM.insert (newKey wls) (Wall { _wlLine = [p0,p1]
|
|||||||
|
|
||||||
|
|
||||||
placeBt bt p rot w = over buttons addBT w
|
placeBt bt p rot w = over buttons addBT w
|
||||||
where addBT bts = IM.insert (newKey bts) (bt {_btPos = p, _btRot = rot, _btID = newKey bts}) bts
|
where
|
||||||
placeFlIt itm p rot w = over floorItems addFI w
|
addBT bts = IM.insert (newKey bts) (bt {_btPos = p, _btRot = rot, _btID = newKey bts}) bts
|
||||||
where addFI fis = IM.insert (newKey fis)
|
|
||||||
|
{-
|
||||||
|
Creates a floor item at a given point.
|
||||||
|
Assigns an id correctly.
|
||||||
|
-}
|
||||||
|
placeFlIt
|
||||||
|
:: Item
|
||||||
|
-> Point2 -- ^ Position
|
||||||
|
-> Float -- ^ Rotation
|
||||||
|
-> World
|
||||||
|
-> World
|
||||||
|
placeFlIt itm p rot = floorItems %~
|
||||||
|
\ fis -> IM.insert (newKey fis)
|
||||||
(FlIt
|
(FlIt
|
||||||
{ _flItPos = p
|
{ _flItPos = p
|
||||||
, _flItRot = rot
|
, _flItRot = rot
|
||||||
@@ -143,6 +151,7 @@ placeFlIt itm p rot w = over floorItems addFI w
|
|||||||
, _flIt = itm
|
, _flIt = itm
|
||||||
}
|
}
|
||||||
) fis
|
) fis
|
||||||
|
|
||||||
placePressPlate pp p rot w = over pressPlates addPP w
|
placePressPlate pp p rot w = over pressPlates addPP w
|
||||||
where addPP pps = IM.insert (newKey pps) (pp {_ppPos = p,_ppRot = rot}) pps
|
where addPP pps = IM.insert (newKey pps) (pp {_ppPos = p,_ppRot = rot}) pps
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ data PSType = PutCrit Creature
|
|||||||
| PutSwitchDoor Color Point2 Float Point2 Point2
|
| PutSwitchDoor Color Point2 Float Point2 Point2
|
||||||
| RandPS (State StdGen PSType)
|
| RandPS (State StdGen PSType)
|
||||||
| PutNothing
|
| PutNothing
|
||||||
| PutID Int
|
| PutID { _putID :: Int}
|
||||||
| CollectivePS
|
| CollectivePS
|
||||||
{ _collectiveID :: Int
|
{ _collectiveID :: Int
|
||||||
, _collectiveNum :: Int
|
, _collectiveNum :: Int
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
module Dodge.Lock
|
||||||
|
where
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE StrictData #-}
|
||||||
|
module Dodge.Lock.Data
|
||||||
|
where
|
||||||
|
import Dodge.Data
|
||||||
|
import Control.Lens
|
||||||
|
|
||||||
|
data Lock = Lock
|
||||||
|
{ _lkUnlocker :: Unlocker
|
||||||
|
}
|
||||||
|
|
||||||
|
data Unlocker
|
||||||
|
= ItemUnlocker Item
|
||||||
|
|
||||||
|
makeLenses ''Lock
|
||||||
+25
-25
@@ -164,12 +164,12 @@ glassSwitchBack = do
|
|||||||
return $ set rmPS plmnts $ roomRect wth hgt 2 6
|
return $ set rmPS plmnts $ roomRect wth hgt 2 6
|
||||||
|
|
||||||
manyDoors :: Int -> Tree (Either Room Room)
|
manyDoors :: Int -> Tree (Either Room Room)
|
||||||
manyDoors i = treePost (replicate i (Left door)) $ Right door
|
manyDoors i = treeFromPost (replicate i (Left door)) $ Right door
|
||||||
|
|
||||||
glassLesson :: RandomGen g => State g (Tree (Either Room Room))
|
glassLesson :: RandomGen g => State g (Tree (Either Room Room))
|
||||||
glassLesson = do
|
glassLesson = do
|
||||||
corridors <- sequence $ replicate 3 $ fmap Left $ randomiseOutLinks corridor
|
corridors <- sequence $ replicate 3 $ fmap Left $ randomiseOutLinks corridor
|
||||||
return $ Node (Left $ botRoom) [deadRoom door,uppers, treePost (Left door : corridors) $ Right door]
|
return $ Node (Left $ botRoom) [deadRoom door,uppers, treeFromPost (Left door : corridors) $ Right door]
|
||||||
where uppers = Node (Left door) [deadRoom topRoom]
|
where uppers = Node (Left door) [deadRoom topRoom]
|
||||||
botRoom = set rmPS botplmnts
|
botRoom = set rmPS botplmnts
|
||||||
$ roomRect 200 200 1 1
|
$ roomRect 200 200 1 1
|
||||||
@@ -212,7 +212,7 @@ miniRoom1 = do
|
|||||||
|
|
||||||
miniTree2 :: RandomGen g => State g (Tree (Either Room Room))
|
miniTree2 :: RandomGen g => State g (Tree (Either Room Room))
|
||||||
miniTree2 = miniRoom1 >>= randomiseOutLinks >>= changeLinkTo (\p -> (snd . fst) p < 70)
|
miniTree2 = miniRoom1 >>= randomiseOutLinks >>= changeLinkTo (\p -> (snd . fst) p < 70)
|
||||||
>>= return . flip branchWith (replicate 3 $ treePost [door,corridor]
|
>>= return . flip branchWith (replicate 3 $ treeFromPost [door,corridor]
|
||||||
critInDeadEnd )
|
critInDeadEnd )
|
||||||
|
|
||||||
miniRoom3 :: RandomGen g => State g (Tree (Either Room Room))
|
miniRoom3 :: RandomGen g => State g (Tree (Either Room Room))
|
||||||
@@ -252,7 +252,7 @@ rot90Around cen p = cen +.+ vNormal (p -.- cen)
|
|||||||
-- So, the idea is to attach outer children to the bottommost right nodes
|
-- So, the idea is to attach outer children to the bottommost right nodes
|
||||||
-- inside an inner tree
|
-- inside an inner tree
|
||||||
roomMiniIntro :: RandomGen g => State g (Tree (Either Room Room))
|
roomMiniIntro :: RandomGen g => State g (Tree (Either Room Room))
|
||||||
roomMiniIntro = fmap (g . expandTreeBy f) $ sequence $ treePost
|
roomMiniIntro = fmap (g . expandTreeBy f) $ sequence $ treeFromPost
|
||||||
[return $ connectRoom door
|
[return $ connectRoom door
|
||||||
,join $ takeOne [miniTree2,glassLesson]
|
,join $ takeOne [miniTree2,glassLesson]
|
||||||
-- ,join $ takeOne [miniRoom1]
|
-- ,join $ takeOne [miniRoom1]
|
||||||
@@ -298,22 +298,22 @@ allPairs xs = [(x,y) | x <- xs, y <- xs, x /= y]
|
|||||||
randomCorridorFrom :: RandomGen g => [a] -> State g (Tree (Either a a))
|
randomCorridorFrom :: RandomGen g => [a] -> State g (Tree (Either a a))
|
||||||
randomCorridorFrom xs = do
|
randomCorridorFrom xs = do
|
||||||
rooms <- sequence $ replicate 5 $ takeOne xs
|
rooms <- sequence $ replicate 5 $ takeOne xs
|
||||||
return $ treeTrunk (map Left $ init rooms) (Node (Right (last rooms)) [])
|
return $ treeFromTrunk (map Left $ init rooms) (Node (Right (last rooms)) [])
|
||||||
|
|
||||||
|
|
||||||
|
{-
|
||||||
|
Probabilites of the type of the first floor weapon.
|
||||||
|
-}
|
||||||
randFirstWeapon :: State StdGen PSType
|
randFirstWeapon :: State StdGen PSType
|
||||||
randFirstWeapon = do
|
randFirstWeapon = do
|
||||||
-- r <- state $ randomR (-pi,pi)
|
takeOne $ map PutFlIt $
|
||||||
takeOne $ map PutFlIt
|
replicate 10 pistol
|
||||||
[ pistol
|
++ replicate 5 ltAutoGun
|
||||||
, ltAutoGun
|
++ replicate 5 spreadGun
|
||||||
-- , autoGun
|
++ replicate 5 multGun
|
||||||
, spreadGun
|
++ replicate 2 autoGun
|
||||||
, multGun
|
++ [launcher]
|
||||||
, launcher
|
++ [lasGun]
|
||||||
-- , lasGun
|
++ [flamer]
|
||||||
-- , flamer
|
|
||||||
]
|
|
||||||
|
|
||||||
--randC1 :: State StdGen PSType
|
--randC1 :: State StdGen PSType
|
||||||
randC1 = RandPS $ takeOne $ map PutCrit $ (armourChaseCrit : replicate 50 chaseCrit)
|
randC1 = RandPS $ takeOne $ map PutCrit $ (armourChaseCrit : replicate 50 chaseCrit)
|
||||||
@@ -341,13 +341,13 @@ weaponUnderCrits = do
|
|||||||
,PS (20,0) (0-pi/2) $ randC1
|
,PS (20,0) (0-pi/2) $ randC1
|
||||||
,PS (20,20) (0-pi/2) $ randC1
|
,PS (20,20) (0-pi/2) $ randC1
|
||||||
]
|
]
|
||||||
let continuationRoom = treeTrunk [Left corridorN,Left corridorN]
|
let continuationRoom = treeFromTrunk [Left corridorN,Left corridorN]
|
||||||
(connectRoom (set rmPS plmnts $ corridorN))
|
(connectRoom (set rmPS plmnts $ corridorN))
|
||||||
rcp' <- roomCenterPillar
|
rcp' <- roomCenterPillar
|
||||||
let rcp = over rmPS ( PS (120,80) 0 putLamp : ) rcp'
|
let rcp = over rmPS ( PS (120,80) 0 putLamp : ) rcp'
|
||||||
deadEndRoom <- takeOne [roomPillars,rcp]
|
deadEndRoom <- takeOne [roomPillars,rcp]
|
||||||
junctionRoom <- takeOne [Left tEast,Left tWest]
|
junctionRoom <- takeOne [Left tEast,Left tWest]
|
||||||
return $ treeTrunk [Left corridorN,Left corridorN]
|
return $ treeFromTrunk [Left corridorN,Left corridorN]
|
||||||
$ Node junctionRoom
|
$ Node junctionRoom
|
||||||
[continuationRoom
|
[continuationRoom
|
||||||
,deadRoom deadEndRoom
|
,deadRoom deadEndRoom
|
||||||
@@ -362,7 +362,7 @@ weaponBehindPillar = do
|
|||||||
,PS crPos (d crPos) $ randC1
|
,PS crPos (d crPos) $ randC1
|
||||||
]
|
]
|
||||||
rcp <- roomCenterPillar
|
rcp <- roomCenterPillar
|
||||||
return $ treeTrunk [Left door
|
return $ treeFromTrunk [Left door
|
||||||
,Left $ over rmLinks tail $ over rmPS (++ plmnts1) rcp]
|
,Left $ over rmLinks tail $ over rmPS (++ plmnts1) rcp]
|
||||||
(connectRoom $ set rmPS [PS (20,60) (0-pi/2) $ randC1]
|
(connectRoom $ set rmPS [PS (20,60) (0-pi/2) $ randC1]
|
||||||
$ corridorN)
|
$ corridorN)
|
||||||
@@ -389,7 +389,7 @@ blockedCorridor = do
|
|||||||
$ reverse $ rectNSWE 10 (-10) (-10) 10
|
$ reverse $ rectNSWE 10 (-10) (-10) 10
|
||||||
,PS (20,15) 0 $ putLamp
|
,PS (20,15) 0 $ putLamp
|
||||||
]
|
]
|
||||||
sequence $ treePost (replicate n $ fmap Left $ randomiseOutLinks corridor)
|
sequence $ treeFromPost (replicate n $ fmap Left $ randomiseOutLinks corridor)
|
||||||
$ fmap Right $ return $ set rmPS plmnts corridor
|
$ fmap Right $ return $ set rmPS plmnts corridor
|
||||||
|
|
||||||
weaponLongCorridor :: RandomGen g => State g (Tree (Either Room Room))
|
weaponLongCorridor :: RandomGen g => State g (Tree (Either Room Room))
|
||||||
@@ -401,8 +401,8 @@ weaponLongCorridor = do
|
|||||||
]
|
]
|
||||||
i1 <- state $ randomR (2,5)
|
i1 <- state $ randomR (2,5)
|
||||||
i2 <- state $ randomR (2,5)
|
i2 <- state $ randomR (2,5)
|
||||||
let branch1 = treeTrunk (replicate i1 $ Left corridorN) (connectRoom $ putCrs connectingRoom)
|
let branch1 = treeFromTrunk (replicate i1 $ Left corridorN) (connectRoom $ putCrs connectingRoom)
|
||||||
let branch2 = treeTrunk (replicate i2 $ Left corridorN) (deadRoom $ putWp corridor)
|
let branch2 = treeFromTrunk (replicate i2 $ Left corridorN) (deadRoom $ putWp corridor)
|
||||||
return $ Node (Left root) [branch1,branch2]
|
return $ Node (Left root) [branch1,branch2]
|
||||||
where putCrs = over rmPS (++ [PS (10,40) (-pi/2) $ randC
|
where putCrs = over rmPS (++ [PS (10,40) (-pi/2) $ randC
|
||||||
,PS (-10,40) (-pi/2) $ randC
|
,PS (-10,40) (-pi/2) $ randC
|
||||||
@@ -618,7 +618,7 @@ shootingRange = do
|
|||||||
>>= filterLinks (\((_,y),r) -> y > 200 && r /= 0)
|
>>= filterLinks (\((_,y),r) -> y > 200 && r /= 0)
|
||||||
rm3 <- shootersRoom >>= changeLinkTo (\((x,y),_) -> y < 10 && x > 20 && x < 180)
|
rm3 <- shootersRoom >>= changeLinkTo (\((x,y),_) -> y < 10 && x > 20 && x < 180)
|
||||||
>>= filterLinks (\(_,r) -> r == 0)
|
>>= filterLinks (\(_,r) -> r == 0)
|
||||||
return $ treePost [Left rm1
|
return $ treeFromPost [Left rm1
|
||||||
,Left $ roomPadCut (rectNSWE 20 (-20) (-80) 80) (0,20)
|
,Left $ roomPadCut (rectNSWE 20 (-20) (-80) 80) (0,20)
|
||||||
,Left rm2
|
,Left rm2
|
||||||
,Left $ roomPadCut (rectNSWE 20 (-20) (-80) 80) (0,20)
|
,Left $ roomPadCut (rectNSWE 20 (-20) (-80) 80) (0,20)
|
||||||
@@ -639,4 +639,4 @@ spawnerRoom = do
|
|||||||
]
|
]
|
||||||
let f ((lx,_),_) = lx < x/2-5
|
let f ((lx,_),_) = lx < x/2-5
|
||||||
roomWithSpawner <- (fmap connectRoom . randomiseOutLinks) =<< filterLinks f (set rmPS plmnts $ roomRect x y 2 2)
|
roomWithSpawner <- (fmap connectRoom . randomiseOutLinks) =<< filterLinks f (set rmPS plmnts $ roomRect x y 2 2)
|
||||||
return $ treeTrunk [Left (airlock 0)] roomWithSpawner
|
return $ treeFromTrunk [Left (airlock 0)] roomWithSpawner
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import Dodge.Data
|
|||||||
import Dodge.Room.Data
|
import Dodge.Room.Data
|
||||||
import Dodge.Room.Placement
|
import Dodge.Room.Placement
|
||||||
import Dodge.LevelGen.Data
|
import Dodge.LevelGen.Data
|
||||||
|
import Dodge.Creature
|
||||||
|
import Dodge.RandomHelp
|
||||||
import Geometry
|
import Geometry
|
||||||
|
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
@@ -40,3 +42,13 @@ roomOctogon x = Room
|
|||||||
|
|
||||||
bossRoom :: RandomGen g => Creature -> State g Room
|
bossRoom :: RandomGen g => Creature -> State g Room
|
||||||
bossRoom cr = pure $ roomOctogon 300 & rmPS %~ ( PS (0,100) (negate $ pi/2) (PutCrit cr) :)
|
bossRoom cr = pure $ roomOctogon 300 & rmPS %~ ( PS (0,100) (negate $ pi/2) (PutCrit cr) :)
|
||||||
|
|
||||||
|
armouredChasers :: RandomGen g => State g Room
|
||||||
|
armouredChasers = do
|
||||||
|
ps <- takeN 5 [(x,y) | x <- [-200,-120 .. 200] ,y <- [-200,-120 .. 200] ]
|
||||||
|
as <- replicateM 5 . state $ randomR (0,2*pi)
|
||||||
|
let theCrits = zipWith3 (\p a c -> PS p a (PutCrit armourChaseCrit)) ps as cs
|
||||||
|
pure $ roomOctogon 300 & rmPS %~ (++ theCrits)
|
||||||
|
where
|
||||||
|
cs = (armourChaseCrit & crState . crDropsOnDeath .~ DropSpecific [0])
|
||||||
|
: replicate 4 (armourChaseCrit & crState . crDropsOnDeath .~ DropSpecific [1])
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ branchRectWith t = do
|
|||||||
y <- state $ randomR (100,200)
|
y <- state $ randomR (100,200)
|
||||||
b <- t
|
b <- t
|
||||||
root <- randomiseOutLinks $ roomRectAutoLinks x y
|
root <- randomiseOutLinks $ roomRectAutoLinks x y
|
||||||
return $ Node (Left root) [Node (Right door) [], fmap rToL $ treeTrunk [Left door] b]
|
return $ Node (Left root) [Node (Right door) [], fmap rToL $ treeFromTrunk [Left door] b]
|
||||||
where rToL :: Either a a -> Either a a
|
where rToL :: Either a a -> Either a a
|
||||||
rToL (Right r) = Left r
|
rToL (Right r) = Left r
|
||||||
rToL (Left r) = Left r
|
rToL (Left r) = Left r
|
||||||
|
|||||||
+9
-17
@@ -7,6 +7,15 @@ import Geometry
|
|||||||
|
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
|
|
||||||
|
{-
|
||||||
|
The '_rmPolys' list states which polygons should be cut out to form the indestructible walls of the room.
|
||||||
|
Link pairs contain a position and rotation to attach to another room;
|
||||||
|
0 is for links going to another room to the north, pi/2 for links going to a room to the west, etc.
|
||||||
|
TODO : Explain path, does it need both directions?
|
||||||
|
Placement spots allow things to be put in the room during level generation.
|
||||||
|
Room bounds between a new room and previously placed rooms are checked during level generation,
|
||||||
|
assigning no bounds will allow rooms to overlap.
|
||||||
|
-}
|
||||||
data Room = Room
|
data Room = Room
|
||||||
{ _rmPolys :: [ [Point2] ]
|
{ _rmPolys :: [ [Point2] ]
|
||||||
, _rmLinks :: [(Point2,Float)]
|
, _rmLinks :: [(Point2,Float)]
|
||||||
@@ -14,21 +23,4 @@ data Room = Room
|
|||||||
, _rmPS :: [PlacementSpot]
|
, _rmPS :: [PlacementSpot]
|
||||||
, _rmBound :: [Point2]
|
, _rmBound :: [Point2]
|
||||||
}
|
}
|
||||||
data RoomLink = RL {_rlPos :: Point2, _rlRot :: Float}
|
|
||||||
|
|
||||||
makeLenses ''Room
|
makeLenses ''Room
|
||||||
makeLenses ''RoomLink
|
|
||||||
|
|
||||||
-- want to split a room into its dimensions and contents
|
|
||||||
|
|
||||||
data Room' = Room'
|
|
||||||
{ _dimensions :: Dimensions
|
|
||||||
, _contents :: [PlacementSpot]
|
|
||||||
}
|
|
||||||
|
|
||||||
data Dimensions = Dimensions
|
|
||||||
{ _dmPolys :: [[Point2]]
|
|
||||||
, _dmLinks :: [(Point2,Float)]
|
|
||||||
, _dmPath :: [(Point2, Point2)]
|
|
||||||
, _dmBound :: [Point2]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
module Dodge.Room.LockAndKeyList
|
||||||
|
where
|
||||||
|
import Dodge.Room.Data
|
||||||
|
import Dodge.Room.RoadBlock
|
||||||
|
import Dodge.Room.Boss
|
||||||
|
|
||||||
|
import Control.Monad.State
|
||||||
|
import System.Random
|
||||||
|
import Data.Tree
|
||||||
|
|
||||||
|
lockAndKeyRoomList :: RandomGen g =>
|
||||||
|
[ (State g (Tree (Either Room Room))
|
||||||
|
,State g (Tree (Either Room Room))
|
||||||
|
) ]
|
||||||
|
lockAndKeyRoomList =
|
||||||
|
[ ( fmap (pure . Right) armouredCorridor
|
||||||
|
, fmap (pure . Left) armouredChasers
|
||||||
|
)
|
||||||
|
]
|
||||||
@@ -3,18 +3,20 @@ module Dodge.Room.Placement
|
|||||||
where
|
where
|
||||||
import Dodge.Data
|
import Dodge.Data
|
||||||
import Dodge.LevelGen.Data
|
import Dodge.LevelGen.Data
|
||||||
import Picture
|
import Dodge.Room.Data
|
||||||
import Dodge.Creature.Inanimate
|
import Dodge.Creature.Inanimate
|
||||||
|
import Picture
|
||||||
import Geometry
|
import Geometry
|
||||||
|
|
||||||
|
import Data.List
|
||||||
|
import Control.Lens
|
||||||
|
|
||||||
|
|
||||||
putLamp = PutCrit lamp
|
putLamp = PutCrit lamp
|
||||||
|
|
||||||
singleBlock :: Point2 -> [PlacementSpot]
|
singleBlock :: Point2 -> [PlacementSpot]
|
||||||
singleBlock a = [PS a 0 $ PutBlock [5,20,20] (greyN 0.5)
|
singleBlock a = [PS a 0 $ PutBlock [5,20,20] (greyN 0.5)
|
||||||
$ reverse $ rectNSWE 10 (-10) (-10) 10]
|
$ reverse $ rectNSWE 10 (-10) (-10) 10]
|
||||||
|
|
||||||
{-
|
{-
|
||||||
Places a line of blocks between two points.
|
Places a line of blocks between two points.
|
||||||
Width 9, also extends out from each point by 9.
|
Width 9, also extends out from each point by 9.
|
||||||
@@ -88,3 +90,31 @@ baseWindowPane = Block
|
|||||||
, _blShadows = []
|
, _blShadows = []
|
||||||
, _blDegrades = [5,5]
|
, _blDegrades = [5,5]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{-
|
||||||
|
Replaces instances of a given 'PutID' with 'PSType's drawn from a list.
|
||||||
|
-}
|
||||||
|
replacePutID
|
||||||
|
:: Int -- ^ The id of 'PutID' to be replaced
|
||||||
|
-> [PSType] -- ^ List of replacements
|
||||||
|
-> Room
|
||||||
|
-> Room
|
||||||
|
replacePutID i psts r =
|
||||||
|
r & rmPS %~ flip (subZipWith (isPutID i) (\ps pt -> ps & psType .~ pt)) psts
|
||||||
|
|
||||||
|
{-
|
||||||
|
Partition a list by a predicate, apply a zip to those elements
|
||||||
|
that satisfy the predicate, concatenate
|
||||||
|
the new zipped list and the other (unchanged) half.
|
||||||
|
-}
|
||||||
|
subZipWith
|
||||||
|
:: (a -> Bool) -- ^ Filter: elements to apply zip to
|
||||||
|
-> (a -> b -> a) -- ^ Combining function
|
||||||
|
-> [a] -- ^ List to be partition
|
||||||
|
-> [b] -- ^ Modifying list
|
||||||
|
-> [a]
|
||||||
|
subZipWith f g xs ys =
|
||||||
|
let (zs,ws) = partition f xs
|
||||||
|
in zipWith g zs ys ++ ws
|
||||||
|
|
||||||
|
isPutID i ps = Just i == ps ^? psType . putID
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
{-
|
||||||
|
Connecting rooms designed with a pass-through technique in mind.
|
||||||
|
-}
|
||||||
|
module Dodge.Room.RoadBlock
|
||||||
|
where
|
||||||
|
import Geometry
|
||||||
|
import Dodge.Room.Data
|
||||||
|
import Dodge.Room.Link
|
||||||
|
import Dodge.Room.Placement
|
||||||
|
import Dodge.LevelGen.Data
|
||||||
|
import Dodge.RandomHelp
|
||||||
|
import Dodge.Creature
|
||||||
|
|
||||||
|
import Data.Tree
|
||||||
|
import Control.Monad.State
|
||||||
|
import System.Random
|
||||||
|
|
||||||
|
armouredCorridor :: RandomGen g => State g Room
|
||||||
|
armouredCorridor = fmap (replacePutID 0 [PutCrit $ addArmour autoCrit]) litCorridor90
|
||||||
|
|
||||||
|
{-
|
||||||
|
A corridor of random length with a 90 degree link at the end.
|
||||||
|
-}
|
||||||
|
litCorridor90 :: RandomGen g => State g Room
|
||||||
|
litCorridor90 = do
|
||||||
|
h <- state $ randomR (500,800)
|
||||||
|
let poly = rectNSWE h 0 0 40
|
||||||
|
poly2 = rectNSWE (h-60) (h-100) (-60) 5
|
||||||
|
pure $ Room
|
||||||
|
{ _rmPolys = [poly,poly2]
|
||||||
|
, _rmLinks = [ ((40,h - 80), -pi/2)
|
||||||
|
, ((20, 0), pi)
|
||||||
|
]
|
||||||
|
, _rmPath = concatMap doublePair
|
||||||
|
[((20,0),(20,h-40))
|
||||||
|
,(( 0,h-40),(20,h-40))
|
||||||
|
,((40,h-40),(20,h-40))
|
||||||
|
]
|
||||||
|
, _rmPS =
|
||||||
|
[ PS (20,h-5) 0 $ putLamp
|
||||||
|
, windowLine (0,h-20) (40,h-20)
|
||||||
|
, PS (-50,h-85) 0 $ putLamp
|
||||||
|
, windowLine (0-40,h-60) (0-40,h-100)
|
||||||
|
, PS ( 20,h-40) 0 $ PutID 0
|
||||||
|
, PS (-20,h-80) 0 $ PutID 2
|
||||||
|
]
|
||||||
|
, _rmBound = poly
|
||||||
|
}
|
||||||
@@ -5,10 +5,14 @@ Typically dead ends.
|
|||||||
module Dodge.Room.Treasure
|
module Dodge.Room.Treasure
|
||||||
where
|
where
|
||||||
import Geometry
|
import Geometry
|
||||||
|
import Dodge.Data
|
||||||
import Dodge.Room.Data
|
import Dodge.Room.Data
|
||||||
|
import Dodge.Room.Placement
|
||||||
import Dodge.LevelGen.Data
|
import Dodge.LevelGen.Data
|
||||||
|
|
||||||
|
import Data.List
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
|
import Control.Lens
|
||||||
import System.Random
|
import System.Random
|
||||||
|
|
||||||
{-
|
{-
|
||||||
@@ -21,18 +25,24 @@ triLootRoom
|
|||||||
-> Float -- Height
|
-> Float -- Height
|
||||||
-> State g Room
|
-> State g Room
|
||||||
triLootRoom w h = pure $ Room
|
triLootRoom w h = pure $ Room
|
||||||
{ _rmPolys = [poly]
|
{ _rmPolys = [ tri
|
||||||
, _rmLinks = [((0,10),pi)]
|
, base
|
||||||
, _rmPath = doublePair ((0,10),(0,h/2))
|
]
|
||||||
|
, _rmLinks = [((0,-80),pi)]
|
||||||
|
, _rmPath = doublePair ((0,-80),(0,h/2))
|
||||||
, _rmPS =
|
, _rmPS =
|
||||||
[PS (15-w,15) 0 $ PutID 0
|
[PS (15-w,15) 0 $ PutID 0
|
||||||
,PS (w-15,15) 0 $ PutID 0
|
,PS (w-15,15) pi $ PutID 0
|
||||||
,PS (0,h-15) 0 $ PutID 2
|
,PS (0,h-35) 0 $ PutID 2
|
||||||
|
,PS (-5,h-10) 0 putLamp
|
||||||
|
,PS (5,h-10) 0 putLamp
|
||||||
|
,PS (0,h-15) 0 putLamp
|
||||||
|
,PS (0,-60) 0 putLamp
|
||||||
]
|
]
|
||||||
, _rmBound = poly
|
, _rmBound = convexHull $ tri ++ base
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
poly =
|
tri =
|
||||||
[ ( -w,30)
|
[ ( -w,30)
|
||||||
, ( -w, 0)
|
, ( -w, 0)
|
||||||
, ( w, 0)
|
, ( w, 0)
|
||||||
@@ -40,3 +50,10 @@ triLootRoom w h = pure $ Room
|
|||||||
, ( 20, h)
|
, ( 20, h)
|
||||||
, (-20, h)
|
, (-20, h)
|
||||||
]
|
]
|
||||||
|
base = rectNSWE 20 (-80) (-20) 20
|
||||||
|
|
||||||
|
lootRoom :: RandomGen g => [Creature] -> [Item] -> State g Room
|
||||||
|
lootRoom crs itms = do
|
||||||
|
let w = 300
|
||||||
|
h = 700
|
||||||
|
fmap (replacePutID 0 (map PutCrit crs) . replacePutID 2 (map PutFlIt itms)) $ triLootRoom w h
|
||||||
|
|||||||
Reference in New Issue
Block a user