module Rattletrap.Type.Attribute.ProductValue where import qualified Data.Foldable as Foldable import qualified Data.Word as Word import qualified Rattletrap.BitGet as BitGet import qualified Rattletrap.BitPut as BitPut import qualified Rattletrap.Schema as Schema import qualified Rattletrap.Type.CompressedWord as CompressedWord 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 import qualified Rattletrap.Utility.Monad as Monad data ProductValue = PaintedOld CompressedWord.CompressedWord | PaintedNew Word.Word32 | TeamEditionOld CompressedWord.CompressedWord | TeamEditionNew Word.Word32 | SpecialEdition Word.Word32 | UserColorOld (Maybe Word.Word32) | UserColorNew U32.U32 | TitleId Str.Str deriving (ProductValue -> ProductValue -> Bool (ProductValue -> ProductValue -> Bool) -> (ProductValue -> ProductValue -> Bool) -> Eq ProductValue forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: ProductValue -> ProductValue -> Bool $c/= :: ProductValue -> ProductValue -> Bool == :: ProductValue -> ProductValue -> Bool $c== :: ProductValue -> ProductValue -> Bool Eq, Int -> ProductValue -> ShowS [ProductValue] -> ShowS ProductValue -> String (Int -> ProductValue -> ShowS) -> (ProductValue -> String) -> ([ProductValue] -> ShowS) -> Show ProductValue forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [ProductValue] -> ShowS $cshowList :: [ProductValue] -> ShowS show :: ProductValue -> String $cshow :: ProductValue -> String showsPrec :: Int -> ProductValue -> ShowS $cshowsPrec :: Int -> ProductValue -> ShowS Show) instance Json.FromJSON ProductValue where parseJSON :: Value -> Parser ProductValue parseJSON = String -> (Object -> Parser ProductValue) -> Value -> Parser ProductValue forall a. String -> (Object -> Parser a) -> Value -> Parser a Json.withObject String "ProductValue" ((Object -> Parser ProductValue) -> Value -> Parser ProductValue) -> (Object -> Parser ProductValue) -> Value -> Parser ProductValue forall a b. (a -> b) -> a -> b $ \Object object -> [Parser ProductValue] -> Parser ProductValue forall (t :: * -> *) (f :: * -> *) a. (Foldable t, Alternative f) => t (f a) -> f a Foldable.asum [ (CompressedWord -> ProductValue) -> Parser CompressedWord -> Parser ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap CompressedWord -> ProductValue PaintedOld (Parser CompressedWord -> Parser ProductValue) -> Parser CompressedWord -> Parser ProductValue forall a b. (a -> b) -> a -> b $ Object -> String -> Parser CompressedWord forall value. FromJSON value => Object -> String -> Parser value Json.required Object object String "painted_old" , (Word32 -> ProductValue) -> Parser Word32 -> Parser ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Word32 -> ProductValue PaintedNew (Parser Word32 -> Parser ProductValue) -> Parser Word32 -> Parser ProductValue forall a b. (a -> b) -> a -> b $ Object -> String -> Parser Word32 forall value. FromJSON value => Object -> String -> Parser value Json.required Object object String "painted_new" , (CompressedWord -> ProductValue) -> Parser CompressedWord -> Parser ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap CompressedWord -> ProductValue TeamEditionOld (Parser CompressedWord -> Parser ProductValue) -> Parser CompressedWord -> Parser ProductValue forall a b. (a -> b) -> a -> b $ Object -> String -> Parser CompressedWord forall value. FromJSON value => Object -> String -> Parser value Json.required Object object String "team_edition_old" , (Word32 -> ProductValue) -> Parser Word32 -> Parser ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Word32 -> ProductValue TeamEditionNew (Parser Word32 -> Parser ProductValue) -> Parser Word32 -> Parser ProductValue forall a b. (a -> b) -> a -> b $ Object -> String -> Parser Word32 forall value. FromJSON value => Object -> String -> Parser value Json.required Object object String "team_edition_new" , (Word32 -> ProductValue) -> Parser Word32 -> Parser ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Word32 -> ProductValue SpecialEdition (Parser Word32 -> Parser ProductValue) -> Parser Word32 -> Parser ProductValue forall a b. (a -> b) -> a -> b $ Object -> String -> Parser Word32 forall value. FromJSON value => Object -> String -> Parser value Json.required Object object String "special_edition" , (Maybe Word32 -> ProductValue) -> Parser (Maybe Word32) -> Parser ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Maybe Word32 -> ProductValue UserColorOld (Parser (Maybe Word32) -> Parser ProductValue) -> Parser (Maybe Word32) -> Parser ProductValue forall a b. (a -> b) -> a -> b $ Object -> String -> Parser (Maybe Word32) forall value. FromJSON value => Object -> String -> Parser value Json.required Object object String "user_color_old" , (U32 -> ProductValue) -> Parser U32 -> Parser ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap U32 -> ProductValue UserColorNew (Parser U32 -> Parser ProductValue) -> Parser U32 -> Parser ProductValue forall a b. (a -> b) -> a -> b $ Object -> String -> Parser U32 forall value. FromJSON value => Object -> String -> Parser value Json.required Object object String "user_color_new" , (Str -> ProductValue) -> Parser Str -> Parser ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Str -> ProductValue TitleId (Parser Str -> Parser ProductValue) -> Parser Str -> Parser ProductValue forall a b. (a -> b) -> a -> b $ Object -> String -> Parser Str forall value. FromJSON value => Object -> String -> Parser value Json.required Object object String "title_id" ] instance Json.ToJSON ProductValue where toJSON :: ProductValue -> Value toJSON ProductValue x = case ProductValue x of PaintedOld CompressedWord y -> [Pair] -> Value Json.object [String -> CompressedWord -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String "painted_old" CompressedWord y] PaintedNew Word32 y -> [Pair] -> Value Json.object [String -> Word32 -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String "painted_new" Word32 y] TeamEditionOld CompressedWord y -> [Pair] -> Value Json.object [String -> CompressedWord -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String "team_edition_old" CompressedWord y] TeamEditionNew Word32 y -> [Pair] -> Value Json.object [String -> Word32 -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String "team_edition_new" Word32 y] SpecialEdition Word32 y -> [Pair] -> Value Json.object [String -> Word32 -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String "special_edition" Word32 y] UserColorOld Maybe Word32 y -> [Pair] -> Value Json.object [String -> Maybe Word32 -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String "user_color_old" Maybe Word32 y] UserColorNew U32 y -> [Pair] -> Value Json.object [String -> U32 -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String "user_color_new" U32 y] TitleId Str y -> [Pair] -> Value Json.object [String -> Str -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String "title_id" Str y] schema :: Schema.Schema schema :: Schema schema = String -> Value -> Schema Schema.named String "attribute-product-value" (Value -> Schema) -> ([Value] -> Value) -> [Value] -> Schema forall b c a. (b -> c) -> (a -> b) -> a -> c . [Value] -> Value Schema.oneOf ([Value] -> Schema) -> [Value] -> Schema forall a b. (a -> b) -> a -> b $ ((String, Value) -> Value) -> [(String, Value)] -> [Value] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (\(String k, Value v) -> [(Pair, Bool)] -> Value Schema.object [(String -> Value -> Pair forall value pair. (ToJSON value, KeyValue pair) => String -> value -> pair Json.pair String k Value v, Bool True)]) [ (String "painted_old", Schema -> Value Schema.ref Schema CompressedWord.schema) , (String "painted_new", Schema -> Value Schema.ref Schema Schema.integer) , (String "team_edition_old", Schema -> Value Schema.ref Schema CompressedWord.schema) , (String "team_edition_new", Schema -> Value Schema.ref Schema Schema.integer) , (String "special_edition", Schema -> Value Schema.ref Schema Schema.integer) , (String "user_color_old", Schema -> Value Schema.json (Schema -> Value) -> Schema -> Value forall a b. (a -> b) -> a -> b $ Schema -> Schema Schema.maybe Schema Schema.integer) , (String "user_color_new", Schema -> Value Schema.ref Schema U32.schema) , (String "title_id", Schema -> Value Schema.ref Schema Str.schema) ] bitPut :: ProductValue -> BitPut.BitPut bitPut :: ProductValue -> BitPut bitPut ProductValue val = case ProductValue val of PaintedOld CompressedWord x -> CompressedWord -> BitPut CompressedWord.bitPut CompressedWord x PaintedNew Word32 x -> Int -> Word32 -> BitPut forall a. Bits a => Int -> a -> BitPut BitPut.bits Int 31 Word32 x TeamEditionOld CompressedWord x -> CompressedWord -> BitPut CompressedWord.bitPut CompressedWord x TeamEditionNew Word32 x -> Int -> Word32 -> BitPut forall a. Bits a => Int -> a -> BitPut BitPut.bits Int 31 Word32 x SpecialEdition Word32 x -> Int -> Word32 -> BitPut forall a. Bits a => Int -> a -> BitPut BitPut.bits Int 31 Word32 x UserColorOld Maybe Word32 x -> case Maybe Word32 x of Maybe Word32 Nothing -> Bool -> BitPut BitPut.bool Bool False Just Word32 y -> Bool -> BitPut BitPut.bool Bool True BitPut -> BitPut -> BitPut forall a. Semigroup a => a -> a -> a <> Int -> Word32 -> BitPut forall a. Bits a => Int -> a -> BitPut BitPut.bits Int 31 Word32 y UserColorNew U32 x -> U32 -> BitPut U32.bitPut U32 x TitleId Str x -> Str -> BitPut Str.bitPut Str x bitGet :: Version.Version -> U32.U32 -> Maybe Str.Str -> BitGet.BitGet ProductValue bitGet :: Version -> U32 -> Maybe Str -> BitGet ProductValue bitGet Version version U32 objectId Maybe Str maybeObjectName = case (Str -> String) -> Maybe Str -> Maybe String forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Str -> String Str.toString Maybe Str maybeObjectName of Just String "TAGame.ProductAttribute_Painted_TA" -> Version -> BitGet ProductValue decodePainted Version version Just String "TAGame.ProductAttribute_SpecialEdition_TA" -> BitGet ProductValue decodeSpecialEdition Just String "TAGame.ProductAttribute_TeamEdition_TA" -> Version -> BitGet ProductValue decodeTeamEdition Version version Just String "TAGame.ProductAttribute_TitleID_TA" -> BitGet ProductValue decodeTitle Just String "TAGame.ProductAttribute_UserColor_TA" -> Version -> BitGet ProductValue decodeColor Version version Just String objectName -> String -> BitGet ProductValue forall (m :: * -> *) a. MonadFail m => String -> m a fail (String "[RT05] unknown object name " String -> ShowS forall a. Semigroup a => a -> a -> a <> ShowS forall a. Show a => a -> String show String objectName String -> ShowS forall a. Semigroup a => a -> a -> a <> String " for ID " String -> ShowS forall a. Semigroup a => a -> a -> a <> U32 -> String forall a. Show a => a -> String show U32 objectId ) Maybe String Nothing -> String -> BitGet ProductValue forall (m :: * -> *) a. MonadFail m => String -> m a fail (String "[RT06] missing object name for ID " String -> ShowS forall a. Semigroup a => a -> a -> a <> U32 -> String forall a. Show a => a -> String show U32 objectId) decodeSpecialEdition :: BitGet.BitGet ProductValue decodeSpecialEdition :: BitGet ProductValue decodeSpecialEdition = (Word32 -> ProductValue) -> Get BitString Identity Word32 -> BitGet ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Word32 -> ProductValue SpecialEdition (Get BitString Identity Word32 -> BitGet ProductValue) -> Get BitString Identity Word32 -> BitGet ProductValue forall a b. (a -> b) -> a -> b $ Int -> Get BitString Identity Word32 forall a. Bits a => Int -> BitGet a BitGet.bits Int 31 decodePainted :: Version.Version -> BitGet.BitGet ProductValue decodePainted :: Version -> BitGet ProductValue decodePainted Version version = if Version -> Bool hasNewPainted Version version then (Word32 -> ProductValue) -> Get BitString Identity Word32 -> BitGet ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Word32 -> ProductValue PaintedNew (Get BitString Identity Word32 -> BitGet ProductValue) -> Get BitString Identity Word32 -> BitGet ProductValue forall a b. (a -> b) -> a -> b $ Int -> Get BitString Identity Word32 forall a. Bits a => Int -> BitGet a BitGet.bits Int 31 else (CompressedWord -> ProductValue) -> Get BitString Identity CompressedWord -> BitGet ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap CompressedWord -> ProductValue PaintedOld (Get BitString Identity CompressedWord -> BitGet ProductValue) -> Get BitString Identity CompressedWord -> BitGet ProductValue forall a b. (a -> b) -> a -> b $ Word -> Get BitString Identity CompressedWord CompressedWord.bitGet Word 13 decodeTeamEdition :: Version.Version -> BitGet.BitGet ProductValue decodeTeamEdition :: Version -> BitGet ProductValue decodeTeamEdition Version version = if Version -> Bool hasNewPainted Version version then (Word32 -> ProductValue) -> Get BitString Identity Word32 -> BitGet ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Word32 -> ProductValue TeamEditionNew (Get BitString Identity Word32 -> BitGet ProductValue) -> Get BitString Identity Word32 -> BitGet ProductValue forall a b. (a -> b) -> a -> b $ Int -> Get BitString Identity Word32 forall a. Bits a => Int -> BitGet a BitGet.bits Int 31 else (CompressedWord -> ProductValue) -> Get BitString Identity CompressedWord -> BitGet ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap CompressedWord -> ProductValue TeamEditionOld (Get BitString Identity CompressedWord -> BitGet ProductValue) -> Get BitString Identity CompressedWord -> BitGet ProductValue forall a b. (a -> b) -> a -> b $ Word -> Get BitString Identity CompressedWord CompressedWord.bitGet Word 13 decodeColor :: Version.Version -> BitGet.BitGet ProductValue decodeColor :: Version -> BitGet ProductValue decodeColor Version version = if Int -> Int -> Int -> Version -> Bool Version.atLeast Int 868 Int 23 Int 8 Version version then (U32 -> ProductValue) -> Get BitString Identity U32 -> BitGet ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap U32 -> ProductValue UserColorNew Get BitString Identity U32 U32.bitGet else do Bool hasValue <- BitGet Bool BitGet.bool (Maybe Word32 -> ProductValue) -> Get BitString Identity (Maybe Word32) -> BitGet ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Maybe Word32 -> ProductValue UserColorOld (Get BitString Identity (Maybe Word32) -> BitGet ProductValue) -> Get BitString Identity (Maybe Word32) -> BitGet ProductValue forall a b. (a -> b) -> a -> b $ Bool -> Get BitString Identity Word32 -> Get BitString Identity (Maybe Word32) forall (m :: * -> *) a. Applicative m => Bool -> m a -> m (Maybe a) Monad.whenMaybe Bool hasValue (Int -> Get BitString Identity Word32 forall a. Bits a => Int -> BitGet a BitGet.bits Int 31) hasNewPainted :: Version.Version -> Bool hasNewPainted :: Version -> Bool hasNewPainted = Int -> Int -> Int -> Version -> Bool Version.atLeast Int 868 Int 18 Int 0 decodeTitle :: BitGet.BitGet ProductValue decodeTitle :: BitGet ProductValue decodeTitle = (Str -> ProductValue) -> Get BitString Identity Str -> BitGet ProductValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Str -> ProductValue TitleId Get BitString Identity Str Str.bitGet