module Rattletrap.Decode.SpawnedReplication ( decodeSpawnedReplicationBits ) where import Rattletrap.Decode.Common import Rattletrap.Decode.Initialization import Rattletrap.Decode.Word32le import Rattletrap.Type.ClassAttributeMap import Rattletrap.Type.CompressedWord import Rattletrap.Type.SpawnedReplication import Rattletrap.Type.Str import Rattletrap.Type.Word32le import qualified Control.Monad.Trans.Class as Trans import qualified Control.Monad.Trans.State as State import qualified Data.Map as Map decodeSpawnedReplicationBits :: (Int, Int, Int) -> ClassAttributeMap -> CompressedWord -> State.StateT (Map.Map CompressedWord Word32le) DecodeBits SpawnedReplication decodeSpawnedReplicationBits version classAttributeMap actorId = do flag <- Trans.lift getBool nameIndex <- decodeWhen (version >= (868, 14, 0)) (Trans.lift decodeWord32leBits) name <- either fail pure (lookupName classAttributeMap nameIndex) objectId <- Trans.lift decodeWord32leBits State.modify (Map.insert actorId objectId) objectName <- either fail pure (lookupObjectName classAttributeMap objectId) className <- either fail pure (lookupClassName objectName) let hasLocation = classHasLocation className let hasRotation = classHasRotation className initialization <- Trans.lift (decodeInitializationBits version hasLocation hasRotation) pure (SpawnedReplication flag nameIndex name objectId objectName className initialization ) lookupName :: ClassAttributeMap -> Maybe Word32le -> Either String (Maybe Str) lookupName classAttributeMap maybeNameIndex = case maybeNameIndex of Nothing -> Right Nothing Just nameIndex -> case getName (classAttributeMapNameMap classAttributeMap) nameIndex of Nothing -> Left ("could not get name for index " <> show nameIndex) Just name -> Right (Just name) lookupObjectName :: ClassAttributeMap -> Word32le -> Either String Str lookupObjectName classAttributeMap objectId = case getObjectName (classAttributeMapObjectMap classAttributeMap) objectId of Nothing -> Left ("could not get object name for id " <> show objectId) Just objectName -> Right objectName lookupClassName :: Str -> Either String Str lookupClassName objectName = case getClassName objectName of Nothing -> Left ("could not get class name for object " <> show objectName) Just className -> Right className