{-# 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