Files
loop/src/Dodge/Data/GenWorld.hs
T

160 lines
5.3 KiB
Haskell

{-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-}
module Dodge.Data.GenWorld (
module Dodge.Data.GenWorld,
module Dodge.Data.Room,
module Dodge.Data.RoomCluster,
module Dodge.Data.World,
) where
import ShortShow
import Control.Lens
import Control.Monad.State
import qualified Data.Set as S
import Data.Tile
import Dodge.Data.Room
import Dodge.Data.RoomCluster
import Dodge.Data.World
import Geometry.Data
import qualified IntMapHelp as IM
import System.Random
data GenWorld = GenWorld
{ _gwWorld :: World
, _genRooms :: IM.IntMap Room
, _genPmnt :: IM.IntMap Placement
, _genInts :: IM.IntMap Int
}
---- ROOM DATATYPES
data PSType
= PutCrit {_unPutCrit :: Creature}
| PutMachine
{ _putMachinePoly :: [Point2]
, _putMachineMachine :: Machine
, _putMachineWall :: Wall
, _putMachineMaybeItem :: Maybe Item
}
| PutLS LightSource
| PutButton {_putButton :: Button}
| PutProp Prop
| PutTerminal {_unputTerminal :: Terminal}
| PutFlIt {_putItem :: Item}
| PutBlock {_putBlock :: Block, _putWall :: Wall, _putPoly :: [Point2]}
| PutCoord Point2
| PutMod Modification
| PutTrigger Bool
| PutLineBlock
{ _putWall :: Wall
, _putWidth :: Float
, _putStartPoint :: Point2
, _putEndPoint :: Point2
}
| PutWall {_pwPoly :: [Point2], _pwWall :: Wall}
| PutSlideDr Door Wall (S.Set EdgeObstacle) Float Point2 Point2
-- | PutDoor Color EdgeObstacle WdBl [(Point2, Point2)]
| PutDoor (S.Set EdgeObstacle) WdBl Float Point2A Point2A -- [(Point2, Point2)]
| RandPS (State StdGen PSType)
| PutForeground ForegroundShape
| PutWorldUpdate (Int -> PlacementSpot -> GenWorld -> GenWorld)
| PutNothing
| PutID {_putID :: Int}
| PutChasm {_putChasmPoly :: [Point2]}
| PutLabel {_putLabel :: String} -- currently not actually put anywhere
-- just used for later inspection as top level
-- of a continuing placement in a room placement list
instance ShortShow PSType where
shortShow PutCrit {} = "PutCrit"
shortShow PutMachine {} = "PutMachine"
shortShow PutLS {} = "PutLS"
shortShow PutButton {} = "PutButton"
shortShow PutProp {} = "PutProp"
shortShow PutTerminal {} = "PutTerminal"
shortShow PutFlIt {} = "PutFlIt"
shortShow PutBlock {} = "PutBlock"
shortShow PutCoord {} = "PutCoord"
shortShow PutMod {} = "PutMod"
shortShow PutTrigger {} = "PutTrigger"
shortShow PutLineBlock {} = "PutLineBlock"
shortShow PutWall {} = "PutWall"
shortShow PutSlideDr {} = "PutSlideDr"
shortShow PutDoor {} = "PutDoor"
shortShow RandPS {} = "RandPS"
shortShow PutForeground {} = "PutForeground"
shortShow PutWorldUpdate {} = "PutWorldUpdate"
shortShow PutNothing = "PutNothing"
shortShow PutID {} = "PutID"
shortShow PutChasm {} = "PutChasm"
shortShow PutLabel {} = "PutLabel"
-- maybe there is a monadic implementation of this?
-- add room effect for any placement spot?
data PlacementSpot
= PS {_psPos :: Point2, _psRot :: Float}
| PSNoShiftCont {_psPos :: Point2, _psRot :: Float}
| PSPos
{ _psSelect :: RoomPos -> Room -> Maybe (PlacementSpot, RoomPos)
, _psRoomEff :: RoomPos -> Room -> Room
, _psFallback :: Maybe Placement
}
| PSRoomRand
{ _psRoomRandPointNum :: Int
, _psRandShift :: (Point2, Float) -> PlacementSpot
}
-- TODO attempt to unify/simplify this union type
data Placement = Placement
{ _plSpot :: PlacementSpot
, _plType :: PSType
, _plMID :: Maybe Int
, _plExternalID :: Maybe Int
, _plIDCont :: GenWorld -> Placement -> Maybe Placement
}
{- The '_rmPolys' lists 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
{ _rmPolys :: [[Point2]]
, _rmLinks :: [RoomLink]
, -- the Int is the number of previous outlinks that have been assigned
_rmLinkEff ::
RoomLink -> -- child link
Room -> -- child room
Int -> -- child number
RoomLink -> -- parent link
Room -> -- parent room
Room
, _rmPos :: [RoomPos]
, _rmPath :: S.Set (Point2, Point2)
, _rmPmnts :: [Placement]
, _rmInPmnt :: [(Int,GenWorld -> Placement)]
, _rmBound :: [[Point2]]
, _rmFloor :: Floor
, _rmName :: String
, _rmShift :: (Point2, Float)
, _rmViewpoints :: [Point2]
, _rmRandPSs :: [State StdGen (Point2, Float)]
, _rmStartWires :: IM.IntMap RoomWire
, _rmEndWires :: IM.IntMap RoomWire
, _rmConnectsTo :: S.Set RoomLinkType -> Bool
, _rmMID :: Maybe Int
, _rmMParent :: Maybe Int
, _rmChildren :: [Int]
, _rmType :: RoomType
, _rmClusterStatus :: ClusterStatus
}
makeLenses ''GenWorld
makeLenses ''Room
makeLenses ''RoomType
makeLenses ''PSType
makeLenses ''PlacementSpot
makeLenses ''Placement