mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
fixed encodings on DetailedCharacterData, DetailedConstructionToolData, DroppodData, HandheldData, OMFTData, and REKData patterns; added a deprecated pattern for weapon data that permits no ammunition fields; adjusted relevant tests (#263)
This commit is contained in:
parent
ad60b443e1
commit
ef65c91740
|
|
@ -21,7 +21,8 @@ class ACEConverter extends ObjectCreateConverter[ConstructionItem]() {
|
|||
None,
|
||||
None,
|
||||
PlanetSideGUID(0)
|
||||
)
|
||||
),
|
||||
obj.FireModeIndex
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -39,7 +40,8 @@ class ACEConverter extends ObjectCreateConverter[ConstructionItem]() {
|
|||
None,
|
||||
None,
|
||||
PlanetSideGUID(0)
|
||||
)
|
||||
),
|
||||
obj.FireModeIndex
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ final case class ImplantEntry(implant : ImplantType.Value,
|
|||
|
||||
object ImplantEntry {
|
||||
def apply(implant : ImplantType.Value, initialization : Option[Int]) : ImplantEntry = {
|
||||
ImplantEntry(implant, initialization, false)
|
||||
ImplantEntry(implant, initialization, active = false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,11 +155,10 @@ final case class DetailedCharacterB(unk1 : Option[Long],
|
|||
0L
|
||||
}
|
||||
//character is at least BR24
|
||||
val br24 = DetailedCharacterData.isBR24(bep)
|
||||
val unk9Size : Long = if(br24) { 0L } else { 13L }
|
||||
val unk9Size : Long = if(unk9.isEmpty) { 0L } else { 13L }
|
||||
val unkASize : Long = unkA.length * 32L
|
||||
val unkBSize : Long = unkB.foldLeft(0L)(_ + StreamBitSize.stringBitSize(_))
|
||||
val cosmeticsSize : Long = if(br24) { cosmetics.get.bitsize } else { 0L }
|
||||
val cosmeticsSize : Long = if(DetailedCharacterData.isBR24(bep)) { cosmetics.get.bitsize } else { 0L }
|
||||
|
||||
val paddingSize : Int =
|
||||
DetailedCharacterData.paddingCalculations(pad_length, implants, Nil)(unk2Len) + /* unk2 */
|
||||
|
|
@ -214,7 +213,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
0L,
|
||||
0L,
|
||||
healthMax, health,
|
||||
false,
|
||||
unk4 = false,
|
||||
armor,
|
||||
0L,
|
||||
staminaMax, stamina,
|
||||
|
|
@ -240,10 +239,10 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
None,
|
||||
Nil,
|
||||
Nil,
|
||||
false,
|
||||
unkC = false,
|
||||
cosmetics
|
||||
)
|
||||
(pad_length : Option[Int]) => DetailedCharacterData(a, b(a.bep, pad_length))(pad_length)
|
||||
pad_length : Option[Int] => DetailedCharacterData(a, b(a.bep, pad_length))(pad_length)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -261,7 +260,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
ImplantEntry(ImplantType(implant), None, activeBool) //TODO catch potential NoSuchElementException?
|
||||
|
||||
case implant :: false :: extra :: HNil => //uninitialized (timer), inactive
|
||||
ImplantEntry(ImplantType(implant), Some(extra), false) //TODO catch potential NoSuchElementException?
|
||||
ImplantEntry(ImplantType(implant), Some(extra), active = false) //TODO catch potential NoSuchElementException?
|
||||
},
|
||||
{
|
||||
case ImplantEntry(implant, None, n) => //initialized (no timer), active/inactive?
|
||||
|
|
@ -298,7 +297,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
* `Codec` for a `List` of `DCDExtra1` objects.
|
||||
* The first entry contains a padded `String` so it must be processed different from the remainder.
|
||||
*/
|
||||
private def dcd_list_codec(padFunc : (Long)=>Int) : Codec[List[DCDExtra1]] = (
|
||||
private def dcd_list_codec(padFunc : Long=>Int) : Codec[List[DCDExtra1]] = (
|
||||
uint8 >>:~ { size =>
|
||||
conditional(size > 0, dcd_extra1_codec(padFunc(size))) ::
|
||||
PacketHelpers.listOfNSized(size - 1, dcd_extra1_codec(0))
|
||||
|
|
@ -344,7 +343,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
* The first entry contains a padded `String` so it must be processed different from the remainder.
|
||||
* @param padFunc a curried function awaiting the extracted length of the current `List`
|
||||
*/
|
||||
private def eventsListCodec(padFunc : (Long)=>Int) : Codec[List[String]] = (
|
||||
private def eventsListCodec(padFunc : Long=>Int) : Codec[List[String]] = (
|
||||
uint32L >>:~ { size =>
|
||||
conditional(size > 0, PacketHelpers.encodedStringAligned(padFunc(size))) ::
|
||||
PacketHelpers.listOfNSized(size - 1, PacketHelpers.encodedString)
|
||||
|
|
@ -382,7 +381,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
* @see `paddingCalculations`
|
||||
* @param padFunc a curried function awaiting the extracted length of the current `List` and will count the padding bits
|
||||
*/
|
||||
private def unkBCodec(padFunc : (Long)=>Int) : Codec[List[String]] = (
|
||||
private def unkBCodec(padFunc : Long=>Int) : Codec[List[String]] = (
|
||||
uint16L >>:~ { size =>
|
||||
conditional(size > 0, PacketHelpers.encodedStringAligned(padFunc(size))) ::
|
||||
PacketHelpers.listOfNSized(size - 1, PacketHelpers.encodedString)
|
||||
|
|
@ -405,7 +404,16 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
)
|
||||
|
||||
/**
|
||||
* Suport function that obtains the "absolute list value" of an `Option` object.
|
||||
* A `Codec[Boolean]` that parses a `1u` value according to a NOT truth table.
|
||||
* `0` is `true` and `1` is `false`.
|
||||
*/
|
||||
private val isFalse : Codec[Boolean] = bool.xmap[Boolean] (
|
||||
value => !value,
|
||||
value => !value
|
||||
)
|
||||
|
||||
/**
|
||||
* Support function that obtains the "absolute list value" of an `Option` object.
|
||||
* @param opt the `Option` object
|
||||
* @return if defined, returns a `List` of the `Option` object's contents;
|
||||
* if undefined (`None`), returns an empty list
|
||||
|
|
@ -577,19 +585,17 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
("unk6" | uint32L) ::
|
||||
("unk7" | uint32L) ::
|
||||
("unk8" | uint32L) ::
|
||||
(bool >>:~ { br24 => //BR24+
|
||||
conditional(!br24, "unk9" | dcd_extra2_codec) >>:~ { unk9 =>
|
||||
("unkA" | listOfN(uint16L, uint32L)) ::
|
||||
("unkB" | unkBCodec(
|
||||
paddingCalculations(
|
||||
displaceByUnk9(pad_length, unk9, 5),
|
||||
implants,
|
||||
List(optToList(unk9), tut, fte, unk3, unk2)
|
||||
)
|
||||
)) ::
|
||||
("unkC" | bool) ::
|
||||
conditional(br24, "cosmetics" | Cosmetics.codec)
|
||||
}
|
||||
(optional(isFalse, "unk9" | dcd_extra2_codec) >>:~ { unk9 =>
|
||||
("unkA" | listOfN(uint16L, uint32L)) ::
|
||||
("unkB" | unkBCodec(
|
||||
paddingCalculations(
|
||||
displaceByUnk9(pad_length, unk9, 5),
|
||||
implants,
|
||||
List(optToList(unk9), tut, fte, unk3, unk2)
|
||||
)
|
||||
)) ::
|
||||
("unkC" | bool) ::
|
||||
conditional(isBR24(bep), "cosmetics" | Cosmetics.codec)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -598,7 +604,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
})
|
||||
).exmap[DetailedCharacterB] (
|
||||
{
|
||||
case u1 :: implants :: u2 :: u3 :: fte :: tut :: u4 :: u5 :: u6 :: u7 :: u8 :: _ :: u9 :: uA :: uB :: uC :: cosmetics :: HNil =>
|
||||
case u1 :: implants :: u2 :: u3 :: fte :: tut :: u4 :: u5 :: u6 :: u7 :: u8 :: u9 :: uA :: uB :: uC :: cosmetics :: HNil =>
|
||||
Attempt.successful(
|
||||
DetailedCharacterB(u1, implants, u2, u3, fte, tut, u4, u5, u6, u7, u8, u9, uA, uB, uC, cosmetics)(bep, pad_length)
|
||||
)
|
||||
|
|
@ -612,10 +618,9 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
else {
|
||||
recursiveEnsureImplantSlots(implantCapacity, implants)
|
||||
}
|
||||
val br24 : Boolean = isBR24(bep)
|
||||
val cos : Option[Cosmetics] = if(br24) { cosmetics } else { None }
|
||||
val cos : Option[Cosmetics] = if(isBR24(bep)) { cosmetics } else { None }
|
||||
Attempt.successful(
|
||||
u1 :: implantList :: u2 :: u3 :: fte :: tut :: u4 :: u5 :: u6 :: u7 :: u8 :: br24 :: u9 :: uA :: uB :: uC :: cos :: HNil
|
||||
u1 :: implantList :: u2 :: u3 :: fte :: tut :: u4 :: u5 :: u6 :: u7 :: u8 :: u9 :: uA :: uB :: uC :: cos :: HNil
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,26 +11,29 @@ import shapeless.{::, HNil}
|
|||
* `DetailedBoomerTriggerData` - `data.faction` can be `NEUTRAL`, `data.unk1` is `true`
|
||||
* `DetailedTelepadData` - `data.faction` can be `NEUTRAL`, `data.jammered` is the router's GUID
|
||||
*/
|
||||
final case class DetailedConstructionToolData(data : CommonFieldData) extends ConstructorData {
|
||||
final case class DetailedConstructionToolData(data : CommonFieldData, mode : Int) extends ConstructorData {
|
||||
override def bitsize : Long = 28L + data.bitsize
|
||||
}
|
||||
|
||||
object DetailedConstructionToolData extends Marshallable[DetailedConstructionToolData] {
|
||||
def apply(data : CommonFieldData) : DetailedConstructionToolData = DetailedConstructionToolData(data, 0)
|
||||
|
||||
implicit val codec : Codec[DetailedConstructionToolData] = (
|
||||
("data" | CommonFieldData.codec(false)) ::
|
||||
uint8 ::
|
||||
uint(18) ::
|
||||
("mode" | uint16) ::
|
||||
uint2 ::
|
||||
uint2
|
||||
).exmap[DetailedConstructionToolData] (
|
||||
{
|
||||
case data :: 1 :: 1 :: _ :: HNil =>
|
||||
Attempt.successful(DetailedConstructionToolData(data))
|
||||
case data :: 1 :: mode :: 1 :: _ :: HNil =>
|
||||
Attempt.successful(DetailedConstructionToolData(data, mode))
|
||||
case data =>
|
||||
Attempt.failure(Err(s"invalid detailed construction tool data format - $data"))
|
||||
},
|
||||
{
|
||||
case DetailedConstructionToolData(data) =>
|
||||
Attempt.successful(data :: 1 :: 1 :: 0 :: HNil)
|
||||
case DetailedConstructionToolData(data, mode) =>
|
||||
Attempt.successful(data :: 1 :: mode :: 1 :: 0 :: HNil)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,14 +26,15 @@ import shapeless.{::, HNil}
|
|||
* When `basic.player_guid` is defined, the droppod will not be at the world ceiling anymore and its boosters will be activate.
|
||||
* Does this `basic.player_guid` actually represent the player who is in the pod?
|
||||
* @param basic data common to objects
|
||||
* @param burn whether the boosters are ignited
|
||||
* @param health the amount of health the object has, as a percentage of a filled bar
|
||||
* @param burn whether the boosters are ignited
|
||||
* @see `DroppodLaunchRequestMessage`
|
||||
* @see `DroppodLaunchResponseMessage`
|
||||
*/
|
||||
final case class DroppodData(basic : CommonFieldDataWithPlacement,
|
||||
burn : Boolean = false,
|
||||
health : Int = 255
|
||||
health : Int,
|
||||
burn : Boolean,
|
||||
unk : Boolean
|
||||
) extends ConstructorData {
|
||||
override def bitsize : Long = {
|
||||
val basicSize = basic.bitsize
|
||||
|
|
@ -42,6 +43,8 @@ final case class DroppodData(basic : CommonFieldDataWithPlacement,
|
|||
}
|
||||
|
||||
object DroppodData extends Marshallable[DroppodData] {
|
||||
def apply(basic : CommonFieldDataWithPlacement) : DroppodData = DroppodData(basic, 255, burn = false, unk = false)
|
||||
|
||||
implicit val codec : Codec[DroppodData] = (
|
||||
("basic" | CommonFieldDataWithPlacement.codec) ::
|
||||
bool ::
|
||||
|
|
@ -50,20 +53,20 @@ object DroppodData extends Marshallable[DroppodData] {
|
|||
uint4L :: //0xF
|
||||
uintL(6) :: //0x0
|
||||
("boosters" | uint4L) :: //0x9 on standby, 0x0 when burning and occupied (basic.player_guid?)
|
||||
bool
|
||||
("unk" | bool)
|
||||
).exmap[DroppodData] (
|
||||
{
|
||||
case basic :: false :: health :: 0 :: 0xF :: 0 :: boosters :: false :: HNil =>
|
||||
case basic :: false :: health :: 0 :: 0xF :: 0 :: boosters :: unk :: HNil =>
|
||||
val burn : Boolean = boosters == 0
|
||||
Attempt.successful(DroppodData(basic, burn, health))
|
||||
Attempt.successful(DroppodData(basic, health, burn, unk))
|
||||
|
||||
case data =>
|
||||
Attempt.failure(Err(s"invalid droppod data format - $data"))
|
||||
},
|
||||
{
|
||||
case DroppodData(basic, burn, health) =>
|
||||
case DroppodData(basic, health, burn, unk) =>
|
||||
val boosters : Int = if(burn) { 0 } else { 9 }
|
||||
Attempt.successful(basic :: false :: health :: 0 :: 0xF :: 0 :: boosters :: false :: HNil)
|
||||
Attempt.successful(basic :: false :: health :: 0 :: 0xF :: 0 :: boosters :: unk :: HNil)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,29 +18,34 @@ import shapeless.{::, HNil}
|
|||
* - v4 - not used, i.e., the simple format `CommonFieldData` object is employed
|
||||
* - v5 - for the telepad, this field is expected to be the GUID of the associated Router
|
||||
*/
|
||||
final case class HandheldData(data : CommonFieldData) extends ConstructorData {
|
||||
final case class HandheldData(data : CommonFieldData,
|
||||
mode : Int,
|
||||
unk : Int) extends ConstructorData {
|
||||
override def bitsize : Long = {
|
||||
11L + data.bitsize
|
||||
}
|
||||
}
|
||||
|
||||
object HandheldData extends Marshallable[HandheldData] {
|
||||
def apply(data : CommonFieldData) : HandheldData = HandheldData(data, 0, 0)
|
||||
|
||||
def apply(data : CommonFieldData, mode : Int) : HandheldData = HandheldData(data, mode, 0)
|
||||
|
||||
implicit val codec : Codec[HandheldData] = (
|
||||
("data" | CommonFieldData.codec) ::
|
||||
uint4 ::
|
||||
uint4 ::
|
||||
uint(3)
|
||||
("mode" | uint8) ::
|
||||
("unk" | uint(3))
|
||||
).exmap[HandheldData] (
|
||||
{
|
||||
case data :: 0 :: 0 :: 0 :: HNil =>
|
||||
Attempt.successful(HandheldData(data))
|
||||
case data :: mode :: unk :: HNil =>
|
||||
Attempt.successful(HandheldData(data, mode, unk))
|
||||
|
||||
case data =>
|
||||
Attempt.failure(Err(s"invalid handheld tool data format - $data"))
|
||||
},
|
||||
{
|
||||
case HandheldData(data) =>
|
||||
Attempt.successful(data :: 0 :: 0 :: 0 :: HNil)
|
||||
case HandheldData(data, mode, unk) =>
|
||||
Attempt.successful(data :: mode :: unk :: HNil)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,84 +48,6 @@ object OneMannedFieldTurretData extends Marshallable[OneMannedFieldTurretData] {
|
|||
def apply(deploy : CommonFieldDataWithPlacement, health : Int, internals : InventoryData) : OneMannedFieldTurretData =
|
||||
new OneMannedFieldTurretData(deploy, health, Some(internals))
|
||||
|
||||
// /**
|
||||
// * Prefabricated weapon data for a weaponless field turret mount (`portable_manned_turret`).
|
||||
// * @param wep_guid the uid to assign to the weapon
|
||||
// * @param wep_unk1 na;
|
||||
// * used by `WeaponData`
|
||||
// *
|
||||
// * @param wep_unk2 na;
|
||||
// * used by `WeaponData`
|
||||
// * @param ammo_guid the uid to assign to the ammo
|
||||
// * @param ammo_unk na;
|
||||
// * used by `AmmoBoxData`
|
||||
// * @return an `InternalSlot` object
|
||||
// */
|
||||
// def generic(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
|
||||
// InternalSlot(ObjectClass.energy_gun, wep_guid, 1,
|
||||
// WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
|
||||
// CommonFieldData(PlanetSideEmpire.NEUTRAL, ammo_unk(false)
|
||||
// )
|
||||
// )
|
||||
//
|
||||
// /**
|
||||
// * Prefabricated weapon data for the Terran Republic field turret, the Avenger (`portable_manned_turret_tr`).
|
||||
// * @param wep_guid the uid to assign to the weapon
|
||||
// * @param wep_unk1 na;
|
||||
// * used by `WeaponData`
|
||||
// *
|
||||
// * @param wep_unk2 na;
|
||||
// * used by `WeaponData`
|
||||
// * @param ammo_guid the uid to assign to the ammo
|
||||
// * @param ammo_unk na;
|
||||
// * used by `AmmoBoxData`
|
||||
// * @return an `InternalSlot` object
|
||||
// */
|
||||
// def avenger(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
|
||||
// InternalSlot(ObjectClass.energy_gun_tr, wep_guid, 1,
|
||||
// WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
|
||||
// CommonFieldData(PlanetSideEmpire.NEUTRAL, ammo_unk(false)
|
||||
// )
|
||||
// )
|
||||
//
|
||||
// /**
|
||||
// * Prefabricated weapon data for the New Conglomerate field turret, the Osprey (`portable_manned_turret_vnc`).
|
||||
// * @param wep_guid the uid to assign to the weapon
|
||||
// * @param wep_unk1 na;
|
||||
// * used by `WeaponData`
|
||||
// * @param wep_unk2 na;
|
||||
// * used by `WeaponData`
|
||||
// * @param ammo_guid the uid to assign to the ammo
|
||||
// * @param ammo_unk na;
|
||||
// * used by `AmmoBoxData`
|
||||
// * @return an `InternalSlot` object
|
||||
// */
|
||||
// def osprey(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
|
||||
// InternalSlot(ObjectClass.energy_gun_nc, wep_guid, 1,
|
||||
// WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
|
||||
// CommonFieldData(PlanetSideEmpire.NEUTRAL, ammo_unk(false)
|
||||
// )
|
||||
// )
|
||||
//
|
||||
// /**
|
||||
// * Prefabricated weapon data for the Vanu Soveriegnty field turret, the Orion (`portable_manned_turret_vs`).
|
||||
// * @param wep_guid the uid to assign to the weapon
|
||||
// * @param wep_unk1 na;
|
||||
// * used by `WeaponData`
|
||||
// * @param wep_unk2 na;
|
||||
// * used by `WeaponData`
|
||||
// * @param ammo_guid the uid to assign to the ammo
|
||||
// * @param ammo_unk na;
|
||||
// * used by `AmmoBoxData`
|
||||
// * @return an `InternalSlot` object
|
||||
// */
|
||||
// def orion(wep_guid : PlanetSideGUID, wep_unk1 : Int, wep_unk2 : Int, ammo_guid : PlanetSideGUID, ammo_unk : Int) : InternalSlot =
|
||||
// InternalSlot(ObjectClass.energy_gun_vs, wep_guid, 1,
|
||||
// WeaponData(wep_unk1, wep_unk2, ObjectClass.energy_gun_ammo, ammo_guid, 0,
|
||||
// CommonFieldData(PlanetSideEmpire.NEUTRAL, ammo_unk(false)
|
||||
// )
|
||||
// )
|
||||
|
||||
implicit val codec : Codec[OneMannedFieldTurretData] = (
|
||||
("deploy" | CommonFieldDataWithPlacement.codec2) ::
|
||||
PlanetSideGUID.codec :: //hoist/extract with the deploy.owner_guid in field above
|
||||
|
|
|
|||
|
|
@ -9,32 +9,34 @@ import shapeless.{::, HNil}
|
|||
/**
|
||||
* na
|
||||
* @param data na
|
||||
* @param unk na;
|
||||
* @param unk1 na;
|
||||
* defaults to 0
|
||||
* @see `DetailedREKData`
|
||||
*/
|
||||
final case class REKData(data : CommonFieldData,
|
||||
unk : Int = 0
|
||||
unk1 : Int,
|
||||
unk2 : Int
|
||||
) extends ConstructorData {
|
||||
override def bitsize : Long = 50L
|
||||
}
|
||||
|
||||
object REKData extends Marshallable[REKData] {
|
||||
def apply(data : CommonFieldData) : REKData = REKData(data, 0, 0)
|
||||
|
||||
implicit val codec : Codec[REKData] = (
|
||||
("data" | CommonFieldData.codec2) ::
|
||||
uint8 ::
|
||||
("unk" | uint8) ::
|
||||
uint(10)
|
||||
("unk1" | uint16) ::
|
||||
("unk2" | uint(10))
|
||||
).exmap[REKData] (
|
||||
{
|
||||
case data :: 0 :: unk :: 0 :: HNil =>
|
||||
Attempt.successful(REKData(data, unk))
|
||||
case data :: u1 :: u2 :: HNil =>
|
||||
Attempt.successful(REKData(data, u1, u2))
|
||||
case data =>
|
||||
Attempt.failure(Err(s"invalid rek data format - $data"))
|
||||
},
|
||||
{
|
||||
case REKData(data, unk) =>
|
||||
Attempt.successful(data :: 0 :: unk :: 0 :: HNil)
|
||||
case REKData(data, u1, u2) =>
|
||||
Attempt.successful(data :: u1 :: u2 :: HNil)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,9 @@ object WeaponData extends Marshallable[WeaponData] {
|
|||
else {
|
||||
Attempt.successful(WeaponData(data, fmode, ammo, unk))
|
||||
}
|
||||
|
||||
case data :: fmode :: false :: None :: unk :: HNil =>
|
||||
//rare pass condition, usually found in LockerContainer objects or temporarily existing as a dropped item
|
||||
Attempt.successful(WeaponData(data, fmode, Nil, unk))
|
||||
case data =>
|
||||
Attempt.failure(Err(s"invalid weapon data format - $data"))
|
||||
},
|
||||
|
|
@ -159,7 +161,6 @@ object WeaponData extends Marshallable[WeaponData] {
|
|||
else {
|
||||
Attempt.successful(data :: fmode :: false :: Some(InventoryData(ammo)) :: unk :: HNil)
|
||||
}
|
||||
|
||||
case _ =>
|
||||
Attempt.failure(Err("invalid weapon data format"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class HandheldDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(3336)
|
||||
parent.get.slot mustEqual 0
|
||||
data match {
|
||||
case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
|
||||
case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), mode, unk) =>
|
||||
faction mustEqual PlanetSideEmpire.NC
|
||||
bops mustEqual false
|
||||
alternate mustEqual false
|
||||
|
|
@ -50,7 +50,7 @@ class HandheldDataTest extends Specification {
|
|||
parent.isDefined mustEqual false
|
||||
data.isInstanceOf[DroppedItemData[_]] mustEqual true
|
||||
data match {
|
||||
case DroppedItemData(pos, HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid))) =>
|
||||
case DroppedItemData(pos, HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), mode, unk)) =>
|
||||
pos.coord mustEqual Vector3(4708.461f, 5547.539f, 72.703125f)
|
||||
pos.orient mustEqual Vector3.z(194.0625f)
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ class HandheldDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(430)
|
||||
parent.get.slot mustEqual 0
|
||||
data match {
|
||||
case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
|
||||
case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), mode, unk) =>
|
||||
faction mustEqual PlanetSideEmpire.TR
|
||||
bops mustEqual false
|
||||
alternate mustEqual false
|
||||
|
|
@ -142,7 +142,7 @@ class HandheldDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(4272)
|
||||
parent.get.slot mustEqual 0
|
||||
data match {
|
||||
case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
|
||||
case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), mode, unk) =>
|
||||
faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
bops mustEqual false
|
||||
alternate mustEqual false
|
||||
|
|
@ -182,7 +182,7 @@ class HandheldDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(4149)
|
||||
parent.get.slot mustEqual 0
|
||||
data match {
|
||||
case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid)) =>
|
||||
case HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), mode, unk) =>
|
||||
faction mustEqual PlanetSideEmpire.NC
|
||||
bops mustEqual false
|
||||
alternate mustEqual false
|
||||
|
|
@ -208,7 +208,7 @@ class HandheldDataTest extends Specification {
|
|||
guid mustEqual PlanetSideGUID(3682)
|
||||
parent.isDefined mustEqual false
|
||||
data match {
|
||||
case DroppedItemData(pos, HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid))) =>
|
||||
case DroppedItemData(pos, HandheldData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), mode, unk)) =>
|
||||
pos.coord mustEqual Vector3(4777.633f, 5485.4062f, 85.8125f)
|
||||
pos.orient mustEqual Vector3.z(14.0625f)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class REKDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(4174)
|
||||
parent.get.slot mustEqual 0
|
||||
data match {
|
||||
case REKData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), unk) =>
|
||||
case REKData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), unk1, unk2) =>
|
||||
faction mustEqual PlanetSideEmpire.TR
|
||||
bops mustEqual false
|
||||
alternate mustEqual false
|
||||
|
|
@ -33,7 +33,8 @@ class REKDataTest extends Specification {
|
|||
v4.contains(false) mustEqual true
|
||||
v5.isEmpty mustEqual true
|
||||
fguid mustEqual PlanetSideGUID(0)
|
||||
unk mustEqual 0
|
||||
unk1 mustEqual 0
|
||||
unk2 mustEqual 0
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -50,7 +51,7 @@ class REKDataTest extends Specification {
|
|||
guid mustEqual PlanetSideGUID(4355)
|
||||
parent.isDefined mustEqual false
|
||||
data match {
|
||||
case DroppedItemData(pos, REKData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), unk)) =>
|
||||
case DroppedItemData(pos, REKData(CommonFieldData(faction, bops, alternate, v1, v2, v3, v4, v5, fguid), unk1, unk2)) =>
|
||||
pos.coord mustEqual Vector3(4675.039f, 5506.953f, 72.703125f)
|
||||
pos.orient mustEqual Vector3.z(230.625f)
|
||||
|
||||
|
|
@ -64,7 +65,8 @@ class REKDataTest extends Specification {
|
|||
v5.isEmpty mustEqual true
|
||||
fguid mustEqual PlanetSideGUID(0)
|
||||
|
||||
unk mustEqual 3
|
||||
unk1 mustEqual 3
|
||||
unk2 mustEqual 0
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
|
@ -83,7 +85,7 @@ class REKDataTest extends Specification {
|
|||
"encode (dropped)" in {
|
||||
val obj = DroppedItemData(
|
||||
PlacementData(4675.039f, 5506.953f, 72.703125f, 0f, 0f, 230.625f),
|
||||
REKData(CommonFieldData(PlanetSideEmpire.VS, false, false, false, None, false, Some(false), None, PlanetSideGUID(0)), 3)
|
||||
REKData(CommonFieldData(PlanetSideEmpire.VS, false, false, false, None, false, Some(false), None, PlanetSideGUID(0)), 3, 0)
|
||||
)
|
||||
val msg = ObjectCreateMessage(ObjectClass.remote_electronics_kit, PlanetSideGUID(4355), obj)
|
||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -25,7 +25,7 @@ class DetailedConstructionToolDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(3104)
|
||||
parent.get.slot mustEqual 0
|
||||
data match {
|
||||
case DetailedConstructionToolData(cdata) =>
|
||||
case DetailedConstructionToolData(cdata, mode) =>
|
||||
cdata.faction mustEqual PlanetSideEmpire.VS
|
||||
cdata.bops mustEqual false
|
||||
cdata.alternate mustEqual false
|
||||
|
|
@ -65,7 +65,7 @@ class DetailedConstructionToolDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(2502)
|
||||
parent.get.slot mustEqual 0
|
||||
data match {
|
||||
case DetailedConstructionToolData(cdata) =>
|
||||
case DetailedConstructionToolData(cdata, mode) =>
|
||||
cdata.faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
cdata.bops mustEqual false
|
||||
cdata.alternate mustEqual false
|
||||
|
|
@ -105,7 +105,7 @@ class DetailedConstructionToolDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(414)
|
||||
parent.get.slot mustEqual 0
|
||||
data match {
|
||||
case DetailedConstructionToolData(cdata) =>
|
||||
case DetailedConstructionToolData(cdata, mode) =>
|
||||
cdata.faction mustEqual PlanetSideEmpire.NC
|
||||
cdata.bops mustEqual false
|
||||
cdata.alternate mustEqual false
|
||||
|
|
@ -133,7 +133,7 @@ class DetailedConstructionToolDataTest extends Specification {
|
|||
parent.get.guid mustEqual PlanetSideGUID(340)
|
||||
parent.get.slot mustEqual 9
|
||||
data match {
|
||||
case DetailedConstructionToolData(cdata) =>
|
||||
case DetailedConstructionToolData(cdata, mode) =>
|
||||
cdata.faction mustEqual PlanetSideEmpire.VS
|
||||
cdata.bops mustEqual false
|
||||
cdata.alternate mustEqual false
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class NonstandardVehiclesTest extends Specification {
|
|||
guid mustEqual PlanetSideGUID(3595)
|
||||
parent.isDefined mustEqual false
|
||||
data match {
|
||||
case DroppodData(basic, burn, health) =>
|
||||
case DroppodData(basic, health, burn, unk) =>
|
||||
basic.pos.coord mustEqual Vector3(5108.0f, 6164.0f, 1023.9844f)
|
||||
basic.pos.orient mustEqual Vector3.z(90.0f)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue