Files
loop/src/Dodge/Data.hs
T
2022-06-02 22:50:42 +01:00

1591 lines
47 KiB
Haskell

{- |
Contains base datatypes that cannot be seperated into
different modules because they are interdependent;
circular imports are probably not a good idea.
-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DeriveGeneric #-}
module Dodge.Data
( module Dodge.Data
, module Dodge.Combine.Data
, module Dodge.Distortion.Data
, module Dodge.Data.DamageType
, module Dodge.Data.SoundOrigin
, module Dodge.Creature.State.Data
, module Dodge.Creature.Stance.Data
, module Dodge.Creature.Perception.Data
, module Dodge.Creature.Memory.Data
, module Dodge.Item.Attachment.Data
, module Dodge.Item.Data
, module Dodge.Config.Data
, module Dodge.Equipment.Data
) where
import Dodge.ShortShow
import Dodge.Creature.State.Data
import Dodge.Creature.Stance.Data
import Dodge.Creature.Perception.Data
import Dodge.Creature.Memory.Data
import Dodge.Distortion.Data
import Dodge.Equipment.Data
import Dodge.Data.SoundOrigin
import Dodge.Data.DamageType
import Dodge.Combine.Data
import Dodge.Config.Data
import Dodge.Config.KeyConfig
import Dodge.Item.Attachment.Data
import Dodge.Item.Data
import Dodge.Bounds
import Data.Preload
import Picture.Data
import ShapePicture
import Geometry.Data
import Geometry.ConvexPoly
import Sound.Data
import Dodge.GameRoom
import Color
import Shape
import Data.Tile
--import qualified Data.Vector as V
import GHC.Generics
import Control.Lens
import Control.Monad.State
import System.Random
import Data.Graph.Inductive
import qualified Data.Set as S
import qualified Data.IntSet as IS
import qualified Data.IntMap.Strict as IM
import qualified Data.Map.Strict as M
import qualified Data.Text as T
import SDL (Scancode, MouseButton)
type CRUpdate = Creature -> World -> (World -> World, Maybe Creature)
type CRUpdate' = Creature -> World -> (World -> World, Creature)
data Universe = Universe
{ _uvWorld :: World
, _preloadData :: PreloadData
, _menuLayers :: [ScreenLayer]
, _savedWorlds :: M.Map SaveSlot World
, _keyConfig :: KeyConfigSDL
, _config :: Configuration
}
data World = World
{ _keys :: S.Set Scancode
, _mouseButtons :: S.Set MouseButton
, _mousePos :: Point2
, _cameraCenter :: Point2
, _cameraRot :: Float
, _cameraZoom :: Float
, _cameraViewFrom :: Point2
, _viewDistance :: Float
, _creatures :: IM.IntMap Creature
, _creaturesZone :: Zone (IM.IntMap Creature)
, _creatureGroups :: IM.IntMap CrGroupParams
, _itemPositions :: IM.IntMap ItemPos
, _clouds :: [Cloud]
, _cloudsZone :: Zone [Cloud]
, _gusts :: IM.IntMap Gust
, _gustsZone :: Zone (IM.IntMap Gust)
, _props :: IM.IntMap Prop
, _instantParticles :: [Particle]
, _particles :: [Particle]
, _newBeams :: WorldBeams
, _beams :: WorldBeams
, _walls :: IM.IntMap Wall
, _doors :: IM.IntMap Door
, _machines :: IM.IntMap Machine
, _terminals :: IM.IntMap Terminal
, _magnets :: IM.IntMap Magnet
, _blocks :: IM.IntMap Block
, _coordinates :: IM.IntMap Point2
, _triggers :: IM.IntMap (World -> Bool)
, _wallsZone :: Zone (IM.IntMap Wall)
, _floorItems :: IM.IntMap FloorItem
, _floorTiles :: [(Point3,Point3)]
, _randGen :: StdGen
, _testString :: World -> [String]
, _debugPicture :: Picture
, _modifications :: IM.IntMap Modification
, _yourID :: Int
, _worldEvents :: World -> World
, _delayedEvents :: [(Int,World -> World)]
, _pressPlates :: IM.IntMap PressPlate
, _buttons :: IM.IntMap Button
, _toPlaySounds :: M.Map SoundOrigin Sound
, _playingSounds :: M.Map SoundOrigin Sound
, _decorations :: IM.IntMap Picture
, _foregroundShape :: Shape
, _corpses :: Zone [Corpse]
, _clickMousePos :: Point2
, _pathGraph :: ~(Gr Point2 Float)
, _pathGraphP :: ~[(Point2,Point2)]
, _pathPoints :: ~(IM.IntMap (IM.IntMap [(Int,Point2)]))
, _hud :: HUD
, _lightSources :: IM.IntMap LightSource
, _tempLightSources :: [TempLightSource]
, _closeObjects :: [Either FloorItem Button]
, _rbOptions :: RightButtonOptions
, _seenLocations :: IM.IntMap (World -> Point2,String)
, _selLocation :: Int
, _sideEffects :: Universe -> IO Universe
, _distortions :: [Distortion]
, _worldBounds :: Bounds
, _gameRooms :: [GameRoom] -- consider using an IntMap
, _roomClipping :: [ConvexPoly]
, _maybeWorld :: Maybe' World
, _rewindWorlds :: [World]
, _timeFlow :: TimeFlowStatus
, _worldClock :: Int
, _doubleMouseHammer :: HammerPosition
, _backspaceTimer :: Int
, _genParams :: GenParams
, _genPlacements :: IM.IntMap [(Placement,Int)]
, _genRooms :: IM.IntMap Room
}
newtype GenParams = GenParams
{ _sensorCoding :: M.Map DamageType (PaletteColor,DecorationShape)
}
data DecorationShape = PlusDecoration | SquareDecoration | CircleDecoration | ThreeLineDecoration
deriving (Eq,Ord,Enum,Show)
data HUDElement
= DisplayInventory {_subInventory :: SubInventory}
| DisplayCarte
-- deriving (Eq,Ord,Show)
data RightButtonOptions
= NoRightButtonOptions
| EquipOptions
{_opEquip :: [EquipPosition]
,_opSel :: Int
,_opCurInvPos :: Int
,_opAllocateEquipment :: AllocateEquipment
,_opActivateEquipment :: ActivateEquipment
}
data ActivateEquipment
= ActivateEquipment {_activateEquipment :: Int }
| DeactivateEquipment {_deactivateEquipment :: Int}
| ActivateDeactivateEquipment {_activateEquipment :: Int ,_deactivateEquipment :: Int}
| NoChangeActivateEquipment
data AllocateEquipment
= DoNotMoveEquipment
| PutOnEquipment
{ _allocNewPos :: EquipPosition
}
| MoveEquipment
{ _allocNewPos :: EquipPosition
, _allocOldPos :: EquipPosition
}
| SwapEquipment
{ _allocNewPos :: EquipPosition
, _allocOldPos :: EquipPosition
, _allocSwapID :: Int
}
| ReplaceEquipment
{ _allocNewPos :: EquipPosition
, _allocRemoveID :: Int
}
| RemoveEquipment
{ _allocOldPos :: EquipPosition
}
data SubInventory
= NoSubInventory
| TweakInventory
| CombineInventory {_combineInvSel :: Maybe Int}
| InspectInventory
| LockedInventory
| DisplayTerminal
{_termParams :: TerminalParams
,_termID :: Int
}
-- deriving (Eq,Ord,Show)
data HUD = HUD
{ _hudElement :: HUDElement
, _carteCenter :: Point2
, _carteZoom :: Float
, _carteRot :: Float
}
data TimeFlowStatus
= RewindingNow
| RewindingLastFrame
| NormalTimeFlow
deriving (Eq,Ord)
data SaveSlot = QuicksaveSlot | LevelStartSlot
deriving (Eq,Ord)
data Magnet = Magnet
{ _mgID :: Int
, _mgUpdate :: Magnet -> Maybe Magnet
, _mgPos :: Point2
, _mgField :: Magnet -> Particle -> Particle
}
data OptionScreenFlag = NormalOptions | GameOverOptions
data ScreenLayer
= OptionScreen
{ _scTitle :: Universe -> String
, _scOptions :: [MenuOption]
, _scDefaultEff :: Universe -> IO (Maybe Universe)
, _scOptionFlag :: OptionScreenFlag
}
| ColumnsScreen
{ _scTitle :: Universe -> String
, _scColumns :: [(String,String)]
}
| InputScreen
{ _scInput :: T.Text
, _scFooter :: String
}
| WaitScreen
{ _scWaitMessage :: Universe -> String
, _scWaitTime :: Int
}
| DisplayScreen
{ _scDisplay :: Universe -> Picture
}
data MenuOption
= Toggle
{ _moEff :: Universe -> IO (Maybe Universe)
, _moString :: Universe -> Either String (String,String)
, _moKey :: Scancode
}
| Toggle2
{ _moKey1 :: Scancode
, _moEff1 :: Universe -> IO (Maybe Universe)
, _moKey2 :: Scancode
, _moEff2 :: Universe -> IO (Maybe Universe)
, _moString :: Universe -> Either String (String,String)
}
| InvisibleToggle
{ _moKey :: Scancode
, _moEff :: Universe -> IO (Maybe Universe)
}
data CrGroupParams = CrGroupParams
{ _crGroupParamID :: Int
, _crGroupIDs :: IS.IntSet
, _crGroupCenter :: Point2
, _crGroupUpdate :: World -> CrGroupParams -> Maybe CrGroupParams
}
data Corpse = Corpse
{ _cpPos :: Point2
, _cpPict :: Picture
, _cpRes :: Creature
}
data Gust = Gust
{ _guID :: Int
, _guPos :: Point2
, _guVel :: Point2
, _guTime :: Int
}
data Cloud = Cloud
{ _clPos :: Point3
, _clVel :: Point3
, _clPict :: Cloud -> Picture
, _clRad :: Float
, _clAlt :: Float
, _clTimer :: Int
, _clType :: CloudType
, _clEffect :: Cloud -> World -> World
}
data CloudType
= SmokeCloud
| GasCloud
data LSParam = LSParam
{ _lsPos :: !Point3
, _lsRad :: !Float
, _lsCol :: !Point3
}
data LightSource = LS
{ _lsID :: !Int
, _lsParam :: LSParam
, _lsDir :: !Float
, _lsPict :: LightSource -> Picture
}
data TempLightSource = TLS
{ _tlsParam :: LSParam
, _tlsUpdate :: World -> TempLightSource -> Maybe TempLightSource
, _tlsTime :: !Int
}
data Creature = Creature
{ _crPos :: Point2
, _crOldPos :: Point2
, _crVel :: Point2
, _crDir :: Float
, _crOldDir :: Float
, _crMvDir :: Float
, _crTwist :: Float
, _crID :: Int
, _crPict :: Creature -> Configuration -> World -> SPic
, _crUpdate :: Creature -> World -> World
, _crRad :: Float
, _crMass :: Float
, _crHP :: Int
, _crMaxHP :: Int
, _crInv :: IM.IntMap Item
, _crInvSel :: Int
, _crInvCapacity :: Int
, _crInvLock :: Bool
, _crInvEquipped :: IM.IntMap EquipPosition
, _crEquipment :: M.Map EquipPosition Int
, _crLeftInvSel :: Maybe Int
, _crState :: CreatureState
, _crCorpse :: Picture
, _crApplyDamage :: [Damage] -> Creature -> World -> World
, _crPastDamage :: Int
, _crStance :: Stance
, _crActionPlan :: ActionPlan
, _crMeleeCooldown :: Int
, _crPerception :: PerceptionState
, _crMemory :: MemoryState
, _crVocalization :: Vocalization
, _crFaction :: Faction
, _crGroup :: CrGroup
, _crIntention :: Intention
, _crMvType :: CrMvType
, _crHammerPosition :: HammerPosition
, _crName :: String
, _crStatistics :: CreatureStatistics
, _crCamouflage :: CamouflageStatus
}
data CamouflageStatus
= FullyVisible
| Invisible
deriving (Eq,Ord,Enum)
data CreatureStatistics = CreatureStatistics
{ _crStrength :: Int
, _crDexterity :: Int
, _crIntelligence :: Int
}
data Vocalization
= Mute
| Vocalization
{_vcSound :: SoundID
,_vcWarnings :: [SoundID]
,_vcMaxCoolDown :: Int
,_vcCoolDown :: Int
}
data Intention = Intention
{ _targetCr :: Maybe Creature
, _mvToPoint :: Maybe Point2
, _viewPoint :: Maybe Point2
}
data CrMvType
= NoMvType
| MvWalking { _mvSpeed :: Float }
| CrMvType
{ _mvSpeed :: Float
, _mvTurnRad :: Float -> Float
, _mvTurnJit :: Float
, _mvAimSpeed :: Float -> Float
}
data Button = Button
{ _btPict :: Button -> SPic
, _btPos :: Point2
, _btRot :: Float
, _btEvent :: Button -> World -> World
, _btID :: Int
, _btText :: String
, _btState :: ButtonState
, _btTerminalParams :: World -> TerminalParams
, _btName :: String
}
data TerminalParams = NoTerminalParams | TerminalParams
{ _termDisplayedLines :: [World -> (String,Color)]
, _termFutureLines :: [TerminalLine]
, _termMaxLines :: Int
, _termTitle :: String
, _termSel :: Maybe (Int,Int)
-- , _termOptions :: [(String, World -> World)]
, _termInput :: Maybe T.Text
, _termScrollCommands :: [TerminalCommand]
, _termWriteCommands :: [TerminalCommand]
}
data TerminalLine
= TerminalLineDisplay
{_tlPause :: Int
,_tlString :: World -> (String, Color)
}
-- | TerminalLineChoice
-- {_tlPause :: Int
-- ,_tlOptions :: [(String,World -> World)]
-- }
| TerminalLineInput
{_tlPause :: Int
,_tlScrollCommands :: [TerminalCommand]
,_tlWriteCommands :: [TerminalCommand]
}
| TerminalLineEffect
{_tlPause :: Int
,_tlEffect :: SubInventory -> World -> World
}
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 ItemUse
= RightUse
{ _rUse :: Item -> Creature -> World -> World
, _useDelay :: UseDelay
, _useMods :: [(Item -> Creature -> World -> World) -> Item -> Creature -> World -> World]
, _useHammer :: HammerType
, _useAim :: AimParams
, _heldScroll :: Float -> Creature -> Item -> Item
}
| LeftUse
{ _lUse :: Item -> Creature -> World -> World
, _useDelay :: UseDelay
, _useHammer :: HammerType
, _eqSite :: EquipSite
, _eqUse :: Item -> Creature -> World -> World
, _eqOnEquip :: Item -> Creature -> World -> World
, _eqOnRemove :: Item -> Creature -> World -> World
, _eqParams :: EquipParams
}
| ConsumeUse
{ _cUse :: Item -> Creature -> World -> World
}
| EquipUse
{ _eqUse :: Item -> Creature -> World -> World
, _eqOnEquip :: Item -> Creature -> World -> World
, _eqOnRemove :: Item -> Creature -> World -> World
, _eqSite :: EquipSite
, _eqParams :: EquipParams
}
| NoUse
_itUseAimStance :: Item -> AimStance
_itUseAimStance = _aimStance . _useAim . _itUse
data ItemConsumption
= LoadableAmmo
{ _aoType :: AmmoType
, _ammoBaseMax :: Int
, _ammoLoaded :: Int
, _reloadTime :: Int
, _reloadState :: Maybe' Int
, _reloadType :: ReloadType
}
| ChargeableAmmo
{ _wpMaxCharge :: Int
, _wpCharge :: Int
}
| ItemItselfConsumable
{ _itAmount :: Int
}
| NoConsumption
data Item = Item
{ _itName :: String
, _itConsumption :: ItemConsumption
, _itUse :: ItemUse
, _itEquipPict :: Creature -> Item -> SPic
, _itType :: CombineType
, _itAttachment :: ItAttachment
, _itID :: Maybe Int
, _itInvPos :: Maybe Int
, _itIsHeld :: Bool
, _itEffect :: ItEffect
, _itInvSize :: Float
, _itInvDisplay :: Item -> [String]
, _itInvColor :: Color
, _itTargeting :: Targeting
, _itDimension :: ItemDimension
, _itCurseStatus :: CurseStatus
, _itTweaks :: ItemTweaks
, _itModules :: M.Map ModuleSlot ItemModule
, _itScope :: Scope
, _itValue :: ItemValue
, _itParams :: ItemParams
}
data ItemValue = ItemValue
{ _ivInt :: Int
, _ivType :: ItemValueType
}
data ItemValueType = MundaneItem | ArtefactItem
data Targeting
= NoTargeting
| Targeting
{ _tgPos :: Maybe Point2
, _tgUpdate :: Item -> Creature -> World -> Targeting -> (World, Targeting)
, _tgDraw :: Int -> Item -> Creature -> Configuration -> World -> Picture
, _tgID :: Maybe Int
, _tgActive :: Bool
}
data ModuleSlot
= ModBullet
| ModRifleMag
| ModAutoMag
| ModTarget
| ModBulletTrajectory
| ModLauncherHoming
| ModBattery
| ModTeleport
| ModDualBeam
deriving (Eq,Ord)
data ItemModule
= DefaultModule
| ItemModule
{ _modName :: [String]
, _modSize :: Int
, _modModification :: Item -> Item
}
data ItemDimension = ItemDimension
{ _dimRad :: Float
, _dimCenter :: Point3
, _dimPortage :: ItemPortage
, _dimSPic :: Item -> SPic
}
data ItemPortage
= HeldItem
{ _handlePos :: Float
, _muzPos :: Float
}
| WornItem
data ReloadType
= ActiveClear
| ActivePartial Int
| PassiveReload SoundID
deriving Eq
-- I believe this is called every frame, not sure when though
data ItEffect
= NoItEffect
-- | ItSimpleInvEffect
-- {_itInvEffect :: Item -> Creature -> World -> World
-- }
| ItInvEffect
{_itInvEffect :: Item -> Creature -> World -> World
,_itEffectCounter :: Int
}
| ItRewindEffect
{_itInvEffect :: Item -> Creature -> World -> World
,_itStoredWorlds :: [World]
}
| ItEffect
{_itInvEffect :: Item -> Creature -> World -> World
,_itFloorEffect :: Int -> World -> World
,_itEffectCounter :: Int
}
| ItInvEffectID
{_itInvEffect :: Item -> Creature -> World -> World
,_itEffectID :: Maybe Int
}
| ItInvEffectDrop
{ _itInvEffect :: Item -> Creature -> World -> World
, _itEffectDrop :: Item -> Creature -> World -> World
, _itEffectMID :: Maybe Int
}
data IntID a = IntID Int a
data WorldBeams = WorldBeams
{_blockingBeams :: [Beam]
,_lightBeams :: [Beam]
,_positronBeams :: [Beam]
,_electronBeams :: [Beam]
}
{- | Linear beams. Last only one frame.
- Can interact with one another in a limited manner
-}
data Beam = Beam
{ _bmDraw :: Beam -> Picture
, _bmPos :: Point2
, _bmDir :: Float
, _bmDamage :: Int
, _bmColor :: Color
, _bmPoints :: [Point2]
, _bmFirstPoints :: [Point2]
, _bmRange :: Float
, _bmPhaseV :: Float
, _bmOrigin :: Maybe Int
, _bmType :: BeamType
}
data BeamType
= BeamCombine
{_beamCombine :: (Point2 , (Point2,Point2,Beam) , (Point2,Point2,Beam)) -> World -> World}
| BeamSimple
{- Objects without ids.
Update themselves, perhaps with side effects. -}
data Particle
= Particle
{ _ptDraw :: Particle -> Picture
, _ptUpdate :: World -> Particle -> (World, Maybe Particle)
}
| RadarCircleParticle
{ _ptDraw :: Particle -> Picture
, _ptUpdate :: World -> Particle -> (World, Maybe Particle)
, _ptTimer :: Int
, _ptRad :: Float
, _ptPos :: Point2
}
| LaserParticle
{ _ptDraw :: Particle -> Picture
, _ptUpdate :: World -> Particle -> (World, Maybe Particle)
, _ptRange :: Float
, _ptDamage :: Int
, _ptColor :: Color
, _ptPhaseV :: Float
}
| LinearParticle
{ _ptDraw :: Particle -> Picture
, _ptUpdate :: World -> Particle -> (World, Maybe Particle)
, _ptPoints :: [Point2]
, _ptTimer :: Int
, _ptColor :: Color
}
| BulletPt
{ _ptDraw :: Particle -> Picture
, _ptUpdate :: World -> Particle -> (World, Maybe Particle)
, _ptVel :: Point2
, _btDrag :: Float
, _ptColor :: Color
, _ptTrail :: [Point2]
, _ptCrIgnore :: Maybe Int
, _ptWidth :: Float
, _ptTimer :: Int
, _ptHitEff :: HitEffect
}
| PtZ
{ _ptDraw :: Particle -> Picture
, _ptUpdate :: World -> Particle -> (World, Maybe Particle)
, _ptVel :: Point2
, _ptColor :: Color
, _ptPos :: Point2
, _ptCrIgnore :: Maybe Int
, _ptWidth :: Float
, _ptTimer :: Int
, _ptHitEff :: HitEffect
, _ptZ :: Float
}
| Shockwave
{ _ptDraw :: Particle -> Picture
, _ptUpdate :: World -> Particle -> (World, Maybe Particle)
, _ptColor :: Color
, _ptPos :: Point2
, _ptRad :: Float
, _ptDam :: Int
, _ptPush :: Float
, _ptMaxTime :: Int
, _ptTimer :: Int
}
| ShockLine
{ _ptDraw :: Particle -> Picture
, _ptUpdate :: World -> Particle -> (World, Maybe Particle)
, _ptPointDirs :: [[(Point2,Float)]]
, _ptTimer :: Int
, _ptColor :: Color
, _ptCenter :: Point2
}
type HitEffect = Particle
-> [(Point2, Either Creature Wall)]
-> World
-> (World,Maybe Particle)
data BulletTrajectory
= BasicBulletTrajectory
| BezierTrajectory
| FlechetteTrajectory
| MagnetTrajectory
data AmmoType
= ProjectileAmmo
{ _amPayload :: Point2 -> World -> World
, _amString :: String
, _amPjDraw :: Prop -> SPic
, _amPjCreation :: Item -> Creature -> World -> World
-- , _aProjectile :: Ammo -> Prop
}
| BulletAmmo
{ _amString :: String
, _amBulEff :: HitEffect
, _amBulWth :: Float
, _amBulVel :: Point2
, _amBulTraj :: BulletTrajectory
}
| DroneAmmo
{ _amString :: String }
| GasAmmo
{ _amString :: String
, _amCreateGas :: Float -> Point2 -> Float -> Creature -> World -> World
}
| GenericAmmo
data ItemTweaks
= NoTweaks
| Tweakable
{ _tweakParams :: IM.IntMap TweakParam
, _tweakSel :: Int
}
data TweakParam = TweakParam
{ _doTweak :: Int -> Item -> Item
, _curTweak :: Int
, _maxTweak :: Int
, _showTweak :: Int -> String
, _nameTweak :: String
}
data Nozzle = Nozzle
{ _nzPressure :: Float
, _nzDir :: Float
, _nzMaxWalkAngle :: Float
, _nzCurrentWalkAngle :: Float
, _nzWalkSpeed :: Float
, _nzLength :: Float
}
data GunBarrels
= MultiBarrel
{ _brlSpread :: BarrelSpread
, _brlNum :: Int
, _brlInaccuracy :: Float
}
| RotBarrel
{ _brlNum :: Int
, _brlInaccuracy :: Float
}
| SingleBarrel {_brlInaccuracy :: Float}
data EquipParams
= NoEquipParams
| EquipID {_eparamID :: Int}
| EquipCounter {_eparamInt :: Int}
data ItemParams
= NoParams
| ShellLauncher
{ _shellSpinDrag :: Int
, _shellSpinAmount :: Int
, _shellThrustDelay :: Int
}
| Refracting
{ _phaseV :: Float
, _lasColor :: Color
, _lasColor2 :: Color
, _lasCycle :: Int
, _lasDamage :: Int
}
| DualBeam
{ _phaseV :: Float
, _lasColor :: Color
, _lasColor2 :: Color
, _lasCycle :: Int
, _lasDamage :: Int
, _lasBeam :: BeamType
, _subParams :: Maybe ItemParams
}
| Attracting {_attractionPower :: Point2}
| BulletShooter
{ _muzVel :: Float
, _rifling :: Float
, _bore :: Float
, _gunBarrels :: GunBarrels
, _recoil :: Float
, _torqueAfter :: Float
, _randomOffset :: Float
}
| Sprayer { _sprayNozzles :: [Nozzle] }
| AngleWalk
{ _maxWalkAngle :: Float
, _currentWalkAngle :: Float
, _walkSpeed :: Float
}
| Arcing
{ _currentArc :: Maybe [ArcStep]
, _arcSize :: Float
, _arcNumber :: Int
, _newArcStep :: ItemParams -> World
-> ArcStep
-> State StdGen (Maybe ArcStep)
, _previousArcEffect :: PreviousArcEffect
}
| ParamMID {_paramMID :: Maybe Int}
data ArcStep = ArcStep
{ _asPos :: Point2
, _asDir :: Float
, _asObject :: Maybe (Either Creature Wall)
}
data PreviousArcEffect = NoPreviousArcEffect | PerturbTillBreakPreviousArc
data Modification
= ModIDTimerPoint3Bool
{ _mdID :: Int
, _mdExternalID :: Int
, _mdUpdate :: Modification -> World -> World
, _mdTimer :: Int
, _mdPoint3 :: Point3
, _mdBool :: Bool
}
| ModIDID
{ _mdID :: Int
, _mdExternalID1 :: Int
, _mdExternalID2 :: Int
, _mdUpdate :: Modification -> World -> World
}
data Prop
= Projectile
{ _pjPos :: Point2
, _pjStartPos :: Point2
, _pjVel :: Point2
, _prDraw :: Prop -> SPic
, _pjID :: Int
, _pjUpdate :: Prop -> World -> World
}
| Drone
{ _pjPos :: Point2
, _pjStartPos :: Point2
, _pjVel :: Point2
, _prDraw :: Prop -> SPic
, _pjID :: Int
, _pjUpdate :: Prop -> World -> World
}
| RecursiveProp
{ _pjPos :: Point2
, _pjID :: Int
, _pjDraw :: Prop -> SPic
, _pjUpdate :: Prop -> World -> World
, _pjProp :: Prop
}
| ProjectileTimed
{ _pjPos :: Point2
, _pjStartPos :: Point2
, _pjVel :: Point2
, _prDraw :: Prop -> SPic
, _pjID :: Int
, _pjUpdate :: Prop -> World -> World
, _pjTime :: Int
}
| ShapeProp
{ _pjPos :: Point2
, _pjID :: Int
, _pjRot :: Float
, _pjUpdate :: Prop -> World -> World
, _prDraw :: Prop -> SPic
, _prToggle :: Bool
}
| RemoteShell
{ _pjPos :: Point2
, _pjStartPos :: Point2
, _pjVel :: Point2
, _prDraw :: Prop -> SPic
, _pjID :: Int
, _pjUpdate :: Prop -> World -> World
, _pjPayload :: Point2 -> World -> World
}
| Shell
{ _pjPos :: Point2
, _pjStartPos :: Point2
, _pjVel :: Point2
, _pjAcc :: Point2
, _pjDir :: Float
, _pjSpin :: Float
, _prDraw :: Prop -> SPic
, _pjID :: Int
, _pjUpdate :: Prop -> World -> World
, _pjPayload :: Point2 -> World -> World
, _pjTimer :: Int
, _pjZ :: Float
}
| Bomb
{ _pjPos :: Point2
, _pjVel :: Point2
, _pjZ :: Float
, _pjVelZ :: Float
, _prDraw :: Prop -> SPic
, _pjID :: Int
, _pjUpdate :: Prop -> World -> World
, _pjPayload :: Point2 -> World -> World
, _pjTimer :: Int
}
| LinearShockwave
{ _prDraw :: Prop -> SPic
, _pjPos :: Point2
, _pjID :: Int
, _pjUpdate :: Prop -> World -> World
, _pjPoints :: [(Point2,Point2)]
, _pjTimer :: Int
}
data Either3 a b c = E3x1 a | E3x2 b | E3x3 c
data Block = Block
{ _blID :: Int
, _blWallIDs :: IS.IntSet
, _blHPs :: [Int]
, _blShadows :: [Int]
, _blMaterial :: BlockMaterial
}
data BlockMaterial = WoodBlock | DirtBlock | StoneBlock | GlassBlock | MetalBlock
data Terminal = Terminal
{ _tmID :: Int
, _tmParams :: TerminalParams
, _tmButtonID :: Int
, _tmMachineID :: Int
, _tmName :: String
}
data Machine = Machine
{ _mcID :: Int
, _mcWallIDs :: IS.IntSet
, _mcUpdate :: Machine -> World -> World
, _mcDraw :: Machine -> SPic
, _mcPos :: Point2
, _mcDir :: Float
, _mcHP :: Int
, _mcSensor :: Sensor
, _mcDamage :: [Damage]
, _mcLSs :: [Int]
, _mcType :: MachineType
, _mcName :: String
}
data Sensor = NoSensor
| SensorToggleAmount
{ _sensToggle :: Bool
, _sensAmount :: Int
}
| SensorCloseToggle
{ _sensCloseToggle :: CloseToggle
, _sensToggle :: Bool
}
deriving (Eq,Ord)
data CloseToggle = NotClose | IsClose
deriving (Eq,Ord)
data MachineType
= StaticMachine
| Turret
{ _tuWeapon :: Item
, _tuTurnSpeed :: Float
, _tuFireTime :: Int
, _tuMCrID :: Maybe Int
}
data Door = Door
{ _drID :: Int
, _drWallIDs :: IS.IntSet
, _drStatus :: DoorStatus
, _drTrigger :: World -> Bool
, _drMech :: Door -> World -> World
, _drPos :: (Point2,Point2)
, _drOpenPos :: (Point2,Point2)
, _drClosePos :: (Point2,Point2)
}
data DoorStatus = DoorOpen | DoorClosed | DoorHalfway | DoorInt Int
deriving (Eq, Ord, Show)
data Wall = Wall
{ _wlLine :: (Point2,Point2)
, _wlID :: Int
, _wlColor :: Color
, _wlSeen :: Bool
, _wlOpacity :: Opacity
, _wlPathable :: Bool
, _wlWalkable :: Bool
, _wlTouchThrough :: Bool
, _wlFireThrough :: Bool
, _wlReflect :: Bool
, _wlDraw :: Bool
, _wlRotateTo :: Bool
, _wlStructure :: WallStructure
, _wlHeight :: Float
, _wlDamageEff :: Damage -> Wall -> World -> World
}
data Opacity
= SeeThrough
| SeeAbove
| Opaque
deriving (Eq,Ord,Show)
data WallStructure
= StandaloneWall
| DoorPart { _wlStDoor :: Int }
| MachinePart { _wlStMachine :: Int }
| BlockPart { _wlStBlock :: Int }
| CreaturePart
{ _wlStCreature :: Int
, _wlStDamCreature :: Damage -> Wall -> Int -> World -> World
}
-- | Strict maybe
data Maybe' a = Just' {__Just' :: a} | Nothing'
deriving (Eq,Ord,Show)
strictify :: Maybe a -> Maybe' a
strictify Nothing = Nothing'
strictify (Just x) = Just' x
data ActionPlan
= Inanimate
| ActionPlan
{_crImpulse :: [Impulse]
,_crAction :: [Action]
,_crStrategy :: Strategy
,_crGoal :: [Goal]
}
data Impulse
= Move Point2
| MoveForward Float
| Turn Float
| RandomTurn Float
| RandomImpulse (State StdGen Impulse)
| TurnToward Point2 Float
| MvTurnToward Point2
| MvForward
| TurnTo Point2
| UseItem
| SwitchToItem Int
| DropItem
| Bark SoundID -- placeholder for various communication types
| Melee Int
| ChangePosture Posture
| MakeSound SoundID
| ChangeStrategy Strategy
| AddGoal Goal
| ArbitraryImpulseFunction (World -> Creature -> Creature)
| ArbitraryImpulse (Creature -> World -> Impulse)
| ArbitraryImpulseEffect (Creature -> World -> World)
| ImpulseUseTargetCID
{_impulseUseTargetCID :: Int -> Impulse
}
| ImpulseUseTarget
{_impulseUseTarget :: Creature -> Impulse
}
| ImpulseUseAheadPos
{_impulseUseAheadPos :: Point2 -> Impulse
}
instance Show Impulse where
show imp = case imp of
Move p -> "Move "++shortPoint2 p
MoveForward f -> "MoveForward "++ show f
Turn f -> "Turn "++show f
RandomTurn f -> "RandomTurn "++show f
TurnToward p f -> "TurnToward "++shortPoint2 p++show f
MvTurnToward p -> "MvTurnToward "++shortPoint2 p
MvForward -> "MvForward"
TurnTo p -> "TurnTo "++shortPoint2 p
UseItem -> "UseItem"
SwitchToItem i -> "SwitchToItem "++show i
DropItem -> "DropItem"
Bark sid -> "Bark "++show sid
Melee i -> "Melee "++show i
ChangePosture post -> "ChangePosture " ++ show post
MakeSound sid -> "MakeSound " ++ show sid
ChangeStrategy s -> "ChangeStrategy " ++ show s
AddGoal g -> "AddGoal " ++ show g
ArbitraryImpulseFunction {} -> "ArbitraryImpulseFunction"
ArbitraryImpulse {} -> "ArbitraryImpulse"
ArbitraryImpulseEffect {} -> "ArbitraryImpulseEffect"
ImpulseUseTargetCID {} -> "ImpulseUseTargetCID"
ImpulseUseTarget {} -> "ImpulseUseTarget"
ImpulseUseAheadPos {} -> "ImpulseUseAheadPos"
RandomImpulse {} -> "RandomImpulse"
-- deriving (Eq,Ord,Show)
infixr 9 `WaitThen`
infixr 9 `DoActionThen`
infixr 9 `DoActionWhile`
infixr 9 `DoReplicate`
infixr 9 `DoImpulsesAlongside`
data Action
= LabelAction
{_actLabel :: String
,_actAction :: Action
}
| AimAt
{_targetID :: Int
,_targetSeenAt :: Point2
}
| PathTo
{_pathToPoint :: Point2
}
| TurnToA
{_turnToAPoint :: Point2
}
-- | PickupItem
-- {_pickupItemID :: Int
-- }
| ImpulsesList
{_impulsesListList :: [[Impulse]]
}
| DoImpulses
{_doImpulsesList :: [Impulse]
}
| WaitThen
{_waitThenTimer :: Int
,_waitThenAction :: Action
}
| DoActionWhile
{_doActionWhileCondition :: World -> Creature -> Bool
,_doActionWhileAction :: Action
}
| DoActionWhilePartial
{_doActionWhilePartial :: Action
,_doActionWhileCondition :: World -> Creature -> Bool
,_doActionWhileAction :: Action
}
| DoActionIf
{_doActionIfCondition :: World -> Creature -> Bool
,_doActionIfAction :: Action
}
| DoActionIfElse
{_doActionIfElseIfAction :: Action
,_doActionIfElseCondition :: World -> Creature -> Bool
,_doActionIfElseElseAction :: Action
}
| DoActionWhileInterrupt
{_doActionWhileThenDo :: Action
,_doActionWhileThenCondition :: World -> Creature -> Bool
,_doActionWhileThenThen :: Action
}
| DoActions
{_doActionsList :: [Action]
}
| DoActionThen
{_doActionThenFirst :: Action
,_doActionThenSecond :: Action
}
-- | DoGuardActions
-- {_doGuardActionsList :: [( (World, Creature) -> Bool, Action, Maybe Action)]
-- }
| DoReplicate
{_doReplicateTimes :: Int
,_doReplicateAction :: Action
}
| DoReplicatePartial
{_partialAction :: Action
,_doReplicateTimes :: Int
,_doReplicateAction :: Action
}
| LeadTarget
{_leadTargetBy :: Point2
}
| NoAction
| StartSentinelPost
| UseTarget
{_useTarget :: Maybe Creature -> Action
}
| UseSelf
{_useSelf :: Creature -> Action
}
| UseAheadPos
{_useAheadPos :: Point2 -> Action
}
| UseMvTargetPos
{_useMvTargetPos :: Maybe Point2 -> Action
}
| ArbitraryAction
{ _arbitraryAction :: Creature -> World -> Action }
| DoImpulsesAlongside
-- ^ Repeatedly perform impulses alongside a main action until the main action terminates
{_sideImpulses :: [Impulse]
,_mainAction :: Action
}
deriving (Generic)
instance Show Action where
show act = case act of
LabelAction
{_actLabel = str
,_actAction = subAct
} -> str++":"++show subAct
AimAt
{_targetID = tid
,_targetSeenAt = p
} -> "AimAt tid:"++show tid++" seenAt:"++shortPoint2 p
PathTo
{_pathToPoint = p
} -> "PathTo:"++shortPoint2 p
TurnToA
{_turnToAPoint = p
} -> "TurnToA:"++shortPoint2 p
---- | PickupItem
---- {_pickupItemID :: Int
---- }
ImpulsesList
{_impulsesListList = iss
} -> "ImpulsesList:"++show iss
DoImpulses
{_doImpulsesList = is
} -> "DoImpulses:"++show is
WaitThen
{_waitThenTimer = i
,_waitThenAction = a
} -> "WaitThen timer:"++show i++" act:"++show a
DoActionWhile
{_doActionWhileCondition = _
,_doActionWhileAction = a
} -> "DoActionWhile (function) act:"++show a
DoActionWhilePartial
{_doActionWhilePartial = partact
,_doActionWhileCondition = _
,_doActionWhileAction = a
} -> "DoActionWhilePartial partAct:"++show partact++" resetAct:"++show a
DoActionIf
{_doActionIfCondition = _
,_doActionIfAction = a
} -> "DoActionIf act:"++show a
DoActionIfElse
{_doActionIfElseIfAction = ifa
,_doActionIfElseCondition = _
,_doActionIfElseElseAction = elsea
} -> "DoActionIfElse ifa:"++show ifa++" elsea:"++show elsea
DoActionWhileInterrupt
{_doActionWhileThenDo = whilea
,_doActionWhileThenCondition = _
,_doActionWhileThenThen = thena
} -> "DoActionWhileInterrupt whilea:" ++show whilea++" interrupta:"++show thena
DoActions
{_doActionsList = as
} -> "DoActions " ++ foldMap show as
DoActionThen
{_doActionThenFirst = a1
,_doActionThenSecond = a2
} -> "DoActionThen " ++ show a1 ++ " then:" ++ show a2
---- | DoGuardActions
---- {_doGuardActionsList :: [( (World, Creature) -> Bool, Action, Maybe Action)]
---- }
DoReplicate
{_doReplicateTimes = i
,_doReplicateAction = a
} -> "DoReplicate times:" ++ show i ++ " act:"++ show a
DoReplicatePartial
{_partialAction = pa
,_doReplicateTimes = i
,_doReplicateAction = ra
} -> "DoReplicatePartial pa:" ++ show pa ++ " times:" ++ show i ++ " reset:"++ show ra
LeadTarget
{_leadTargetBy = p
} -> "LeadTarget by:"++ show p
NoAction -> "NoAction"
StartSentinelPost -> "StartSentinelPost"
UseTarget
{_useTarget = _
} -> "UseTarget func"
UseSelf
{_useSelf = _
} -> "UseSelf func"
UseAheadPos
{_useAheadPos = _
} -> "UseAheadPos func"
UseMvTargetPos
{_useMvTargetPos = _
} -> "UseMvTargetPos func"
ArbitraryAction {} -> "ArbitraryAction func"
DoImpulsesAlongside
{_sideImpulses = is
,_mainAction = a
} -> "DoImpulsesAlongside sideImpulses:"++show is ++ " mainA:"++show a
-- deriving (Eq,Ord,Show)
data Strategy
= Flank Int
| Ambush Int
| Lure Int Point2
| Patrol [Point2]
| ShootAt Int
| FollowImpulses
| WatchAndWait
| WarningCry
| LookAround
| CloseToMelee Int
| StrategyActions Strategy [Action]
| GetTo Point2
| Reload
| Flee
| MeleeStrike
deriving (Generic,Show)
-- deriving (Eq,Ord,Show)
data Goal
= LiveLongAndProsper
| Kill Int
| SentinelAt Point2 Float
deriving (Show)
newtype Zone a = Zone
{ _znObjects :: IM.IntMap (IM.IntMap a)
}
data DamageEffect
= PushDamage
{ _dePush :: Float
, _dePushExp :: Float
, _dePushRadius :: Float
}
| TorqueDamage { _deTorque :: Float }
| PushBackDamage {_dePushBack :: Point2 }
| BounceBullet {_bulToBounce :: Particle}
| DamageSpawn {_spawnFunc
:: Either Creature Wall -> Damage -> State StdGen Particle}
| NoDamageEffect
-- deriving (Eq,Ord,Show)
data Damage = Damage
{ _dmType :: DamageType
, _dmAmount :: Int , _dmFrom :: Point2 , _dmAt :: Point2 , _dmTo :: Point2
, _dmEffect :: DamageEffect
}
-- deriving (Eq,Ord,Show)
isElectrical :: Damage -> Bool
isElectrical dm = case _dmType dm of
Electrical{} -> True
_ -> False
isMovementDam :: Damage -> Bool
isMovementDam dm = case _dmType dm of
TorqueDam{} -> True
PushDam{} -> True
_ -> False
data CreatureState = CrSt
{ _crDamage :: [Damage]
-- , _crPastDamage :: V.Vector [Damage]
, _crSpState :: CrSpState
, _crDropsOnDeath :: CreatureDropType
}
data TerminalCommand = TerminalCommand
{ _tcString :: String
, _tcAlias :: [String]
, _tcHelp :: String
, _tcArgumentType :: Maybe String
, _tcArguments :: World -> [String]
, _tcEffect :: [String] -> World -> Either String World
}
---- ROOM DATATYPES
data PSType = PutCrit {_unPutCrit :: Creature}
| PutMachine { _putMachineColor :: Color, _putMachinePoly :: [Point2], _unPutMachine :: Machine }
| PutLS LightSource
| PutButton {_putButton :: Button}
| PutProp Prop
| PutFlIt Item
| PutPPlate PressPlate
| PutBlock BlockMaterial Int [Int] Wall [Point2]
| PutCoord Point2
| PutMod Modification
| PutTrigger (World -> Bool)
| PutLineBlock {_putWall :: Wall, _putBlockMaterial :: BlockMaterial
, _putWidth :: Float, _putDepth :: Float, _putStartPoint :: Point2, _putEndPoint :: Point2}
| PutWall { _pwPoly :: [Point2] , _pwWall :: Wall }
| PutSlideDr Bool Color (World -> Bool) Float Point2 Point2 Float
| PutDoor Color (World -> Bool) [(Point2,Point2)]
| RandPS (State StdGen PSType)
| PutShape Shape
| PutWorldUpdate (PlacementSpot -> World -> World)
| PutNothing
| PutUsingGenParams (World -> (World,PSType))
| PutID { _putID :: Int}
-- 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
, _plIDCont :: World -> Placement -> Maybe Placement
}
| PlacementUsingPos Point3 (Point3 -> Placement) -- allows a placement to use a shifted position
| RandomPlacement {_unRandomPlacement :: State StdGen Placement}
| PickOnePlacement Int 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 :: [(Point2, Point2)]
, _rmPmnts :: [Placement]
, _rmInPmnt :: [InPlacement]
, _rmOutPmnt :: [OutPlacement]
, _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
}
data RoomLink = RoomLink
{ _rlType :: S.Set RoomLinkType
, _rlPos :: Point2
, _rlDir :: Float
} deriving (Eq,Ord)
data RoomType = DefaultRoomType
| RectRoomType
{ _numLinkEW :: Int
, _numLinkNS :: Int
, _linkGapEW :: Float
, _linkGapNS :: Float
, _rmWidth :: Float
, _rmHeight :: Float
}
deriving (Eq,Ord)
data RoomLinkType
= OutLink
| InLink
| LabLink Int
| OnEdge CardinalPoint
| FromSouth Int
| FromNorth Int
| FromWest Int
| FromEast Int
| BlockedLink
deriving (Eq,Ord,Show)
data CardinalPoint
= North
| East
| South
| West
deriving (Eq,Ord,Show)
data RoomWire
= --RoomWire Point2 Float
WallWire Point2 Float Float
data RPLinkStatus
= UsedOutLink
{ _rplsType :: S.Set RoomLinkType
, _rplsChildNum :: Int
, _rplsOutRoomID :: Int
}
| UsedInLink
{ _rplsType :: S.Set RoomLinkType
, _rplsInRoomID :: Int
}
| UnusedLink { _rplsType :: S.Set RoomLinkType }
| NotLink
deriving (Eq,Ord,Show)
data OutPlacement = OutPlacement
{ _opPlacement :: Placement
, _opPlacementID :: Int
}
data InPlacement = InPlacement
{ _ipPlacement :: [Placement] -> Placement
, _ipPlacementID :: Int
}
data RoomPos = RoomPos
{ _rpPos :: Point2
, _rpDir :: Float
, _rpType :: S.Set RoomPosType
, _rpLinkStatus :: RPLinkStatus
, _rpPlacementUse :: Int
}
deriving (Eq,Ord,Show)
data RoomPosType
= RoomPosOnPath
| RoomPosOffPath
| RoomPosExLink
| RoomPosLab Int
deriving (Eq,Ord,Show)
makeLenses ''CreatureState
makeLenses ''Damage
makeLenses ''DamageEffect
makeLenses ''World
makeLenses ''Cloud
makeLenses ''Creature
makeLenses ''LightSource
makeLenses ''TempLightSource
makeLenses ''Item
makeLenses ''ItemUse
makeLenses ''ItemPos
makeLenses ''ItEffect
makeLenses ''FloorItem
makeLenses ''ItemConsumption
makeLenses ''AmmoType
makeLenses ''TweakParam
makeLenses ''Prop
makeLenses ''Modification
makeLenses ''Particle
makeLenses ''Wall
makeLenses ''WallStructure
makeLenses ''PressPlate
makeLenses ''Button
makeLenses ''ActionPlan
makeLenses ''Impulse
makeLenses ''Action
makeLenses ''CrGroupParams
makeLenses ''CrMvType
makeLenses ''Intention
makeLenses ''Door
makeLenses ''Block
makeLenses ''Terminal
makeLenses ''Machine
makeLenses ''MachineType
makeLenses ''Zone
makeLenses ''ItemDimension
makeLenses ''Vocalization
makeLenses ''Universe
makeLenses ''LSParam
makeLenses ''ItemParams
makeLenses ''ItemTweaks
makeLenses ''Maybe'
makeLenses ''ItemPortage
makeLenses ''Magnet
makeLenses ''Gust
makeLenses ''GunBarrels
makeLenses ''ItemModule
makeLenses ''Targeting
makeLenses ''Nozzle
makeLenses ''HUD
makeLenses ''HUDElement
makeLenses ''SubInventory
makeLenses ''TerminalParams
makeLenses ''TerminalLine
makeLenses ''ItemValue
makeLenses ''ScreenLayer
makeLenses ''Sensor
makeLenses ''Beam
makeLenses ''BeamType
makeLenses ''WorldBeams
makeLenses ''ArcStep
makeLenses ''CreatureStatistics
makeLenses ''RightButtonOptions
makeLenses ''AllocateEquipment
makeLenses ''ActivateEquipment
makeLenses ''EquipParams
makeLenses ''TerminalCommand
makeLenses ''GenParams
----- ROOM LENSES
makeLenses ''Room
makeLenses ''RoomType
makeLenses ''PSType
makeLenses ''PlacementSpot
makeLenses ''Placement
makeLenses ''RoomLink
makeLenses ''RoomPos
makeLenses ''RoomPosType
makeLenses ''RPLinkStatus