module Rattletrap.Type.ReplicationValue where import qualified Data.Foldable as Foldable import qualified Data.Map as Map import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema import qualified Rattletrap.Type.ClassAttributeMap as ClassAttributeMap import qualified Rattletrap.Type.CompressedWord as CompressedWord import qualified Rattletrap.Type.Replication.Destroyed as Destroyed import qualified Rattletrap.Type.Replication.Spawned as Spawned import qualified Rattletrap.Type.Replication.Updated as Updated import qualified Rattletrap.Type.Str as Str import qualified Rattletrap.Type.U32 as U32 import qualified Rattletrap.Type.Version as Version import qualified Rattletrap.Utility.Json as Json data ReplicationValue = -- | Creates a new actor. Spawned Spawned.Spawned | -- | Updates an existing actor. Updated Updated.Updated | -- | Destroys an existing actor. Destroyed Destroyed.Destroyed deriving (Eq, Show) instance Json.FromJSON ReplicationValue where parseJSON = Json.withObject "ReplicationValue" $ \object -> Foldable.asum [ fmap Spawned $ Json.required object "spawned", fmap Updated $ Json.required object "updated", fmap Destroyed $ Json.required object "destroyed" ] instance Json.ToJSON ReplicationValue where toJSON x = case x of Spawned y -> Json.object [Json.pair "spawned" y] Updated y -> Json.object [Json.pair "updated" y] Destroyed y -> Json.object [Json.pair "destroyed" y] schema :: Schema.Schema schema = Schema.named "replicationValue" . Schema.oneOf $ fmap (\(k, v) -> Schema.object [(Json.pair k $ Schema.ref v, True)]) [ ("spawned", Spawned.schema), ("updated", Updated.schema), ("destroyed", Destroyed.schema) ] bitPut :: ReplicationValue -> BitPut.BitPut bitPut value = case value of Spawned x -> BitPut.bool True <> BitPut.bool True <> Spawned.bitPut x Updated x -> BitPut.bool True <> BitPut.bool False <> Updated.bitPut x Destroyed x -> BitPut.bool False <> Destroyed.bitPut x bitGet :: Maybe Str.Str -> Version.Version -> Maybe Str.Str -> ClassAttributeMap.ClassAttributeMap -> CompressedWord.CompressedWord -> Map.Map CompressedWord.CompressedWord U32.U32 -> BitGet.BitGet ( Map.Map CompressedWord.CompressedWord U32.U32, ReplicationValue ) bitGet matchType version buildVersion classAttributeMap actorId actorMap = BitGet.label "ReplicationValue" $ do isOpen <- BitGet.bool if isOpen then do isNew <- BitGet.bool if isNew then do (newActorMap, spawned) <- Spawned.bitGet matchType version classAttributeMap actorId actorMap pure (newActorMap, Spawned spawned) else do updated <- Updated.bitGet version buildVersion classAttributeMap actorMap actorId pure (actorMap, Updated updated) else do destroyed <- Destroyed.bitGet pure (actorMap, Destroyed destroyed)