{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE StrictData #-} module Dodge.Data ( module Dodge.Data , module Dodge.Data.Menu , module Dodge.Data.DamageType , module Dodge.Data.SoundOrigin , module Dodge.Creature.Data , module Dodge.Creature.State.Data , Point2 (..) , Sound (..) , soundTime ) where import Dodge.Creature.Data import Dodge.Creature.State.Data import Dodge.Data.Menu import Dodge.Data.SoundOrigin import Dodge.Data.DamageType import Dodge.Config.Data import Dodge.Config.KeyConfig import Preload.Data import Picture.Data import Geometry.Data import Sound.Data import Control.Lens import Control.Monad.State import System.Random import Data.Graph.Inductive import Data.Int (Int16) import qualified Data.Set as S import qualified Data.IntMap.Strict as IM import qualified Data.Map as M import qualified Data.DList as DL import SDL (Scancode, MouseButton) import qualified SDL.Mixer as Mix import Graphics.Rendering.OpenGL (PrimitiveMode (..),GLfloat,Program,VertexArrayObject,BufferObject) import Codec.Picture (Image,PixelRGBA8) data World = World { _keys :: !(S.Set Scancode) , _mouseButtons :: !(S.Set MouseButton) , _cameraCenter :: !Point2 , _cameraRot :: !Float , _cameraZoom :: !Float , _cameraViewFrom :: !Point2 , _creatures :: IM.IntMap Creature , _creaturesZone :: IM.IntMap (IM.IntMap (IM.IntMap Creature)) , _itemPositions :: IM.IntMap ItemPos , _clouds :: IM.IntMap Cloud , _cloudsZone :: IM.IntMap (IM.IntMap (IM.IntMap Cloud)) , _projectiles :: IM.IntMap Projectile , _particles' :: ![Particle'] , _walls :: !(IM.IntMap Wall) , _wallsZone :: (IM.IntMap (IM.IntMap (IM.IntMap Wall))) , _forceFields :: IM.IntMap ForceField , _floorItems :: IM.IntMap FloorItem , _randGen :: StdGen , _mousePos :: !(Float,Float) , _testString :: String , _yourID :: !Int , _worldEvents :: !(World -> World) , _pressPlates :: IM.IntMap PressPlate , _buttons :: IM.IntMap Button , _soundQueue :: [(Int,Int16)] , _sounds :: M.Map SoundOrigin Sound , _decorations :: IM.IntMap Picture , _corpses :: IM.IntMap (IM.IntMap [Corpse]) , _clickMousePos :: (Float,Float) , _pathGraph :: ~(Gr Point2 Float) , _pathGraph' :: ~[(Point2,Point2)] , _pathPoints :: ~(IM.IntMap (IM.IntMap [(Int,Point2)])) , _pathInc :: ~(M.Map Point2 [Point2]) , _storedLevel :: Maybe World , _menuLayers :: [MenuLayer] , _worldState :: M.Map WorldState Bool , _worldTriggers :: S.Set WorldTrigger , _windowX :: !Float , _windowY :: !Float , _carteDisplay :: !Bool , _carteCenter :: !Point2 , _carteZoom :: !Float , _carteRot :: !Float , _lightSources :: !(IM.IntMap LightSource) , _tempLightSources :: ![TempLightSource] , _closeActiveObjects :: [Either FloorItem Button] , _seenLocations :: IM.IntMap (World -> Point2,String) , _selLocation :: Int , _keyConfig :: KeyConfigSDL , _varMovementSpeedModifier :: Float , _varMovementStrafeSpeedModifier :: Float , _debugMode :: Bool , _config :: Configuration , _sideEffects :: [PreloadData SoundOrigin -> IO (PreloadData SoundOrigin)] , _doneSideEffects :: [PreloadData SoundOrigin -> IO (PreloadData SoundOrigin)] } data Corpse = Corpse { _cpPos :: Point2 , _cpPict :: Picture , _cpRes :: Creature } data Layer = PtLayer | CrLayer | WlLayer | BgLayer | ShadowLayer | FlItLayer | LabelLayer | InvLayer | MenuDepth | PressPlateLayer | CorpseLayer | UPtLayer | HPtLayer | GloomLayer data Cloud = Cloud { _clID :: Int , _clPos :: Point2 , _clVel :: Point2 , _clPict :: Cloud -> Picture , _clRad :: Float , _clTimer :: Int , _clEffect :: Cloud -> World -> World } data LightSource = LS { _lsID :: !Int , _lsPos :: !Point2 , _lsDir :: !Float , _lsRad :: !Float , _lsIntensity :: !Float } data TempLightSource = TLS { _tlsPos :: !Point2 , _tlsRad :: !Float , _tlsIntensity :: !Float , _tlsUpdate :: World -> TempLightSource -> (World, Maybe TempLightSource) } data Creature = Creature { _crPos :: Point2 , _crOldPos :: Point2 , _crVel :: Point2 , _crDir :: Float , _crID :: Int , _crPict :: Creature -> Picture , _crUpdate :: World -> (World -> World,StdGen) -> Creature -> ((World -> World,StdGen), Maybe Creature) , _crRad :: Float , _crMass :: Float , _crHP :: Int , _crMaxHP :: Int , _crInv :: IM.IntMap Item , _crInvSel :: Int , _crState :: CreatureState , _crCorpse :: Picture , _crApplyDamage :: [DamageType] -> Creature -> (World -> World,Creature) } data WorldState = DoorNumOpen Int | CrNumAlive Int deriving (Eq,Ord) data WorldTrigger = ResetLevel Int deriving (Eq,Ord) data Button = Button { _btPict :: Picture , _btPos :: Point2 , _btRot :: Float , _btEvent :: Button -> World -> World , _btID :: Int , _btText :: String , _btState :: ButtonState } data ButtonState = BtOn | BtOff | BtNoLabel deriving (Eq, Show) data PressPlate = PressPlate { _ppPict :: Picture , _ppPos :: Point2 , _ppRot :: Float , _ppEvent :: PressPlate -> World -> World , _ppID :: Int , _ppText :: String } data FloorItem = FlIt { _flIt :: Item , _flItPos :: Point2 , _flItRot :: Float, _flItID :: Int} data ItemPos = InInv { _itCrId :: Int , _itInvId :: Int } | OnFloor { _itFlID :: Int } data Item = Weapon { _itName :: String , _wpMaxAmmo :: Int , _wpLoadedAmmo :: Int , _wpReloadTime :: Int , _wpReloadState :: Int , _wpFireRate :: Int , _wpFireState :: Int , _wpFire :: Int -> World -> World , _wpSpread :: Float , _wpRange :: Float , _itHammer :: HammerPosition , _itFloorPict :: Picture , _itMaxStack :: Int , _itAmount :: Int , _itAimingSpeed :: Float , _itAimingRange :: Float , _itZoom :: ItZoom , _itEquipPict :: Creature -> Int -> Picture , _itScrollUp :: Int -> World -> World , _itScrollDown :: Int -> World -> World , _itIdentity :: ItemIdentity , _itAttachment :: Maybe ItAttachment , _itID :: Maybe Int , _itEffect :: ItEffect , _itInvDisplay :: Item -> String , _itInvColor :: Color } | Consumable { _itName :: String , _itMaxStack :: Int , _itAmount :: Int , _cnEffect :: Int -> World -> Maybe World , _itFloorPict :: Picture , _itEquipPict :: Creature -> Int -> Picture , _itIdentity :: ItemIdentity , _itID :: Maybe Int , _itInvDisplay :: Item -> String , _itInvColor :: Color , _itEffect :: ItEffect , _itHammer :: HammerPosition } | Craftable { _itName :: String , _itMaxStack :: Int , _itAmount :: Int , _itFloorPict :: Picture , _itEquipPict :: Creature -> Int -> Picture , _itIdentity :: ItemIdentity , _itID :: Maybe Int , _itInvDisplay :: Item -> String , _itInvColor :: Color } | Equipment { _itName :: String , _itMaxStack :: Int , _itAmount :: Int , _itFloorPict :: Picture , _itEquipPict :: Creature -> Int -> Picture , _itIdentity :: ItemIdentity , _itEffect :: ItEffect , _itID :: Maybe Int , _itAimingSpeed :: Float , _itAimingRange :: Float , _itZoom :: ItZoom , _itInvDisplay :: Item -> String , _itInvColor :: Color , _itHammer :: HammerPosition } | Throwable { _itName :: String , _itMaxStack :: Int , _itAmount :: Int , _itFloorPict :: Picture , _twMaxRange :: Float , _twAccuracy :: Float , _twFire :: Int -> World -> World , _itAimingSpeed :: Float , _itAimingRange :: Float , _itZoom :: ItZoom , _itEquipPict :: Creature -> Int -> Picture , _itIdentity :: ItemIdentity , _itID :: Maybe Int , _itAttachment :: Maybe ItAttachment , _itInvDisplay :: Item -> String , _itInvColor :: Color , _itEffect :: ItEffect , _itHammer :: HammerPosition , _itScrollUp :: Int -> World -> World , _itScrollDown :: Int -> World -> World } | NoItem data ItAttachment = ItScope {_scopePos :: Point2 ,_scopeZoomChange :: Int ,_scopeZoom :: Float ,_scopeIsCamera :: Bool } | ItFuse {_itFuseTime :: Int} | ItPhaseV {_itPhaseV :: Float} | ItMode {_itMode :: Int} | ItTargetPos { _itTargetPos :: Point2 } data ItEffect = NoItEffect | ItInvEffect {_itInvEffect :: Creature -> Int -> World -> World ,_itEffectCounter :: Int } | ItEffect {_itInvEffect :: Creature -> Int -> World -> World ,_itFloorEffect :: Int -> World -> World ,_itEffectCounter :: Int } data ItZoom = ItZoom {_itAimZoomMax :: Float ,_itAimZoomMin :: Float ,_itAimZoomFac :: Float ,_itZoomMax :: Float ,_itZoomMin :: Float ,_itZoomFac :: Float } data IntID a = IntID Int a data HammerPosition = HammerDown | HammerReleased | HammerUp | NoHammer data ItemIdentity = Pistol | SpreadGun | MultGun | HvAutoGun | AutoGun | LtAutoGun | MiniGun | Medkit25 | MagShield | FrontArmour | JetPack | FlameShield | Generic | SparkGun | ShatterGun | LongGun | Flamethrower | Blinker | Grenade | RemoteBomb | TeslaGun | LasGun | ForceFieldGun | GrapGun | TractorGun | Launcher | RemoteLauncher | LightningGun | PoisonSprayer deriving (Eq,Show,Ord,Enum) data Particle' = Particle' { _ptDraw :: Particle' -> Picture , _ptUpdate' :: World -> Particle' -> (World, Maybe Particle') } | Bul' { _ptDraw :: Particle' -> Picture , _ptUpdate' :: World -> Particle' -> (World, Maybe Particle') , _btVel' :: Point2 , _btColor' :: Color , _btTrail' :: [Point2] , _btPassThrough' :: Maybe Int , _btWidth' :: Float , _btTimer' :: Int , _btHitEffect' :: HitEffect } | Pt' { _ptDraw :: Particle' -> Picture , _ptUpdate' :: World -> Particle' -> (World, Maybe Particle') , _btVel' :: Point2 , _btColor' :: Color , _btPos' :: Point2 , _btPassThrough' :: Maybe Int , _btWidth' :: Float , _btTimer' :: Int , _btHitEffect' :: HitEffect } | Shockwave' { _ptDraw :: Particle' -> Picture , _ptUpdate' :: World -> Particle' -> (World, Maybe Particle') , _btColor' :: Color , _btPos' :: Point2 , _btRad' :: Float , _btDam' :: Int , _btPush' :: Float , _btMaxTime' :: Int , _btTimer' :: Int } type HitEffect = Particle' -> [(Point2, (Either3 Creature Wall ForceField))] -> World -> (World,Maybe Particle') data Projectile = Projectile { _pjPos :: Point2 , _pjStartPos :: Point2 , _pjVel :: Point2 , _pjPict :: Picture , _pjID :: Int , _pjUpdate :: World -> World } | Shell { _pjPos :: Point2 , _pjStartPos :: Point2 , _pjVel :: Point2 , _pjPict :: Picture , _pjID :: Int , _pjUpdate :: World -> World , _pjPayload :: Point2-> World -> World } data Either3 a b c = E3x1 a | E3x2 b | E3x3 c data Wall = Wall { _wlLine :: [Point2] , _wlID :: Int , _wlColor :: Color , _wlDraw :: Maybe (Wall -> Picture) , _wlSeen :: Bool , _wlIsSeeThrough :: Bool } | BlockAutoDoor { _wlLine :: [Point2] , _wlID :: Int , _doorMech :: World -> World , _wlColor :: Color , _wlDraw :: Maybe (Wall -> Picture) , _wlSeen :: Bool , _blIDs :: [Int] , _blHP :: Int , _wlIsSeeThrough :: Bool } | Door { _wlLine :: [Point2] , _wlID :: Int , _doorMech :: World -> World , _wlColor :: Color , _wlDraw :: Maybe (Wall -> Picture) , _wlSeen :: Bool , _wlIsSeeThrough :: Bool , _doorPathable :: Bool } | Block { _wlLine :: [Point2] , _wlID :: Int , _wlColor :: Color , _wlDraw :: Maybe (Wall -> Picture) , _wlSeen :: Bool , _blIDs :: [Int] , _blHP :: Int , _wlIsSeeThrough :: Bool , _blVisible :: Bool , _blDegrades :: [Int] , _blShadows :: [Int] } data ForceField = FF { _ffLine :: [Point2] , _ffID :: Int , _ffColor :: Color , _ffDeflect :: Maybe (StdGen -> Point2 -> ForceField -> (Point2,StdGen)) , _ffState :: FFState } data FFState = FFDestroyable { _ffsHP :: Int } makeLenses ''World makeLenses ''Cloud makeLenses ''Creature makeLenses ''LightSource makeLenses ''TempLightSource makeLenses ''Stance makeLenses ''Item makeLenses ''ItemPos makeLenses ''ItEffect makeLenses ''ItAttachment makeLenses ''ItZoom makeLenses ''FloorItem makeLenses ''Projectile makeLenses ''Particle' makeLenses ''Wall makeLenses ''ForceField makeLenses ''FFState makeLenses ''PressPlate makeLenses ''Button numColor :: Int -> Color numColor 0 = (1,0,0,1) numColor 1 = (0,1,0,1) numColor 2 = (0,0,1,1) numColor 3 = (1,1,0,1) numColor 4 = (0,1,1,1) numColor 5 = (1,0,1,1) numColor 6 = (1,0,0.5,1) numColor 7 = (0.5,0,1,1) numColor 8 = (0,0.5,1,1) numColor 9 = (0,1,0.5,1) numColor 10 = (0.5,1,0,1) numColor 11 = (1,0.5,0,1) numColor 12 = (1,1,1,1)