179 lines
5.4 KiB
Haskell
179 lines
5.4 KiB
Haskell
{- Rooms containing particularly challenging creatures, that may drop useful loot. -}
|
|
module Dodge.Room.Boss where
|
|
|
|
import Dodge.Creature
|
|
import Dodge.Data.GenWorld
|
|
import Dodge.Default.Room
|
|
import Dodge.LevelGen.PlacementHelper
|
|
import Dodge.LevelGen.StaticWalls
|
|
import Dodge.Placement.Instance
|
|
import Dodge.Room.Corridor
|
|
import Dodge.Room.Link
|
|
import Dodge.Room.Path
|
|
import Dodge.Room.Procedural
|
|
import Dodge.RoomLink
|
|
import Dodge.Tree
|
|
import Geometry
|
|
import LensHelp
|
|
import RandomHelp
|
|
import Control.Monad
|
|
|
|
-- pathing needs to be done
|
|
roomGlassOctogon :: Float -> Room
|
|
roomGlassOctogon x =
|
|
-- createPathGrid $
|
|
defaultRoom
|
|
{ _rmPolys =
|
|
[ rectNSWE x (- x) (- x) x
|
|
, rectNSWE 0 (- (x + 40)) (-20) 20
|
|
]
|
|
, _rmLinks = lnks'
|
|
, _rmPath =
|
|
linksDAGToPath lnks' [ (V2 0 x, V2 0 (- (x + 40))) ]
|
|
, _rmPmnts =
|
|
[ sPS (V2 fx fx) 0 putLamp
|
|
, sPS (V2 (- fx) fx) 0 putLamp
|
|
, sPS (V2 fx (- fx)) 0 putLamp
|
|
, sPS (V2 (- fx) (- fx)) 0 putLamp
|
|
, crystalLine (V2 (- x) (x / 2)) (V2 (negate (x / 2)) x)
|
|
, crystalLine (V2 x (x / 2)) (V2 (x / 2) x)
|
|
, crystalLine (V2 (x / 2) (- x)) (V2 x (negate (x / 2)))
|
|
, crystalLine (V2 (negate $ x / 2) (- x)) (V2 (- x) (negate (x / 2)))
|
|
, blockLine (V2 (-40) (50 - x)) (V2 40 (50 - x))
|
|
]
|
|
, _rmBound = [rectNSWE x (- x) (- x) x]
|
|
, _rmName = "glass8gon"
|
|
}
|
|
where
|
|
fx = 5 * x / 6
|
|
lnks' = map (uncurry outLink) (init lnks) ++ [uncurry inLink $ last lnks]
|
|
lnks =
|
|
[ (V2 0 x, 0)
|
|
, (V2 0 (- (x + 40)), pi)
|
|
]
|
|
|
|
bossRoom :: RandomGen g => Creature -> State g Room
|
|
bossRoom cr = randomMediumRoom <&> rmPmnts .:~ sPS (V2 0 100) (negate $ pi / 2) (PutCrit cr)
|
|
|
|
armouredChasers :: RandomGen g => State g (Tree Room)
|
|
armouredChasers = do
|
|
ps <- takeN 5 [V2 x y | x <- [-100, -80 .. 100], y <- [-100, -80 .. 100]]
|
|
as <- replicateM 5 . state $ randomR (0, 2 * pi)
|
|
let theCrits = zipWith3 (\p a c -> sPS p a (PutCrit c)) ps as cs
|
|
treeFromPost [corridor, corridor] <$> (randomMediumRoom <&> rmPmnts %~ (++ theCrits))
|
|
where
|
|
cs =
|
|
--(armourChaseCrit & crState . csDropsOnDeath .~ DropSpecific [0]) :
|
|
armourChaseCrit :
|
|
replicate 4 chaseCrit
|
|
|
|
randomMediumRoom :: RandomGen g => State g Room
|
|
randomMediumRoom =
|
|
takeOne
|
|
[ roomGlassOctogon 300
|
|
, roomCross 180 300
|
|
, roomShuriken 200 300
|
|
, roomTwistCross 230 300 0
|
|
]
|
|
|
|
roomCross ::
|
|
-- | First width/2
|
|
Float ->
|
|
-- | Second width/2
|
|
Float ->
|
|
Room
|
|
roomCross x y =
|
|
defaultRoom
|
|
{ _rmPolys =
|
|
[ rectNSWE y (- y) (- x) x
|
|
, rectNSWE (- x) x y (- y)
|
|
]
|
|
, _rmLinks =
|
|
map
|
|
(uncurry outLink)
|
|
[ (V2 x (y -20), negate $ pi / 2)
|
|
, (V2 x (20 - y), negate $ pi / 2)
|
|
, (V2 (20 - y) x, 0)
|
|
, (V2 (y -20) x, 0)
|
|
, (V2 (- x) (y -20), pi / 2)
|
|
, (V2 (- x) (20 - y), pi / 2)
|
|
, (V2 (20 - y) (- x), pi)
|
|
]
|
|
++ [ uncurry inLink (V2 (y -20) (- x), pi)
|
|
]
|
|
, _rmPath = mempty
|
|
, _rmPmnts =
|
|
[ spanLightI (V2 (x + 5) x) (V2 (x + 5) (- x))
|
|
, spanLightI (V2 (- x -5) x) (V2 (- x -5) (- x))
|
|
]
|
|
, _rmBound =
|
|
[ rectNSWE y (- y) (- x) x
|
|
, rectNSWE x (- x) (- y) y
|
|
]
|
|
, _rmName = "cross"
|
|
}
|
|
|
|
-- | TODO: pathing
|
|
roomShuriken ::
|
|
-- | First width/2
|
|
Float ->
|
|
-- | Second width/2
|
|
Float ->
|
|
Room
|
|
roomShuriken x y =
|
|
let ps =
|
|
[ map
|
|
toV2
|
|
[ (0, -20)
|
|
, (x, -20)
|
|
, (x, y)
|
|
, (0, x)
|
|
]
|
|
]
|
|
corner =
|
|
defaultRoom
|
|
{ _rmPolys = ps
|
|
, _rmLinks = [toBothLnk (V2 (x -1) (y -20), negate $ pi / 2)]
|
|
, _rmPath = mempty
|
|
, _rmPmnts = [mntLS iShape (V2 x x) (V3 (x -20) x 70)]
|
|
, _rmBound = ps
|
|
}
|
|
in (foldr1 combineRooms $ map (\r -> moveRoomBy (V2 0 0, r) corner) [0, pi / 2, pi, 3 * pi / 2])
|
|
{ _rmName = "shuriken"
|
|
}
|
|
|
|
{- | TODO: pathing
|
|
Precondition: first float is less than the second by at least 40.
|
|
-}
|
|
roomTwistCross ::
|
|
-- | First width/2,
|
|
Float ->
|
|
-- | Second width/2, should be biggest
|
|
Float ->
|
|
-- | Third width, should be smallest, possibly negative
|
|
Float ->
|
|
Room
|
|
roomTwistCross x y z =
|
|
let ps =
|
|
[ map
|
|
toV2
|
|
[ (x, negate $ z + 20)
|
|
, (x, x)
|
|
, (z, y)
|
|
, (z -20, x)
|
|
, (z, negate $ z + 20)
|
|
]
|
|
, rectNSWE (x -5) 0 0 (x -5)
|
|
]
|
|
corner =
|
|
defaultRoom
|
|
{ _rmPolys = ps
|
|
, _rmLinks = [toBothLnk (V2 z (y -20), pi / 2)]
|
|
, _rmPath = mempty
|
|
, _rmPmnts = [mntLS iShape (V2 x x) (V3 (x -20) (x -20) 70)]
|
|
, _rmBound = map (expandPolyCorners 10) ps
|
|
}
|
|
in (foldr1 combineRooms $ map (\r -> moveRoomBy (V2 0 0, r) corner) [0, pi / 2, pi, 3 * pi / 2])
|
|
{ _rmName = "twistCross"
|
|
}
|