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:
Fate-JH 2019-08-21 10:36:56 -04:00 committed by GitHub
parent ad60b443e1
commit ef65c91740
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 621 additions and 158 deletions

View file

@ -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
)
)
}

View file

@ -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
)
}
)

View file

@ -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)
}
)
}

View file

@ -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)
}
)
}

View file

@ -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)
}
)
}

View file

@ -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

View file

@ -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)
}
)
}

View file

@ -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"))
}

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)