{- | 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 ) 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.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 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 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 , _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] , _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 } data HUDElement = DisplayInventory {_subInventory :: SubInventory} | DisplayCarte -- deriving (Eq,Ord,Show) 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 :: String , _scFooter :: String } | WaitScreen { _scWaitMessage :: Universe -> String , _scWaitTime :: Int } | DisplayScreen { _scDisplay :: Universe -> Picture } data MenuOption = Toggle { _moKey :: Scancode , _moEff :: Universe -> IO (Maybe Universe) , _moString :: Universe -> Either String (String,String) } | 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 } 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 :: TerminalParams } data TerminalParams = NoTerminalParams | TerminalParams { _termDisplayedLines :: [World -> (String,Color)] , _termFutureLines :: [TerminalLine] , _termMaxLines :: Int , _termTitle :: String } data TerminalLine = TerminalLineDisplay {_tlPause :: Int ,_tlString :: World -> (String, Color) } | 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 } | LeftUse { _lUse :: Creature -> Int -> World -> World , _useDelay :: UseDelay , _useHammer :: HammerType } | ConsumeUse { _cUse :: Item -> Creature -> World -> World } | EquipUse { _eqUse :: Creature -> Int -> World -> World , _eqSite :: EquipSite } | NoUse data EquipSite = GoesOnHead | GoesOnChest | GoesOnBack | GoesOnWrist | GoesOnLegs | GoesOnSpecial deriving (Eq,Ord,Show) data EquipPosition = OnHead | OnChest | OnBack | OnLeftWrist | OnRightWrist | OnLegs | OnSpecial deriving (Eq,Ord,Show) _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 -> Int -> SPic , _itScroll :: Float -> Creature -> Item -> Item , _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 , _itParams :: ItemParams , _itTweaks :: ItemTweaks , _itModules :: M.Map ModuleSlot ItemModule , _itScope :: Scope , _itValue :: ItemValue } 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 } 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) } | 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 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 } 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 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 } 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 } 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 ''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