module Octane.Type.Value
( Value(..)
, BooleanValue(..)
, ByteValue(..)
, CamSettingsValue(..)
, DemolishValue(..)
, EnumValue(..)
, ExplosionValue(..)
, FlaggedIntValue(..)
, FloatValue(..)
, GameModeValue(..)
, IntValue(..)
, LoadoutValue(..)
, LoadoutOnlineValue(..)
, LocationValue(..)
, MusicStingerValue(..)
, PickupValue(..)
, PrivateMatchSettingsValue(..)
, QWordValue(..)
, RelativeRotationValue(..)
, ReservationValue(..)
, RigidBodyStateValue(..)
, StringValue(..)
, TeamPaintValue(..)
, UniqueIdValue(..)
) where
import Data.Aeson ((.=))
import qualified Control.DeepSeq as DeepSeq
import qualified Data.Aeson as Aeson
import qualified Data.Bimap as Bimap
import qualified Data.Default.Class as Default
import qualified Data.OverloadedRecords.TH as OverloadedRecords
import qualified Data.Text as StrictText
import qualified GHC.Generics as Generics
import qualified Octane.Data as Data
import qualified Octane.Type.Boolean as Boolean
import qualified Octane.Type.CompressedWord as CompressedWord
import qualified Octane.Type.Float32 as Float32
import qualified Octane.Type.Int32 as Int32
import qualified Octane.Type.RemoteId as RemoteId
import qualified Octane.Type.Text as Text
import qualified Octane.Type.Vector as Vector
import qualified Octane.Type.Word16 as Word16
import qualified Octane.Type.Word32 as Word32
import qualified Octane.Type.Word64 as Word64
import qualified Octane.Type.Word8 as Word8
newtype BooleanValue = BooleanValue
{ booleanValueUnpack :: Boolean.Boolean
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData BooleanValue
newtype ByteValue = ByteValue
{ byteValueUnpack :: Word8.Word8
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData ByteValue
data CamSettingsValue = CamSettingsValue
{ camSettingsValueFov :: Float32.Float32
, camSettingsValueHeight :: Float32.Float32
, camSettingsValueAngle :: Float32.Float32
, camSettingsValueDistance :: Float32.Float32
, camSettingsValueStiffness :: Float32.Float32
, camSettingsValueSwivelSpeed :: Float32.Float32
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData CamSettingsValue
data DemolishValue = DemolishValue
{ demolishValueAttackerFlag :: Boolean.Boolean
, demolishValueAttackerActorId :: Word32.Word32
, demolishValueVictimFlag :: Boolean.Boolean
, demolishValueVictimActorId :: Word32.Word32
, demolishValueAttackerVelocity :: Vector.Vector Int
, demolishValueVictimVelocity :: Vector.Vector Int
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData DemolishValue
data EnumValue = EnumValue
{ enumValueValue :: Word16.Word16
, enumValueFlag :: Boolean.Boolean
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData EnumValue
data ExplosionValue = ExplosionValue
{ explosionValueActorless :: Boolean.Boolean
, explosionValueActorId :: Maybe Int32.Int32
, explosionValuePosition :: Vector.Vector Int
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData ExplosionValue
data FlaggedIntValue = FlaggedIntValue
{ flaggedIntValueFlag :: Boolean.Boolean
, flaggedIntValueInt :: Int32.Int32
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData FlaggedIntValue
newtype FloatValue = FloatValue
{ floatValueUnpack :: Float32.Float32
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData FloatValue
newtype GameModeValue = GameModeValue
{ gameModeValueUnpack :: Word8.Word8
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData GameModeValue
newtype IntValue = IntValue
{ intValueUnpack :: Int32.Int32
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData IntValue
data LoadoutValue = LoadoutValue
{ loadoutValueVersion :: Word8.Word8
, loadoutValueBody :: Word32.Word32
, loadoutValueDecal :: Word32.Word32
, loadoutValueWheels :: Word32.Word32
, loadoutValueRocketTrail :: Word32.Word32
, loadoutValueAntenna :: Word32.Word32
, loadoutValueTopper :: Word32.Word32
, loadoutValueUnknown1 :: Word32.Word32
, loadoutValueUnknown2 :: Maybe Word32.Word32
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData LoadoutValue
newtype LoadoutOnlineValue = LoadoutOnlineValue
{ loadoutOnlineValueUnpack :: [[(Word32.Word32, CompressedWord.CompressedWord)]]
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData LoadoutOnlineValue
newtype LocationValue = LocationValue
{ locationValueUnpack :: Vector.Vector Int
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData LocationValue
data MusicStingerValue = MusicStingerValue
{ musicStingerValueFlag :: Boolean.Boolean
, musicStingerValueCue :: Word32.Word32
, musicStingerValueTrigger :: Word8.Word8
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData MusicStingerValue
data PickupValue = PickupValue
{ pickupValueHasInstigator :: Boolean.Boolean
, pickupValueInstigatorId :: Maybe Word32.Word32
, pickupValuePickedUp :: Boolean.Boolean
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData PickupValue
data PrivateMatchSettingsValue = PrivateMatchSettingsValue
{ privateMatchSettingsValueMutators :: Text.Text
, privateMatchSettingsValueJoinableBy :: Word32.Word32
, privateMatchSettingsValueMaxPlayers :: Word32.Word32
, privateMatchSettingsValueGameName :: Text.Text
, privateMatchSettingsValuePassword :: Text.Text
, privateMatchSettingsValueFlag :: Boolean.Boolean
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData PrivateMatchSettingsValue
newtype QWordValue = QWordValue
{ qWordValueUnpack :: Word64.Word64
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData QWordValue
newtype RelativeRotationValue = RelativeRotationValue
{ relativeRotationValueUnpack :: Vector.Vector Float
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData RelativeRotationValue
data ReservationValue = ReservationValue
{ reservationValueNumber :: CompressedWord.CompressedWord
, reservationValueSystemId :: Word8.Word8
, reservationValueRemoteId :: RemoteId.RemoteId
, reservationValueLocalId :: Maybe Word8.Word8
, reservationValuePlayerName :: Maybe Text.Text
, reservationValueUnknown1 :: Boolean.Boolean
, reservationValueUnknown2 :: Boolean.Boolean
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData ReservationValue
data RigidBodyStateValue = RigidBodyStateValue
{ rigidBodyStateValueSleeping :: Boolean.Boolean
, rigidBodyStateValuePosition :: Vector.Vector Int
, rigidBodyStateValueRotation :: Vector.Vector Float
, rigidBodyStateValueLinearVelocity :: Maybe (Vector.Vector Int)
, rigidBodyStateValueAngularVelocity :: Maybe (Vector.Vector Int)
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData RigidBodyStateValue
newtype StringValue = StringValue
{ stringValueUnpack :: Text.Text
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData StringValue
data TeamPaintValue = TeamPaintValue
{ teamPaintValueTeam :: Word8.Word8
, teamPaintValuePrimaryColor :: Word8.Word8
, teamPaintValueAccentColor :: Word8.Word8
, teamPaintValuePrimaryFinish :: Word32.Word32
, teamPaintValueAccentFinish :: Word32.Word32
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData TeamPaintValue
data UniqueIdValue = UniqueIdValue
{ uniqueIdValueSystemId :: Word8.Word8
, uniqueIdValueRemoteId :: RemoteId.RemoteId
, uniqueIdValueLocalId :: Maybe Word8.Word8
} deriving (Eq, Generics.Generic, Show)
instance DeepSeq.NFData UniqueIdValue
data Value
= ValueBoolean BooleanValue
| ValueByte ByteValue
| ValueCamSettings CamSettingsValue
| ValueDemolish DemolishValue
| ValueEnum EnumValue
| ValueExplosion ExplosionValue
| ValueFlaggedInt FlaggedIntValue
| ValueFloat FloatValue
| ValueGameMode GameModeValue
| ValueInt IntValue
| ValueLoadout LoadoutValue
| ValueLoadoutOnline LoadoutOnlineValue
| ValueLocation LocationValue
| ValueMusicStinger MusicStingerValue
| ValuePickup PickupValue
| ValuePrivateMatchSettings PrivateMatchSettingsValue
| ValueQWord QWordValue
| ValueRelativeRotation RelativeRotationValue
| ValueReservation ReservationValue
| ValueRigidBodyState RigidBodyStateValue
| ValueString StringValue
| ValueTeamPaint TeamPaintValue
| ValueUniqueId UniqueIdValue
deriving (Eq, Generics.Generic, Show)
$(OverloadedRecords.overloadedRecords
Default.def
[ ''BooleanValue
, ''ByteValue
, ''CamSettingsValue
, ''DemolishValue
, ''EnumValue
, ''ExplosionValue
, ''FlaggedIntValue
, ''FloatValue
, ''GameModeValue
, ''IntValue
, ''LoadoutValue
, ''LoadoutOnlineValue
, ''LocationValue
, ''MusicStingerValue
, ''PickupValue
, ''PrivateMatchSettingsValue
, ''QWordValue
, ''RelativeRotationValue
, ''ReservationValue
, ''RigidBodyStateValue
, ''StringValue
, ''TeamPaintValue
, ''UniqueIdValue
])
instance DeepSeq.NFData Value
instance Aeson.ToJSON Value where
toJSON value =
Aeson.object ["Type" .= typeName value, "Value" .= jsonValue value]
typeName :: Value -> StrictText.Text
typeName value =
case value of
ValueBoolean _ -> "Boolean"
ValueByte _ -> "Byte"
ValueCamSettings _ -> "CameraSettings"
ValueDemolish _ -> "Demolition"
ValueEnum _ -> "Enum"
ValueExplosion _ -> "Explosion"
ValueFlaggedInt _ -> "FlaggedInt"
ValueFloat _ -> "Float"
ValueGameMode _ -> "GameMode"
ValueInt _ -> "Int"
ValueLoadout _ -> "Loadout"
ValueLoadoutOnline _ -> "OnlineLoadout"
ValueLocation _ -> "Position"
ValueMusicStinger _ -> "MusicStinger"
ValuePickup _ -> "Pickup"
ValuePrivateMatchSettings _ -> "PrivateMatchSettings"
ValueQWord _ -> "QWord"
ValueRelativeRotation _ -> "RelativeRotation"
ValueReservation _ -> "Reservation"
ValueRigidBodyState _ -> "RigidBodyState"
ValueString _ -> "String"
ValueTeamPaint _ -> "Paint"
ValueUniqueId _ -> "UniqueId"
jsonValue :: Value -> Aeson.Value
jsonValue value =
case value of
ValueBoolean x -> Aeson.toJSON (#unpack x)
ValueByte x -> Aeson.toJSON (#unpack x)
ValueCamSettings x ->
Aeson.object
[ "FOV" .= #fov x
, "Height" .= #height x
, "Angle" .= #angle x
, "Distance" .= #distance x
, "Stiffness" .= #stiffness x
, "SwivelSpeed" .= #swivelSpeed x
]
ValueDemolish x ->
Aeson.object
[ "AttackerFlag" .= #attackerFlag x
, "AttackerActorId" .= #attackerActorId x
, "VictimFlag" .= #victimFlag x
, "VictimActorId" .= #victimActorId x
, "AttackerVelocity" .= #attackerVelocity x
, "VictimVelocity" .= #victimVelocity x
]
ValueEnum x -> Aeson.object ["Value" .= #value x, "Flag" .= #flag x]
ValueExplosion x ->
Aeson.object
[ "Actorless" .= #actorless x
, "ActorId" .= #actorId x
, "Position" .= #position x
]
ValueFlaggedInt x -> Aeson.object ["Flag" .= #flag x, "Int" .= #int x]
ValueFloat x -> Aeson.toJSON (#unpack x)
ValueGameMode x ->
Aeson.object ["Id" .= #unpack x, "Name" .= getGameMode (#unpack x)]
ValueInt x -> Aeson.toJSON (#unpack x)
ValueLoadout x ->
Aeson.object
[ "Version" .= #version x
, "Body" .=
Aeson.object ["Id" .= #body x, "Name" .= getProduct (#body x)]
, "Decal" .=
Aeson.object ["Id" .= #decal x, "Name" .= getProduct (#decal x)]
, "Wheels" .=
Aeson.object ["Id" .= #wheels x, "Name" .= getProduct (#wheels x)]
, "RocketTrail" .=
Aeson.object
["Id" .= #rocketTrail x, "Name" .= getProduct (#rocketTrail x)]
, "Antenna" .=
Aeson.object ["Id" .= #antenna x, "Name" .= getProduct (#antenna x)]
, "Topper" .=
Aeson.object ["Id" .= #topper x, "Name" .= getProduct (#topper x)]
, "Unknown1" .= #unknown1 x
, "Unknown2" .= #unknown2 x
]
ValueLoadoutOnline x -> Aeson.toJSON (#unpack x)
ValueLocation x -> Aeson.toJSON (#unpack x)
ValueMusicStinger x ->
Aeson.object ["Flag" .= #flag x, "Cue" .= #cue x, "Trigger" .= #trigger x]
ValuePickup x ->
Aeson.object
[ "HasInstigator" .= #hasInstigator x
, "InstigatorId" .= #instigatorId x
, "PickedUp" .= #pickedUp x
]
ValuePrivateMatchSettings x ->
Aeson.object
[ "Mutators" .= #mutators x
, "JoinableBy" .= #joinableBy x
, "MaxPlayers" .= #maxPlayers x
, "Name" .= #gameName x
, "Password" .= #password x
, "Unknown" .= #flag x
]
ValueQWord x -> Aeson.toJSON (#unpack x)
ValueRelativeRotation x -> Aeson.toJSON (#unpack x)
ValueReservation x ->
Aeson.object
[ "Number" .= #number x
, "SystemId" .= #systemId x
, "RemoteId" .= #remoteId x
, "LocalId" .= #localId x
, "Name" .= #playerName x
, "Unknown1" .= #unknown1 x
, "Unknown2" .= #unknown2 x
]
ValueRigidBodyState x ->
Aeson.object
[ "Sleeping" .= #sleeping x
, "Position" .= #position x
, "Rotation" .= #rotation x
, "LinearVelocity" .= #linearVelocity x
, "AngularVelocity" .= #angularVelocity x
]
ValueString x -> Aeson.toJSON (#unpack x)
ValueTeamPaint x ->
Aeson.object
[ "Team" .= #team x
, "PrimaryColor" .= #primaryColor x
, "AccentColor" .= #accentColor x
, "PrimaryFinish" .=
Aeson.object
["Id" .= #primaryFinish x, "Name" .= getProduct (#primaryFinish x)]
, "AccentFinish" .=
Aeson.object
["Id" .= #accentFinish x, "Name" .= getProduct (#accentFinish x)]
]
ValueUniqueId x ->
Aeson.object
[ "System" .=
case #systemId x of
0 -> "Local"
1 -> "Steam"
2 -> "PlayStation"
4 -> "Xbox"
y -> "Unknown system " ++ show y
, "Remote" .= #remoteId x
, "Local" .= #localId x
]
getGameMode :: Word8.Word8 -> Maybe StrictText.Text
getGameMode x = Bimap.lookup (Word8.fromWord8 x) Data.gameModes
getProduct :: Word32.Word32 -> Maybe StrictText.Text
getProduct x = Bimap.lookup (Word32.fromWord32 x) Data.products