module Game.LambdaHack.Common.State
(
State
, sdungeon, sdepth, sactorD, sitemD, sfactionD, stime, scops, shigh
, defStateGlobal, emptyState, localFromGlobal
, updateDungeon, updateDepth, updateActorD, updateItemD
, updateFaction, updateTime, updateCOps, getLocalTime
, isHumanFaction, usesAIFaction, isSpawnFaction, isSummonFaction
) where
import Data.Binary
import qualified Data.EnumMap.Strict as EM
import Data.Text (Text)
import Game.LambdaHack.Common.Actor
import Game.LambdaHack.Common.Faction
import qualified Game.LambdaHack.Common.HighScore as HighScore
import qualified Game.LambdaHack.Common.Kind as Kind
import Game.LambdaHack.Common.Level
import Game.LambdaHack.Common.Point
import Game.LambdaHack.Common.PointXY
import Game.LambdaHack.Common.Time
import Game.LambdaHack.Content.TileKind
data State = State
{ _sdungeon :: !Dungeon
, _sdepth :: !Int
, _sactorD :: !ActorDict
, _sitemD :: !ItemDict
, _sfactionD :: !FactionDict
, _stime :: !Time
, _scops :: Kind.COps
, _shigh :: !HighScore.ScoreTable
}
deriving (Show, Eq)
unknownLevel :: Kind.Ops TileKind -> Int -> X -> Y
-> Text -> (Point, Point) -> Int
-> Level
unknownLevel Kind.Ops{ouniqGroup} ldepth lxsize lysize ldesc lstair lclear =
let unknownId = ouniqGroup "unknown space"
in Level { ldepth
, lprio = EM.empty
, lfloor = EM.empty
, ltile = unknownTileMap unknownId lxsize lysize
, lxsize = lxsize
, lysize = lysize
, lsmell = EM.empty
, ldesc
, lstair
, lseen = 0
, lclear
, ltime = timeZero
, litemNum = 0
, lsecret = 0
, lhidden = 0
}
unknownTileMap :: Kind.Id TileKind -> Int -> Int -> TileMap
unknownTileMap unknownId cxsize cysize =
let bounds = (origin, toPoint cxsize $ PointXY (cxsize 1, cysize 1))
in Kind.listArray bounds (repeat unknownId)
defStateGlobal :: Dungeon -> Int
-> FactionDict -> Kind.COps -> HighScore.ScoreTable
-> State
defStateGlobal _sdungeon _sdepth _sfactionD _scops _shigh =
State
{ _sactorD = EM.empty
, _sitemD = EM.empty
, _stime = timeZero
, ..
}
emptyState :: State
emptyState =
State
{ _sdungeon = EM.empty
, _sdepth = 0
, _sactorD = EM.empty
, _sitemD = EM.empty
, _sfactionD = EM.empty
, _stime = timeZero
, _scops = undefined
, _shigh = HighScore.empty
}
localFromGlobal :: State -> State
localFromGlobal State{_scops=_scops@Kind.COps{cotile}, .. } =
State
{ _sdungeon =
EM.map (\Level{ldepth, lxsize, lysize, ldesc, lstair, lclear} ->
unknownLevel cotile ldepth lxsize lysize ldesc lstair lclear)
_sdungeon
, ..
}
updateDungeon :: (Dungeon -> Dungeon) -> State -> State
updateDungeon f s = s {_sdungeon = f (_sdungeon s)}
updateDepth :: (Int -> Int) -> State -> State
updateDepth f s = s {_sdepth = f (_sdepth s)}
updateActorD :: (ActorDict -> ActorDict) -> State -> State
updateActorD f s = s {_sactorD = f (_sactorD s)}
updateItemD :: (ItemDict -> ItemDict) -> State -> State
updateItemD f s = s {_sitemD = f (_sitemD s)}
updateFaction :: (FactionDict -> FactionDict) -> State -> State
updateFaction f s = s {_sfactionD = f (_sfactionD s)}
updateTime :: (Time -> Time) -> State -> State
updateTime f s = s {_stime = f (_stime s)}
updateCOps :: (Kind.COps -> Kind.COps) -> State -> State
updateCOps f s = s {_scops = f (_scops s)}
getLocalTime :: LevelId -> State -> Time
getLocalTime lid s = ltime $ _sdungeon s EM.! lid
isHumanFaction :: FactionId -> State -> Bool
isHumanFaction fid s = isHumanFact $ _sfactionD s EM.! fid
usesAIFaction :: FactionId -> State -> Bool
usesAIFaction fid s = usesAIFact $ _sfactionD s EM.! fid
isSpawnFaction :: FactionId -> State -> Bool
isSpawnFaction fid s = isSpawnFact (_scops s) $ _sfactionD s EM.! fid
isSummonFaction :: FactionId -> State -> Bool
isSummonFaction fid s = isSummonFact (_scops s) $ _sfactionD s EM.! fid
sdungeon :: State -> Dungeon
sdungeon = _sdungeon
sdepth :: State -> Int
sdepth = _sdepth
sactorD :: State -> ActorDict
sactorD = _sactorD
sitemD :: State -> ItemDict
sitemD = _sitemD
sfactionD :: State -> FactionDict
sfactionD = _sfactionD
stime :: State -> Time
stime = _stime
scops :: State -> Kind.COps
scops = _scops
shigh :: State -> HighScore.ScoreTable
shigh = _shigh
instance Binary State where
put State{..} = do
put _sdungeon
put _sdepth
put _sactorD
put _sitemD
put _sfactionD
put _stime
put _shigh
get = do
_sdungeon <- get
_sdepth <- get
_sactorD <- get
_sitemD <- get
_sfactionD <- get
_stime <- get
_shigh <- get
let _scops = undefined
return State{..}